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

Source for file Gtk2.php

Documentation is available at Gtk2.php

  1. <?php
  2. require_once 'PEAR/Config.php';
  3. require_once 'PEAR/Frontend.php';
  4.  
  5. require_once 'PEAR/Frontend/Gtk2/About.php';
  6. require_once 'PEAR/Frontend/Gtk2/ChannelDialog.php';
  7. require_once 'PEAR/Frontend/Gtk2/Channels.php';
  8. require_once 'PEAR/Frontend/Gtk2/Config.php';
  9. require_once 'PEAR/Frontend/Gtk2/Packages.php';
  10. require_once 'PEAR/Frontend/Gtk2/Installation.php';
  11.  
  12. /**
  13. *   Graphical frontend for PEAR, based on PHP-Gtk2
  14. *
  15. *   TODO:
  16. *   - Package categories aren't updated/extendet if there is an error at startup loading/packages are refreshed and a new category is required
  17. *   - Drop package file onto install button -> install it
  18. *   - Warn if the package list is older than 5 days
  19. *   - upgrade-all menu option
  20. *   - Filter by upgradeable/installed/installable/all packages
  21. *
  22. *   Don't know how to do:
  23. *   - installation dialog showing has to be updated correctly
  24. *   - Installation: shrink window if expander is collapsed
  25. *
  26. *   Done:
  27. *   - Install pecl packages - error messages aren't shown
  28. *   - channel discovery
  29. *   - better installation ok icon
  30. *   - Window icon - shows the php icon on windows currently
  31. *   - When no internet connection on startup, no categories are loaded and no local packages are shown
  32. *   - When no pear cache directory exists, the check warning is shown - pear cache directory is created now
  33. *   - uninstall: pear/liveuser is required by installed package "pear/Event_Dispatcher"
  34. *   - use menu options (deps, nodeps)
  35. *   - refresh online info (clear cache or so)
  36. *   - offline mode
  37. *   - save and load settings
  38. *   - scroll text in installation
  39. *
  40. *   @author Christian Weiske <cweiske@php.net>
  41. */
  42. class PEAR_Frontend_Gtk2 extends PEAR_Frontend
  43. {
  44.     /**
  45.     *   The widgets which shall be loaded from the glade
  46.     *   file into the $arWidgets array
  47.     *   @var array 
  48.     */
  49.     protected static $arRequestedWidgets = array(
  50.         'dlgInstaller''lstCategories''lstPackages''txtPackageInfo',
  51.         'cmbChannel''imgChannelLogo''lblSelectedCategory''hboxCategoryInfo',
  52.         'btnInstall','btnUninstall','lblBtnInstall','evboxSelectedCategory','expPackageInfo',
  53.  
  54.         'mnuOptDepsNo','mnuOptDepsReq','mnuOptDepsAll','mnuOptDepNothing',
  55.         'mnuOffline','mnuQuit','mnuAbout','mnuUpdateOnline','mnuUpdateLocal',
  56.         'mnuChannels',
  57.  
  58.         'dlgProgress''lblDescription''imgProgress''lblProgress''progBar'
  59.     );
  60.  
  61.     protected $nProgressImage = 1;
  62.  
  63.     /**
  64.     *   Array with images used for the progress animation
  65.     */
  66.     protected $arAnimationImages = array();
  67.  
  68.     /**
  69.     *   Requested widgets are loaded from glade into this array.
  70.     *   So this is an associative array with all required widgets
  71.     *   from the glade file: name => widget object
  72.     *   @var array 
  73.     */
  74.     protected $arWidgets;
  75.  
  76.     /**
  77.     *   The PEAR_Frontend_Gtk2_Installation object to use
  78.     *   @var PEAR_Frontend_Gtk2_Installation 
  79.     */
  80.     protected $installer = null;
  81.  
  82.     /**
  83.     *   The channel dialog
  84.     *   @var PEAR_Frontend_Gtk2_ChannelDialog 
  85.     */
  86.     protected $channelDialog = null;
  87.  
  88.     protected $selectedPackage          = null;
  89.     protected $strSelectedCategoryName  = null;
  90.     protected $strSelectedCategoryKey   = null;
  91.  
  92.     /**
  93.     *   The package information class instance
  94.     *   @var PEAR_Frontend_Gtk2_Packages 
  95.     */
  96.     protected $packages = null;
  97.  
  98.     const CATEGORY_ALL      = 12345678;
  99.     const CATEGORY_SELECTED = 12345679;
  100.  
  101.  
  102.  
  103.     /**
  104.     *   Special categories which are added to the
  105.     *   channel categories
  106.     *   @var array 
  107.     */
  108.     protected static $arSpecialCategories = array(
  109.         PEAR_Frontend_Gtk2::CATEGORY_ALL      => '*All packages',
  110. //        PEAR_Frontend_Gtk2::CATEGORY_SELECTED => '*Selected for install'
  111.     );
  112.  
  113.  
  114.     public function __construct()
  115.     {
  116.         $this->loadConfig();
  117.         PEAR_Frontend_Gtk2_Config::loadConfig();
  118.         $this->buildDialog();
  119.         PEAR_Frontend_Gtk2_Config::loadCurrentConfigIntoGui($this);
  120.         $this->loadChannels(PEAR_Frontend_Gtk2_Config::$strDefaultChannel);
  121.         $this->selectPackageByName(PEAR_Frontend_Gtk2_Config::$strDefaultPackage);
  122.     }//public function __construct()
  123.  
  124.  
  125.  
  126.     function loadConfig()
  127.     {
  128.         $this->config   = PEAR_Config::singleton();
  129.         $this->packages = new PEAR_Frontend_Gtk2_Packages($this->config);
  130.     }//function loadConfig()
  131.  
  132.  
  133.  
  134.     /**
  135.     *   Fill the channel dropdown with channel names
  136.     *
  137.     *   @param string   $strDefaultChannel  The channel to set active
  138.     */
  139.     public function loadChannels($strDefaultChannel = null)
  140.     {
  141.         if ($strDefaultChannel == null{
  142.             $strDefaultChannel $this->arWidgets['cmbChannel']->get_active_text();
  143.         }
  144.  
  145.         //After all has been initiated, load the data
  146.         PEAR_Frontend_Gtk2_Channels::loadChannels(
  147.             $this->arWidgets['cmbChannel'],
  148.             $this->config,
  149.             $strDefaultChannel
  150.         );
  151.     }//public function loadChannels($strDefault = null)
  152.  
  153.  
  154.  
  155.     public function quitApp()
  156.     {
  157.         PEAR_Frontend_Gtk2_Config::loadConfigurationFromGui($this);
  158.         PEAR_Frontend_Gtk2_Config::saveConfig();
  159.         Gtk::main_quit();
  160.     }//public function quitApp()
  161.  
  162.  
  163.  
  164.     /**
  165.     *   load the glade file, load the widgets, connect the signals
  166.     */
  167.     protected function buildDialog()
  168.     {
  169.         $this->glade = new GladeXML(dirname(__FILE__'/Gtk2/installer.glade');
  170.         foreach (self::$arRequestedWidgets as $strWidgetName{
  171.             $this->arWidgets[$strWidgetName$this->glade->get_widget($strWidgetName);
  172.         }
  173.  
  174.         $this->arWidgets['dlgInstaller']->connect_simple('destroy'array($this'quitApp'));
  175.         $strIcon = dirname(__FILE__'/Gtk2/runicon.png';
  176.         if (file_exists($strIcon)) {
  177.             $this->arWidgets['dlgInstaller']->set_icon_from_file($strIcon);
  178.         }
  179.  
  180.         $this->arWidgets['lblSelectedCategory']->set_use_markup(true);
  181.  
  182.         $this->arWidgets['cmbChannel']->connect('changed'array($this'selectChannel'));
  183.  
  184.         $this->arWidgets['lstCategories']->set_model(new GtkListStore(Gtk::TYPE_STRINGGtk::TYPE_STRING));
  185.         $cell_renderer = new GtkCellRendererText();
  186.         $column = new GtkTreeViewColumn('test'$cell_renderer"text"0);
  187.         $this->arWidgets['lstCategories']->append_column($column);
  188.  
  189.         $this->arWidgets['btnInstall']  ->connect_simple('clicked'array($this'installPackage')true);
  190.         $this->arWidgets['btnUninstall']->connect_simple('clicked'array($this'installPackage')false);
  191.  
  192.         $this->arWidgets['dlgProgress']->connect('delete-event'array($this'deleteProgressWindow'));
  193.  
  194.         //Menu entries
  195.         $this->arWidgets['mnuQuit']         ->connect_simple('activate'array($this'quitApp'));
  196.         $this->arWidgets['mnuAbout']        ->connect_simple('activate'array('PEAR_Frontend_Gtk2_About''showMe'));
  197.         $this->arWidgets['mnuUpdateLocal']  ->connect_simple('activate'array($this'refreshLocalPackages'));
  198.         $this->arWidgets['mnuUpdateOnline'->connect_simple('activate'array($this'refreshOnlinePackages'));
  199.         $this->arWidgets['mnuChannels']     ->connect_simple('activate'array($this'showChannelDialog'));
  200.  
  201.  
  202.         //that's channel name and array key of the packages
  203.         $this->arWidgets['lstPackages']->set_model(new GtkListStore(Gtk::TYPE_STRINGGtk::TYPE_STRINGGtk::TYPE_STRINGGtk::TYPE_STRINGGtk::TYPE_PHP_VALUE));
  204.         $cell_renderer = new GtkCellRendererText();
  205.  
  206.         $colName = new GtkTreeViewColumn('Package'$cell_renderer"text"0);
  207.         $colName->set_resizable(true);
  208.         $colName->set_sort_column_id(0);
  209.         $this->arWidgets['lstPackages']->append_column($colName);
  210.  
  211.         $colInstalled = new GtkTreeViewColumn('Installed'$cell_renderer"text"1);
  212.         $colInstalled->set_resizable(true);
  213.         $colInstalled->set_sort_column_id(1);
  214.         $this->arWidgets['lstPackages']->append_column($colInstalled);
  215.  
  216.         $colNew = new GtkTreeViewColumn('New version'$cell_renderer"text"2);
  217.         $colNew->set_resizable(true);
  218.         $colNew->set_sort_column_id(2);
  219.         $this->arWidgets['lstPackages']->append_column($colNew);
  220.  
  221.         $colSummary = new GtkTreeViewColumn('Summary'$cell_renderer"text"3);
  222.         $colSummary->set_resizable(true);
  223.         $colSummary->set_sort_column_id(3);
  224.         $this->arWidgets['lstPackages']->append_column($colSummary);
  225.  
  226.         $selCategories $this->arWidgets['lstCategories']->get_selection();
  227.         $selCategories->set_mode(Gtk::SELECTION_SINGLE);
  228.         $selCategories->connect('changed'array($this'selectCategory'));
  229.  
  230.         $selPackages $this->arWidgets['lstPackages']->get_selection();
  231.         $selPackages->set_mode(Gtk::SELECTION_SINGLE);
  232.         $selPackages->connect('changed'array($this'selectPackage'));
  233.  
  234.         for ($nA = 1; $nA <= 3; $nA++{
  235.             $this->arAnimationImages[= GdkPixbuf::new_from_file(dirname(__FILE__'/Gtk2/pixmaps/progress/load-anim-' $nA '.png');
  236.         }
  237.         $this->nProgressImage = 0;
  238.  
  239.         $this->loadInstaller();
  240.     }//protected function buildDialog()
  241.  
  242.  
  243.  
  244.     protected function loadInstaller()
  245.     {
  246.         $this->installer = new PEAR_Frontend_Gtk2_Installation($this->arWidgets['dlgInstaller']$this->glade);
  247.         PEAR_Frontend::setFrontendObject($this->installer);
  248.     }//protected function loadInstaller()
  249.  
  250.  
  251.  
  252.     public function getInstaller()
  253.     {
  254.         return $this->installer;
  255.     }//public function getInstaller()
  256.  
  257.  
  258.  
  259.     public function showChannelDialog()
  260.     {
  261.         if ($this->channelDialog === null{
  262.             $this->channelDialog = new PEAR_Frontend_Gtk2_ChannelDialog($this->glade$this);
  263.         }
  264.         $this->channelDialog->show();
  265.     }//public function showChannelDialog()
  266.  
  267.  
  268.  
  269.     /**
  270.     *   A channel has been selected from the channel combo box
  271.     *
  272.     *   Has to be public as it is a callback function
  273.     *
  274.     *   @param GtkComboBox  $cmbChannel     The channel selection combo box
  275.     *   @param boolean      $bSecondTime    If the function is being run a second time (because the first run had a problem) - used to detect infinite loops.
  276.     */
  277.     public function selectChannel($cmbChannel$bSecondTime = false)
  278.     {
  279.         $strChannel $cmbChannel->get_active_text();
  280.  
  281.         $this->setChannelStyles($strChannel);
  282.  
  283.         $model $this->arWidgets['lstCategories']->get_model();
  284.         $model->clear();
  285.         $this->arWidgets['lstPackages']->get_model()->clear();
  286.  
  287.         //Channel categories
  288.         $this->packages->setActiveChannel($strChannel);
  289.  
  290.         if (!$this->packages->packagesLoaded()) {
  291.             //show the progress dialog before it gets loaded with the first callback
  292.             $this->showProgressDialog(true);
  293.         }
  294.  
  295.         try {
  296.             $arCategories $this->packages->getCategories(array($this'packagesCallback')$this->getWorkOffline());
  297.         catch (Exception $e{
  298.             $this->hideProgressDialog();
  299.             $dialog = new GtkMessageDialog(
  300.                 $this->arWidgets['dlgInstaller'],
  301.                 0,
  302.                 Gtk::MESSAGE_ERROR,
  303.                 Gtk::BUTTONS_OK,
  304.                 'Can\'t list the categories:' "\r\n"
  305.                 . $e->getCode(': ' $e->getMessage()
  306.                 . "\r\n\r\nMake sure you have an internet connection."
  307.             );
  308.             $dialog->set_transient_for($this->arWidgets['dlgInstaller']);
  309.             $dialog->set_position(Gtk::WIN_POS_CENTER_ON_PARENT);
  310.             $dialog->run();
  311.             $dialog->destroy();
  312.  
  313.             if (!$bSecondTime{
  314.                 //The exception code seem to vary on every run - so I can't check for a certain code.
  315.                 //But as we still can load the local packages, we can work offline.
  316.                 $this->setWorkOffline(true);
  317.                 $this->selectChannel($cmbChanneltrue);
  318.                 return;
  319.             else {
  320.                 //no chance to do a fix - do nothing
  321.                 return;
  322.             }
  323.         }
  324.  
  325.         $arCategories $this->appendSpecialCategories(
  326.             $arCategories
  327.         );
  328.  
  329.         foreach ($arCategories as $key => $strCategory{
  330.             $model->set($model->append()0$strCategory1$key);
  331.         }
  332.  
  333.         //Clear packages
  334.         $this->arWidgets['lstPackages']->get_model()->clear();
  335.         $this->arWidgets['lstCategories']->get_selection()->select_path('0');
  336.  
  337.         $this->hideProgressDialog();
  338.     }//public function selectChannel($cmbChannel, $bSecondTime = false)
  339.  
  340.  
  341.  
  342.     protected function setChannelStyles($strChannel)
  343.     {
  344.         //Logo
  345.         $strIcon dirname(__FILE__'/Gtk2/pixmaps/' $strChannel '.png';
  346.         if (!file_exists($strIcon)) {
  347.             $strIcon dirname(__FILE__'/Gtk2/pixmaps/default.png';
  348.         }
  349.         if (file_exists($strIcon)) {
  350.             $this->arWidgets['imgChannelLogo']->set_from_file($strIcon);
  351.         }
  352.  
  353.         //Colors
  354.         $strColorChannel $strChannel;
  355.         if (!isset(PEAR_Frontend_Gtk2_Config::$arChannels[$strColorChannel])) {
  356.             $strColorChannel 'default';
  357.         }
  358.         $colBg = GdkColor::parse(PEAR_Frontend_Gtk2_Config::$arChannels[$strColorChannel]['background-color']);
  359.         $colFg = GdkColor::parse(PEAR_Frontend_Gtk2_Config::$arChannels[$strColorChannel]['color']);
  360.  
  361.         $this->arWidgets['evboxSelectedCategory']->modify_bg(Gtk::STATE_NORMAL$colBg);
  362.         $this->arWidgets['lblSelectedCategory']->modify_fg(Gtk::STATE_NORMAL$colFg);
  363.     }//protected function setChannelStyles($strChannel)
  364.  
  365.  
  366.  
  367.     /**
  368.     *   Appends defined special categories to the given
  369.     *   list
  370.     *
  371.     *   @param  array   Array of categories
  372.     *   @return array   Array of categories with special ones
  373.     */
  374.     function appendSpecialCategories($arCategories)
  375.     {
  376.         foreach (PEAR_Frontend_Gtk2::$arSpecialCategories as $key => $value{
  377.             $arCategories[$key$value;
  378.         }
  379.         return $arCategories;
  380.     }//function appendSpecialCategories($arCategories)
  381.  
  382.  
  383.  
  384.     /**
  385.     *   A category has been selected
  386.     */
  387.     function selectCategory($selection)
  388.     {
  389.         list($model$iter$selection->get_selected();
  390.         if ($iter === null{
  391.             $this->arWidgets['lblSelectedCategory']->set_text('No category selected');
  392.             return;
  393.         }
  394.  
  395.         $this->strSelectedCategoryName  $model->get_value($iter0);
  396.         $this->strSelectedCategoryKey   $model->get_value($iter1);
  397.         $this->arWidgets['lblSelectedCategory']->set_markup('<b>' $this->strSelectedCategoryName '</b>');
  398.  
  399.         if ($this->strSelectedCategoryKey == self::CATEGORY_ALL{
  400.             $this->strSelectedCategoryName = null;
  401.         }
  402.         $this->showPackageList($this->strSelectedCategoryName);
  403.     }//function selectCategory($selection)
  404.  
  405.  
  406.  
  407.     /**
  408.     *   Fill the package list for the given category
  409.     */
  410.     protected function showPackageList($strCategory)
  411.     {
  412.         //Show packages
  413.         $model $this->arWidgets['lstPackages']->get_model();
  414.         $model->clear();
  415.         $arPackages $this->packages->getPackages($strCategory);
  416.         if (count($arPackages> 0{
  417.             foreach ($arPackages as $key => $package{
  418.                 $model->set(
  419.                     $model->append(),
  420.                     0$package->getName(),
  421.                     1$package->getInstalledVersion(),
  422.                     2$package->getLatestVersion(),
  423.                     3$package->getSummary(),
  424.                     4$package
  425.                 );
  426.             }
  427.         }
  428.     }//protected function showPackageList($strCategory)
  429.  
  430.  
  431.  
  432.     /**
  433.     *   Selects the given package
  434.     *
  435.     *   @param string $strPackage   The package name (without channel!)
  436.     */
  437.     public function selectPackageByName($strPackage)
  438.     {
  439.         if ($strPackage === null{
  440.             return;
  441.         }
  442.  
  443.         //select the "*all*" category to make sure the package
  444.         // is shown
  445.         $selection $this->arWidgets['lstCategories']->get_selection();
  446.         $model     $this->arWidgets['lstCategories']->get_model();
  447.         $selection->select_iter(
  448.             $model->get_iter_from_string(
  449.                 //gets number of children - 1 = from 0
  450.                 $model->iter_n_children(null- 1
  451.             )
  452.         );
  453.  
  454.         //now, select the package
  455.         $model $this->arWidgets['lstPackages']->get_model();
  456.         $iter  $model->get_iter_first();
  457.         while ($iter !== null{
  458.             if ($model->get_value($iter0== $strPackage{
  459.                 $this->arWidgets['lstPackages']->get_selection()->select_iter(
  460.                     $iter
  461.                 );
  462.                 break;
  463.             }
  464.             $iter $model->iter_next($iter);
  465.         }
  466.     }//public function selectPackageByName($strPackage)
  467.  
  468.  
  469.  
  470.     /**
  471.     *   Update the package list model entries for the given packages.
  472.     *   Useful after installing/uninstalling a package
  473.     *
  474.     *   @param array    $arPackages     Array of packages which model entry shall be updated
  475.     */
  476.     protected function updatePackageList($arPackages)
  477.     {
  478.         $model $this->arWidgets['lstPackages']->get_model();
  479.         $iter  $model->get_iter_first();
  480.         while ($iter !== null{
  481.             $package $model->get_value($iter4);
  482.             if (in_array($package$arPackages)) {
  483.                 $model->set(
  484.                     $iter,
  485.                     0$package->getName(),
  486.                     1$package->getInstalledVersion(),
  487.                     2$package->getLatestVersion(),
  488.                     3$package->getSummary(),
  489.                     4$package
  490.                 );
  491.             }
  492.             $iter $model->iter_next($iter);
  493.         }
  494.     }//protected function updatePackageList($arPackages)
  495.  
  496.  
  497.  
  498.     /**
  499.     *   Callback for the package loading functions
  500.     */
  501.     function packagesCallback($nPackageCount$nCurrentPackage)
  502.     {
  503.         $dlgProgress $this->arWidgets['dlgProgress'];
  504.         if ($nPackageCount === true{
  505.             //we're done
  506.             $this->hideProgressDialog();
  507.             return;
  508.         }
  509.         $this->showProgressDialog();
  510.         $this->arWidgets['lblProgress']->set_text($nCurrentPackage ' / ' $nPackageCount);
  511.         $this->arWidgets['progBar']->set_fraction(1/$nPackageCount $nCurrentPackage);
  512.  
  513.         $this->nProgressImage++;
  514.         if (!isset($this->arAnimationImages[$this->nProgressImage])) {
  515.             $this->nProgressImage = 0;
  516.         }
  517.         //TODO: hold the images in memory
  518.         $this->arWidgets['imgProgress']->set_from_pixbuf($this->arAnimationImages[$this->nProgressImage]);
  519.         while (Gtk::events_pending()) Gtk::main_iteration();}
  520.     }//function packagesCallback($nPackageCount, $nCurrentPackage)
  521.  
  522.  
  523.  
  524.     public function selectPackage($selection)
  525.     {
  526.         list($model$iter$selection->get_selected();
  527.         if ($iter === null{
  528.             $strDescription '';
  529.             $this->setSelectedPackage(null);
  530.             $this->arWidgets['btnUninstall']->hide();
  531.             $this->arWidgets['btnInstall']  ->set_sensitive(false);
  532.         else {
  533.             $package $model->get_value($iter4);
  534.             $this->setSelectedPackage($package);
  535.             $strDescription $package->getDescription();
  536.             $this->ableInstallButtons($package);
  537.             if ($package->getInstalledVersion(=== null || $package->getInstalledVersion(== ''{
  538.                 $this->arWidgets['lblBtnInstall']->set_label('Inst_all package');
  539.             else {
  540.                 $this->arWidgets['lblBtnInstall']->set_label('Upgr_ade package');
  541.             }
  542.         }
  543.  
  544.         $this->arWidgets['txtPackageInfo']->get_buffer()->set_text($strDescription);
  545.     }//public function selectPackage($selection)
  546.  
  547.  
  548.  
  549.     /**
  550.     *   Enables or disables the install buttons depending
  551.     *   on the installation status of $package
  552.     *
  553.     *   @param PEAR_Frontend_Gtk2_Package $package  The package to check
  554.     */
  555.     protected function ableInstallButtons($package)
  556.     {
  557.         if ($package === null{
  558.             return;
  559.         }
  560.  
  561.         $this->arWidgets['btnInstall']->set_sensitive(
  562.             $package->getLatestVersion(!== null
  563.             && $package->getLatestVersion(!== ''
  564.         );
  565.  
  566.         if ($package->getInstalledVersion(== ''{
  567.             $this->arWidgets['btnUninstall']->hide();
  568.             $this->arWidgets['btnUninstall']->set_sensitive(false);
  569.         else {
  570.             $this->arWidgets['btnUninstall']->show();
  571.             $this->arWidgets['btnUninstall']->set_sensitive(true);
  572.         }
  573.     }//protected function ableInstallButtons($package)
  574.  
  575.  
  576.  
  577.     protected function updateInstallButtons()
  578.     {
  579.         $selection $this->arWidgets['lstPackages']->get_selection();
  580.         list($model$iter$selection->get_selected();
  581.         $package $model->get_value($iter4);
  582.         $this->ableInstallButtons($package);
  583.     }//protected function updateInstallButtons()
  584.  
  585.  
  586.  
  587.     protected function getSelectedPackage()
  588.     {
  589.         return $this->selectedPackage;
  590.     }//protected function getSelectedPackage()
  591.  
  592.  
  593.  
  594.     protected function setSelectedPackage($package)
  595.     {
  596.         $this->selectedPackage $package;
  597.     }//protected function setSelectedPackage($package)
  598.  
  599.  
  600.  
  601.     /**
  602.     *   Installs (or uninstalls) the selected package
  603.     *
  604.     *   @param boolean $bInstall    True if the package shall be installed, false if it shall be uninstalled
  605.     */
  606.     function installPackage($bInstall = true)
  607.     {
  608.         $strChannel $this->packages->getActiveChannel();
  609.         $package $this->getSelectedPackage();
  610.         if ($package === null{
  611.             $dialog = new GtkMessageDialog(
  612.                 $this->arWidgets['dlgInstaller']0Gtk::MESSAGE_ERRORGtk::BUTTONS_OK,
  613.                 'You have to select a package before you can install it.'
  614.             );
  615.             $dialog->run();
  616.             $dialog->destroy();
  617.             return;
  618.         }
  619.  
  620.         //get changes done in gui into config
  621.         PEAR_Frontend_Gtk2_Config::loadConfigurationFromGui($this);
  622.  
  623.         $this->installer->installPackage(
  624.             $strChannel,
  625.             $package->getName(),
  626.             $package->getLatestVersion(),
  627.             $bInstall,
  628.             PEAR_Frontend_Gtk2_Config::$strDepOptions
  629.         );
  630.  
  631.         $package->refreshLocalInfo();
  632.         $this->updatePackageList(array($package));
  633.         $this->updateInstallButtons();
  634.     }//function installPackage($bInstall = true)
  635.  
  636.  
  637.  
  638.     /**
  639.     *   Shows the progress dialog if that hasn't already been done
  640.     *
  641.     *   @param boolean  $bInitWithZero  If the dialog's labels should be initialized (if the dialog has been hidden)
  642.     */
  643.     protected function showProgressDialog($bInitWithZero = false)
  644.     {
  645.         $dlgProgress $this->arWidgets['dlgProgress'];
  646.         if ($dlgProgress->window === null || !$dlgProgress->window->is_visible()) {
  647.             //show it
  648.             $dlgProgress->modify_bg(Gtk::STATE_NORMALGdkColor::parse('#FFFFFF'));
  649.             $dlgProgress->set_transient_for($this->arWidgets['dlgInstaller']);
  650.             $dlgProgress->set_position(Gtk::WIN_POS_CENTER_ON_PARENT);
  651.  
  652.             if ($bInitWithZero{
  653.                 $this->arWidgets['lblProgress']->set_text('');
  654.                 $this->arWidgets['progBar']->set_fraction(0);
  655.             }
  656.  
  657.             $dlgProgress->show_now();
  658.             while (Gtk::events_pending()) Gtk::main_iteration();}
  659.         }
  660.     }//protected function showProgressDialog($bInitWithZero = false)
  661.  
  662.  
  663.  
  664.     /**
  665.     *   Hides the progress dialog
  666.     */
  667.     protected function hideProgressDialog()
  668.     {
  669.         $this->arWidgets['dlgProgress']->hide();
  670.         while (Gtk::events_pending()) Gtk::main_iteration();}
  671.     }//protected function hideProgressDialog()
  672.  
  673.  
  674.  
  675.     /**
  676.     *   The user may not close the progress window by hand
  677.     */
  678.     public function deleteProgressWindow()
  679.     {
  680.         return true;
  681.     }//public function deleteProgressWindow()
  682.  
  683.  
  684.  
  685.     /**
  686.     *   Check if the user wants to work offline
  687.     *   @return boolean     True, if the offline setting is active (work offline), false if working online
  688.     */
  689.     protected function getWorkOffline()
  690.     {
  691.         return $this->arWidgets['mnuOffline']->get_active();
  692.     }//protected function getWorkOffline()
  693.  
  694.  
  695.  
  696.     /**
  697.     *   Set the offline setting
  698.     *   @param boolean $bOffline    If the user wants to work offline (true) or not (false)
  699.     */
  700.     protected function setWorkOffline($bOffline)
  701.     {
  702.         return $this->arWidgets['mnuOffline']->set_active($bOffline);
  703.     }//protected function setWorkOffline($bOffline)
  704.  
  705.  
  706.  
  707.     public function getWidget($strWidget)
  708.     {
  709.         return $this->arWidgets[$strWidget];
  710.     }//public function getWidget($strWidget)
  711.  
  712.  
  713.  
  714.     /**
  715.     *   Reload local package information and update the list.
  716.     */
  717.     public function refreshLocalPackages()
  718.     {
  719.         $this->packages->refreshLocalPackages();
  720.         $this->showPackageList($this->strSelectedCategoryName);
  721.     }//public function refreshLocalPackages()
  722.  
  723.  
  724.  
  725.     /**
  726.     *   Reload the online package list and package information,
  727.     *   and update the list here.
  728.     */
  729.     public function refreshOnlinePackages()
  730.     {
  731.         $this->packages->refreshRemotePackages(nullarray($this'packagesCallback'));
  732.         $this->showPackageList($this->strSelectedCategoryName);
  733.     }//public function refreshOnlinePackages()
  734.  
  735.  
  736.  
  737.     public function userConfirm()
  738.     {
  739.         //just to make sure that the class is recognized as proper PEAR_Frontend class
  740.     }
  741.  
  742.  
  743.  
  744.     /**
  745.     *   A fatal error occured
  746.     *
  747.     *   @param PEAR_Error $error The error
  748.     */
  749.     public function displayFatalError($error)
  750.     {
  751.         $strMessage $error->getMessage();
  752.  
  753.         //404 occurs often and isn't that bad, so we can ignore it
  754.         //404 occurs, if a package exists but hasn't released a version.
  755.         if (strpos(strtolower($strMessage)'404 not found'=== false{
  756.             $dialog = new GtkMessageDialog(
  757.                 $this->arWidgets['dlgInstaller'],
  758.                 Gtk::DIALOG_MODAL,
  759.                 Gtk::MESSAGE_ERROR,
  760.                 Gtk::BUTTONS_OK,
  761.                 'A fatal error occured:' "\r\n" $strMessage
  762.             );
  763.             $answer $dialog->run();
  764.             $dialog->destroy();
  765.         }
  766.     }//public function displayFatalError($error)
  767.  
  768. }//class PEAR_Frontend_Gtk2
  769. ?>

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