Current File : //opt/RZphp72/includes/PEAR/Frontend/Gtk2.php |
<?php
require_once 'PEAR/Frontend/Gtk2/Checks.php';
require_once 'PEAR/Config.php';
require_once 'PEAR/Frontend.php';
require_once 'PEAR/Frontend/Gtk2/About.php';
require_once 'PEAR/Frontend/Gtk2/ChannelDialog.php';
require_once 'PEAR/Frontend/Gtk2/Channels.php';
require_once 'PEAR/Frontend/Gtk2/Config.php';
require_once 'PEAR/Frontend/Gtk2/Packages.php';
require_once 'PEAR/Frontend/Gtk2/Installation.php';
require_once 'Gtk2/FileDrop.php';
/**
* Graphical frontend for PEAR, based on PHP-Gtk2
*
* TODO:
* - Package categories aren't updated/extendet if there is an error at startup loading/packages are refreshed and a new category is required
* - Warn if the package list is older than 5 days
* - upgrade-all menu option
* - Filter by upgradeable/installed/installable/all packages
* - Channel server icons in channel.xml -> use them and cache locally
* - Config settings window
*
* Don't know how to do:
* - installation dialog showing has to be updated correctly
* - Installation: shrink window if expander is collapsed
*
* Done:
* - Drop package file onto install button -> install it
* - Install pecl packages - error messages aren't shown
* - channel discovery
* - better installation ok icon
* - Window icon - shows the php icon on windows currently
* - When no internet connection on startup, no categories are loaded and no local packages are shown
* - When no pear cache directory exists, the check warning is shown - pear cache directory is created now
* - uninstall: pear/liveuser is required by installed package "pear/Event_Dispatcher"
* - use menu options (deps, nodeps)
* - refresh online info (clear cache or so)
* - offline mode
* - save and load settings
* - scroll text in installation
*
* @author Christian Weiske <cweiske@php.net>
*/
class PEAR_Frontend_Gtk2 extends PEAR_Frontend
{
/**
* The widgets which shall be loaded from the glade
* file into the $arWidgets array
* @var array
*/
protected static $arRequestedWidgets = array(
'dlgInstaller', 'lstCategories', 'lstPackages', 'txtPackageInfo',
'cmbChannel', 'imgChannelLogo', 'lblSelectedCategory', 'hboxCategoryInfo',
'btnInstall','btnUninstall','lblBtnInstall','evboxSelectedCategory','expPackageInfo',
'mnuOptDepsNo','mnuOptDepsReq','mnuOptDepsAll','mnuOptDepNothing',
'mnuOptForce',
'mnuOffline','mnuQuit','mnuAbout','mnuUpdateOnline','mnuUpdateLocal',
'mnuChannels','mnuConfig','mnuInstallLocal',
'dlgProgress', 'lblDescription', 'imgProgress', 'lblProgress', 'progBar'
);
protected $nProgressImage = 1;
/**
* Array with images used for the progress animation
*/
protected $arAnimationImages = array();
/**
* Requested widgets are loaded from glade into this array.
* So this is an associative array with all required widgets
* from the glade file: name => widget object
* @var array
*/
protected $arWidgets;
/**
* The PEAR_Frontend_Gtk2_Installation object to use
* @var PEAR_Frontend_Gtk2_Installation
*/
protected $installer = null;
/**
* The channel dialog
* @var PEAR_Frontend_Gtk2_ChannelDialog
*/
protected $channelDialog = null;
protected $selectedPackage = null;
protected $strSelectedCategoryName = null;
protected $strSelectedCategoryKey = null;
/**
* The package information class instance
* @var PEAR_Frontend_Gtk2_Packages
*/
protected $packages = null;
/**
* Last package file that has been installed
*
* @var string
*/
protected $strLastFile = null;
const CATEGORY_ALL = 12345678;
const CATEGORY_SELECTED = 12345679;
/**
* Special categories which are added to the
* channel categories
* @var array
*/
protected static $arSpecialCategories = array(
PEAR_Frontend_Gtk2::CATEGORY_ALL => '*All packages',
// PEAR_Frontend_Gtk2::CATEGORY_SELECTED => '*Selected for install'
);
public function __construct()
{
$this->loadConfig();
PEAR_Frontend_Gtk2_Config::loadConfig();
$this->buildDialog();
PEAR_Frontend_Gtk2_Config::loadCurrentConfigIntoGui($this);
$this->loadChannels(PEAR_Frontend_Gtk2_Config::$strDefaultChannel);
$this->selectPackageByName(PEAR_Frontend_Gtk2_Config::$strDefaultPackage);
}//public function __construct()
function loadConfig()
{
$this->config = PEAR_Config::singleton();
$this->packages = new PEAR_Frontend_Gtk2_Packages($this->config);
}//function loadConfig()
/**
* Fill the channel dropdown with channel names
*
* @param string $strDefaultChannel The channel to set active
*/
public function loadChannels($strDefaultChannel = null)
{
if ($strDefaultChannel == null) {
$strDefaultChannel = $this->arWidgets['cmbChannel']->get_active_text();
}
//After all has been initiated, load the data
PEAR_Frontend_Gtk2_Channels::loadChannels(
$this->arWidgets['cmbChannel'],
$this->config,
$strDefaultChannel
);
}//public function loadChannels($strDefault = null)
public function quitApp()
{
PEAR_Frontend_Gtk2_Config::loadConfigurationFromGui($this);
PEAR_Frontend_Gtk2_Config::saveConfig();
Gtk::main_quit();
}//public function quitApp()
/**
* load the glade file, load the widgets, connect the signals
*/
protected function buildDialog()
{
$this->glade = new GladeXML(dirname(__FILE__) . '/Gtk2/installer.glade');
foreach (self::$arRequestedWidgets as $strWidgetName) {
$this->arWidgets[$strWidgetName] = $this->glade->get_widget($strWidgetName);
}
$this->arWidgets['dlgInstaller']->connect_simple('destroy', array($this, 'quitApp'));
$strIcon = dirname(__FILE__) . '/Gtk2/runicon.png';
if (file_exists($strIcon)) {
$this->arWidgets['dlgInstaller']->set_icon_from_file($strIcon);
}
$this->arWidgets['lblSelectedCategory']->set_use_markup(true);
$this->arWidgets['cmbChannel']->connect('changed', array($this, 'selectChannel'));
$this->arWidgets['lstCategories']->set_model(
new GtkListStore(Gobject::TYPE_STRING, Gobject::TYPE_STRING)
);
$cell_renderer = new GtkCellRendererText();
$column = new GtkTreeViewColumn('test', $cell_renderer, "text", 0);
$this->arWidgets['lstCategories']->append_column($column);
$this->arWidgets['btnInstall'] ->connect_simple('clicked', array($this, 'installPackage'), true);
$this->arWidgets['btnUninstall']->connect_simple('clicked', array($this, 'installPackage'), false);
//drop files onto install button
Gtk2_FileDrop::attach(
$this->arWidgets['btnInstall'],
array('application/x-tgz','.tgz'),
array($this, 'onFilesDropped'),
false
);
//and onto package list
Gtk2_FileDrop::attach(
$this->arWidgets['lstPackages'],
array('application/x-tgz','.tgz'),
array($this, 'onFilesDropped'),
false
);
$this->arWidgets['dlgProgress']->connect('delete-event', array($this, 'deleteProgressWindow'));
//Menu entries
$this->arWidgets['mnuQuit'] ->connect_simple('activate', array($this, 'quitApp'));
$this->arWidgets['mnuAbout'] ->connect_simple('activate', array('PEAR_Frontend_Gtk2_About', 'showMe'));
$this->arWidgets['mnuInstallLocal'] ->connect_simple('activate', array($this, 'onInstallLocalPackage'));
$this->arWidgets['mnuUpdateLocal'] ->connect_simple('activate', array($this, 'refreshLocalPackages'));
$this->arWidgets['mnuUpdateOnline'] ->connect_simple('activate', array($this, 'refreshOnlinePackages'));
$this->arWidgets['mnuChannels'] ->connect_simple('activate', array($this, 'showChannelDialog'));
//that's channel name and array key of the packages
$this->arWidgets['lstPackages']->set_model(
new GtkListStore(
Gobject::TYPE_STRING, Gobject::TYPE_STRING,
Gobject::TYPE_STRING, Gobject::TYPE_STRING,
Gobject::TYPE_PHP_VALUE
)
);
$cell_renderer = new GtkCellRendererText();
$colName = new GtkTreeViewColumn('Package', $cell_renderer, "text", 0);
$colName->set_resizable(true);
$colName->set_sort_column_id(0);
$this->arWidgets['lstPackages']->append_column($colName);
$colInstalled = new GtkTreeViewColumn('Installed', $cell_renderer, "text", 1);
$colInstalled->set_resizable(true);
$colInstalled->set_sort_column_id(1);
$this->arWidgets['lstPackages']->append_column($colInstalled);
$colNew = new GtkTreeViewColumn('New version', $cell_renderer, "text", 2);
$colNew->set_resizable(true);
$colNew->set_sort_column_id(2);
$this->arWidgets['lstPackages']->append_column($colNew);
$colSummary = new GtkTreeViewColumn('Summary', $cell_renderer, "text", 3);
$colSummary->set_resizable(true);
$colSummary->set_sort_column_id(3);
$this->arWidgets['lstPackages']->append_column($colSummary);
$selCategories = $this->arWidgets['lstCategories']->get_selection();
$selCategories->set_mode(Gtk::SELECTION_SINGLE);
$selCategories->connect('changed', array($this, 'selectCategory'));
$selPackages = $this->arWidgets['lstPackages']->get_selection();
$selPackages->set_mode(Gtk::SELECTION_SINGLE);
$selPackages->connect('changed', array($this, 'selectPackage'));
for ($nA = 1; $nA <= 3; $nA++) {
$this->arAnimationImages[] = GdkPixbuf::new_from_file(dirname(__FILE__) . '/Gtk2/pixmaps/progress/load-anim-' . $nA . '.png');
}
$this->nProgressImage = 0;
$this->loadInstaller();
}//protected function buildDialog()
protected function loadInstaller()
{
$this->installer = new PEAR_Frontend_Gtk2_Installation($this->arWidgets['dlgInstaller'], $this->glade);
PEAR_Frontend::setFrontendObject($this->installer);
}//protected function loadInstaller()
public function getInstaller()
{
return $this->installer;
}//public function getInstaller()
public function showChannelDialog()
{
if ($this->channelDialog === null) {
$this->channelDialog = new PEAR_Frontend_Gtk2_ChannelDialog($this->glade, $this);
}
$this->channelDialog->show();
}//public function showChannelDialog()
/**
* A channel has been selected from the channel combo box
*
* Has to be public as it is a callback function
*
* @param GtkComboBox $cmbChannel The channel selection combo box
* @param boolean $bSecondTime If the function is being run a second time (because the first run had a problem) - used to detect infinite loops.
*/
public function selectChannel($cmbChannel, $bSecondTime = false)
{
$strChannel = $cmbChannel->get_active_text();
if ($strChannel === null) {
return;
}
$this->setChannelStyles($strChannel);
$model = $this->arWidgets['lstCategories']->get_model();
$model->clear();
$this->arWidgets['lstPackages']->get_model()->clear();
//Channel categories
$this->packages->setActiveChannel($strChannel);
if (!$this->packages->packagesLoaded()) {
//show the progress dialog before it gets loaded with the first callback
$this->showProgressDialog(true);
}
try {
$arCategories = $this->packages->getCategories(
array($this, 'packagesCallback'),
$this->getWorkOffline()
);
} catch (Exception $e) {
$this->hideProgressDialog();
$dialog = new GtkMessageDialog(
$this->arWidgets['dlgInstaller'],
0,
Gtk::MESSAGE_ERROR,
Gtk::BUTTONS_OK,
'Can\'t list the categories:' . "\r\n"
. $e->getCode() . ': ' . $e->getMessage()
. "\r\n\r\nMake sure you have an internet connection."
);
$dialog->set_transient_for($this->arWidgets['dlgInstaller']);
$dialog->set_position(Gtk::WIN_POS_CENTER_ON_PARENT);
$dialog->run();
$dialog->destroy();
if (!$bSecondTime) {
//The exception code seem to vary on every run - so I can't check for a certain code.
//But as we still can load the local packages, we can work offline.
$this->setWorkOffline(true);
$this->selectChannel($cmbChannel, true);
return;
} else {
//no chance to do a fix - do nothing
return;
}
}
$arCategories = $this->appendSpecialCategories(
$arCategories
);
foreach ($arCategories as $key => $strCategory) {
$model->set($model->append(), 0, $strCategory, 1, $key);
}
//Clear packages
$this->arWidgets['lstPackages']->get_model()->clear();
$this->arWidgets['lstCategories']->get_selection()->select_path('0');
$this->hideProgressDialog();
}//public function selectChannel($cmbChannel, $bSecondTime = false)
protected function setChannelStyles($strChannel)
{
//Logo
$strIcon = dirname(__FILE__) . '/Gtk2/pixmaps/' . $strChannel . '.png';
if (!file_exists($strIcon)) {
$strIcon = dirname(__FILE__) . '/Gtk2/pixmaps/default.png';
}
if (file_exists($strIcon)) {
$this->arWidgets['imgChannelLogo']->set_from_file($strIcon);
}
//Colors
$strColorChannel = $strChannel;
if (!isset(PEAR_Frontend_Gtk2_Config::$arChannels[$strColorChannel])) {
$strColorChannel = 'default';
}
$colBg = GdkColor::parse(PEAR_Frontend_Gtk2_Config::$arChannels[$strColorChannel]['background-color']);
$colFg = GdkColor::parse(PEAR_Frontend_Gtk2_Config::$arChannels[$strColorChannel]['color']);
$this->arWidgets['evboxSelectedCategory']->modify_bg(Gtk::STATE_NORMAL, $colBg);
$this->arWidgets['lblSelectedCategory']->modify_fg(Gtk::STATE_NORMAL, $colFg);
}//protected function setChannelStyles($strChannel)
/**
* Appends defined special categories to the given
* list
*
* @param array Array of categories
* @return array Array of categories with special ones
*/
function appendSpecialCategories($arCategories)
{
foreach (PEAR_Frontend_Gtk2::$arSpecialCategories as $key => $value) {
$arCategories[$key] = $value;
}
return $arCategories;
}//function appendSpecialCategories($arCategories)
/**
* A category has been selected
*/
function selectCategory($selection)
{
list($model, $iter) = $selection->get_selected();
if ($iter === null) {
$this->arWidgets['lblSelectedCategory']->set_text('No category selected');
return;
}
$this->strSelectedCategoryName = $model->get_value($iter, 0);
$this->strSelectedCategoryKey = $model->get_value($iter, 1);
$this->arWidgets['lblSelectedCategory']->set_markup('<b>' . $this->strSelectedCategoryName . '</b>');
if ($this->strSelectedCategoryKey == self::CATEGORY_ALL) {
$this->strSelectedCategoryName = null;
}
$this->showPackageList($this->strSelectedCategoryName);
}//function selectCategory($selection)
/**
* Fill the package list for the given category
*/
protected function showPackageList($strCategory)
{
//Show packages
$model = $this->arWidgets['lstPackages']->get_model();
$model->clear();
$arPackages = $this->packages->getPackages($strCategory);
if (count($arPackages) > 0) {
foreach ($arPackages as $key => $package) {
$model->set(
$model->append(),
0, $package->getName(),
1, $package->getInstalledVersion(),
2, $package->getLatestVersion(),
3, $package->getSummary(),
4, $package
);
}
}
}//protected function showPackageList($strCategory)
/**
* Selects the given package
*
* @param string $strPackage The package name (without channel!)
*/
public function selectPackageByName($strPackage)
{
if ($strPackage === null) {
return;
}
//select the "*all*" category to make sure the package
// is shown
$selection = $this->arWidgets['lstCategories']->get_selection();
$model = $this->arWidgets['lstCategories']->get_model();
$selection->select_iter(
$model->get_iter_from_string(
//gets number of children - 1 = from 0
$model->iter_n_children(null) - 1
)
);
//now, select the package
$model = $this->arWidgets['lstPackages']->get_model();
$iter = $model->get_iter_first();
while ($iter !== null) {
if ($model->get_value($iter, 0) == $strPackage) {
$this->arWidgets['lstPackages']->get_selection()->select_iter(
$iter
);
break;
}
$iter = $model->iter_next($iter);
}
}//public function selectPackageByName($strPackage)
/**
* Update the package list model entries for the given packages.
* Useful after installing/uninstalling a package
*
* @param array $arPackages Array of packages which model entry shall be updated
*/
protected function updatePackageList($arPackages)
{
$model = $this->arWidgets['lstPackages']->get_model();
$iter = $model->get_iter_first();
while ($iter !== null) {
$package = $model->get_value($iter, 4);
if (in_array($package, $arPackages)) {
$model->set(
$iter,
0, $package->getName(),
1, $package->getInstalledVersion(),
2, $package->getLatestVersion(),
3, $package->getSummary(),
4, $package
);
}
$iter = $model->iter_next($iter);
}
}//protected function updatePackageList($arPackages)
/**
* Callback for the package loading functions
*/
function packagesCallback($nPackageCount, $nCurrentPackage)
{
$dlgProgress = $this->arWidgets['dlgProgress'];
if ($nPackageCount === true) {
//we're done
$this->hideProgressDialog();
return;
}
$this->showProgressDialog();
$this->arWidgets['lblProgress']->set_text($nCurrentPackage . ' / ' . $nPackageCount);
$this->arWidgets['progBar']->set_fraction(1/$nPackageCount * $nCurrentPackage);
$this->nProgressImage++;
if (!isset($this->arAnimationImages[$this->nProgressImage])) {
$this->nProgressImage = 0;
}
//TODO: hold the images in memory
$this->arWidgets['imgProgress']->set_from_pixbuf($this->arAnimationImages[$this->nProgressImage]);
while (Gtk::events_pending()) { Gtk::main_iteration();}
}//function packagesCallback($nPackageCount, $nCurrentPackage)
public function selectPackage($selection)
{
list($model, $iter) = $selection->get_selected();
if ($iter === null) {
$strDescription = '';
$this->setSelectedPackage(null);
$this->arWidgets['btnUninstall']->hide();
$this->arWidgets['btnInstall'] ->set_sensitive(false);
} else {
$package = $model->get_value($iter, 4);
$this->setSelectedPackage($package);
$strDescription = $package->getDescription();
$this->ableInstallButtons($package);
if ($package->getInstalledVersion() === null || $package->getInstalledVersion() == '') {
$this->arWidgets['lblBtnInstall']->set_label('Inst_all package');
} else {
$this->arWidgets['lblBtnInstall']->set_label('Upgr_ade package');
}
}
$this->arWidgets['txtPackageInfo']->get_buffer()->set_text($strDescription);
}//public function selectPackage($selection)
/**
* Enables or disables the install buttons depending
* on the installation status of $package
*
* @param PEAR_Frontend_Gtk2_Package $package The package to check
*/
protected function ableInstallButtons($package)
{
if ($package === null) {
return;
}
$this->arWidgets['btnInstall']->set_sensitive(
$package->getLatestVersion() !== null
&& $package->getLatestVersion() !== ''
);
if ($package->getInstalledVersion() == '') {
$this->arWidgets['btnUninstall']->hide();
$this->arWidgets['btnUninstall']->set_sensitive(false);
} else {
$this->arWidgets['btnUninstall']->show();
$this->arWidgets['btnUninstall']->set_sensitive(true);
}
}//protected function ableInstallButtons($package)
protected function updateInstallButtons()
{
$selection = $this->arWidgets['lstPackages']->get_selection();
list($model, $iter) = $selection->get_selected();
$package = $model->get_value($iter, 4);
$this->ableInstallButtons($package);
}//protected function updateInstallButtons()
protected function getSelectedPackage()
{
return $this->selectedPackage;
}//protected function getSelectedPackage()
protected function setSelectedPackage($package)
{
$this->selectedPackage = $package;
}//protected function setSelectedPackage($package)
/**
* Installs (or uninstalls) the selected package
*
* @param boolean $bInstall True if the package shall be installed, false if it shall be uninstalled
*/
function installPackage($bInstall = true)
{
$strChannel = $this->packages->getActiveChannel();
$package = $this->getSelectedPackage();
if ($package === null) {
$dialog = new GtkMessageDialog(
$this->arWidgets['dlgInstaller'], 0, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK,
'You have to select a package before you can install it.'
);
$dialog->run();
$dialog->destroy();
return;
}
//get changes done in gui into config
PEAR_Frontend_Gtk2_Config::loadConfigurationFromGui($this);
$this->installer->installPackage(
$strChannel,
$package->getName(),
$package->getLatestVersion(),
$bInstall,
PEAR_Frontend_Gtk2_Config::$strDepOptions,
PEAR_Frontend_Gtk2_Config::$bForceInstall
);
$package->refreshLocalInfo();
$this->updatePackageList(array($package));
$this->updateInstallButtons();
}//function installPackage($bInstall = true)
/**
* Shows the progress dialog if that hasn't already been done
*
* @param boolean $bInitWithZero If the dialog's labels should be initialized (if the dialog has been hidden)
*/
protected function showProgressDialog($bInitWithZero = false)
{
$dlgProgress = $this->arWidgets['dlgProgress'];
if ($dlgProgress->window === null || !$dlgProgress->window->is_visible()) {
//show it
$dlgProgress->modify_bg(Gtk::STATE_NORMAL, GdkColor::parse('#FFFFFF'));
$dlgProgress->set_transient_for($this->arWidgets['dlgInstaller']);
$dlgProgress->set_position(Gtk::WIN_POS_CENTER_ON_PARENT);
if ($bInitWithZero) {
$this->arWidgets['lblProgress']->set_text('');
$this->arWidgets['progBar']->set_fraction(0);
}
$dlgProgress->show_now();
while (Gtk::events_pending()) { Gtk::main_iteration();}
}
}//protected function showProgressDialog($bInitWithZero = false)
/**
* Hides the progress dialog
*/
protected function hideProgressDialog()
{
$this->arWidgets['dlgProgress']->hide();
while (Gtk::events_pending()) { Gtk::main_iteration();}
}//protected function hideProgressDialog()
/**
* The user may not close the progress window by hand
*/
public function deleteProgressWindow()
{
return true;
}//public function deleteProgressWindow()
/**
* Check if the user wants to work offline
* @return boolean True, if the offline setting is active (work offline), false if working online
*/
protected function getWorkOffline()
{
return $this->arWidgets['mnuOffline']->get_active();
}//protected function getWorkOffline()
/**
* Set the offline setting
* @param boolean $bOffline If the user wants to work offline (true) or not (false)
*/
protected function setWorkOffline($bOffline)
{
return $this->arWidgets['mnuOffline']->set_active($bOffline);
}//protected function setWorkOffline($bOffline)
public function getWidget($strWidget)
{
return $this->arWidgets[$strWidget];
}//public function getWidget($strWidget)
/**
* Reload local package information and update the list.
*/
public function refreshLocalPackages()
{
$this->packages->refreshLocalPackages();
$this->showPackageList($this->strSelectedCategoryName);
}//public function refreshLocalPackages()
/**
* Reload the online package list and package information,
* and update the list here.
*/
public function refreshOnlinePackages()
{
$this->packages->refreshRemotePackages(null, array($this, 'packagesCallback'));
$this->showPackageList($this->strSelectedCategoryName);
}//public function refreshOnlinePackages()
/**
* Let the user select a .tgz package file that will be installed.
*/
public function onInstallLocalPackage()
{
$fcd = new GtkFileChooserDialog(
'Select a package file to install',
$this->arWidgets['dlgInstaller'],
Gtk::FILE_CHOOSER_ACTION_OPEN,
array(
Gtk::STOCK_CANCEL, Gtk::RESPONSE_NO,
Gtk::STOCK_OPEN, Gtk::RESPONSE_YES
)
);
$fcd->set_select_multiple(false);
if ($this->strLastFile !== null) {
$fcd->set_filename($this->strLastFile);
}
$ffilter = new GtkFileFilter();
$ffilter->add_pattern('*.tgz');
$ffilter->add_pattern('*');
$fcd->set_filter($ffilter);
if ($fcd->run() == Gtk::RESPONSE_NO) {
$fcd->destroy();
return;
}
$strFile = $fcd->get_filename();
$fcd->destroy();
if (!file_exists($strFile)) {
//FIXME: Error message
return;
}
$this->installFile($strFile);
}//public function onInstallLocalPackage()
/**
* Some files have been dropped on the install button
*/
public function onFilesDropped($widget, $arFiles)
{
$strFile = reset($arFiles);
$this->installFile($strFile);
}//public function onFilesDropped($widget, $arFiles)
/**
* Install the given package file
*
* @param string $strFile File to install
*/
protected function installFile($strFile)
{
//get changes done in gui into config
PEAR_Frontend_Gtk2_Config::loadConfigurationFromGui($this);
$this->installer->installPackage(
null,
$strFile,
null,
true,
PEAR_Frontend_Gtk2_Config::$strDepOptions,
PEAR_Frontend_Gtk2_Config::$bForceInstall
);
$this->refreshLocalPackages();
$this->strLastFile = $strFile;
}//protected function installFile($strFile)
public function userConfirm()
{
//just to make sure that the class is recognized as proper PEAR_Frontend class
}//public function userConfirm()
/**
* A fatal error occured
*
* @param PEAR_Error $error The error
*/
public function displayFatalError($error)
{
$strMessage = $error->getMessage();
//404 occurs often and isn't that bad, so we can ignore it
//404 occurs, if a package exists but hasn't released a version.
if (strpos(strtolower($strMessage), '404 not found') === false) {
$dialog = new GtkMessageDialog(
$this->arWidgets['dlgInstaller'],
Gtk::DIALOG_MODAL,
Gtk::MESSAGE_ERROR,
Gtk::BUTTONS_OK,
'A fatal error occured:' . "\r\n" . $strMessage
);
$answer = $dialog->run();
$dialog->destroy();
}
}//public function displayFatalError($error)
}//class PEAR_Frontend_Gtk2
?>