This set does the Delete All button in a different way, as well as fix up some small unrelated problems with the dialog.
Please see:
http://clumens.fedorapeople.org/resize-1.png http://clumens.fedorapeople.org/resize-2.png http://clumens.fedorapeople.org/resize-3.png
- Chris
This allows for clearing all editable disks in one button click. It is positioned on the far right of the list of action buttons and schedules a delete action for all disks. Should you later wish to undo this action, the button will also do a preserve all.
This also required moving the shrink slider down. --- pyanaconda/ui/gui/spokes/lib/resize.glade | 50 ++++++++++++++++++++----------- pyanaconda/ui/gui/spokes/lib/resize.py | 39 ++++++++++++++++++------ 2 files changed, 63 insertions(+), 26 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/lib/resize.glade b/pyanaconda/ui/gui/spokes/lib/resize.glade index 3a4c5eb..bd6cdd4 100644 --- a/pyanaconda/ui/gui/spokes/lib/resize.glade +++ b/pyanaconda/ui/gui/spokes/lib/resize.glade @@ -53,13 +53,13 @@ <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> - <property name="halign">end</property> <property name="use_stock">True</property> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> <property name="position">0</property> + <property name="non_homogeneous">True</property> </packing> </child> <child> @@ -69,14 +69,14 @@ <property name="sensitive">False</property> <property name="can_focus">True</property> <property name="receives_default">True</property> - <property name="halign">end</property> <property name="use_underline">True</property> <signal name="clicked" handler="on_resize_clicked" swapped="no"/> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="position">1</property> + <property name="position">2</property> + <property name="non_homogeneous">True</property> </packing> </child> </object> @@ -213,6 +213,7 @@ <object class="GtkBox" id="box2"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="margin_top">6</property> <child> <object class="GtkButton" id="preserveButton"> <property name="label" translatable="yes">_Preserve</property> @@ -247,7 +248,7 @@ </child> <child> <object class="GtkButton" id="shrinkButton"> - <property name="label" translatable="yes">_Shrink to</property> + <property name="label" translatable="yes">_Shrink</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> @@ -262,20 +263,18 @@ </packing> </child> <child> - <object class="GtkScale" id="resizeSlider"> + <object class="GtkButton" id="deleteAllButton"> + <property name="label" translatable="yes">Delete _all</property> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="margin_left">12</property> - <property name="margin_right">12</property> - <property name="adjustment">resizeAdjustment</property> - <property name="round_digits">1</property> - <property name="digits">0</property> - <signal name="format-value" handler="resize_slider_format" swapped="no"/> - <signal name="value-changed" handler="on_resize_value_changed" swapped="no"/> + <property name="receives_default">True</property> + <property name="use_underline">True</property> + <signal name="clicked" handler="on_delete_all_clicked" swapped="no"/> </object> <packing> - <property name="expand">True</property> + <property name="expand">False</property> <property name="fill">True</property> + <property name="pack_type">end</property> <property name="position">3</property> </packing> </child> @@ -287,6 +286,23 @@ </packing> </child> <child> + <object class="GtkScale" id="resizeSlider"> + <property name="can_focus">True</property> + <property name="no_show_all">True</property> + <property name="margin_bottom">12</property> + <property name="adjustment">resizeAdjustment</property> + <property name="round_digits">0</property> + <property name="digits">0</property> + <signal name="format-value" handler="resize_slider_format" swapped="no"/> + <signal name="value-changed" handler="on_resize_value_changed" swapped="no"/> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">4</property> + </packing> + </child> + <child> <object class="GtkLabel" id="reclaimableSpaceLabel"> <property name="visible">True</property> <property name="can_focus">False</property> @@ -298,7 +314,7 @@ <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="position">4</property> + <property name="position">5</property> </packing> </child> <child> @@ -313,7 +329,7 @@ <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="position">5</property> + <property name="position">6</property> </packing> </child> <child> @@ -328,7 +344,7 @@ <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="position">6</property> + <property name="position">7</property> </packing> </child> </object> @@ -342,7 +358,7 @@ </child> <action-widgets> <action-widget response="0">cancelButton</action-widget> - <action-widget response="1">resizeButton</action-widget> + <action-widget response="2">resizeButton</action-widget> </action-widgets> </object> </interface> diff --git a/pyanaconda/ui/gui/spokes/lib/resize.py b/pyanaconda/ui/gui/spokes/lib/resize.py index 30518aa..2df4c59 100644 --- a/pyanaconda/ui/gui/spokes/lib/resize.py +++ b/pyanaconda/ui/gui/spokes/lib/resize.py @@ -317,18 +317,18 @@ class ResizeDialog(GUIObject): return False
def on_preserve_clicked(self, button): - self._actionChanged(PRESERVE) + (model, itr) = self.builder.get_object("diskView-selection").get_selected() + self._actionChanged(itr, PRESERVE)
def on_shrink_clicked(self, button): - self._actionChanged(SHRINK) + (model, itr) = self.builder.get_object("diskView-selection").get_selected() + self._actionChanged(itr, SHRINK)
def on_delete_clicked(self, button): - self._actionChanged(DELETE) - - def _actionChanged(self, newAction): - selection = self.builder.get_object("diskView-selection") - (model, itr) = selection.get_selected() + (model, itr) = self.builder.get_object("diskView-selection").get_selected() + self._actionChanged(itr, DELETE)
+ def _actionChanged(self, itr, newAction): if not itr: return
@@ -340,7 +340,7 @@ class ResizeDialog(GUIObject): # it contains. device = self.storage.devicetree.getDeviceByID(selectedRow[DEVICE_ID_COL]) if device.isDisk and device.partitioned: - partItr = model.iter_children(itr) + partItr = self._diskStore.iter_children(itr) while partItr: self._diskStore[partItr][ACTION_COL] = _(newAction)
@@ -352,7 +352,7 @@ class ResizeDialog(GUIObject): part = self.storage.devicetree.getDeviceByID(self._diskStore[partItr][DEVICE_ID_COL]) self._diskStore[partItr][EDITABLE_COL] = not part.protected
- partItr = model.iter_next(partItr) + partItr = self._diskStore.iter_next(partItr)
# And then we're keeping a running tally of how much space the user # has selected to reclaim, so reflect that in the UI. @@ -386,6 +386,27 @@ class ResizeDialog(GUIObject): def on_resize_clicked(self, *args): self._diskStore.foreach(self._scheduleActions, None)
+ def on_delete_all_clicked(self, button, *args): + if button.get_label() == _("Delete _all"): + action = DELETE + button.set_label(_("Preserve _all")) + else: + action = PRESERVE + button.set_label(_("Delete _all")) + + itr = self._diskStore.get_iter_first() + while itr: + if not self._diskStore[itr][EDITABLE_COL]: + itr = self._diskStore.iter_next(itr) + continue + + (ident, ) = self._diskStore.get(itr, DEVICE_ID_COL) + device = self.storage.devicetree.getDeviceByID(ident) + if device.isDisk: + self._actionChanged(itr, action) + + itr = self._diskStore.iter_next(itr) + def on_row_clicked(self, view, path, column): # This handles when the user clicks on a row in the view. We use it # only for expanding/collapsing disk headers.
On Tue, 2013-06-04 at 13:27 -0400, Chris Lumens wrote:
This allows for clearing all editable disks in one button click. It is positioned on the far right of the list of action buttons and schedules a delete action for all disks. Should you later wish to undo this action, the button will also do a preserve all.
This also required moving the shrink slider down.
pyanaconda/ui/gui/spokes/lib/resize.glade | 50 ++++++++++++++++++++----------- pyanaconda/ui/gui/spokes/lib/resize.py | 39 ++++++++++++++++++------ 2 files changed, 63 insertions(+), 26 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/lib/resize.py b/pyanaconda/ui/gui/spokes/lib/resize.py index 30518aa..2df4c59 100644 --- a/pyanaconda/ui/gui/spokes/lib/resize.py +++ b/pyanaconda/ui/gui/spokes/lib/resize.py @@ -317,18 +317,18 @@ class ResizeDialog(GUIObject): return False
def on_preserve_clicked(self, button):
self._actionChanged(PRESERVE)
(model, itr) = self.builder.get_object("diskView-selection").get_selected()
self._actionChanged(itr, PRESERVE)
def on_shrink_clicked(self, button):
self._actionChanged(SHRINK)
(model, itr) = self.builder.get_object("diskView-selection").get_selected()
self._actionChanged(itr, SHRINK)
def on_delete_clicked(self, button):
self._actionChanged(DELETE)
- def _actionChanged(self, newAction):
selection = self.builder.get_object("diskView-selection")
(model, itr) = selection.get_selected()
(model, itr) = self.builder.get_object("diskView-selection").get_selected()
self._actionChanged(itr, DELETE)
I think the "diskView-selection" widget should be pulled once and stored as e.g. "self._viewSelection". If nothing else, in case of changing the widget's ID in the .glade file, it won't require a change in multiple places.
- def _actionChanged(self, itr, newAction): if not itr: return
@@ -340,7 +340,7 @@ class ResizeDialog(GUIObject): # it contains. device = self.storage.devicetree.getDeviceByID(selectedRow[DEVICE_ID_COL]) if device.isDisk and device.partitioned:
partItr = model.iter_children(itr)
partItr = self._diskStore.iter_children(itr) while partItr: self._diskStore[partItr][ACTION_COL] = _(newAction)
@@ -352,7 +352,7 @@ class ResizeDialog(GUIObject): part = self.storage.devicetree.getDeviceByID(self._diskStore[partItr][DEVICE_ID_COL]) self._diskStore[partItr][EDITABLE_COL] = not part.protected
partItr = model.iter_next(partItr)
partItr = self._diskStore.iter_next(partItr) # And then we're keeping a running tally of how much space the user # has selected to reclaim, so reflect that in the UI.
@@ -386,6 +386,27 @@ class ResizeDialog(GUIObject): def on_resize_clicked(self, *args): self._diskStore.foreach(self._scheduleActions, None)
- def on_delete_all_clicked(self, button, *args):
if button.get_label() == _("Delete _all"):
action = DELETE
button.set_label(_("Preserve _all"))
else:
action = PRESERVE
button.set_label(_("Delete _all"))
itr = self._diskStore.get_iter_first()
while itr:
if not self._diskStore[itr][EDITABLE_COL]:
itr = self._diskStore.iter_next(itr)
continue
(ident, ) = self._diskStore.get(itr, DEVICE_ID_COL)
Is there any particular reason for using 'get' instead of [itr][DEVICE_ID_COL]?
I think the "diskView-selection" widget should be pulled once and stored as e.g. "self._viewSelection". If nothing else, in case of changing the widget's ID in the .glade file, it won't require a change in multiple places.
Yeah, good idea. The number of times I was grabbing that got away from me. Fixed locally.
Is there any particular reason for using 'get' instead of [itr][DEVICE_ID_COL]?
.get was already in use elsewhere in the file, and it seemed like a good idea at the time. Patch #3 gets rid of this, though. I can clean it up in git history if you really care.
- Chris
On Fri, 2013-06-07 at 13:48 -0400, Chris Lumens wrote:
I think the "diskView-selection" widget should be pulled once and stored as e.g. "self._viewSelection". If nothing else, in case of changing the widget's ID in the .glade file, it won't require a change in multiple places.
Yeah, good idea. The number of times I was grabbing that got away from me. Fixed locally.
Is there any particular reason for using 'get' instead of [itr][DEVICE_ID_COL]?
.get was already in use elsewhere in the file, and it seemed like a good idea at the time. Patch #3 gets rid of this, though. I can clean it up in git history if you really care.
Ah,I've overlooked that. No problem than. Thanks.
For shrunk filesystems, the amount of free space made was not being reflected after the user clicked on a different partition. --- pyanaconda/ui/gui/spokes/lib/resize.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/lib/resize.py b/pyanaconda/ui/gui/spokes/lib/resize.py index 2df4c59..1ec737a 100644 --- a/pyanaconda/ui/gui/spokes/lib/resize.py +++ b/pyanaconda/ui/gui/spokes/lib/resize.py @@ -432,16 +432,19 @@ class ResizeDialog(GUIObject): selection = self.builder.get_object("diskView-selection") (model, itr) = selection.get_selected()
+ old_delta = rng.get_adjustment().get_upper()-model[itr][RESIZE_TARGET_COL] + self._selectedReclaimableSpace -= old_delta + # Update the target size in the store. model[itr][RESIZE_TARGET_COL] = rng.get_value()
# Update the "Total selected space" label. delta = rng.get_adjustment().get_upper()-rng.get_value() - self._update_labels(selectedReclaimable=self._selectedReclaimableSpace+delta) + self._selectedReclaimableSpace += delta + self._update_labels(selectedReclaimable=self._selectedReclaimableSpace)
# And then the reclaim button, in case they've made enough space. - newTotal = self._selectedReclaimableSpace + delta - self._update_reclaim_button(Size(spec="%s MB" % newTotal)) + self._update_reclaim_button(Size(spec="%s MB" % self._selectedReclaimableSpace))
def resize_slider_format(self, scale, value): # This makes the value displayed under the slider prettier than just a
--- pyanaconda/ui/gui/spokes/lib/resize.py | 59 ++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 27 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/lib/resize.py b/pyanaconda/ui/gui/spokes/lib/resize.py index 1ec737a..a44db64 100644 --- a/pyanaconda/ui/gui/spokes/lib/resize.py +++ b/pyanaconda/ui/gui/spokes/lib/resize.py @@ -20,6 +20,7 @@ #
from __future__ import division +from collections import namedtuple
# pylint: disable-msg=E0611 from gi.repository import Gdk, Gtk @@ -41,6 +42,10 @@ TOOLTIP_COL = 6 RESIZE_TARGET_COL = 7 NAME_COL = 8
+PartStoreRow = namedtuple("PartStoreRow", ["id", "desc", "fs", "reclaimable", + "action", "editable", "tooltip", + "target", "name"]) + PRESERVE = N_("Preserve") SHRINK = N_("Shrink") DELETE = N_("Delete") @@ -239,32 +244,33 @@ class ResizeDialog(GUIObject): self._resizeSlider.add_mark(device.size, Gtk.PositionType.BOTTOM, size_str(device.size))
def _update_action_buttons(self, row): - device = self.storage.devicetree.getDeviceByID(row[DEVICE_ID_COL]) + obj = PartStoreRow._make(row) + device = self.storage.devicetree.getDeviceByID(obj.id)
# Disks themselves may be editable in certain ways, but they are never # shrinkable. - self._preserveButton.set_sensitive(row[EDITABLE_COL]) - self._shrinkButton.set_sensitive(row[EDITABLE_COL] and not device.isDisk) - self._deleteButton.set_sensitive(row[EDITABLE_COL]) + self._preserveButton.set_sensitive(obj.editable) + self._shrinkButton.set_sensitive(obj.editable and not device.isDisk) + self._deleteButton.set_sensitive(obj.editable) self._resizeSlider.set_visible(False)
- if not row[EDITABLE_COL]: + if not obj.editable: return
# If the selected filesystem does not support shrinking, make that # button insensitive. self._shrinkButton.set_sensitive(device.resizable)
- self._setup_slider(device, row[RESIZE_TARGET_COL]) + self._setup_slider(device, obj.target)
# Then, disable the button for whatever action is currently selected. # It doesn't make a lot of sense to allow clicking that. - if row[ACTION_COL] == _(PRESERVE): + if obj.action == _(PRESERVE): self._preserveButton.set_sensitive(False) - elif row[ACTION_COL] == _(SHRINK): + elif obj.action == _(SHRINK): self._shrinkButton.set_sensitive(False) self._resizeSlider.set_visible(True) - elif row[ACTION_COL] == _(DELETE): + elif obj.action == _(DELETE): self._deleteButton.set_sensitive(False)
def _update_reclaim_button(self, got): @@ -301,17 +307,17 @@ class ResizeDialog(GUIObject): self._deleteButton.emit("clicked")
def _sumReclaimableSpace(self, model, path, itr, *args): - (editable, action, ident, targetSize) = model.get(itr, EDITABLE_COL, ACTION_COL, DEVICE_ID_COL, RESIZE_TARGET_COL) + obj = PartStoreRow._make(model[itr])
- if not editable: + if not obj.editable: return False
- device = self.storage.devicetree.getDeviceByID(ident) - if action == _(PRESERVE): + device = self.storage.devicetree.getDeviceByID(obj.id) + if obj.action == _(PRESERVE): return False - if action == _(SHRINK): - self._selectedReclaimableSpace += device.size - targetSize - elif action == _(DELETE): + if obj.action == _(SHRINK): + self._selectedReclaimableSpace += device.size - obj.target + elif obj.action == _(DELETE): self._selectedReclaimableSpace += device.size
return False @@ -364,21 +370,20 @@ class ResizeDialog(GUIObject): self._update_action_buttons(selectedRow)
def _scheduleActions(self, model, path, itr, *args): - (editable, action, ident, target) = model.get(itr, EDITABLE_COL, ACTION_COL, DEVICE_ID_COL, RESIZE_TARGET_COL) - - device = self.storage.devicetree.getDeviceByID(ident) + obj = PartStoreRow._make(model[itr]) + device = self.storage.devicetree.getDeviceByID(obj.id)
- if not editable: + if not obj.editable: return False
- if action == _(PRESERVE): + if obj.action == _(PRESERVE): return False - elif action == _(SHRINK): + elif obj.action == _(SHRINK): if device.resizable: - self.storage.resizeDevice(device, target) + self.storage.resizeDevice(device, obj.target) else: self.storage.recursiveRemove(device) - elif action == _(DELETE): + elif obj.action == _(DELETE): self.storage.recursiveRemove(device)
return False @@ -396,12 +401,12 @@ class ResizeDialog(GUIObject):
itr = self._diskStore.get_iter_first() while itr: - if not self._diskStore[itr][EDITABLE_COL]: + obj = PartStoreRow._make(self._diskStore[itr]) + if not obj.editable: itr = self._diskStore.iter_next(itr) continue
- (ident, ) = self._diskStore.get(itr, DEVICE_ID_COL) - device = self.storage.devicetree.getDeviceByID(ident) + device = self.storage.devicetree.getDeviceByID(obj.id) if device.isDisk: self._actionChanged(itr, action)
On Tue, 2013-06-04 at 13:27 -0400, Chris Lumens wrote:
pyanaconda/ui/gui/spokes/lib/resize.py | 59 ++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 27 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/lib/resize.py b/pyanaconda/ui/gui/spokes/lib/resize.py index 1ec737a..a44db64 100644 --- a/pyanaconda/ui/gui/spokes/lib/resize.py +++ b/pyanaconda/ui/gui/spokes/lib/resize.py @@ -20,6 +20,7 @@ #
from __future__ import division +from collections import namedtuple
# pylint: disable-msg=E0611 from gi.repository import Gdk, Gtk @@ -41,6 +42,10 @@ TOOLTIP_COL = 6 RESIZE_TARGET_COL = 7 NAME_COL = 8
+PartStoreRow = namedtuple("PartStoreRow", ["id", "desc", "fs", "reclaimable",
"action", "editable", "tooltip",
"target", "name"])
PRESERVE = N_("Preserve") SHRINK = N_("Shrink") DELETE = N_("Delete") @@ -239,32 +244,33 @@ class ResizeDialog(GUIObject): self._resizeSlider.add_mark(device.size, Gtk.PositionType.BOTTOM, size_str(device.size))
def _update_action_buttons(self, row):
device = self.storage.devicetree.getDeviceByID(row[DEVICE_ID_COL])
obj = PartStoreRow._make(row)
Great idea! You just don't need to use '_make' and just create a new instance by 'PartStoreRow(row)'. Apart from this and the two comments to PATCH 1/3 these all look good to me.
anaconda-patches@lists.fedorahosted.org