PEAR_PackageFileManager_GUI_Gtk
[ class tree: PEAR_PackageFileManager_GUI_Gtk ] [ index: PEAR_PackageFileManager_GUI_Gtk ] [ all elements ]

Source for file Gtk.php

Documentation is available at Gtk.php

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. /**
  4.  * A Gtk GUI frontend for the PEAR_PackageFileManager class.
  5.  *
  6.  * A PHP-GTK 1 frontend for the PEAR_PackageFileManager class.
  7.  * It makes it easier for developers to create and maintain
  8.  * PEAR package.xml files.
  9.  *
  10.  * Features:
  11.  * - Update existing package files or create new ones
  12.  * - Import values from an existing package file
  13.  * - Drag-n-Drop package directory into the application for easy
  14.  *   loading (requires PEAR::Gtk_FileDrop)
  15.  * - Set package level information (package name, description, etc.)
  16.  * - Set release level information (version, release notes, etc.)
  17.  * - Easily add maintainers
  18.  * - Browse package files as a tree and click to add a dependency
  19.  * - Add install time global and file replacements
  20.  * - Package file preview window
  21.  * - Package the package using the new package file
  22.  *
  23.  * Example:
  24.  * More detail can be found in
  25.  * doc/PEAR_PackageFileManager_GUI_Gtk/example.php
  26.  * 
  27.  * <code>
  28.  * if (!extension_loaded('gtk')) {
  29.  *     dl( 'php_gtk.' . PHP_SHLIB_SUFFIX);
  30.  * }
  31.  *
  32.  * require_once 'PEAR/PackageFileManager/GUI/Gtk.php';
  33.  * $pfmGtk =& new PEAR_PackageFileManager_GUI_Gtk();
  34.  * $pfmGtk->show();
  35.  * gtk::main();
  36.  * </code>
  37.  *
  38.  * @todo Allow other (non-package) dependencies (Maybe)
  39.  *
  40.  * @category   PEAR
  41.  * @package    PEAR_PackageFileManager_GUI_Gtk
  42.  * @author     Scott Mattocks
  43.  * @copyright  &copy; (c) Copyright 2005 Scott Mattocks
  44.  * @license    PHP 3.0
  45.  * @version    API: @version@ CVS: $Id:$
  46.  * @link       http://pear.php.net/package/PEAR_PackageFileManager_GUI_Gtk
  47.  */
  48.  
  49.     /**
  50.      * PEAR_PackageFileManager instance.
  51.      * @var    object 
  52.      * @access private
  53.      */
  54.     var $_packageFileManager;
  55.     /**
  56.      * PEAR_PackageFileManager options array
  57.      * @var    array 
  58.      * @access private
  59.      */
  60.     var $_options = array();
  61.     /**
  62.      * The main gtk window.
  63.      * @var object 
  64.      */
  65.     var $widget;
  66.     /**
  67.      * The GtkNotebook used to display the different tasks.
  68.      * @var object 
  69.      */
  70.     var $notebook;
  71.     /**
  72.      * The GtkText that will display the warnings.
  73.      * @var object 
  74.      */
  75.     var $warningsArea;
  76.     /**
  77.      * The GtkWindow that will hold the preview information.
  78.      * @var object 
  79.      */
  80.     var $previewWindow;
  81.     /**
  82.      * Keep track of whether or not the file has been previewed
  83.      * in its current state.
  84.      * @var boolean 
  85.      */
  86.     var $previewed = false;
  87.     /**
  88.      * Keep track of whether or not the file has been saved in
  89.      * its current state.
  90.      * @var boolean 
  91.      */
  92.     var $saved = false;
  93.  
  94.     /**
  95.      * Constructor.
  96.      * 
  97.      * Creates the package file manager and then calls the
  98.      * method to create the rest of the application.
  99.      *
  100.      * @param  boolean $isMain Whether or not this class is the
  101.      *                          main application for this Gtk loop
  102.      * @return void 
  103.      * @access public
  104.      */
  105.     function PEAR_PackageFileManager_GUI_Gtk($isMain = true)
  106.     {
  107.         // Instantiate the package file manager.
  108.         require_once 'PEAR/PackageFileManager.php';
  109.         $this->_packageFileManager =new PEAR_PackageFileManager();
  110.  
  111.         // Create the application.
  112.         $this->_createApplication($isMain);
  113.     }
  114.     
  115.     /**
  116.      * Shows all widgets.
  117.      *
  118.      * Please note: The regular issues associated with show_all()
  119.      * still apply. show_all() does not always trickle all of the
  120.      * way down to the very last child widget. For more info please
  121.      * see the PHP-GTK website {@link http://gtk.php.net}
  122.      * 
  123.      * @param  none 
  124.      * @return void 
  125.      * @access public
  126.      */
  127.     function show()
  128.     {
  129.         $this->widget->show_all();
  130.     }
  131.  
  132.     /**
  133.      * Returns the main application window.
  134.      *
  135.      * This is a standard PEAR-PHP-GTK method. It has
  136.      * been added for consistency. It would be useful if
  137.      * the PEAR_Frontend_Gtk class had a "New Package"
  138.      * feature. The PEAR_Frontend_Gtk code could just
  139.      * instantiate this class and call getWidget(). It
  140.      * could then show the window when ever it wanted or
  141.      * make some changes to the window itself. It could
  142.      * even pull the child from the window and embed the
  143.      * rest of this application in itself.
  144.      * 
  145.      * @param  none 
  146.      * @return &object 
  147.      * @access public
  148.      */
  149.     function &getWidget()
  150.     {
  151.         return $this->widget();
  152.     }
  153.  
  154.     /**
  155.      * Creates and shows an about window.
  156.      *
  157.      * The about window contains the package name, current
  158.      * package version number, the list of developers and where
  159.      * to find the latest information for the package.
  160.      *
  161.      * It would be nice if this window also told the user what
  162.      * version of PEAR_PackageFileManager was being used but I
  163.      * don't know that that information is necessarily part of
  164.      * this package.
  165.      *
  166.      * @param  none 
  167.      * @return void 
  168.      * @access public
  169.      */
  170.     function about()
  171.     {
  172.         // Create the window.
  173.         $aboutWin =new GtkWindow();
  174.         $aboutWin->set_title('PEAR_PackageFileManager');
  175.  
  176.         // Add a pretty frame.
  177.         $aboutFrame =new GtkFrame('About');
  178.         $aboutWin->add($aboutFrame);
  179.         
  180.         // Add the data in an organized manner.
  181.         // The best way is probably with a GtkTable.
  182.         $table =new GtkTable();
  183.         $table->set_col_spacings(3);
  184.  
  185.         // Create an array of row labels.
  186.         $labels = array('Package'
  187.                         'Version'
  188.                         'Maintainers',
  189.                         'Summary',
  190.                         'Additional Info'
  191.                         );
  192.         
  193.         // Attach each child in the first column.
  194.         foreach ($labels as $row => $label{
  195.             $label =new GtkLabel($label ':');
  196.             $label->set_alignment(00);
  197.             $table->attach($label01$row$row + 1);
  198.         }
  199.  
  200.         // Create an array of values.
  201.         $values = array('PEAR_PackageFileManager_GUI_Gtk',
  202.                         '@version@',
  203.                         'Scott Mattocks',
  204.                         '@summary@',
  205.                         'http://pear.php.net/'
  206.                         );
  207.         
  208.         // Add the values in the second column.
  209.         foreach ($values as $row => $value{
  210.             $label =new GtkLabel($value);
  211.             $label->set_alignment(00);
  212.             $table->attach($label12$row$row + 1);
  213.         }
  214.  
  215.         // Add a close button.
  216.         $closeBox    =new GtkHBox();
  217.         $closeButton =new GtkButton('Close');
  218.         $closeButton->connect_object('clicked'array(&$aboutWin'destroy'));
  219.  
  220.         $closeBox->pack_end($closeButtonfalsefalse3);
  221.         $table->attach($closeBox02count($labels)count($labels+ 1);
  222.  
  223.         // Add the table and show everything.
  224.         $aboutFrame->add($table);
  225.         $aboutWin->show_all();
  226.     }
  227.  
  228.     /**
  229.      * Shows the warnings in the text area.
  230.      * 
  231.      * Each warning will be displayed on its own line.
  232.      * 
  233.      * @param  string $message Optional message to add to the warnings.
  234.      * @return void 
  235.      * @access public
  236.      */
  237.     function showWarnings($message = NULL)
  238.     {
  239.         if (!empty($message)) {
  240.             $this->warningsArea->insert_text($message "\n"$this->warningsArea->get_length());
  241.         }
  242.  
  243.         foreach ($this->_packageFileManager->getWarnings(as $warning{
  244.             $this->warningsArea->insert_text($warning['message'"\n----\n"$this->warningsArea->get_length());
  245.         }
  246.     }
  247.  
  248.     /**
  249.      * Checks to see if the file has been saved before destroying the
  250.      * main window.
  251.      * 
  252.      * The user should save their file before the application closes.
  253.      * If they have not, they will be prompted to save or close any
  254.      * way.
  255.      *
  256.      * This method will also kill the main gtk loop if told to. If
  257.      * this class is imbedded in another class, you probably don't
  258.      * want to do that. Pass false to the constructor to prevent
  259.      * this from happening.
  260.      *
  261.      * @param  boolean $killMainLoop 
  262.      * @return void 
  263.      * @access public
  264.      */
  265.     function checkBeforeQuit($killMainLoop)
  266.     {
  267.         // Check to see if the file was saved.
  268.         if (!$this->saved{
  269.             // Prompt the user with a GtkDialog window.
  270.             $dialog =new GtkDialog();
  271.             
  272.             $vBox $dialog->vbox;
  273.             $vBox->pack_start(new GtkLabel('Your package file has not been saved. Would you like to save it now?'));
  274.             
  275.             $dialog->show_all();
  276.             gtk::main();
  277.         }
  278.  
  279.         // Kill the main loop if requested.
  280.         if ($killMainLoop{
  281.             return gtk::main_quit();
  282.         else {
  283.             return true;
  284.         }
  285.     }
  286.  
  287.     /**
  288.      * Creates the main PHP-GTK application.
  289.      *
  290.      * @param  boolean $isMain Whether or not this class is the
  291.      *                          main application for this Gtk loop
  292.      * @return void 
  293.      * @access private
  294.      */
  295.     function _createApplication($isMain)
  296.     {
  297.         // Build the main window
  298.         $this->widget =new GtkWindow();
  299.         $this->widget->set_title('PackageFileManager');
  300.         //$this->widget->connect_object('destroy', array(&$this, 'checkBeforeQuit'), $isMain);
  301.         $this->widget->connect_object('destroy'array('gtk''main_quit'));
  302.         
  303.         // The main container for the window.
  304.         $vBox =new GtkVBox();
  305.         $this->widget->add($vBox);
  306.         
  307.         // Add the menu.
  308.         $vBox->pack_start($this->_buildMenu()falsetrue3);
  309.  
  310.         // Add the notebook.
  311.         $vBox->pack_start($this->_buildNotebook());
  312.     }
  313.  
  314.     /**
  315.      * Builds the application's menu.
  316.      *
  317.      * The menu is used for such things as the open and save
  318.      * dialogs. The menu should also have an about option and
  319.      * an exit option.
  320.      * 
  321.      * @param  none 
  322.      * @return object  container holding the menu.
  323.      * @access private
  324.      */
  325.     function &_buildMenu()
  326.     {
  327.         // Create the menu bar.
  328.         $menuBar =new GtkMenuBar();
  329.         $accel   =new GtkAccelGroup();
  330.         $this->widget->add_accel_group($accel);
  331.  
  332.         // Create the main (only) menu item.
  333.         $fileHeader =new GtkMenuItem('File');
  334.         $helpHeader =new GtkMenuItem('Help');
  335.  
  336.         // Add the menu item to the menu bar.
  337.         $menuBar->append($fileHeader);
  338.         $menuBar->append($helpHeader);
  339.  
  340.         // Create the file menu
  341.         $fileMenu =new GtkMenu();
  342.         $helpMenu =new GtkMenu();
  343.  
  344.         // Add the menu items
  345.         // Allow users to preview the package file (debugPackageFile)
  346.         $preview      =new GtkMenuItem('');
  347.         $previewLabel =  $preview->child;
  348.         $previewKey   =  $previewLabel->parse_uline('_Preview');
  349.         $preview->add_accelerator('activate'$accel$previewKeyGDK_CONTROL_MASKGTK_ACCEL_VISIBLE);
  350.         $preview->lock_accelerators();
  351.         $preview->connect_object('activate'array(&$this'_previewFile'));
  352.         $fileMenu->append($preview);
  353.         
  354.         // Allow users to save the package file (writePackageFile)
  355.         $save      =new GtkMenuItem('');
  356.         $saveLabel =  $save->child;
  357.         $saveKey   =  $saveLabel->parse_uline('_Save');
  358.         $save->add_accelerator('activate'$accel$saveKeyGDK_CONTROL_MASKGTK_ACCEL_VISIBLE);
  359.         $save->lock_accelerators();
  360.         $save->connect_object('activate'array(&$this'_writePackageFile'));
  361.         $fileMenu->append($save);
  362.  
  363.         // Allow users to package the package.
  364.         $package      =new GtkMenuItem('');
  365.         $packageLabel =  $package->child;
  366.         $packageKey   =  $packageLabel->parse_uline('P_ackage');
  367.         $package->add_accelerator('activate'$accel$packageKeyGDK_CONTROL_MASKGTK_ACCEL_VISIBLE);
  368.         $package->lock_accelerators();
  369.         $package->connect_object('activate'array(&$this'_packagePackage'));
  370.         $fileMenu->append($package);
  371.  
  372.         // Allow users to exit.
  373.         $exit =new GtkMenuItem('Exit');
  374.         $exit->connect_object('activate'array('gtk''main_quit'));
  375.         $fileMenu->append($exit);
  376.  
  377.         $about =new GtkMenuItem('About...');
  378.         $about->connect('activate'array(&$this'about'));
  379.         $helpMenu->append($about);        
  380.         
  381.         // Complete the menu.
  382.         $fileHeader->set_submenu($fileMenu);
  383.         $helpHeader->set_submenu($helpMenu);
  384.  
  385.         return $menuBar;
  386.     }
  387.  
  388.     /**
  389.      * Builds the main display widget.
  390.      *
  391.      * To make the user interface more navigable, a GtkNotebook
  392.      * is used. This lets the user appear to be working through
  393.      * a wizard when they are actually just changing pages.
  394.      *
  395.      * @param  none 
  396.      * @return &object 
  397.      * @access private
  398.      */
  399.     function &_buildNotebook()
  400.     {
  401.         // Create the notebook.
  402.         $this->notebook =new GtkNotebook();
  403.         $this->notebook->set_scrollable(true);
  404.         $this->notebook->popup_enable();
  405.  
  406.         // Add the package info page.
  407.         $this->_addNotebookPage($this->_createPackagePage());
  408.  
  409.         // Add the release info page.
  410.         $this->_addNotebookPage($this->_createReleasePage());
  411.  
  412.         // Add the addMaintainer page.
  413.         // This can't happen until the options are set!
  414.         //$this->_addNotebookPage($this->_createAddMaintainerPage());
  415.  
  416.         // Add the addDependencies page.
  417.         // This can't happen until the options are set!
  418.         //$this->_addNotebookPage($this->_createAddDependenciesPage());
  419.  
  420.         // Add the addReplacements page.
  421.         // This can't happen until the options are set!
  422.         //$this->_addNotebookPage($this->_createAddReplacementsPage());
  423.  
  424.         // Add the warnings page.
  425.         $this->_addNotebookPage($this->_createWarningsPage());
  426.  
  427.         // When the page is switched, get any new warnings.
  428.         $this->notebook->connect_object('switch-page'array(&$this'showWarnings'));
  429.  
  430.         // Return the notebook.
  431.         return $this->notebook;
  432.     }
  433.  
  434.     /**
  435.      * Appends the given container to the notebook.
  436.      *
  437.      * @param  array   $page array(container, label)
  438.      * @param  boolean $last Whether this page should be the last page or not
  439.      * @return integer 
  440.      * @access private
  441.      */
  442.     function _addNotebookPage($page$last = true)
  443.     {
  444.         // Add the container and the tab label.
  445.         if ($last{
  446.             $this->notebook->append_page($page[0]$page[1]);
  447.         else {
  448.             // Make this the second to last page.
  449.             $position count($this->notebook->children()) - 1;
  450.             $this->notebook->insert_page($page[0]$page[1]$position);
  451.             $this->notebook->show_all();
  452.         }
  453.     }
  454.  
  455.     /**
  456.      * Creates the page for displaying the package file manager
  457.      * options that relate to the entire package, regardless of
  458.      * the release.
  459.      *
  460.      * Package options are those such as: base install directory,
  461.      * the license, the package name, etc.
  462.      *
  463.      * @param  none 
  464.      * @return array 
  465.      * @access private
  466.      */
  467.     function _createPackagePage()
  468.     {
  469.         // Create some containers.
  470.         $mainVBox =new GtkVBox();
  471.  
  472.         // Create the hbox for the file selection.
  473.         $packageDirHBox =new GtkHBox();
  474.  
  475.         // We need an entries for the file.
  476.         $packageDirEntry  =new GtkEntry();
  477.         $packageDirButton =new GtkButton('Select');
  478.  
  479.         // Allow users to drop files in the entry box if possible.
  480.         @include_once 'Gtk/FileDrop.php';
  481.         if (class_exists('Gtk_FileDrop')) {
  482.             Gtk_FileDrop::attach($packageDirEntryarray('inode/directory'));
  483.         }
  484.  
  485.         // Create the file selection.
  486.         $packageDirFS =new GtkFileSelection('Package Directory');
  487.         $packageDirFS->set_position(GTK_WIN_POS_CENTER);
  488.  
  489.         // Set the default path to the pear directory.
  490.         require_once 'PEAR/Config.php';
  491.         $pearConfig =new PEAR_Config();
  492.         $packageDirFS->set_filename($pearConfig->get('php_dir'));
  493.  
  494.         // Make the ok button set the entry value.
  495.         $okButton $packageDirFS->ok_button;
  496.         $okButton->connect_object('clicked'array(&$this'_setPackageDirEntry')$packageDirEntry$packageDirFS);
  497.  
  498.         // Make the cancel button hide the selection.
  499.         $cancelButton $packageDirFS->cancel_button;
  500.         $cancelButton->connect_object('clicked'array(&$packageDirFS'hide'));
  501.  
  502.         // Make the button show the file selection.
  503.         $packageDirButton->connect_object('clicked'array(&$packageDirFS'show'));
  504.         
  505.         // Pack the package file directory pieces.
  506.         $packageDirLabel =new GtkLabel('Package File Directory');
  507.         $packageDirLabel->set_usize(140-1);
  508.         $packageDirLabel->set_alignment(0.5);
  509.  
  510.         $packageDirHBox->pack_start($packageDirLabelfalsefalse3);
  511.         $packageDirHBox->pack_start($packageDirEntry,  falsefalse3);
  512.         $packageDirHBox->pack_start($packageDirButtonfalsefalse3);
  513.  
  514.         // We need an entry for the package name.
  515.         $packageNameEntry =new GtkEntry();
  516.         $packageNameBox   =new GtkHBox();
  517.         $packageNameLabel =new GtkLabel('Package Name');
  518.         $packageNameLabel->set_usize(140-1);
  519.         $packageNameLabel->set_alignment(0.5);
  520.         $packageNameBox->pack_start($packageNameLabelfalsefalse3);
  521.         $packageNameBox->pack_start($packageNameEntryfalsefalse3);
  522.  
  523.         // We need a simple entry box for the base install directory.
  524.         $baseEntry =new GtkEntry();
  525.         $baseBox   =new GtkHBox();
  526.         $baseLabel =new GtkLabel('Base Install Dir');
  527.         $baseLabel->set_usize(140-1);
  528.         $baseLabel->set_alignment(0.5);
  529.         $baseBox->pack_start($baseLabelfalsefalse3);
  530.         $baseBox->pack_start($baseEntryfalsefalse3);
  531.  
  532.         // We need an entry for the summary.
  533.         $summaryEntry =new GtkEntry();
  534.         $summaryBox   =new GtkHBox();
  535.         $summaryLabel =new GtkLabel('Package Summary');
  536.         $summaryLabel->set_usize(140-1);
  537.         $summaryLabel->set_alignment(0.5);
  538.         $summaryBox->pack_start($summaryLabelfalsefalse3);
  539.         $summaryBox->pack_start($summaryEntryfalsefalse3);
  540.  
  541.         // We need a text area for the description.
  542.         $descriptionText =new GtkText();
  543.         $descriptionBox   =new GtkVBox();
  544.         $descriptionLabel =new GtkLabel('Package Description');
  545.  
  546.         $descriptionLabel->set_usize(140-1);
  547.         $descriptionLabel->set_alignment(0.5);
  548.         $descriptionText->set_editable(true);
  549.         $descriptionText->set_line_wrap(true);
  550.         $descriptionText->set_word_wrap(true);
  551.         $descriptionText->set_usize(-1100);
  552.  
  553.         $descriptionBox->pack_start($descriptionLabelfalsefalse3);
  554.         $descriptionBox->pack_start($descriptionTexttruetrue3);
  555.  
  556.         // We need a button to do the work.
  557.         $submitButton =new GtkButton('Submit');
  558.         $submitButton->connect_object('clicked'array(&$this'_setPackageOptions')$packageDirEntry$packageNameEntry$baseEntry$summaryEntry$descriptionText);
  559.  
  560.         $submitBox =new GtkHBox();
  561.         $submitBox->pack_end($submitButtonfalsefalse5);
  562.  
  563.         // Import the options if there is a package.xml file
  564.         // in the package directory.
  565.         $packageDirEntry->connect('changed'array(&$this'_importPackageOptions')$packageNameEntry$baseEntry$summaryEntry$descriptionText);
  566.  
  567.         // Pack everything away.
  568.         $mainVBox->pack_start($packageDirHBoxfalsefalse3);
  569.         $mainVBox->pack_start($packageNameBoxfalsefalse3);
  570.         $mainVBox->pack_start($baseBox,        falsefalse3);
  571.         $mainVBox->pack_start($summaryBox,     falsefalse3);
  572.         $mainVBox->pack_start($descriptionBoxtrue,  true,  3);
  573.         $mainVBox->pack_start($submitBox,      falsefalse3);
  574.  
  575.         return array(&$mainVBoxnew GtkLabel('Package'));
  576.     }
  577.  
  578.     /**
  579.      * Creates the page for displaying the package file
  580.      * manager release options fields.
  581.      *
  582.      * The release options consist of features including, the
  583.      * release date, the package version and state, and the
  584.      * release notes.
  585.      * 
  586.      * Options that do not relate to individual releases are
  587.      * covered on a seperate page.
  588.      * 
  589.      * @param  none 
  590.      * @return array 
  591.      * @access private
  592.      */
  593.     function _createReleasePage()
  594.     {
  595.         // Create some containers.
  596.         $mainVBox =new GtkVBox();
  597.         
  598.         // We need a combo list for the version.
  599.         $stateCombo =new GtkCombo();
  600.  
  601.         // Set up the combo.
  602.         $stateList  =  $stateCombo->list;
  603.         $stateEntry =  $stateCombo->entry;
  604.         $stateList->set_selection_mode(GTK_SELECTION_SINGLE);
  605.         $stateEntry->set_text('Select One');
  606.         $stateEntry->set_editable(false);
  607.  
  608.         // Add the states to the select box.
  609.         $states = array('alpha''beta''stable');
  610.         for ($i = 0; $i count($states)$i++{
  611.             $item  =new GtkListItem();
  612.             $box   =new GtkHBox();
  613.             $label =new GtkLabel($states[$i]);
  614.             $box->pack_start($labelfalsefalse10);
  615.             $item->add($box);
  616.             $stateCombo->set_item_string($item$states[$i]);
  617.             $item->set_data('state'$states[$i]);
  618.             $stateList->add($item);
  619.             $item->show_all();
  620.         }
  621.  
  622.         // Put the state combo in a box.
  623.         $stateBox =new GtkHBox();
  624.         $stateLabel =new GtkLabel('State');
  625.         $stateLabel->set_usize(140-1);
  626.         $stateLabel->set_alignment(0.5);
  627.         $stateBox->pack_start($stateLabelfalsefalse3);
  628.         $stateBox->pack_start($stateCombofalsefalse3);
  629.  
  630.         // We need a simple entry box for the version.
  631.         $verEntry =new GtkEntry();
  632.         $verBox   =new GtkHBox();
  633.         $verLabel =new GtkLabel('Version');
  634.         $verLabel->set_usize(140-1);
  635.         $verLabel->set_alignment(0.5);
  636.         $verBox->pack_start($verLabelfalsefalse3);
  637.         $verBox->pack_start($verEntryfalsefalse3);
  638.  
  639.         // Create a text box for the release notes.
  640.         $notes =new GtkText();
  641.         $notes->set_word_wrap(false);
  642.         $notes->set_line_wrap(true);
  643.         $notes->set_editable(true);
  644.         
  645.         // Put the notes stuff in a box with a label.
  646.         $notesBox   =new GtkVBox();
  647.         $notesLabel =new GtkLabel('Release Notes');
  648.         $notesLabel->set_alignment(0.5);
  649.  
  650.         $notesBox->pack_start($notesLabelfalsefalse3);
  651.         $notesBox->pack_start($notes,      falsefalse3);
  652.  
  653.         // We need a button to do the work.
  654.         $submitButton =new GtkButton('Submit');
  655.         $submitButton->connect_object('clicked'array(&$this'_setReleaseOptions')$stateCombo$verEntry$notes);
  656.  
  657.         $submitBox =new GtkHBox();
  658.         $submitBox->pack_end($submitButtonfalsefalse5);
  659.  
  660.         // Pack the containers into the main container.
  661.         $mainVBox->pack_start($stateBox,       falsefalse3);
  662.         $mainVBox->pack_start($verBox,         falsefalse3);
  663.         $mainVBox->pack_start($notesBox,       falsefalse6);
  664.         $mainVBox->pack_start($submitBox,      falsefalse6);
  665.  
  666.         return array($mainVBoxnew GtkLabel('Release'));
  667.     }
  668.  
  669.     /**
  670.      * Creates a page for displaying (and clearing) warnings.
  671.      *
  672.      * The warnings page consists of a text area and a button.
  673.      * The text area should be set to wrap text but not be
  674.      * editable. The button should clear the text area of any
  675.      * warnings.
  676.      *
  677.      * @param  none 
  678.      * @return array 
  679.      * @access private
  680.      */
  681.     function _createWarningsPage()
  682.     {
  683.         // Pack everything in a vBox.
  684.         $vBox =new GtkVBox();
  685.         $sWin =new GtkScrolledWindow();
  686.         $sWin->set_policy(GTK_POLICY_AUTOMATICGTK_POLICY_AUTOMATIC);
  687.  
  688.         // Set up the warnings area.
  689.         $this->warningsArea =new GtkText();
  690.         $this->warningsArea->set_editable(false);
  691.         $this->warningsArea->set_word_wrap(true);
  692.         $sWin->add($this->warningsArea);
  693.  
  694.         // Add a button to clear the warnings area.
  695.         $hBox   =new GtkHBox();
  696.         $button =new GtkButton('Clear');
  697.         $button->connect_object('clicked'array(&$this->warningsArea'delete_text')0-1);
  698.         $hBox->pack_end($buttonfalsefalse5);
  699.         
  700.         // Pack everything in.
  701.         $vBox->pack_start($sWintruetrue10);
  702.         $vBox->pack_start($hBoxfalsetrue);
  703.  
  704.         return array($vBoxnew GtkLabel('Warnings'));
  705.     }
  706.  
  707.     /**
  708.      * Creates a page for gathering information about developers.
  709.      *
  710.      * The add maintainer page needs to get the developer's name,
  711.      * handle, email address and role. The role should be a
  712.      * GtkCombo which doesn't allow the user to enter anything
  713.      * that is not a valid role.
  714.      *
  715.      * @param  none 
  716.      * @return array 
  717.      * @access private
  718.      */
  719.     function _createAddMaintainersPage()
  720.     {
  721.         // To lay things out, use a combination of h and v boxes.
  722.         $mainVBox  =new GtkVBox();
  723.         $mainHBox  =new GtkHBox();
  724.         $leftVBox  =new GtkVBox();
  725.         $rightVBox =new GtkVBox();
  726.         $subHBox   =new GtkHBox();
  727.  
  728.         // We need to display the current maintainers in a cList
  729.         $currentList =new GtkCList(3array('Developer''Email''Role'));
  730.  
  731.         // Make the first two columns auto resize and sort
  732.         // the list.
  733.         $currentList->set_column_auto_resize(0true);
  734.         $currentList->set_column_auto_resize(1true);
  735.         $currentList->set_auto_sort(true);
  736.  
  737.         // Add the current maintainers to the list.
  738.         $this->_listDevelopers($currentList);
  739.         
  740.         // We need three entries and three labels.
  741.         $handleEntry =new GtkEntry();
  742.         $handleLabel =new GtkLabel('Handle');
  743.         $nameEntry   =new GtkEntry();
  744.         $nameLabel   =new GtkLabel('Name');
  745.         $emailEntry  =new GtkEntry();
  746.         $emailLabel  =new GtkLabel('Email');
  747.         
  748.         // We also need a combo for the developer role.
  749.         $roleLabel =new GtkLabel('Role');
  750.         $roleCombo =new GtkCombo();
  751.  
  752.         // Set up the combo.
  753.         $roleList  =  $roleCombo->list;
  754.         $roleEntry =  $roleCombo->entry;
  755.         $roleList->set_selection_mode(GTK_SELECTION_SINGLE);
  756.         $roleEntry->set_text('Select One');
  757.         $roleEntry->set_editable(false);
  758.  
  759.         // Add the roles to the select box.
  760.         $roles = array('Contributor''Developer''Helper''Lead');
  761.         for ($i = 0; $i count($roles)$i++{
  762.             $item  =new GtkListItem();
  763.             $box   =new GtkHBox();
  764.             $label =new GtkLabel($roles[$i]);
  765.             $box->pack_start($labelfalsefalse10);
  766.             $item->add($box);
  767.             $roleCombo->set_item_string($item$roles[$i]);
  768.             $item->set_data('role'$roles[$i]);
  769.             $roleList->add($item);
  770.             $item->show_all();
  771.         }
  772.  
  773.         // We need a button to do the work.
  774.         $button =new GtkButton('Add Maintainer');
  775.         $button->connect_object('clicked'array(&$this'_addMaintainer')$handleEntry$roleCombo$nameEntry$emailEntry$currentList);
  776.  
  777.         // Put it all together.
  778.         // All of the labels should be aligned.
  779.         $handleLabel->set_alignment(1.5);
  780.         $nameLabel->set_alignment(1.5);
  781.         $emailLabel->set_alignment(1.5);
  782.         $roleLabel->set_alignment(1.5);
  783.  
  784.         // The left VBox is for the labels.
  785.         $leftVBox->pack_start($handleLabelfalsetrue3);
  786.         $leftVBox->pack_start($nameLabel,   falsetrue3);
  787.         $leftVBox->pack_start($emailLabel,  falsetrue3);
  788.         $leftVBox->pack_start($roleLabel,   falsetrue3);
  789.         
  790.         // The right VBox is for the entries and the combo.
  791.         $rightVBox->pack_start($handleEntryfalsefalse0);
  792.         $rightVBox->pack_start($nameEntry,   falsefalse0);
  793.         $rightVBox->pack_start($emailEntry,  falsefalse0);
  794.         $rightVBox->pack_start($roleCombo,   falsefalse0);
  795.  
  796.         // The two VBoxes go in the main HBox.
  797.         $mainHBox->pack_start($leftVBox,  truetrue2);
  798.         $mainHBox->pack_start($rightVBoxtruetrue20);
  799.         
  800.         // The subHBox holds the button.
  801.         $subHBox->pack_end($buttonfalsefalse20);
  802.  
  803.         // The label and the two HBoxes go in the main VBox.
  804.         $mainVBox->pack_start($mainHBox,    falsefalse10);
  805.         $mainVBox->pack_start($subHBox,     falsefalse2);
  806.         $mainVBox->pack_start($currentListfalsefalse2);
  807.         
  808.         // Return the page information.
  809.         return array(&$mainVBoxnew GtkLabel('Maintainers'));
  810.     }
  811.  
  812.     /**
  813.      * Add the widgets that make up the dependencies page.
  814.      *
  815.      * The dependencies page consists of one widget to
  816.      * display installed packages, one widget to display
  817.      * packages selected as dependencies, a button to clear
  818.      * the selected list and a button to add the dependencies.
  819.      *
  820.      * @param  none 
  821.      * @return array 
  822.      * @access private
  823.      */
  824.     function _createAddDependenciesPage()
  825.     {
  826.         // An HBox holds everything.
  827.         $mainVBox =new GtkVBox();
  828.         
  829.         // Two VBoxes hold the tree and list.
  830.         $topVBox    =new GtkVBox();
  831.         $bottomVBox =new GtkVBox();
  832.         $buttonHBox =new GtkHBox();
  833.  
  834.         // We need a label to make to tell people to click
  835.         // the package make it optional.
  836.         $instructions =new GtkLabel('Click a package to make it an optional dependency.');
  837.  
  838.         // Put the tree in a scrolling window.
  839.         $treeScrolledWindow =new GtkScrolledWindow();
  840.         $treeScrolledWindow->set_policy(GTK_POLICY_NEVERGTK_POLICY_AUTOMATIC);
  841.         $listScrolledWindow =new GtkScrolledWindow();
  842.         $listScrolledWindow->set_policy(GTK_POLICY_AUTOMATICGTK_POLICY_AUTOMATIC);
  843.         $treeScrolledWindow->set_usize(200150);
  844.         $listScrolledWindow->set_usize(200150);
  845.  
  846.         // Create the tree.
  847.         $cTree =new GtkCTree(10);
  848.         $cTree->set_line_style(GTK_CTREE_LINES_SOLID);
  849.         $root  =$cTree->insert_node(NULLNULLarray('Packages')0NULLNULLNULLNULLNULLNULL);
  850.  
  851.         // Use PEAR_Registry to build the tree.
  852.         require_once 'PEAR/Registry.php';
  853.         $reg = new PEAR_Registry();
  854.  
  855.         // Loop through the packages and add a node for each
  856.         // package with a child for the version.
  857.         foreach ($reg->packageInfo(as $package{
  858.             // I don't know why but some return info from PEAR_Registry
  859.             // has no package name. That aint cool!
  860.             if (empty($package['package'])) {
  861.                 continue;
  862.             }
  863.  
  864.             $name    =$cTree->insert_node($rootNULLarray($package['package'])0NULLNULLNULLNULLNULLNULL);
  865.             $version =$cTree->insert_node($nameNULLarray($package['version'])0NULLNULLNULLNULLNULLNULL);
  866.  
  867.             // Set some data so that we can tell what the user
  868.             // selected later.
  869.             $cTree->node_set_row_data($versionarray($package['package']$package['version']''));
  870.             
  871.             // Add the older versions if there are any.
  872.             if (count($package['changelog'])) {
  873.                 foreach($package['changelog'as $change{
  874.                     if ($change['version'!= $package['version']{
  875.                         $oldVersion =$cTree->insert_node($nameNULLarray($change['version'])0NULLNULLNULLNULLNULLNULL);
  876.                         $cTree->node_set_row_data($oldVersionarray($package['package']$change['version']''));
  877.                     }
  878.                 }
  879.             }
  880.         }
  881.         
  882.         // Organize the list.
  883.         $cTree->sort();
  884.  
  885.         // Create a GtkCList to show the added dependencies.
  886.         $cList =new GtkCList(3array('Package''Version''Optional'));
  887.  
  888.         // Make the first column automatically adjust to
  889.         // the needed width.
  890.         $cList->set_column_auto_resize(0true);
  891.         
  892.         // Automatically sort the entries.
  893.         $cList->set_auto_sort(true);
  894.  
  895.         // When the user selects a package we want to toggle
  896.         // its optional status.
  897.         $cList->connect('select-row'array(&$this'_toggleOptional'));
  898.  
  899.         // Connect the tree-select-row so that the user
  900.         // can add information.
  901.         $cTree->connect('tree-select-row'array(&$this'_treeToCList')$cList);
  902.  
  903.         // Show dependencies from import in cList.
  904.         $this->_getDependencies($cList);
  905.  
  906.         // Add some buttons to make things a little easier to
  907.         // work with.
  908.         $clearButton =new GtkButton('Clear');
  909.         $addButton   =new GtkButton('Add Dependencies');
  910.  
  911.         // We also want an auto detect button.
  912.         $autoButton  =new GtkButton('Auto Detect');
  913.  
  914.         // The clear but should clear out the cList.
  915.         // Clearing dependencies already in a package file
  916.         // is not possible.
  917.         $clearButton->connect_object('clicked'array(&$cList'clear'));
  918.         $clearButton->connect_object('clicked'array(&$this->_packageFileManager'setOptions')$this->_options + array('deps' => array()));
  919.  
  920.         // The auto detect button should be connected to the PFM
  921.         // detectDependencies method.
  922.         $autoButton->connect_object('clicked'array(&$this->_packageFileManager'detectDependencies'));
  923.  
  924.         // We need to let the user know that it did something.
  925.         $autoButton->connect_object_after('clicked'array(&$this'_getDependencies')$cList);
  926.  
  927.         // The add button should add the dependencies from the cList
  928.         // to the package. 
  929.         $addButton->connect_object('clicked'array(&$this'_addDependencies')$cList);
  930.  
  931.         // Pack everything away.
  932.         $treeScrolledWindow->add($cTree);
  933.         $topVBox->pack_start($treeScrolledWindow);
  934.  
  935.         $listScrolledWindow->add($cList);
  936.         $bottomVBox->pack_start($listScrolledWindow);
  937.  
  938.         $buttonHBox->pack_start($clearButtonfalsefalse3);
  939.         $buttonHBox->pack_start($autoButtonfalsefalse3);
  940.         $buttonHBox->pack_end($addButtonfalsefalse3);
  941.  
  942.         $mainVBox->pack_start($topVBox);
  943.         $mainVBox->pack_start($bottomVBox);
  944.         $mainVBox->pack_start($instructions);
  945.         $mainVBox->pack_start($buttonHBox);
  946.  
  947.         return array(&$mainVBoxnew GtkLabel('Depenedencies'));
  948.     }
  949.  
  950.     /**
  951.      * Creates the container and label for the add replacements
  952.      * page.
  953.      *
  954.      * Replacements are install time search and replace strings
  955.      * that can be used to set certain package variables to
  956.      * values found on the user's system or that are specific
  957.      * to the version of the installed package.
  958.      *
  959.      * This package uses a replacement to put the proper version
  960.      * number in the about window so that I don't have to go and
  961.      * recode that every time.
  962.      *
  963.      * @param  none 
  964.      * @return array   The page container and a label for the tab.
  965.      * @access private
  966.      */
  967.     function _createAddReplacementsPage()
  968.     {
  969.         // Create the main box.
  970.         $mainVBox    =new GtkVBox();
  971.  
  972.         // And the sub boxes
  973.         $globalVBox  =new GtkVBox();
  974.         $globalHBox0 =new GtkHBox();
  975.         $globalHBox1 =new GtkHBox();
  976.         $globalHBox2 =new GtkHBox();
  977.         $globalHBox3 =new GtkHBox();
  978.  
  979.         $fileVBox    =new GtkVBOX();
  980.         $fileHBox0   =new GtkHBox();
  981.         $fileHBox1   =new GtkHBox();
  982.         $fileHBox2   =new GtkHBox();
  983.         $fileHBox3   =new GtkHBox();
  984.         $fileHBox4   =new GtkHBox();
  985.  
  986.         // Create two success/failure labels.
  987.         $globalSuccess =new GtkLabel('');
  988.         $fileSuccess   =new GtkLabel('');
  989.  
  990.         // There are two types of replacements: Global and file.
  991.         // First we will set up the global replacements.
  992.         // We can do this with a few combo boxes. We will use 
  993.         // one for the type and one for the to value. The to 
  994.         // values are basically predefined sets that won't 
  995.         // change much. I am not concerned about hard coding 
  996.         // these values into the application. 
  997.         
  998.         // We need to work kind of backwards and create the many
  999.         // to widgets first. Then we can create the type combo.
  1000.         $globalToPHP     =new GtkEntry();
  1001.         $globalToPEAR    =new GtkCombo();
  1002.         $globalToPackage =new GtkCombo();
  1003.         $globalToWidgets = array('php-const'    => &$globalToPHP,
  1004.                                  'pear-config'  => &$globalToPEAR,
  1005.                                  'package-info' => &$globalToPackage
  1006.                                  );
  1007.  
  1008.         // We need a box for the to widgets so that we can swap
  1009.         // them out.
  1010.         $globalToWidgetBox =new GtkHBox();
  1011.  
  1012.         // The PHP widget is easy. It is just an entry because
  1013.         // there are way to many constants to list.
  1014.         
  1015.         // The PEAR widget on the other hand has a shorter list
  1016.         // of valid values. We will get them using PEAR_Config.
  1017.         $globalToPEARList  $globalToPEAR->list;
  1018.         $globalToPEAREntry $globalToPEAR->entry;
  1019.         $globalToPEARList->set_selection_mode(GTK_SELECTION_SINGLE);
  1020.         $globalToPEAREntry->set_text('Select One');
  1021.         $globalToPEAREntry->set_editable(false);
  1022.  
  1023.         // Add the valid values to the list.
  1024.         require_once 'PEAR/Config.php';
  1025.         $pearConfig =new PEAR_Config();
  1026.         foreach ($pearConfig->getKeys(as $pearConfigKey{
  1027.             $item  =new GtkListItem();
  1028.             $box   =new GtkHBox();
  1029.             $label =new GtkLabel($pearConfigKey);
  1030.             $box->pack_start($labelfalsefalse10);
  1031.             $item->add($box);
  1032.             $globalToPEAR->set_item_string($item$pearConfigKey);
  1033.             $item->set_data('type'$pearConfigKey);
  1034.             $globalToPEARList->add($item);
  1035.             $item->show_all();
  1036.         }
  1037.  
  1038.         // The package-info widget is a little different. I can't 
  1039.         // find a method to get the legal values for this set of
  1040.         // replacements. Therefore, I have to hard code the array.
  1041.         // It will also serve as the array for the file replacements.
  1042.         $globalToPackageList  $globalToPackage->list;
  1043.         $globalToPackageEntry $globalToPackage->entry;
  1044.         $globalToPackageList->set_selection_mode(GTK_SELECTION_SINGLE);
  1045.         $globalToPackageEntry->set_text('Select One');
  1046.         $globalToPackageEntry->set_editable(false);
  1047.  
  1048.         $packageOptions = array('name''summary''description''version',
  1049.                                 'license''state''notes''date');
  1050.         foreach ($packageOptions as $option{
  1051.             $item  =new GtkListItem();
  1052.             $box   =new GtkHBox();
  1053.             $label =new GtkLabel($option);
  1054.             $box->pack_start($labelfalsefalse10);
  1055.             $item->add($box);
  1056.             $globalToPackage->set_item_string($item$option);
  1057.             $item->set_data('type'$option);
  1058.             $globalToPackageList->add($item);
  1059.             $item->show_all();
  1060.         }
  1061.  
  1062.  
  1063.         // The globalType combo will not change.
  1064.         $globalTypeCombo =new GtkCombo();
  1065.  
  1066.         // Set up the combo.
  1067.         $globalTypeList  =  $globalTypeCombo->list;
  1068.         $globalTypeEntry =  $globalTypeCombo->entry;
  1069.         $globalTypeList->set_selection_mode(GTK_SELECTION_SINGLE);
  1070.         $globalTypeEntry->set_text('Select One');
  1071.         $globalTypeEntry->set_editable(false);
  1072.  
  1073.         // When the entry's value changes, we want to change the
  1074.         // to widget.
  1075.         $globalTypeEntry->connect('changed'array(&$this'_switchToWidget')$globalToWidgets$globalToWidgetBox);
  1076.  
  1077.         // Add the globalTypes to the select box.
  1078.         $globalTypes = array('php-const''pear-config''package-info');
  1079.         for ($i = 0; $i count($globalTypes)$i++{
  1080.             $item  =new GtkListItem();
  1081.             $box   =new GtkHBox();
  1082.             $label =new GtkLabel($globalTypes[$i]);
  1083.             $box->pack_start($labelfalsefalse10);
  1084.             $item->add($box);
  1085.             $globalTypeCombo->set_item_string($item$globalTypes[$i]);
  1086.             $item->set_data('type'$globalTypes[$i]);
  1087.             $globalTypeList->add($item);
  1088.             $item->show_all();
  1089.         }
  1090.  
  1091.         // The last part of the global puzzle is the from widget.
  1092.         // This is just an entry that will hold the value in the
  1093.         // package files that should be replaced.
  1094.         // Example: 0.11.0
  1095.         $globalFromEntry =new GtkEntry();
  1096.  
  1097.         // It also helps to have buttons to do the actual work.
  1098.         $globalButtonBox =new GtkHBox();
  1099.         $globalAddButton =new GtkButton('Add Replacement');
  1100.         
  1101.         $globalAddButton->connect_object('clicked'array($this'_addReplacement')NULL$globalTypeCombo$globalToWidgetBox$globalFromEntry$globalSuccess);
  1102.         
  1103.         $globalButtonBox->pack_end($globalAddButtonfalsefalse5);
  1104.  
  1105.         // Next we will set up the file specific replacments.
  1106.         // For this we will need a way to get all of the files
  1107.         // that are to be included in the packaging. If PFM 
  1108.         // doesn't have a public method for getting these files
  1109.         // then we will not be able to do this. It will be up to
  1110.         // the developer to edit the file manually.
  1111.         // Until there is a public method, we can use the
  1112.         // PEAR_PackageFileManager_File class to get all of the
  1113.         // files.
  1114.         
  1115.         // Start by creating the widgets for each field.
  1116.         $fileFileCombo   =new GtkCombo();
  1117.         $fileTypeCombo   =new GtkCombo();
  1118.         $fileFromEntry   =new GtkEntry();
  1119.         $fileToWidgetBox =new GtkHBox();
  1120.         $fileToPHP       =new GtkEntry();
  1121.         $fileToPEAR      =new GtkCombo();
  1122.         $fileToPackage   =new GtkCombo();
  1123.         $fileToWidgets   =  array('php-const'    => &$fileToPHP,
  1124.                                   'pear-config'  => &$fileToPEAR,
  1125.                                   'package-info' => &$fileToPackage
  1126.                                   );
  1127.  
  1128.         // Next fill the file combo list.
  1129.         $fileFileList  =  $fileFileCombo->list;
  1130.         $fileFileEntry =  $fileFileCombo->entry;
  1131.         $fileFileList->set_selection_mode(GTK_SELECTION_SINGLE);
  1132.         $fileFileEntry->set_text('Select One');
  1133.         $fileFileEntry->set_editable(false);
  1134.         
  1135.         // Create a file list generator.
  1136.         // We can't do this until after we have the package options.
  1137.         require_once 'PEAR/PackageFileManager/File.php';
  1138.         $pfmFile = new PEAR_PackageFileManager_File($this->_packageFileManager$this->_options);
  1139.         foreach ($pfmFile->dirList($this->_options['packagedirectory']as $file{
  1140.             if (PEAR::isError($file)) {
  1141.                 $this->_pushWarning($result->getCode()array());
  1142.                 break;
  1143.             }
  1144.             // Shorten file to a relative path from the package directory.
  1145.             $shortFile substr($filestrlen($this->_options['packagedirectory']));
  1146.  
  1147.             $item  =new GtkListItem();
  1148.             $box   =new GtkHBox();
  1149.             $label =new GtkLabel($shortFile);
  1150.             $box->pack_start($labelfalsefalse10);
  1151.             $item->add($box);
  1152.             $fileFileCombo->set_item_string($item$shortFile);
  1153.             $item->set_data('type'$file);
  1154.             $fileFileList->add($item);
  1155.             $item->show_all();
  1156.         }
  1157.  
  1158.         // The PHP widget is easy. It is just an entry because
  1159.         // there are way to many constants to list.
  1160.         
  1161.         // The PEAR widget on the other hand has a shorter list
  1162.         // of valid values. We will get them using PEAR_Config.
  1163.         $fileToPEARList  $fileToPEAR->list;
  1164.         $fileToPEAREntry $fileToPEAR->entry;
  1165.         $fileToPEARList->set_selection_mode(GTK_SELECTION_SINGLE);
  1166.         $fileToPEAREntry->set_text('Select One');
  1167.         $fileToPEAREntry->set_editable(false);
  1168.  
  1169.         // Add the valid values to the list.
  1170.         foreach ($pearConfig->getKeys(as $pearConfigKey{
  1171.             $item  =new GtkListItem();
  1172.             $box   =new GtkHBox();
  1173.             $label =new GtkLabel($pearConfigKey);
  1174.             $box->pack_start($labelfalsefalse10);
  1175.             $item->add($box);
  1176.             $fileToPEAR->set_item_string($item$pearConfigKey);
  1177.             $item->set_data('type'$pearConfigKey);
  1178.             $fileToPEARList->add($item);
  1179.             $item->show_all();
  1180.         }
  1181.  
  1182.         // The package-info widget is a little different. I can't 
  1183.         // find a method to get the legal values for this set of
  1184.         // replacements. Therefore, I have to hard code the array.
  1185.         // It will also serve as the array for the file replacements.
  1186.         $fileToPackageList  $fileToPackage->list;
  1187.         $fileToPackageEntry $fileToPackage->entry;
  1188.         $fileToPackageList->set_selection_mode(GTK_SELECTION_SINGLE);
  1189.         $fileToPackageEntry->set_text('Select One');
  1190.         $fileToPackageEntry->set_editable(false);
  1191.  
  1192.         $packageOptions = array('name''summary''description''version',
  1193.                                 'license''state''notes''date');
  1194.         foreach ($packageOptions as $option{
  1195.             $item  =new GtkListItem();
  1196.             $box   =new GtkHBox();
  1197.             $label =new GtkLabel($option);
  1198.             $box->pack_start($labelfalsefalse10);
  1199.             $item->add($box);
  1200.             $fileToPackage->set_item_string($item$option);
  1201.             $item->set_data('type'$option);
  1202.             $fileToPackageList->add($item);
  1203.             $item->show_all();
  1204.         }
  1205.  
  1206.  
  1207.         // The fileType combo will not change.
  1208.         $fileTypeCombo =new GtkCombo();
  1209.  
  1210.         // Set up the combo.
  1211.         $fileTypeList  =  $fileTypeCombo->list;
  1212.         $fileTypeEntry =  $fileTypeCombo->entry;
  1213.         $fileTypeList->set_selection_mode(GTK_SELECTION_SINGLE);
  1214.         $fileTypeEntry->set_text('Select One');
  1215.         $fileTypeEntry->set_editable(false);
  1216.  
  1217.         // When the entry's value changes, we want to change the
  1218.         // to widget.
  1219.         $fileTypeEntry->connect('changed'array(&$this'_switchToWidget')$fileToWidgets$fileToWidgetBox);
  1220.  
  1221.         // Add the fileTypes to the select box.
  1222.         $fileTypes = array('php-const''pear-config''package-info');
  1223.         for ($i = 0; $i count($fileTypes)$i++{
  1224.             $item  =new GtkListItem();
  1225.             $box   =new GtkHBox();
  1226.             $label =new GtkLabel($fileTypes[$i]);
  1227.             $box->pack_start($labelfalsefalse10);
  1228.             $item->add($box);
  1229.             $fileTypeCombo->set_item_string($item$fileTypes[$i]);
  1230.             $item->set_data('type'$fileTypes[$i]);
  1231.             $fileTypeList->add($item);
  1232.             $item->show_all();
  1233.         }
  1234.  
  1235.         // The last part of the file puzzle is the from widget.
  1236.         // This is just an entry that will hold the value in the
  1237.         // package files that should be replaced.
  1238.         // Example: 0.11.0
  1239.         $fileFromEntry =new GtkEntry();
  1240.  
  1241.         // It also helps to have buttons to do the actual work.
  1242.         $fileButtonBox =new GtkHBox();
  1243.         $fileAddButton =new GtkButton('Add Replacement');
  1244.         
  1245.         $fileAddButton->connect_object('clicked'array($this'_addReplacement')$fileFileCombo$fileTypeCombo$fileToWidgetBox$fileFromEntry$fileSuccess);
  1246.         
  1247.         $fileButtonBox->pack_end($fileAddButtonfalsefalse5);
  1248.  
  1249.         // Pack every thing up.
  1250.         $globalHBox0->pack_start($globalSuccesstrue ,true5);
  1251.         $globalHBox1->pack_start(new GtkLabel('Type:')false ,false5);
  1252.         $globalHBox1->pack_end($globalTypeCombofalse ,false5);
  1253.         $globalHBox2->pack_start(new GtkLabel('From: (ex: @php_bin@)')false ,false5);
  1254.         $globalHBox2->pack_end($globalFromEntryfalse ,false5);
  1255.         $globalHBox3->pack_start(new GtkLabel('To:')false ,false5);
  1256.         $globalHBox3->pack_end($globalToWidgetBoxfalse ,false5);
  1257.  
  1258.         // The global to widget box starts off the php-const entry.
  1259.         $globalToWidgetBox->pack_start($globalToPHPfalsefalse0);
  1260.         
  1261.         // Put the hBoxes in the vBox.
  1262.         $globalVBox->pack_start($globalHBox0,     falsefalse5);
  1263.         $globalVBox->pack_start($globalHBox1,     falsefalse5);
  1264.         $globalVBox->pack_start($globalHBox2,     falsefalse5);
  1265.         $globalVBox->pack_start($globalHBox3,     falsefalse5);
  1266.         $globalVBox->pack_start($globalButtonBoxfalsefalse5);
  1267.  
  1268.         // Pack up the file pieces.
  1269.         $fileHBox0->pack_start($fileSuccesstrue ,true5);
  1270.         $fileHBox1->pack_start(new GtkLabel('File:')false ,false5);
  1271.         $fileHBox1->pack_end($fileFileCombofalse ,false5);
  1272.         $fileHBox2->pack_start(new GtkLabel('Type:')false ,false5);
  1273.         $fileHBox2->pack_end($fileTypeCombofalse ,false5);
  1274.         $fileHBox3->pack_start(new GtkLabel('From: (ex: @php_bin@)')false ,false5);
  1275.         $fileHBox3->pack_end($fileFromEntryfalse ,false5);
  1276.         $fileHBox4->pack_start(new GtkLabel('To:')false ,false5);
  1277.         $fileHBox4->pack_end($fileToWidgetBoxfalse ,false5);
  1278.  
  1279.         // The file to widget box starts off the php-const entry.
  1280.         $fileToWidgetBox->pack_start($fileToPHPfalsefalse0);
  1281.         
  1282.         // Put the hBoxes in the vBox.
  1283.         $fileVBox->pack_start($fileHBox0,     falsefalse5);
  1284.         $fileVBox->pack_start($fileHBox1,     falsefalse5);
  1285.         $fileVBox->pack_start($fileHBox2,     falsefalse5);
  1286.         $fileVBox->pack_start($fileHBox3,     falsefalse5);
  1287.         $fileVBox->pack_start($fileHBox4,     falsefalse5);
  1288.         $fileVBox->pack_start($fileButtonBoxfalsefalse5);
  1289.  
  1290.         // Create a pretty frame for the global and file pieces.
  1291.         $globalFrame =new GtkFrame('Global Replacements');
  1292.         $fileFrame   =new GtkFrame('File Replacements');
  1293.         
  1294.         $globalFrame->set_shadow_type(GTK_SHADOW_OUT);
  1295.         $fileFrame->set_shadow_type(GTK_SHADOW_OUT);
  1296.  
  1297.         // Add the global and file boxes to the frames.
  1298.         $globalFrame->add($globalVBox);
  1299.         $fileFrame->add($fileVBox);
  1300.  
  1301.         // Put the global and file frames in the main box.
  1302.         $mainVBox->pack_start($globalFramefalsefalse5);
  1303.         $mainVBox->pack_start($fileFramefalsefalse5);
  1304.  
  1305.         return array(&$mainVBoxnew GtkLabel('Replacements'));
  1306.     }
  1307.  
  1308.     /**
  1309.      * Updates the package file directory entry with the value
  1310.      * from the file selection.
  1311.      *
  1312.      * Takes the value of the file selection and assigns it to
  1313.      * the entry widget. We have to use a helper method because
  1314.      * we need the value in real time. After the value is set,
  1315.      * the file selection is hidden.
  1316.      *
  1317.      * @param  object &$entry         The GtkEntry that should get the value.
  1318.      * @param  object &$fileSelection The GtkFileSelection holding the value.
  1319.      * @return void 
  1320.      * @access private
  1321.      */
  1322.     function _setPackageDirEntry(&$entry&$fileSelection)
  1323.     {
  1324.         $entry->set_text($fileSelection->get_filename());
  1325.         $fileSelection->hide();
  1326.     }
  1327.  
  1328.     /**
  1329.      * Sets that relate to the entire package, regardless of
  1330.      * the release.
  1331.      *
  1332.      * Package options are those such as: base install directory,
  1333.      * the license, the package name, etc. We can't set the options
  1334.      * until we have the rest from the release page. Therefore we
  1335.      * must temporarily store them in the _options member.
  1336.      *
  1337.      * If all goes well, the user will be taken to the next page.
  1338.      *
  1339.      * @param  object  $dirEntry    The GtkEntry holding the package directory.
  1340.      * @param  object  $nameEntry   The GtkEntry holding the package name.
  1341.      * @param  object  $baseInstall The GtkEntry holding the base install directory.
  1342.      * @return void 
  1343.      * @access private
  1344.      * @see    _setReleaseOptions()
  1345.      */
  1346.     function _setPackageOptions($dirEntry$nameEntry$baseInstall,
  1347.                                 $summaryEntry$descriptionText)
  1348.     {
  1349.         // Create an array to hold the information.
  1350.         $options = array();
  1351.         
  1352.         // Check to see of a package directory was given.
  1353.         if ($dirEntry->get_text()) {
  1354.             $options['packagedirectory'$dirEntry->get_text();
  1355.         }
  1356.  
  1357.         // Check to see if a package name was given.
  1358.         if ($nameEntry->get_text()) {
  1359.             $options['package'$nameEntry->get_text();
  1360.         }
  1361.  
  1362.         // Check to see fi a baseinstall directory was given.
  1363.         if ($baseInstall->get_text()) {
  1364.             $options['baseinstalldir'$baseInstall->get_text();
  1365.         }
  1366.  
  1367.         // Check to see if a package summary was given.
  1368.         if ($summaryEntry->get_text()) {
  1369.             $options['summary'$summaryEntry->get_text();
  1370.         }
  1371.  
  1372.         // Check to see if a package description was given.
  1373.         if ($descriptionText->get_chars(0-1)) {
  1374.             $options['description'$descriptionText->get_chars(0-1);
  1375.         }
  1376.         
  1377.         // Add to the options array. After we get the release 
  1378.         // options, these options array will be passed to the
  1379.         // package file manager.
  1380.         $this->_options += $options;
  1381.         $this->notebook->next_page();
  1382.     }
  1383.  
  1384.     /**
  1385.      * Sets the package file anager release options.
  1386.      *
  1387.      * The release options consist of features including, the
  1388.      * release date, the package version and state, and the
  1389.      * release notes.
  1390.      * 
  1391.      * Options that do not relate to individual releases are
  1392.      * adde with {@link _setPackageOptions}.
  1393.      * 
  1394.      * This method sets all the options including the package
  1395.      * options. If there are errors, the user will be taken to
  1396.      * the warnings page. If there are no errors the user will
  1397.      * be taken to the add maintainers page.
  1398.      *
  1399.      * @param  object  $state     The GtkCombo holding the state.
  1400.      * @param  object  $verEntry  The GtkEntry holding the version.
  1401.      * @param  object  $notesArea The GtkText holding the release notes.
  1402.      * @return void 
  1403.      * @access private
  1404.      * @see    _setPackageOptions()
  1405.      */
  1406.     function _setReleaseOptions($state$verEntry$notesArea)
  1407.     {
  1408.         $options = array();
  1409.  
  1410.         $stateItem $state->list->selection[0];        
  1411.         if (isset($stateItem)) {
  1412.             $options['state'$stateItem->get_data('state');
  1413.         }
  1414.         
  1415.         if ($verEntry->get_text()) {
  1416.             $options['version'$verEntry->get_text();
  1417.         }
  1418.  
  1419.         if ($notesArea->get_chars(0-1)) {
  1420.             $options['notes'$notesArea->get_chars(0-1);
  1421.         }
  1422.         
  1423.         // Add to the options array. When the file is saved,
  1424.         // the options array will be passed to the package
  1425.         // file manager.
  1426.         $this->_options += $options;
  1427.  
  1428.         // Set the options so that other things can be done.
  1429.         $result $this->_packageFileManager->setOptions($this->_options);
  1430.  
  1431.         // Check for errors.
  1432.         if (PEAR::isError($result)) {
  1433.             $this->_pushWarning($result->getCode()array());
  1434.             return;
  1435.         }
  1436.         
  1437.         // Now that the options are set, we can create some of 
  1438.         // the other pages.
  1439.         $this->_addNotebookPage($this->_createAddMaintainersPage(),  false);
  1440.         $this->_addNotebookPage($this->_createAddDependenciesPage()false);
  1441.         $this->_addNotebookPage($this->_createAddReplacementsPage()false);
  1442.  
  1443.         $this->notebook->next_page();
  1444.     }
  1445.  
  1446.     /**
  1447.      * Calls the package file manager's debug method.
  1448.      *
  1449.      * The file should always be previewed before it is saved.
  1450.      * 
  1451.      * @param  none 
  1452.      * @return void 
  1453.      * @access private
  1454.      * @see    _writePackageFile()
  1455.      */
  1456.     function _previewFile()
  1457.     {
  1458.         // Create the window.
  1459.         $previewWindow =new GtkWindow();
  1460.         $previewWindow->set_title('Preview');
  1461.  
  1462.         // Create some containers for layout.
  1463.         $frame =new GtkFrame('package.xml');
  1464.         $vBox  =new GtkVBox();
  1465.         $sWin  =new GtkScrolledWindow();
  1466.         $text  =new GtkText();
  1467.         
  1468.         // Set some display properties.
  1469.         $sWin->set_policy(GTK_POLICY_AUTOMATICGTK_POLICY_AUTOMATIC);
  1470.         $text->set_editable(false);
  1471.         $text->set_line_wrap(false);
  1472.         $text->set_usize(200200);
  1473.         
  1474.         // Add everything together.
  1475.         $previewWindow->add($vBox);
  1476.         $vBox->pack_start($frame);
  1477.         $frame->add($sWin);
  1478.         $sWin->add($text);
  1479.     
  1480.         // Get the preview and check for errors.
  1481.         ob_start();
  1482.  
  1483.         // I am calling writePackageFile with cli interface directly
  1484.         // because I don't ever want the user to see entities. It
  1485.         // is possible that they are running this app with PHP 
  1486.         // reporting as cgi. This accomplishes the same thing as
  1487.         // debugPackageFile() in command line mode.
  1488.         $result  $this->_packageFileManager->writePackageFile(false);
  1489.         $preview ob_get_contents();
  1490.  
  1491.         ob_end_clean();
  1492.  
  1493.         // Check for errors.
  1494.         if (PEAR::isError($result)) {
  1495.             $this->_pushWarning($result->getCode()array());
  1496.  
  1497.             // Get rid of the widgets to conserve resources.
  1498.             unset($text);
  1499.             unset($sWin);
  1500.             unset($frame);
  1501.             unset($vBox);
  1502.             unset($preiewWindow);
  1503.             return;
  1504.         }
  1505.  
  1506.         // Clear out any text that may be left over.
  1507.         $text->delete_text(0-1);
  1508.         
  1509.         // Add the preview text.
  1510.         $text->insert_text($preview0);
  1511.         
  1512.         // Add a close button and a save button.
  1513.         $bottomBox   =new GtkHBox();
  1514.         $closeButton =new GtkButton('Close');
  1515.         $saveButton  =new GtkButton('Save');
  1516.         
  1517.         $saveButton->connect_object('clicked'array(&$this'_writePackageFile'));
  1518.         $saveButton->connect_object_after('clicked'array(&$previewWindow'destroy'));
  1519.         $closeButton->connect_object('clicked'array(&$previewWindow'destroy'));
  1520.  
  1521.         // Pack the buttons together and add it to the window.
  1522.         $bottomBox->pack_start($closeButtonfalsefalse3);
  1523.         $bottomBox->pack_end($saveButtonfalsefalse3);
  1524.         $vBox->pack_start($bottomBoxfalsefalse3);
  1525.  
  1526.         // Show the window.
  1527.         $previewWindow->show_all();
  1528.  
  1529.         // Track that the file has been previewed.
  1530.         $this->previewed = true;
  1531.     }
  1532.  
  1533.     /**
  1534.      * Writes the package file to package.xml.
  1535.      *
  1536.      * The package file should be tested first using the
  1537.      * {@link _previewFile} method. The file is written to the
  1538.      * directory given as the package file directory on the
  1539.      * package page.
  1540.      *
  1541.      * If there are problems writing the file, the user will
  1542.      * be taken to the warnings page.
  1543.      * 
  1544.      * @param  none 
  1545.      * @return void 
  1546.      * @access private
  1547.      * @see    _previewPackageFile()
  1548.      */
  1549.     function _writePackageFile()
  1550.     {
  1551.         // Check that the file has been previewed first.
  1552.         if (!$this->previewed{
  1553.             $this->showWarnings('You must preview the file before you can save it.');
  1554.             $this->notebook->set_page(-1);
  1555.             return;
  1556.         }
  1557.         
  1558.         $result $this->_packageFileManager->writePackageFile();
  1559.  
  1560.         // Check for errors.
  1561.         if (PEAR::isError($result)) {
  1562.             $this->_pushWarning($result->getCode()array());
  1563.             return;
  1564.         }
  1565.         
  1566.         // Update the saved state.
  1567.         $this->saved = true;
  1568.     }
  1569.  
  1570.     /**
  1571.      * Uses PEAR to package the package.
  1572.      *
  1573.      * Does the same thing that calling $ pear package package.xml
  1574.      * would do but doesn't require the user to use the command
  1575.      * line.
  1576.      * 
  1577.      * @param  none 
  1578.      * @return void 
  1579.      * @access private
  1580.      */
  1581.     function _packagePackage()
  1582.     {
  1583.         // Check the saved state.
  1584.         // Don't need to check previewed because you can't save
  1585.         // unless you preview.
  1586.         if (!$this->saved{
  1587.             $this->showWarnings('You must save the file before you can package it.');
  1588.             $this->notebook->set_page(-1);
  1589.             return;
  1590.         }
  1591.  
  1592.         // Include PEAR_Packager
  1593.         require_once 'PEAR/Packager.php';
  1594.         
  1595.         // Package the file.
  1596.         $packager =new PEAR_Packager();
  1597.         $retVal $packager->package($this->_options['packagedirectory''/' 'package.xml');
  1598.  
  1599.         // Check for errors.
  1600.         if (PEAR::isError($result)) {
  1601.             $this->_pushWarning($result->getCode()array());
  1602.             return;
  1603.         }
  1604.     }
  1605.  
  1606.     /**
  1607.      * Adds the dependencies from the package file to the cList.
  1608.      *
  1609.      * This method adds the dependencies currently listed in the
  1610.      * package file to the cList. This will not retrieve any real
  1611.      * time additions.
  1612.      *
  1613.      * @param  object  $cList The list that should display the packages.
  1614.      * @return void 
  1615.      * @access private
  1616.      */
  1617.     function _getDependencies($cList)
  1618.     {
  1619.         $options $this->_packageFileManager->getOptions();
  1620.         foreach ($options['deps'as $dep{
  1621.             $this->_addToCList($cListarray($dep['name']$dep['version']($dep['optional'== 'yes' 'optional' '')));
  1622.         }
  1623.  
  1624.     }
  1625.  
  1626.     /**
  1627.      * Swaps out the current to widget with the needed one.
  1628.      *
  1629.      * The to widget gets changed to a widget that will let
  1630.      * the user enter an appropriate value. This can be either
  1631.      * an entry or a combo.
  1632.      *
  1633.      * This method can be used for both the global and file
  1634.      * replacements.
  1635.      * 
  1636.      * @param  object  $entry      The GtkEntry whose value was changed.
  1637.      * @param  array   &$toWidgets The possible to widgets.
  1638.      * @param  object  $toBox      The box that will hold the widget.
  1639.      * @return void 
  1640.      * @access private
  1641.      */
  1642.     function _switchToWidget($entry&$toWidgets$toBox)
  1643.     {
  1644.         // Figure out what the selected value is.
  1645.         $selection $entry->get_text();
  1646.  
  1647.         // Make sure something was selected.
  1648.         if (isset($selection)) {
  1649.             // Unparent the box's current child.
  1650.             $boxChild $toBox->children[0];
  1651.             $child    $boxChild->widget;
  1652.             if (isset($child)) {
  1653.                 $toBox->remove($child);
  1654.             }
  1655.  
  1656.             // Add the correct widget to the box.
  1657.             $toBox->pack_start($toWidgets[$selection]falsefalse0);
  1658.             $toBox->show_all();
  1659.         }
  1660.     }
  1661.  
  1662.     /**
  1663.      * Adds the replacement information to the package file manager.
  1664.      *
  1665.      * Both the global and file replacements use this method. The
  1666.      * difference is that global replacements do not supply a file
  1667.      * path.
  1668.      *
  1669.      * @param  object  $pathWidget The widget holding the file path.
  1670.      * @param  object  $typeWidget The widget holding the replace type.
  1671.      * @param  object  $toWidget   The widget holding the to value.
  1672.      * @param  object  $fromWidget The widget holding the from value.
  1673.      * @param  object  $status     The label that will inform success.
  1674.      * @return void 
  1675.      * @access private
  1676.      */
  1677.     function _addReplacement($pathWidget$typeWidget$toWidget$fromWidget$success)
  1678.     {
  1679.         // Reset the previewed and saved states.
  1680.         $this->previewed = false;
  1681.         $this->saved     = false;
  1682.  
  1683.         // Check to see if a widget was passed for the path.
  1684.         if (!isset($pathWidget)) {
  1685.             $path = NULL;
  1686.         else {
  1687.             $pathItem $pathWidget->list->selection[0];
  1688.  
  1689.             // Make sure something was selected.
  1690.             if (isset($pathItem)) {
  1691.                 $path strtolower($pathItem->get_data('role'));
  1692.             else {
  1693.                 $path '';
  1694.             }
  1695.         }
  1696.  
  1697.         // Collect the rest of the data.
  1698.         $typeItem $typeWidget->list->selection[0];
  1699.         $type     $typeItem->get_data('type');
  1700.  
  1701.         $toWidgetChild $toWidget->children[0];
  1702.         $toWidget      $toWidgetChild->widget;
  1703.         if (get_class($toWidget== 'gtkentry'{
  1704.             $to $toWidget->get_text();
  1705.         else {
  1706.             $toItem $toWidget->list->selection[0];
  1707.             $to     $toItem->get_data('type');
  1708.         }
  1709.  
  1710.         $from $fromWidget->get_text();
  1711.         
  1712.         // Make sure something was selected.
  1713.         if (!isset($type|| !isset($to|| !isset($from)) {
  1714.             $this->showWarnings((isset($pathWidget'File' 'Global'' Replacement information is missing. Please make sure all fields are filled.');
  1715.         }
  1716.  
  1717.         // Figure out which type of replacement this is <global|file>.
  1718.         if (!isset($pathWidget)) {
  1719.             // If no file path widget, this must be global.
  1720.             $result $this->_packageFileManager->addGlobalReplacement($type$from$to);
  1721.         else {
  1722.             // If there is a file path widget this must be a file
  1723.             // replacement.
  1724.             $result $this->_packageFileManager->addReplacement($path$type$from$to);
  1725.         }
  1726.  
  1727.         // Check for errors.
  1728.         if (PEAR::isError($result)) {
  1729.             $this->_pushWarning($result->getCode()array());
  1730.  
  1731.             // Make a note on the replacements page.
  1732.             $success->set_text('Replacement failed for ' $from);
  1733.  
  1734.             // Then jump to the warnings.
  1735.             $this->notebook->set_page(-1);
  1736.         else {
  1737.             // Make a note about successful replacement.
  1738.             $success->set_text($from ' will be replaced with ' $to);
  1739.  
  1740.             // Update the from widget as a second visual indication
  1741.             // of success.
  1742.             $fromWidget->set_text('');
  1743.         }
  1744.     }
  1745.  
  1746.     /**
  1747.      * Adds the data array to the GtkCList.
  1748.      *
  1749.      * First this method checks to see if the data is already
  1750.      * present. (It only checks the first column.) Then it
  1751.      * adds the data.
  1752.      *
  1753.      * @param  object  $cList The GtkCList to which data will be added.
  1754.      * @param  array   $data  The elements to be added to the list.
  1755.      * @access private
  1756.      */
  1757.     function _addToCList($cList$data)
  1758.     {
  1759.         // Look for the same first data element and remove it if found.
  1760.         for ($i = 0; $i $cList->rows; ++$i{
  1761.             if ($data[0== $cList->get_text($i0)) {
  1762.                 $cList->remove($i);
  1763.             }
  1764.         }
  1765.  
  1766.         // Add the package to the clist.
  1767.         $cList->insert(0$data);
  1768.     }
  1769.  
  1770.     /**
  1771.      * Takes data from the GtkCTree and puts it in the GtkCList.
  1772.      *
  1773.      * This is used to take the values from the dependency tree
  1774.      * and put them in the dependency list. Values are not added
  1775.      * as dependencies until the add dependencies button is
  1776.      * pressed.
  1777.      * 
  1778.      * When a row is selected, the tree and node are passed to this
  1779.      * method. When the node is created, some data was stored with
  1780.      * it. That data is the package name and the version. After the
  1781.      * data is extracted, it is passed to the cList.
  1782.      *
  1783.      * @param  object  $tree    The GtkCTree containing the selected node.
  1784.      * @param  object  $node    The GtkCTree that was selected.
  1785.      * @param  mixed   $unknown Who knows. Seriously, if you do email me.
  1786.      *                           It gets passed by the event and we don't
  1787.      *                           know what it is. I will add it to the
  1788.      *                           docs if you can tell me. Thanks.
  1789.      * @param  object  $list    The GtkCList that will hold the data from
  1790.      *                           the selected tree node.
  1791.      * @return void 
  1792.      * @access private
  1793.      * @uses   _addToCList()
  1794.      */
  1795.     function _treeToCList($tree$node$unknown$list)
  1796.     {
  1797.         // Get the data associated with this row.
  1798.         $data $tree->node_get_row_data($node);
  1799.         
  1800.         // Only add if there is some data.
  1801.         // This will prevent package nodes from being
  1802.         // added. We only want version nodes.
  1803.         if (isset($data)) {
  1804.             $this->_addToCList($list$data);
  1805.         }
  1806.     }
  1807.  
  1808.     /**
  1809.      * Toggles the optional status of a dependency when it is
  1810.      * selected.
  1811.      *
  1812.      * PFM lets you mark a package as an optional dependency.
  1813.      * This means that a given package will be used if it is
  1814.      * available but it is not required for proper operation.
  1815.      * This package is optionally dependent on Gtk_FileDrop
  1816.      * and also PHP_Compat. This package will work without
  1817.      * them but if you have them it will add more features.
  1818.      *
  1819.      * @param  object  $cList The GtkClist that holds the data.
  1820.      * @param  integer $row   The row that was selected (starts at 0)
  1821.      * @param  integer $col   The column that was selected (starts at 0)
  1822.      * @param  object  $event The 'select-row' event
  1823.      * @return void 
  1824.      * @access private
  1825.      */
  1826.     function _toggleOptional($cList$row$col$event)
  1827.     {
  1828.         // Figure out the current status.
  1829.         $optional $cList->get_text($row2);
  1830.  
  1831.         // Set the last column to be the oposite of what it is now.
  1832.         $cList->set_text($row2($optional == 'optional' '' 'optional'));
  1833.     }
  1834.     
  1835.     /**
  1836.      * Adds the selected packages as dependencies.
  1837.      * 
  1838.      * All packages from the GtkCList are added as dependencies to
  1839.      * the package being built. As of 2005-03-18, only package
  1840.      * dependencies may be added using this tool. Other types (php,
  1841.      * etc.) may be added at a later date.
  1842.      *
  1843.      * @param  object  $cList The GtkCList holding the packages.
  1844.      * @return void 
  1845.      * @access private
  1846.      */
  1847.     function _addDependencies($cList)
  1848.     {
  1849.         // Clear the previewed and saved states.
  1850.         $this->previewed = false;
  1851.         $this->saved     = false;
  1852.  
  1853.         // Loop through all of the packages in the list.
  1854.         for ($i = 0; $i $cList->rows; ++$i{
  1855.             // Get the optional status.
  1856.             $optional $cList->get_text($i2);
  1857.  
  1858.             // Attempt to add the package as a dependency.
  1859.             $result $this->_packageFileManager->addDependency($cList->get_text($i0)$cList->get_text($i1)'ge''pkg'!empty($optional));
  1860.             
  1861.             // Check for errors.
  1862.             if (PEAR::isError($result)) {
  1863.                 $this->_pushWarning($result->getCode()array());
  1864.                 // There is no need to stop adding the rest just
  1865.                 // because one failed.
  1866.                 //return;
  1867.             }
  1868.         }
  1869.     }
  1870.  
  1871.     /**
  1872.      * Adds a maintainer to the package file.
  1873.      *
  1874.      * Checks that all of the information was given then tries
  1875.      * to add the maintainer. If there is a problem, the user
  1876.      * will be taken to the warnings page.
  1877.      *
  1878.      * @param  object  $handle The entry that has the developer's handle.
  1879.      * @param  object  $role   The combo that has the developer's role.
  1880.      * @param  object  $name   The entry that has the developer's name.
  1881.      * @param  object  $email  The entry that has the developer's email.
  1882.      * @param  object  $currentList The GtkCList that will show the developers.
  1883.      * @return void 
  1884.      * @access private
  1885.      */
  1886.     function _addMaintainer($handle$role$name$email$currentList)
  1887.     {
  1888.         // Reset the previewed and saved states.
  1889.         $this->previewed = false;
  1890.         $this->saved     = false;
  1891.  
  1892.         // Grab the information.
  1893.         // The role is a little tricky.
  1894.         $handleText $handle->get_text();
  1895.         $nameText   $name->get_text();
  1896.         $emailText  $email->get_text();
  1897.         $roleItem   $role->list->selection[0];
  1898.         
  1899.         // Make sure something was selected.
  1900.         if (isset($roleItem)) {
  1901.             $roleText strtolower($roleItem->get_data('role'));
  1902.         else {
  1903.             $roleText '';
  1904.         }
  1905.  
  1906.         // Check to make sure everything is there.
  1907.         if (empty($handleText|| empty($nameText|| empty($emailText|| empty($roleText)) {
  1908.             // Add the warning to the warning stack.
  1909.             $this->showWarnings('Maintainer information is missing. Please check all fields.');
  1910.             $this->notebook->set_page(-1);
  1911.             return;
  1912.         }
  1913.         
  1914.         // Add the maintainer.
  1915.         $result $this->_packageFileManager->addMaintainer($handleText$roleText$nameText$emailText);
  1916.         
  1917.         // Check for errors.
  1918.         if (PEAR::isError($result)) {
  1919.             $this->_pushWarning($result->getCode()array());
  1920.             return;
  1921.         }
  1922.  
  1923.         // Update the current list.
  1924.         $this->_addToCList($currentListarray($nameText$emailText$roleText));
  1925.     }
  1926.  
  1927.     /**
  1928.      * Adds the developers from the previous release to the given
  1929.      * GtkCList.
  1930.      *
  1931.      * This method is used when the developers page is created. It
  1932.      * puts the developers from the previous release into the cList.
  1933.      * Developers added as of this release are added by
  1934.      * {@link _addMaintainer()}.
  1935.      *
  1936.      * @param  object  $cList The GtkCList that will have the developer added.
  1937.      * @return void 
  1938.      * @access private
  1939.      */
  1940.     function _listDevelopers($cList)
  1941.     {
  1942.         // Then add each developer.
  1943.         $options $this->_packageFileManager->getOptions();
  1944.         foreach ($options['maintainers'as $maintainer{
  1945.             $this->_addToCList($cListarray($maintainer['name'],
  1946.                                              $maintainer['email'],
  1947.                                              $maintainer['role']
  1948.                                              )
  1949.                                );
  1950.         }            
  1951.     }
  1952.  
  1953.     /**
  1954.      * Imports the options from a previously created file.
  1955.      *
  1956.      * After importing the options, this method also updates the
  1957.      * values of some widgets.
  1958.      * 
  1959.      * @param  object  $packageDirEntry  The GtkEntry holding the package directory.
  1960.      * @param  object  $pacakgeNameEntry The GtkEntry holding the package name.
  1961.      * @param  object  $baseEntry        The GtkEntry holding the base install directory.
  1962.      * @param  object  $summaryEntry     The GtkEntry holding the package summary.
  1963.      * @param  object  $descriptiontText The GtkText holding the package description.
  1964.      * @return void 
  1965.      * @access private
  1966.      */
  1967.     function _importPackageOptions($packageDirEntry$packageNameEntry$baseEntry$summaryEntry$descriptionText)
  1968.     {
  1969.         // Figure out if there is a package file in the given
  1970.         // directory.
  1971.         if (@is_dir($packageDirEntry->get_text())) {
  1972.             $packageFile $packageDirEntry->get_text('/package.xml';
  1973.         elseif (strrpos($packageDirEntry->get_text()'package.xml')) {
  1974.             // Check if the path is straight to the file not the
  1975.             // directory.
  1976.             $packageFile $packageDirEntry->get_text();
  1977.         else {
  1978.             // No package file to load.
  1979.             return;
  1980.         }
  1981.  
  1982.         // If we can't read it, we can't load it.
  1983.         if (@!is_readable($packageFile)) {
  1984.             return;
  1985.         }
  1986.  
  1987.         // We have a readable package file. Hopefully it will
  1988.         // be valid.
  1989.         $result $this->_packageFileManager->importOptions($packageFile);
  1990.         
  1991.         // Check for errors.
  1992.         if (PEAR::isError($result)) {
  1993.             /*
  1994.             // Try setting a bunch of garbage options first if 
  1995.             // PFM complains about running setOptions().
  1996.             // Please note, this is a dirty hack to make up for
  1997.             // some deficiencies in PFM-1.5.0
  1998.             if ($result->getCode() == PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS) {
  1999.                 $tmpOptions = array('packagedirectory' => '/tmp',
  2000.                                     'package'          => 'TEMP',
  2001.                                     'baseinstalldir'   => '',
  2002.                                     'summary'          => 'TEMP',
  2003.                                     'description'      => 'TEMP',
  2004.                                     'state'            => 'alpha',
  2005.                                     'version'          => '1.0.0a',
  2006.                                     'notes'            => 'temp notes'
  2007.                                     );
  2008.                 $result2 = $this->_packageFileManager->setOptions($tmpOptions);
  2009.                 // Check to see if our garbage was accepted.
  2010.                 if (PEAR::isError($result2)) {
  2011.                     $this->_pushWarning($result2->getCode(), array());
  2012.                 } else {
  2013.                     // Try again....
  2014.                     $result2 = $this->_packageFileManager->importOptions($packageFile);
  2015.                     if (PEAR::isError($result2)) {
  2016.                         // Still no luck. Give up.
  2017.                         $this->_pushWarning($result2->getCode(), array());
  2018.                         return;
  2019.                     }                         
  2020.                 }
  2021.             } else {
  2022.             */
  2023.                 // An error, but not about setting options.
  2024.                 $this->_pushWarning($result->getCode()array());
  2025.                 return;
  2026.                 //}
  2027.         }
  2028.  
  2029.         // No problems. Load the data into the widgets.
  2030.         $options $this->_packageFileManager->getOptions();
  2031.         $packageNameEntry->set_text($options['package']);
  2032.         $baseEntry->set_text($options['baseinstalldir']);
  2033.         $summaryEntry->set_text($options['summary']);
  2034.         
  2035.         // First clear out any text in the description area.
  2036.         $descriptionText->delete_text(0-1);
  2037.         $descriptionText->insert_text($options['description']0);
  2038.     }
  2039.  
  2040.     /**
  2041.      * Adds a warning to the warning stack.
  2042.      * 
  2043.      * After adding the error to the stack, the user is taken to the
  2044.      * warnings page. When the page is switched, warnings are popped
  2045.      * off of the stack.
  2046.      *
  2047.      * @param  integer $code 
  2048.      * @param  array   $info Associative array of message replacement info.
  2049.      * @return void 
  2050.      * @access private
  2051.      */
  2052.     function _pushWarning($code$info)
  2053.     {
  2054.         // Add the warning to the package file manager warnings.
  2055.         $this->_packageFileManager->pushWarning($code$info);
  2056.                 
  2057.         // Then jump to the warnings page.
  2058.         $this->notebook->set_page(-1);
  2059.     }
  2060. }
  2061. ?>

Documentation generated on Mon, 11 Mar 2019 14:21:08 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.