* iw/partition_gui.py (createCB): New function. All the create requests will pas through this function. It pops up a dialog that presents the different creat options to the user. (_doFindFirstChildOfRoot): Helper function for hasFreeHardDrives. (hasFreeHardDrives, hasFreePhysicalVolumes): New functions to get info for the new create screen. * ui/create-storage.glade: New file. Glade file that describes the new screen. --- iw/partition_gui.py | 262 ++++++++++++++++++++++++++++++++- ui/create-storage.glade | 373 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 626 insertions(+), 9 deletions(-) create mode 100644 ui/create-storage.glade diff --git a/iw/partition_gui.py b/iw/partition_gui.py index 847ea2c..dc0ff6a 100644 --- a/iw/partition_gui.py +++ b/iw/partition_gui.py @@ -22,6 +22,7 @@ import gobject import gtk +import gtk.glade try: import gnomecanvas except ImportError: @@ -31,7 +32,6 @@ import gui import parted import string import types -from constants import * import storage from iw_gui import * @@ -505,7 +505,77 @@ class DiskTreeModel(gtk.TreeStore): if selection is not None: selection.unselect_all() gtk.TreeStore.clear(self) - + + def _doFindFirstChildOfRoot(self, rootstr): + """ + _doFindFirstChildOfRoot(string) -> iter + string is used to find the iter related to that string in DiskTreeModel. + The funtion will return the first child (iter) of this root. Returns + None if root was not found or did not have any children + """ + # This is what we are iteriting on: + # "Hard Drives" + # `- Drive "/dev/sda" + # | `- Partition "/dev/sda1" + # | ... + # `- Drive "/dev/sdb" + # `- Partition "/dev/sdb1" + # `- Partition "free" + # ... + # + hd_gp = self.get_iter_root() #hd_gp -> Hard Drive Grand Parent + while True: + # I wonder if implementing an ID field would be better? + if self[hd_gp]["Device"] == rootstr: + break + + if not self.do_iter_next(self, hd_gp): + break + + if not hd_gp: + # Very Strange... + log.error("Could not find the Hard Drive root in DiskTreeModel") + return None + + if not self.iter_has_child(hd_gp): + log.error("No Drives found under the Hard Drive tree in " + "DiskTreeModel") + return None + + return self.iter_children(hd_gp) + + + #FIXME: is there a way to get this info from storage obj? + def hasFreeHardDrives(self): + # We need at least one free partition to activate the partition + # radiobuttons. + found_free = False + + # Find the Partition level + # hd_p -> Hard Drive Parent + hd_p = self._doFindFirstChildOfRoot(_("Hard Drives")) + if not hd_p: + return False + + hd_ch = None #hd_ch -> Hard Drive Child + while True: + if self.iter_has_child(hd_p): + hd_ch = self.iter_children(hd_p) + while True: + if self[hd_ch]["Device"] == _("Free"): + found_free = True + break + + if not self.do_iter_next(self, hd_ch): + break + + if found_free: + break + if not self.do_iter_next(self, hd_p): + break + + return found_free + def __getitem__(self, iter): if type(iter) == gtk.TreeIter: return DiskTreeModelHelper(self, self.titleSlot, iter) @@ -970,7 +1040,7 @@ class PartitionWindow(InstallWindow): self.diskStripeGraph.selectSlice(device) - def newCB(self, widget): + def makepartCB(self, widget): device = self.storage.newPartition(fmt_type=self.storage.defaultFSType, size=200) self.editPartition(device, isNew=1) @@ -999,7 +1069,179 @@ class PartitionWindow(InstallWindow): device.vg._removeLogVol(device) self.refresh(justRedraw=justRedraw) - + + def createCB(self, *args): + # First we must decide what parts of the create_storage_dialog + # we will activate. + + # For the Partition checkboxes. + # If we see that there is free space in the "Hard Drive" list, then we + # must activate all the partition radio buttons (RAID partition, + # LVM partition and Standard partition). We will have only one var to + # control all three activations (Since they all depend on the same + # thing) + activate_create_partition = False + if self.tree.hasFreeHardDrives(): + activate_create_partition = True + + # We activate the create Volume Group radio button if there is a free + # partition with a Physical Volume format. + activate_create_vg = False + if (lvm.has_lvm() + and getFormat("lvmpv").supported + and len(self.storage.unusedPVs()) > 0): + activate_create_vg = True + + # We activate the create RAID dev if there are partitions that have + # raid format and are not related to any raid dev. + activate_create_raid_dev = False + availraidparts = len(self.storage.unusedMDMembers()) + availminors = self.storage.unusedMDMinors + if (len(availminors) > 0 + and getFormat("software RAID").supported + and availraidparts > 1): + activate_create_raid_dev = True + + # FIXME: Why do I need availraidparts to clone? + activate_create_raid_clone = False + if (len(self.storage.disks) > 1 + and availraidparts > 0): + activate_create_raid_clone = True + + # Must check if all the possibilities are False. In this case tell the + # user that he can't create anything and the reasons. + if (not activate_create_partition + and not activate_create_vg + and not activate_create_raid_dev + and not activate_create_raid_clone): + self.intf.messageWindow(_("Cannot perform any creation action"), + _("Follows an explination... "), + custom_icon="warning") + return + + # GTK crap starts here. + create_storage_xml = gtk.glade.XML( + gui.findGladeFile("create-storage.glade"), domain="anaconda") + self.dialog = create_storage_xml.get_widget("create_storage_dialog") + + # Activate the partition radio buttons if needed. + # sp_rb -> standard partition + sp_rb = create_storage_xml.get_widget("create_storage_rb_standard_part") + # lp_rb -> lvm partition (physical volume) + lp_rb = create_storage_xml.get_widget("create_storage_rb_lvm_part") + # rp_rb -> RAID partition + rp_rb = create_storage_xml.get_widget("create_storage_rb_raid_part") + if activate_create_partition: + sp_rb.set_sensitive(True) + lp_rb.set_sensitive(True) + rp_rb.set_sensitive(True) + + # Activate the Volume Group radio buttons if needed. + # vg_rb -> Volume Group + vg_rb = create_storage_xml.get_widget("create_storage_rb_lvm_vg") + if activate_create_vg: + vg_rb.set_sensitive(True) + + # Activate the RAID dev if needed. + # rd_rb -> RAID device + rd_rb = create_storage_xml.get_widget("create_storage_rb_raid_dev") + if activate_create_raid_dev: + rd_rb.set_sensitive(True) + + # Activate RAID clone if needed. + # rc_rb -> RAID clone + rc_rb = create_storage_xml.get_widget("create_storage_rb_raid_clone") + if activate_create_raid_clone: + rc_rb.set_sensitive(True) + + # Before drawing lets select the first radio button that is sensitive: + # How can I get sensitivity from gtk.radiobutton? + if activate_create_partition: + sp_rb.set_active(True) + elif activate_create_vg: + vg_rb.set_active(True) + elif activate_create_raid_dev: + rd_rb.set_active(True) + elif activate_create_raid_clone: + rc_rb.set_active(True) + + gui.addFrame(self.dialog) + self.dialog.show_all() + + # We loop in the self.dialog.run() only for the help screens. + # dialog_rc == 2 -> partition about + # dialog_rc == 3 -> raid about + # dialog_rc == 4 -> lvm about + while True: + dialog_rc = self.dialog.run() + if dialog_rc == 2 or dialog_rc == 3 or dialog_rc == 4: + # FIXME: Code to handle the About messages. + pass + else: + break + + # If Cancel was pressed + if dialog_rc == 0: + self.dialog.destroy() + return + + # If Create was pressed Make sure we do a dialog.destroy before + # calling any other screen. We don't want the create dialog to show + # in the back when we pop up other screens. + if dialog_rc != 1: + log.error("I received a dialog_rc != 1 (%d) witch should not " + "happen" % rc) + self.dialog.destroy() + return + + self.dialog.destroy() + if rp_rb.get_active(): + member = self.storage.newPartition(fmt_type="software RAID", + size=200) + self.editPartition(member, isNew = 1, restrictfs=["mdmember"]) + return + + elif rc_rb.get_active(): + cloneDialog = raid_dialog_gui.RaidCloneDialog(self.storage, + self.intf, + self.parent) + if cloneDialog is None: + self.intf.messageWindow(_("Couldn't Create Drive Clone Editor"), + _("The drive clone editor could not " + "be created for some reason."), + custom_icon="error") + return + + if cloneDialog.run(): + self.refresh() + + cloneDialog.destroy() + return + + elif rd_rb.get_active(): + array = self.storage.newMDArray(fmt_type=self.storage.defaultFSType) + self.editRaidArray(array, isNew=1) + return + + elif lp_rb.get_active(): + member = self.storage.newPartition(fmt_type="physical volume (LVM)", + size=200) + self.editPartition(member, isNew = 1, restrictfs=["lvmpv"]) + return + + elif vg_rb.get_active(): + tempvg = self.storage.newVG() + self.editLVMVolumeGroup(tempvg, isNew = 1) + return + + elif sp_rb.get_active(): + tempformat = self.storage.defaultFSType + device = self.storage.newPartition(fmt_type=tempformat, size=200) + self.editPartition(device, isNew=1) + return + + import pdb ; pdb.set_trace() + def resetCB(self, *args): if not confirmResetPartitionState(self.intf): return @@ -1361,13 +1603,15 @@ class PartitionWindow(InstallWindow): buttonBox = gtk.HButtonBox() buttonBox.set_layout(gtk.BUTTONBOX_SPREAD) - ops = ((_("Ne_w"), self.newCB), + ops = ((_("_Create"), self.createCB), (_("_Edit"), self.editCB), (_("_Delete"), self.deleteCB), - (_("Re_set"), self.resetCB), - (_("R_AID"), self.makeraidCB), - (_("_LVM"), self.makeLvmCB)) - + (_("Re_set"), self.resetCB)) + +# (_("_Partition"), self.makepartCB), +# (_("R_AID"), self.makeraidCB), +# (_("_LVM"), self.makeLvmCB)) + for label, cb in ops: button = gtk.Button(label) buttonBox.add (button) diff --git a/ui/create-storage.glade b/ui/create-storage.glade new file mode 100644 index 0000000..1ab3bff --- /dev/null +++ b/ui/create-storage.glade @@ -0,0 +1,373 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd"> +<!--Generated with glade3 3.4.5 on Wed Jul 29 18:27:47 2009 --> +<glade-interface> + <widget class="GtkDialog" id="create_storage_dialog"> + <property name="visible">True</property> + <property name="title" translatable="yes">Add Storage</property> + <property name="modal">True</property> + <property name="window_position">GTK_WIN_POS_CENTER_ALWAYS</property> + <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> + <child internal-child="vbox"> + <widget class="GtkVBox" id="dialog-vbox1"> + <property name="visible">True</property> + <property name="spacing">2</property> + <child> + <widget class="GtkVBox" id="vbox1"> + <property name="visible">True</property> + <child> + <widget class="GtkHBox" id="hbox1"> + <property name="visible">True</property> + <child> + <widget class="GtkLabel" id="label1"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="xpad">2</property> + <property name="label" translatable="yes">Create Partition</property> + </widget> + </child> + <child> + <widget class="GtkLinkButton" id="linkbutton1"> + <property name="sensitive">False</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="has_tooltip">True</property> + <property name="label" translatable="yes">gtk-about</property> + <property name="relief">GTK_RELIEF_NONE</property> + <property name="use_stock">True</property> + <property name="xalign">1</property> + <property name="response_id">2</property> + <property name="uri">http://glade.gnome.org</property> + </widget> + <packing> + <property name="position">1</property> + </packing> + </child> + </widget> + </child> + <child> + <widget class="GtkVBox" id="vbox2"> + <property name="visible">True</property> + <child> + <widget class="GtkRadioButton" id="create_storage_rb_standard_part"> + <property name="visible">True</property> + <property name="sensitive">False</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">Standard Partition</property> + <property name="response_id">0</property> + <property name="draw_indicator">True</property> + </widget> + </child> + <child> + <widget class="GtkLabel" id="label4"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="xpad">20</property> + <property name="label" translatable="yes"><span size="small" color="gray">Goes to a "Partition Create" window with a file system +selected by default</span></property> + <property name="use_markup">True</property> + </widget> + <packing> + <property name="position">1</property> + </packing> + </child> + </widget> + <packing> + <property name="position">1</property> + </packing> + </child> + <child> + <widget class="GtkHBox" id="hbox2"> + <property name="visible">True</property> + <child> + <widget class="GtkLabel" id="label2"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="xpad">2</property> + <property name="label" translatable="yes">Create Software RAID</property> + </widget> + </child> + <child> + <widget class="GtkLinkButton" id="linkbutton2"> + <property name="sensitive">False</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="has_tooltip">True</property> + <property name="label" translatable="yes">gtk-about</property> + <property name="relief">GTK_RELIEF_NONE</property> + <property name="use_stock">True</property> + <property name="xalign">1</property> + <property name="response_id">3</property> + <property name="uri">http://glade.gnome.org</property> + </widget> + <packing> + <property name="position">1</property> + </packing> + </child> + </widget> + <packing> + <property name="position">2</property> + </packing> + </child> + <child> + <widget class="GtkVBox" id="vbox3"> + <property name="visible">True</property> + <child> + <widget class="GtkRadioButton" id="create_storage_rb_raid_part"> + <property name="visible">True</property> + <property name="sensitive">False</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">RAID Partition</property> + <property name="response_id">0</property> + <property name="draw_indicator">True</property> + <property name="group">create_storage_rb_standard_part</property> + </widget> + </child> + <child> + <widget class="GtkLabel" id="label5"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="xpad">20</property> + <property name="label" translatable="yes"><span size="small" color="gray"> Goes to a "Partition Create" window with a RAID format +selected by default</span></property> + <property name="use_markup">True</property> + </widget> + <packing> + <property name="position">1</property> + </packing> + </child> + </widget> + <packing> + <property name="position">3</property> + </packing> + </child> + <child> + <widget class="GtkVBox" id="vbox4"> + <property name="visible">True</property> + <child> + <widget class="GtkRadioButton" id="create_storage_rb_raid_dev"> + <property name="visible">True</property> + <property name="sensitive">False</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">RAID Device</property> + <property name="response_id">0</property> + <property name="draw_indicator">True</property> + <property name="group">create_storage_rb_standard_part</property> + </widget> + </child> + <child> + <widget class="GtkLabel" id="label6"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="xpad">20</property> + <property name="label" translatable="yes"><span size="small" color="gray">Goes to a "RAID Create" window</span></property> + <property name="use_markup">True</property> + </widget> + <packing> + <property name="position">1</property> + </packing> + </child> + </widget> + <packing> + <property name="position">4</property> + </packing> + </child> + <child> + <widget class="GtkVBox" id="vbox5"> + <property name="visible">True</property> + <child> + <widget class="GtkRadioButton" id="create_storage_rb_raid_clone"> + <property name="visible">True</property> + <property name="sensitive">False</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">RAID Clone</property> + <property name="response_id">0</property> + <property name="draw_indicator">True</property> + <property name="group">create_storage_rb_standard_part</property> + </widget> + </child> + <child> + <widget class="GtkLabel" id="label7"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="xpad">20</property> + <property name="label" translatable="yes"><span size="small" color="gray">Goes to a "RAID Clone" window</span></property> + <property name="use_markup">True</property> + </widget> + <packing> + <property name="position">1</property> + </packing> + </child> + </widget> + <packing> + <property name="position">5</property> + </packing> + </child> + <child> + <widget class="GtkHBox" id="hbox3"> + <property name="visible">True</property> + <child> + <widget class="GtkLabel" id="label3"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="xpad">2</property> + <property name="label" translatable="yes">Create LVM</property> + </widget> + </child> + <child> + <widget class="GtkLinkButton" id="linkbutton3"> + <property name="sensitive">False</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="has_tooltip">True</property> + <property name="label" translatable="yes">gtk-about</property> + <property name="relief">GTK_RELIEF_NONE</property> + <property name="use_stock">True</property> + <property name="xalign">1</property> + <property name="response_id">4</property> + <property name="uri">http://glade.gnome.org</property> + </widget> + <packing> + <property name="position">1</property> + </packing> + </child> + </widget> + <packing> + <property name="position">6</property> + </packing> + </child> + <child> + <widget class="GtkVBox" id="vbox6"> + <property name="visible">True</property> + <child> + <widget class="GtkRadioButton" id="create_storage_rb_lvm_vg"> + <property name="visible">True</property> + <property name="sensitive">False</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">LVM Volume Group</property> + <property name="response_id">0</property> + <property name="draw_indicator">True</property> + <property name="group">create_storage_rb_standard_part</property> + </widget> + </child> + <child> + <widget class="GtkLabel" id="label8"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="xpad">20</property> + <property name="label" translatable="yes"><span size="small" color="gray">Goes to a "Create LVM Volume Group" window</span></property> + <property name="use_markup">True</property> + </widget> + <packing> + <property name="position">1</property> + </packing> + </child> + </widget> + <packing> + <property name="position">7</property> + </packing> + </child> + <child> + <widget class="GtkVBox" id="vbox7"> + <property name="visible">True</property> + <child> + <widget class="GtkRadioButton" id="create_storage_rb_lvm_lv"> + <property name="visible">True</property> + <property name="sensitive">False</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">LVM Logical Volume</property> + <property name="response_id">0</property> + <property name="draw_indicator">True</property> + <property name="group">create_storage_rb_standard_part</property> + </widget> + </child> + <child> + <widget class="GtkLabel" id="label9"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="xpad">20</property> + <property name="label" translatable="yes"><span size="small" color="gray">Goes to a "Create LVM Logical Volume" window</span></property> + <property name="use_markup">True</property> + </widget> + <packing> + <property name="position">1</property> + </packing> + </child> + </widget> + <packing> + <property name="position">8</property> + </packing> + </child> + <child> + <widget class="GtkVBox" id="vbox8"> + <property name="visible">True</property> + <child> + <widget class="GtkRadioButton" id="create_storage_rb_lvm_part"> + <property name="visible">True</property> + <property name="sensitive">False</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">LVM Physical Volume</property> + <property name="response_id">0</property> + <property name="draw_indicator">True</property> + <property name="group">create_storage_rb_standard_part</property> + </widget> + </child> + <child> + <widget class="GtkLabel" id="label10"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="xpad">20</property> + <property name="label" translatable="yes"><span size="small" color="gray">Goes to a "Partition Create" window with a LVM Physical +Volume format selected by default</span></property> + <property name="use_markup">True</property> + </widget> + <packing> + <property name="position">1</property> + </packing> + </child> + </widget> + <packing> + <property name="position">9</property> + </packing> + </child> + </widget> + <packing> + <property name="position">1</property> + </packing> + </child> + <child internal-child="action_area"> + <widget class="GtkHButtonBox" id="dialog-action_area1"> + <property name="visible">True</property> + <property name="layout_style">GTK_BUTTONBOX_END</property> + <child> + <widget class="GtkButton" id="storage_create_button_cancel"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="label" translatable="yes">gtk-cancel</property> + <property name="use_stock">True</property> + <property name="response_id">0</property> + </widget> + </child> + <child> + <widget class="GtkButton" id="storage_create_button_create"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="label" translatable="yes">Create</property> + <property name="response_id">1</property> + </widget> + <packing> + <property name="position">1</property> + </packing> + </child> + </widget> + <packing> + <property name="expand">False</property> + <property name="pack_type">GTK_PACK_END</property> + </packing> + </child> + </widget> + </child> + </widget> +</glade-interface> -- 1.6.0.6 _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/anaconda-devel-list