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

Documentation generated on Mon, 11 Mar 2019 15:46:47 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.