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

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