home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2007 January, February, March & April
/
Chip-Cover-CD-2007-02.iso
/
boot
/
i386
/
root
/
usr
/
share
/
YaST2
/
modules
/
OSRPkgUI.ycp
< prev
next >
Wrap
Text File
|
2006-11-29
|
19KB
|
741 lines
/**
* File: OSRPkgUI.ycp
* Module: repair
* Summary: Packages check UI
* Authors: Johannes Buchhold <jbuch@suse.de>
*
* $Id: OSRPkgUI.ycp 23769 2005-06-21 12:18:10Z jsuchome $
*
* Provide osr mode information.
*/
{
module "OSRPkgUI";
import "HTML";
import "Report";
import "Label";
import "Popup";
import "OSRSystem";
import "OSRExecute";
import "OSRLogFile";
import "OSRProgress";
import "OSRMode";
import "OSRPkgVerify";
import "OSRPopup";
textdomain "repair";
////////////////////////////////////////////////////////
// Static
////////////////////////////////////////////////////////
/**
* Symbol and key's for the widget comunication
*/
symbol package_progress_bar = `package_progress_bar;
string package_widget = "package_widget";
string ok_or_cancel_key = "ok_or_cancel";
string pause_key = "pause";
string mode_key = "mode";
string mode_replace_point_key = "replace_point";
// buttons label
string pause_label = _("&Pause");
// buttons label
string continue_label = _("&Continue");
/**
* All allowed rpm test options with description.
*/
list<list> modes = [
// 'rpm -V <package>' output flag
["S", _("The File Size") ],
["M", _("The File Mode") ],
["5", _("The MD5 Checksum of the File") ],
["D", _("The File Major and Minor Number") ],
["L", _("The File Symbolic Link Content") ],
["U", _("The Owner of the File") ],
["G", _("The File Group") ],
["T", _("The Last Modification Time") ]
];
////////////////////////////////////////////////////////
// Not static
////////////////////////////////////////////////////////
/**
* True if the user have paused the verifying process.
*/
boolean pause = false;
/**
* Show successful package checks too.
*/
boolean show_ok = false;
/**
* Summary text of all passed and not passed packages.
*/
string verified_text_ok = "";
/**
* Summary text of the not passed packages only.
*/
string verified_text = "";
/**
* Count of packages which should be checked.
*/
integer package_count = 0;
/**
* Dialogs for expert and normal mode.
*/
list dialogs = [];
/**
* If expert is activated.
*/
global boolean expert_mode = false;
/**
* if current UI can use `DownloadProgress
*/
boolean has_progress_widget = false;
/**
* packages that should be reinstalled after verification
* (only helper structure, for showing list in dialogs)
*/
list packages_to_reinstall = [];
//-----------------------------------------------------------------
/**
*
*/
boolean protocol_mode = false;
// crate header for verification output richtext
define void set_verify_text_header() {
string header = "";
string hr = "";
list<string> special = [];
// Build headers for the tables in qt-mode
has_progress_widget = UI::HasSpecialWidget (`DownloadProgress);
if (has_progress_widget)
{
special = [ "width=400", "align=right"];
header = "<table %5><tr> <th>%1</th>
<th>%2</th>
<th>%3</th>
<th %6> %4</th>
</tr>";
hr = sformat("<tr> <th><hr></th>
<td><hr></td>
<td><hr></td>
<td %1><hr></td>
</tr>", special[1]:"");
verified_text_ok = sformat( header,
HTML::Bold(_("Package Name")),
HTML::Bold(_("Files")),
HTML::Bold(_("Configuration File")),
HTML::Bold(_("Status")),
special[0]:"",
special[1]:"" );
verified_text_ok = verified_text_ok + hr;
verified_text = verified_text_ok;
}
else {
y2debug("no headline");
}
}
/**
* Reset all (not static) module settings.
*/
global define void Reset()``{
// Reset values
show_ok = false;
pause = false;
package_count = 0;
expert_mode = false;
dialogs = [];
protocol_mode = false;
verified_text = "";
verified_text_ok = "";
packages_to_reinstall = [];
OSRProgress::Reset();
}
/**
* Constructor- reset module settings.
*/
global define void OSRPkgUI()``{
Reset();
}
/**
* Fill a string with the specified character.
* Used in ncurses mode for formatting.
*/
define string fill(string str, integer length, string c)``{
if (size(str) > length ) return substring(str, 0, length);
while( size(str) < length ) { str = str +c ;}
return str;
}
/**
* Return the current dialog ( expert or normal dialog).
*/
define term get_verify_dialog()``{
integer pos = 0;
if (protocol_mode ) pos = 3;
else {
pos = ( expert_mode ) ? 0 : 1 ;
}
return dialogs[ pos ]:`Empty();
}
/**
* Repaint the displayed text depending on the show_ok value (CheckBox Show all).
*/
define boolean repaint()``{
if (UI::WidgetExists(`id(package_widget )))
{
string table = "</table>";
if (!has_progress_widget)
{
table = "";
}
if (show_ok && UI::WidgetExists(`id(package_widget )))
{
return UI::ChangeWidget(`id( package_widget), `Value, verified_text_ok + table );
}
else {
return UI::ChangeWidget(`id( package_widget), `Value, verified_text + table );
}
}
return false;
}
/**
* Switch between expert and normal mode.
*/
define void set_expert_mode(boolean t_expert_mode )``{
//boolean changed = t_expert_mode != expert_mode;
expert_mode = t_expert_mode;
show_ok = true;
if (UI::WidgetExists(`id(mode_replace_point_key)))
{
UI::ReplaceWidget(`id(mode_replace_point_key), get_verify_dialog());
UI::ChangeWidget( `id(mode_key ), `Value, expert_mode);
UI::RecalcLayout();
repaint();
}
if (UI::WidgetExists(`id( package_progress_bar )))
{
UI::ChangeWidget(`id( package_progress_bar), `Value, OSRPkgVerify::VerifiedSize ());
}
}
/**
* Build string: Checking package: (43/234)
*/
define string check_string()``{
// current action label; %1 is current package number, %2 all packages
return sformat(_("Package %1 of %2"), OSRPkgVerify::VerifiedSize (), package_count);
}
/**
* Create to dialogs. One for the expert user mode and one for the
* normal user mode. Save both dialogs in the list dialogs for
* later use.
*/
define void build_verify_dialog_contents(string headline)``{
dialogs = [];
//components for both
term ok_cancel_button = `PushButton( `id(ok_or_cancel_key), Label::CancelButton());
term switch_button = `CheckBox(`id(mode_key ), `opt(`notify), _("Show &Details"), expert_mode );
term progress_bar = OSRProgress::CreateProgressBar(package_progress_bar, check_string(), package_count );
term show_ok_term = `Left(`CheckBox(`id("show_ok"), `opt(`notify), _("Also Show Successfully Verified &Packages"), show_ok));
term protocol = `RichText(`id(package_widget), `opt(`vstretch, `autoScrollDown ) , (show_ok ) ? verified_text_ok : verified_text );
dialogs = add( dialogs,
`HBox(`VSpacing(20),
`VBox(
`HSpacing(80),
show_ok_term,
protocol,
`Left(`PushButton(`id(pause_key), pause_label )))
));
dialogs = add( dialogs, `Empty());
// normal dialog
dialogs = add( dialogs,
`HBox(`HSpacing(3),
`VBox(
`HSpacing(80),
`VBox(
`HSpacing(80),
`Left(`Heading(headline)),
`VSpacing(1),
progress_bar,
`Left(switch_button) ),
`ReplacePoint(`id(mode_replace_point_key ), dialogs[1]:`Empty() ),
ok_cancel_button
),
`HSpacing(3)
));
dialogs = add( dialogs, `HBox(`HWeight(1, `HSpacing(3)),
`HWeight(30,`VBox(`VWeight(10, show_ok_term ),
`VWeight(80, protocol ),
`VWeight(10, `PushButton( `id(ok_or_cancel_key), Label::OKButton()) ))),
`HWeight(1, `HSpacing(1))));
}
/**
* Open the main dialog depending on the values t_expert_mode (expert_mode).
*/
global define boolean OpenVerifyDialog(integer size_progress , string headline , boolean t_expert_mode )``{
if (verified_text == "")
{
set_verify_text_header();
}
// count of package which should be verified.
package_count = size_progress;
// build the dialog depending on the mode.
build_verify_dialog_contents(headline);
// open the dialog.
boolean ret = UI::OpenDialog( dialogs[2]:`Empty() );
// set mode - expert mode or normal mode.
// set_expert_mode( t_expert_mode );
return ret;
}
/**
* Generate a key for a package without error.
*/
define string pkg_name2ok_key(string pkg_name)``{
return "status" + pkg_name ;
}
/**
* Decode the package name from a key for a package without error.
*/
define string ok_key2pkg_name(string input ) ``{
if (substring(input, 0, size("status")) == "status" )
{
string pkg_name = substring(input, size("status") );
if (OSRPkgVerify::PackageVerified (pkg_name))
return pkg_name;
}
return "";
}
/**
* 'translate' booleqan to string which can be shown in dialogs
*/
define string boolean2string (boolean val) ``{
// table entry (value in the column "Configuration file")
// translate it either as True/False or Yes/No
return val ? _("Yes") : _("No");
}
/**
* Update the list of files, which failed during package verification
* returns contents of the richtext
*/
define string update_files (string pkg_name, list<map> pkg_data) {
string ret = "";
string tab_pkg_name_color = contains (
OSRPkgVerify::not_successful_verified, pkg_name) ? "red" : "blue" ;
string line_sf = "<li>%1 %2 %3</li>%4";
string align = "";
if (has_progress_widget)
{
align = "align=right";
line_sf = "<tr><td colspan=2 align=right> %1</td>
<td>%2</td>
<td %4>%3</td>
</tr>";
}
foreach (map line, pkg_data, {
string color = line["green_status"]:"" == ""? "red": "green";
string file_status =
HTML::Bold (HTML::Colorize (line["status"]:"", color));
string file = line["file"]:"";
string config_file = boolean2string (line["config_file"]:false);
if (!has_progress_widget)
{
file = fill (file, 50, ".") + "..";
config_file = fill (config_file, 7, ".");
}
if (line["more"]:false)
{
file = HTML::Link (
// last entry of file list (cut because of length)
HTML::Colorize (_("more..."), tab_pkg_name_color),
pkg_name + "_more_packages"
);
config_file = "";
file_status = "";
}
ret = ret + sformat(line_sf, file, config_file, file_status, align);
});
return ret;
}
/**
* Add a new package entry to the internal list and the displayed text.
* Update the process bar too.
* Afterwards call repaint define.
*/
define boolean update (string pkg_name) {
if (UI::WidgetExists(`id("show_ok")))
show_ok = (boolean) UI::QueryWidget(`id("show_ok"), `Value );
string tab_body = "";
string tab_pkg_status = "";
string tab_pkg_name_color = contains (
OSRPkgVerify::not_successful_verified, pkg_name) ? "red" : "blue" ;
string tab_pkg_name = HTML::Link (HTML::Bold (
HTML::Colorize (pkg_name, tab_pkg_name_color)), pkg_name);
boolean ok = size (OSRPkgVerify::verify_data) == 0;
if (ok)
{
tab_pkg_status = HTML::Link (
HTML::Bold (HTML::Colorize ("ok", "blue")),
pkg_name2ok_key (pkg_name)
);
}
else
{
if (tab_pkg_status == "" ) tab_pkg_status = HTML::Bold("...");
tab_body = update_files (pkg_name, OSRPkgVerify::verify_data);
}
string line_sf = "<tr><th>%1</th>
<th></th>
<th></th>
<th %4> %2</th> %3
</tr>";
string align = "align=right";
if (!has_progress_widget)
{
string n1 = HTML::Bold (_("Package:"));
string n2 = HTML::Bold (ok ? "": _("Files:")) + "<br>";
line_sf =
"<br><br>" + n1 +"<li><b>%1</b> <b>%2</b></li>" + n2 + "%3%4";
tab_pkg_name = tab_pkg_name + fill ("", 60 - size(pkg_name), ".");
align = "";
}
string table =
sformat (line_sf, tab_pkg_name, tab_pkg_status, tab_body, align);
verified_text_ok = verified_text_ok + table;
if (!ok)
{
verified_text = verified_text + table;
}
return repaint();
}
/**
* Show the complete ouptput of package verification
* (in the summary, it is limited to OSRPkgVerify::max_files entries)
*/
define symbol show_complete_verify_list (string pkg_name) {
UI::OpenDialog (`HBox (
`HSpacing (3),
`VSpacing (OSRPkgVerify::max_files + 10),
`VBox (
`HSpacing(80),
`VSpacing (1),
// label - %1 is package name; file list (=result) will follow
`Label (sformat (_("Result of Package '%1' Verification"),
pkg_name)),
`VSpacing (1),
`RichText (`id (`files), `opt(`vstretch, `autoScrollDown), ""),
`PushButton (`id(`ok), Label::OKButton())
),
`HSpacing(3)
));
UI::BusyCursor ();
OSRExecute::CommandOutput (.local.bash,
sformat("LANG=ENG /bin/rpm --root %2 -V %1", pkg_name,
OSRPkgVerify::root_for_verification));
map out = OSRPkgVerify::convert_verify_output (
pkg_name, OSRExecute::stdout, true);
string start = "";
string end = "";
if (has_progress_widget)
{
start = sformat (
"<table><tr>
<th colspan=2 align=right>%1</th>
<th>%2</th>
<th align=right>%3</th>
</tr>",
_("Files "), _("Configuration File"), _("Status"));
end = "</table>";
}
UI::ChangeWidget (`id(`files), `Value,
start + update_files (pkg_name, out["verify_data"]:[]) + end);
UI::NormalCursor ();
UI::UserInput ();
UI::CloseDialog ();
return `again;
}
/**
* popup with the summary of the package
*/
define symbol show_package_details (string pkg_name) {
// popup headline
map ret = OSRPopup::CheckBoxDialog (_("Package Details"),
Pkg::PkgSummary (pkg_name),
[ [ pkg_name,
// checkbox label
_("Reinstall the Package"),
contains (packages_to_reinstall, pkg_name)
] ]
);
foreach (string pkg, boolean reinstall, (map<string,boolean>) ret , ``{
if (reinstall)
{
packages_to_reinstall = union (packages_to_reinstall, [ pkg ]);
}
else
{
packages_to_reinstall = filter (string name,
(list<string>) packages_to_reinstall, ``( name != pkg ));
}
});
return `next;
}
/**
* Toggle the pause button between pause and continue.
*/
define symbol toggle_pause_button() ``{
pause = ! pause;
if (UI::WidgetExists(`id(pause_key)))
{
if (!pause)
{
UI::ChangeWidget(`id(pause_key), `Label, pause_label );
return `continue;
}
else
{
UI::ChangeWidget(`id(pause_key), `Label, continue_label );
return `pause;
}
}
}
/**
* Eval the user input.
*/
global define symbol EvalUserInput (string input) ``{
// if the user pressed the or or cancel button ask or abort
if (input == ok_or_cancel_key )
{
// if not all packages are verified ask the user if he
// want really cancel.
if (package_count > OSRPkgVerify::VerifiedSize () && !protocol_mode)
{
// popup question
if (!Popup::YesNo(_("Really cancel package verification?")))
{
return `again;
}
}
return `abort;
}
else if (input == pause_key )
{
// if the user pressed the pause or continue button
// change the label of the button.
return toggle_pause_button();
}
else if (input == "show_ok")
{
// if the dialog in the expert mode and the user
// clicked the checkbox "show_ok" change the
// shown verify text
show_ok = (boolean) UI::QueryWidget(`id("show_ok"), `Value );
repaint();
}
else if (OSRPkgVerify::PackageVerified (input))
{
// if the dialog in the expert mode and the
// user clicked a package name open a dialog
// with the summary of the package
show_package_details (input);
}
else if (ok_key2pkg_name (input) != "" )
{
// if the dialog in the expert mode and the
// user clicked a package status open a
// dialog with the following message.
Report::Message(sformat(_("
Verifying the package %1 was successful.
"), ok_key2pkg_name(input)));
}
else if (input == mode_key )
{
// change the dialog mode between the expert
// and the normal mode.
set_expert_mode ((boolean)UI::QueryWidget(`id(mode_key ), `Value));
if (pause)
{
toggle_pause_button();
return `continue;
}
}
else if (issubstring (input, "_more_packages"))
{
string pkg_name = substring (input,0,find (input,"_more_packages"));
if (!OSRPkgVerify::PackageVerified (pkg_name))
{
y2warning ("strange, package %1 not verified", pkg_name);
return `again;
}
show_complete_verify_list (pkg_name);
}
else
{
// open a extended dialog which describe the packages status
//S.5....T c <- Config file
string pkg_name = regexpsub (input,
sformat("(.*%1).*", OSRPkgVerify::separator), "\\1");
pkg_name = substring (pkg_name, 0,
size(pkg_name) - size (OSRPkgVerify::separator));
}
return `again;
}
/**
* update the item list of 'missing_packages' with the ones
* selected to reinstall by user during verification
*/
global define list<list> update_missing_packages (
list<list> item_list, boolean check) {
foreach (string item, (list<string>) packages_to_reinstall, {
if (!contains (OSRPkgVerify::not_successful_verified, item))
item_list = add (item_list, [item, check]);
});
return item_list;
}
global define list ProtocolDialog()``{
protocol_mode = true;
UI::OpenDialog( get_verify_dialog() );
symbol ret = `next;
string rret = "";
repaint();
repeat
{
rret = (string) UI::UserInput();
y2milestone(" user input in protocol dialogs : %1", rret);
ret = EvalUserInput (rret);
} until (ret == `abort || ret == `cancel);
UI::CloseDialog();
protocol_mode = false;
list<list> item_list = [];
foreach (string item, OSRPkgVerify::not_successful_verified , {
boolean checked = contains (packages_to_reinstall, item);
item_list = add (item_list, [item, checked]);
});
return update_missing_packages (item_list, true);
}
global define boolean AddPackageSummary (string pkg_name) {
boolean ret = update (pkg_name);
if (UI::WidgetExists(`id( package_progress_bar )))
{
OSRProgress::SetLabel (package_progress_bar, check_string());
}
return ret;
}
/**
* Finish the dialog.
*/
global define void Finish()``{
UI::ChangeWidget(`id(ok_or_cancel_key), `Label, Label::OKButton());
if (UI::WidgetExists(`id(pause_key ) ))
{
UI::ChangeWidget(`id(pause_key), `Enabled, false);
}
}
}//EOF