[PATCH 5/6] Add help text and a help button to the custom storage spoke. (#889570)

David Lehman dlehman at redhat.com
Fri Dec 21 19:57:50 UTC 2012

 pyanaconda/ui/gui/spokes/custom.glade |   85 +++++++++++++++++++++++++++++++++
 pyanaconda/ui/gui/spokes/custom.py    |   79 ++++++++++++++++++++++++++++++
 2 files changed, 164 insertions(+), 0 deletions(-)

diff --git a/pyanaconda/ui/gui/spokes/custom.glade b/pyanaconda/ui/gui/spokes/custom.glade
index c763cf1..465333c 100644
--- a/pyanaconda/ui/gui/spokes/custom.glade
+++ b/pyanaconda/ui/gui/spokes/custom.glade
@@ -2,6 +2,75 @@
   <!-- interface-requires gtk+ 3.0 -->
   <!-- interface-requires AnacondaWidgets 1.0 -->
+  <object class="GtkDialog" id="help_dialog">
+    <property name="can_focus">False</property>
+    <property name="border_width">5</property>
+    <property name="title" translatable="yes">Help</property>
+    <property name="modal">True</property>
+    <property name="window_position">center-on-parent</property>
+    <property name="type_hint">dialog</property>
+    <property name="width_request">600</property>
+    <property name="height_request">400</property>
+    <signal name="close" handler="on_close" swapped="no"/>
+    <child internal-child="vbox">
+      <object class="GtkBox" id="dialog-vbox6">
+        <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">2</property>
+        <child internal-child="action_area">
+          <object class="GtkButtonBox" id="dialog-action_area6">
+            <property name="can_focus">False</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="help_close_button">
+                <property name="label">gtk-close</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkScrolledWindow" id="scrolledwindow3">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="shadow_type">in</property>
+            <child>
+              <object class="GtkTextView" id="help_text_view">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="editable">False</property>
+                <property name="wrap_mode">word</property>
+                <property name="cursor_visible">False</property>
+                <property name="buffer">help_text_buffer</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="0">help_close_button</action-widget>
+    </action-widgets>
+  </object>
   <object class="GtkDialog" id="addDialog">
     <property name="can_focus">False</property>
     <property name="border_width">5</property>
@@ -1665,6 +1734,21 @@ you'll be able to view their details here.</property>
                             <property name="homogeneous">True</property>
+                        <child>
+                          <object class="GtkToolButton" id="helpButton">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="label" translatable="yes">Help</property>
+                            <property name="tooltip_text" translatable="yes">Click for help</property>
+                            <property name="use_underline">True</property>
+                            <property name="icon_name">system-help-symbolic</property>
+                            <signal name="clicked" handler="on_help_clicked" swapped="no"/>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="homogeneous">True</property>
+                          </packing>
+                        </child>
                         <property name="left_attach">0</property>
@@ -2276,6 +2360,7 @@ you'll be able to view their details here.</property>
       <action-widget response="1">select_button</action-widget>
+  <object class="GtkTextBuffer" id="help_text_buffer"/>
   <object class="GtkEntryCompletion" id="mountPointCompletion">
     <property name="model">mountPointStore</property>
diff --git a/pyanaconda/ui/gui/spokes/custom.py b/pyanaconda/ui/gui/spokes/custom.py
index 08e35e7..597c90e 100644
--- a/pyanaconda/ui/gui/spokes/custom.py
+++ b/pyanaconda/ui/gui/spokes/custom.py
@@ -414,6 +414,20 @@ class VolumeGroupDialog(GUIObject):
     def run(self):
         return self.window.run()
+class HelpDialog(GUIObject):
+    builderObjects = ["help_dialog", "help_text_view", "help_text_buffer"]
+    mainWidgetName = "help_dialog"
+    uiFile = "spokes/custom.glade"
+    def run(self):
+        help_text = help_text_template % {"productName": productName}
+        help_buffer = self.builder.get_object("help_text_buffer")
+        help_buffer.set_text(help_text)
+        self.window.run()
+    def on_close(self, button):
+        self.window.destroy()
 class CustomPartitioningSpoke(NormalSpoke, StorageChecker):
     builderObjects = ["customStorageWindow", "sizeAdjustment",
@@ -1990,6 +2004,10 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker):
+    def on_help_clicked(self, button):
+        help_window = HelpDialog(self.data)
+        help_window.run()
     def on_configure_clicked(self, button):
         selector = self._current_selector
         if not selector:
@@ -2501,3 +2519,64 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker):
         self._unused_devices = None     # why do we cache this?
         self._current_selector = None
+help_text_template = """You have chosen to manually set up the filesystems for your new %(productName)s installation. Before you begin, you might want to take a minute to learn the lay of the land. Quite a bit has changed.
+The most important change is that creation of new filesystems has been streamlined. You no longer have to build complex devices like LVM logical volumes in stages (physical volume, then volume group, then logical volume) -- now you just create a logical volume and we'll handle the legwork of setting up the physical volumes and volume group to contain it. We'll also handle adjusting the volume group as you add, remove, and resize logical volumes so you don't have to worry about the mundane details.
+Screen Layout
+The left-hand side of the screen shows the OS installations we were able to find on this computer. The new %(productName)s installation is at the top of the list. You can click on the names of the installations to see what filesystems they contain.
+Below the various installations and mountpoints on the left-hand side there are buttons to add a new filesystem, remove the selected filesystem, or configure the selected filesystem.
+The right-hand side of the screen is where you can customize the currently-selected mountpoint.
+On the bottom-left you will see a summary of the disks you have chosen to use for the installation. You can click on the blue text to see more detailed information about your selected disks.
+How to create a new filesystem on a new device
+1. Click on the + button.
+2. Enter the mountpoint and size. (Hint: Hover the mouse pointer over either of the text entry areas for help.)
+3. Select the new mountpoint under "New %(productName)s Installation" on the left-hand side of the screen and customize it to suit your needs.
+How to reformat a device/filesystem that already exists on your disk
+1. Select the filesystem from the left-hand side of the screen.
+2. Click on the "Customize" expander in the mountpoint customization area on the right-hand side of the screen.
+3. Activate the "Reformat" checkbutton, select a filesystem type and, if applicable, enter a mountpoint above in the "Mountpoint" text entry area.
+4. Click on "Apply changes"
+How to set a mountpoint for a filesystem that already exists on your disk
+1. Select the filesystem from the left-hand side of the screen.
+2. Enter a mountpoint in the "Mountpoint" text entry area in the mountpoint customization area.
+3. Click on "Apply changes"
+How to remove a filesystem that already exists on your disk
+1. Select the filesystem you wish to remove on the left-hand side of the screen.
+2. Click the - button.
+Hint: Removing a device that already exists on your disk from the "New %(productName)s Installation" does not remove it from the disk. It only resets that device to its original state. To remove a device that already exists on your disk, you must select it from under any of the other detected installations (or "Unknown") and hit the - button.
+Tips and hints
+You can enter sizes for new filesystems that are greater than the total available free space. The installer will come as close as possible to the size you request.
+By default, new devices use any/all of your selected disks.
+You can change which disks a new device may be allocated from by clicking the configure button (the one with a tools graphic) while that device is selected.
+When adding a new mountpoint by clicking the + button, leave the size entry blank to make the new device use all available free space.
+When you remove the last device from a container device like an LVM volume group, we will automatically remove that container device to make room for new devices.
+When the last partition is removed from a disk, that disk may be reinitialized with a new partition table if we think there is a more appropriate type for that disk.

More information about the anaconda-patches mailing list