/** * File: modules/Progress.ycp * Module: Progress * Summary: Progress bar * Authors: Petr Blahos * * $Id: Progress.ycp 33164 2006-09-27 08:42:24Z jsrain $ * * Functions for progress bar.
*
 * Dialog Title
 *
 * [x] Stage 1
 * [x] Stage 2
 *  => Stage 3
 *  -  Stage 4
 *  -  Stage 5
 *
 * Progress Title
 * [============================90%=======================------]
 *
 * 
* Example of progress bar usage (don't forget the translation marks in your code): * Progress bar supposes main wizard dialog is created.
 * Progress::Simple ("Some progress bar", "Progress runs here...", 3, "");
 * Progress::NextStep (); // the 1st one does nothing!
 * Progress::NextStep ();
 * Progress::NextStep ();
 * Progress::NextStep ();
* * Another example:
 * Progress::New ("Complex progress bar", " ", 100, [
 *      "Stage1", "Stage2", "Stage3",
 *      ], [
 *      "Stage 1 ...", "Stage 2 ...", "Stage 3 ...", "Finished",
 *      ], "Help text");
 * Progress::NextStage ();
 * Progress::NextStageStep (20);
 * Progress::Stage (0, "I am back", 2);
 * Progress::Title ("Still in stage 0");
 * Progress::NextStageStep (90);
 * Progress::Finish ();
* * See also hand made documentation. * Progress.html */ { module "Progress"; textdomain "base"; import "CommandLine"; import "Wizard"; import "Mode"; // Number of stages. integer stages = 0; // Number of steps integer steps = 0; // Current stage integer current_stage = 0; // Current step integer current_step = 0; // list of stage-titles list titles = []; // is progress bar used? boolean visible = true; // superior progress (stages) bar integer super_steps = 0; integer super_step = 0; list super_stages = []; /** * Sets progress bar state: * on = normal operation, off = All Progress:: calls return immediatelly. * @param state on or off * @return previous state */ global define boolean set (boolean state) { boolean prev = visible; visible = state; return prev; } /** * Returns currently selected visibility status of all UI-modifying Progress:: functions. * * @return boolean whether the progress bar is used * @see Progress::set * @see Progress::off * @see Progress::on */ global define boolean status () { return visible; } /** * Turns progress bar off. All Progress:: calls return immediatelly. * @deprecated set */ global define void off () { // no "deprecated" warning // because it is ok to use this function in testsuites visible = false; } /** * Turns progress bar on after calling Progress::off. * @deprecated set */ global define void on () { y2warning (-1, "Deprecated function. Use Progress::set instead"); visible = true; } /** * @param kind `todo, `current or `done * @return UI mark for stages */ any Mark (symbol kind) { if (kind == `todo) return "- "; if (kind == `current) return UI::Glyph (`BulletArrowRight); if (kind == `done) return UI::Glyph (`CheckMark); return "?@%!"; } /** * @param i stage number * @return widget `id(...) for the marker */ term MarkId (integer i) { return `id (sformat ("mark_stage_%1",i)); } /** * New complex progress bar with stages. * @param window_title title of the window * @param progress_title title of the progress bar. Pass at least " " * (one space) if you want some progress bar title. * @param length number of steps. If 0, no progress bar is created, * there are only stages and bottom title. THIS IS NOT * NUMBER OF STAGES! * @param stg list of strings - stage names. If it is nil, then there * are no stages. * @param tits Titles corresponding to stages. When stage changes, * progress bar title changes to one of these titles. May * be nil/empty. * @param help_text help text */ global define void New (string window_title, string progress_title, integer length, list stg, list tits, string help_text) ``{ if (!visible) return ; steps = length; stages = size (stg); titles = tits; current_step = -1; current_stage = -1; if (Mode::commandline ()) return; if (progress_title == "") { // Reserve space for future progress bar labels. The ProgressBar // widget will suppress the label above the progress bar if the // initial label string is empty. progress_title = " "; } term bar = `VBox( // progressbar only `ProgressBar(`id(`pb),progress_title,length,0) ); if (0 != stages) { // version with stages bar = `VBox (`VSpacing (1)); integer i = 0; any label_heading = Mark (`todo); foreach (string item, stg, ``{ bar = add (bar, `HBox ( `HSpacing (1), // check_ycp wants this text to be translatable. I do not know why. `Heading (MarkId (i), label_heading), `Label (`opt (`hstretch), item) ) ); i = i+1; }); if (0 != steps) { // stages and progress bar = add (bar, `VBox ( `VStretch (), `ProgressBar (`id (`pb), progress_title, length, 0), `VSpacing (2) )); } else { // stages only bar = add (bar, `VBox ( `VStretch (), `Label (`id (`pb), `opt (`hstretch), progress_title), `VSpacing (2) )); } } UI::ReplaceWidget (`id (`contents), bar); if (! UI::WizardCommand(`SetDialogHeading( window_title ) ) ) { UI::ChangeWidget (`id (`title), `Value, window_title); } if ("" != help_text && nil != help_text) { Wizard::SetHelpText (help_text); } Wizard::DisableBackButton (); Wizard::DisableNextButton (); } /** * Create simple progress bar with no stages, only with progress bar. * @param window_title Title of the window. * @param progress_title Title of the progress bar. * @param length Number of steps. * @param help_text Help text. */ global define void Simple (string window_title, string progress_title, integer length, string help_text) ``{ New (window_title, progress_title, length, [], [], help_text); } /** * Uses current_step */ void UpdateProgressBar () { if (current_step > steps) { y2error (-2, "Progress bar has only %1 steps, not %2.", steps, current_step); return ; } UI::ChangeWidget (`id (`pb), `Value, current_step); } /** * the bar is either `ProgressBar or `Label * @param s title */ void SetProgressBarTitle (string s) { UI::ChangeWidget (`id (`pb), 0 == steps ? `Value : `Label, s); } /** * Some people say it is the best operating system ever. But now to the * function. Advances progress bar value by 1. */ global define void NextStep () ``{ if (!visible || Mode::commandline () || 0 == steps) return ; current_step = current_step + 1; UpdateProgressBar (); } /** * Advance stage, advance step by 1 and set progress bar caption to * that defined in New. */ global define void NextStage () ``{ if (!visible) return ; NextStep (); if (0 == stages || current_stage > stages) { y2error ("Non-existing stage requested."); return ; } current_stage = current_stage + 1; if ( Mode::commandline ()) { if (current_stage < stages && current_stage < size (titles)) { CommandLine::PrintVerbose(titles[current_stage]:""); } return; } if (current_stage > 0) { UI::ChangeWidget (MarkId (current_stage-1), `Value, Mark (`done)); } // we may be past the last stage if (current_stage < stages ) { if (current_stage < size (titles)) { SetProgressBarTitle (titles[current_stage]:""); } UI::ChangeWidget (MarkId (current_stage), `Value, Mark (`current)); } } /** * Changes progress bar value to st. * @param st new value */ global define void Step (integer st) ``{ if (!visible || Mode::commandline () || 0 == steps) return ; current_step = st; UpdateProgressBar (); } /** * Go to stage st, change progress bar title to title and set progress * bar step to step. * @param st New stage. * @param title New title for progress bar. If nil, title specified in * New is used. * @param step New step or -1 if step should not change. */ global define void Stage (integer st, string title, integer step) ``{ if (!visible) return ; if (-1 != step) { Step (step); } if (!Mode::commandline () && current_stage >= 0) { UI::ChangeWidget(MarkId (current_stage), `Value, Mark (st > current_stage ? `done: `todo)); } current_stage = st; string s = ""; if (current_stage < size (titles)) { s = titles[current_stage]:""; } if (nil != title) { s = title; } if (current_stage < size (titles)) { if (Mode::commandline ()) { CommandLine::PrintVerbose (s); return; } else { SetProgressBarTitle (s); } } if (current_stage < stages) { UI::ChangeWidget(MarkId (current_stage), `Value, Mark (`current)); } } /** * Jumps to the next stage and sets step to st. * @param st new progress bar value */ global define void NextStageStep (integer st) ``{ if (!visible || Mode::commandline ()) return ; NextStage (); Step (st); } /** * Change progress bar title. * @param t new title. Use ""(empty string) if you want an empty progress bar. */ global define void Title (string t) ``{ if (visible && ! Mode::commandline ()) SetProgressBarTitle (t); } /** * Moves progress bar to the end and marks all stages as completed. */ global define void Finish () ``{ if (!visible || Mode::commandline ()) return ; if (0 != stages) { while (current_stage < stages) NextStage (); } if (0 != steps) { current_step = steps; UpdateProgressBar (); } SetProgressBarTitle (" "); } /** * Creates a higher-level progress bar made of stages. Currently it is * placed instead of help text. * @param title title of the progress... * @param stages list of stage descriptions */ global define void OpenSuperior (string title, list stages) { if (UI::HasSpecialWidget(`Wizard)) { Wizard::OpenAcceptAbortStepsDialog(); UI::WizardCommand(`AddStepHeading(title)); integer idx = 0; super_steps = size (stages); super_step = -1; foreach (string s, stages, { string id = sformat ("super_progress_%1", idx); UI::WizardCommand (`AddStep (s, id)); }); UI::WizardCommand(`UpdateSteps() ); } else // old behaviour { term left = `VBox (`VStretch ()); term right = `VBox (`VStretch ()); integer idx = 0; super_steps = size (stages); super_step = -1; foreach (string i, stages, { string id = sformat ("super_progress_%1", idx); left = add (left, `Heading (`id (id), "- ")); right = add (right, `Label (`opt (`hstretch), i)); left = add (left, `VStretch ()); right = add (right, `VStretch ()); idx = idx + 1; }); left = add (left, `HSpacing (4)); right = add (right, `HStretch ()); Wizard::ReplaceHelp (`VBox ( `HBox ( `HSpacing (1), `Frame ( title, `HBox (`HSpacing (1), left, right) ) ), `VSpacing (0.5) ) ); } } /** * Replaces stages of superior progress by an empty help text. */ global define void CloseSuperior () ``{ if (UI::HasSpecialWidget(`Wizard)) { UI::CloseDialog(); } else { Wizard::RestoreHelp (""); } super_steps = 0; super_step = 0; } /** * Make one step in a superior progress bar. */ global define void StepSuperior () ``{ if (super_step >= 0 && super_step < super_steps) { if (!UI::HasSpecialWidget(`Wizard)) { UI::ChangeWidget (`id (sformat ("super_progress_%1", super_step)), `Value, UI::Glyph (`CheckMark)); } } super_step = super_step + 1; if (super_step >= super_steps) { return; } if (UI::HasSpecialWidget(`Wizard)) { UI::WizardCommand (`SetCurrentStep (sformat ("super_progress_%1", super_step))); } else { UI::ChangeWidget (`id (sformat ("super_progress_%1", super_step)), `Value, UI::Glyph (`BulletArrowRight)); } } /* EOF */ }