[ Index ]
 

Code source de PHP PEAR 1.4.5

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/PEAR/PackageFileManager/GUI/ -> Gtk.php (source)

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


Généré le : Sun Feb 25 14:08:00 2007 par Balluche grâce à PHPXref 0.7