Author: jsuchome
Date: Fri Jul 4 09:35:50 2008
New Revision: 48861
URL: http://svn.opensuse.org/viewcvs/yast?rev=48861&view=rev
Log:
YCP modules needed to be adapted to get 'yast2 timezone' run
Added:
branches/tmp/lslezak/workshop/ycp_modules/
branches/tmp/lslezak/workshop/ycp_modules/Arch.ycp (with props)
branches/tmp/lslezak/workshop/ycp_modules/Directory.ycp (with props)
branches/tmp/lslezak/workshop/ycp_modules/Encoding.ycp (with props)
branches/tmp/lslezak/workshop/ycp_modules/Language.ycp (with props)
branches/tmp/lslezak/workshop/ycp_modules/Misc.ycp (with props)
branches/tmp/lslezak/workshop/ycp_modules/Wizard.ycp (with props)
Added: branches/tmp/lslezak/workshop/ycp_modules/Arch.ycp
URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/lslezak/workshop/ycp_modules/Arch.ycp?rev=48861&view=auto
==============================================================================
--- branches/tmp/lslezak/workshop/ycp_modules/Arch.ycp (added)
+++ branches/tmp/lslezak/workshop/ycp_modules/Arch.ycp Fri Jul 4 09:35:50 2008
@@ -0,0 +1,500 @@
+/**
+ * File: modules/Arch.ycp
+ * Module: yast2
+ * Summary: Architecture, board and bios data
+ * Authors: Klaus Kaempf
+ * Flags: Stable
+ *
+ * $Id$
+ */
+
+{
+
+module "Arch";
+
+import "DBus";
+
+// local variables
+
+string _architecture = nil;
+
+string _board_compatible = nil;
+
+string _checkgeneration = "";
+
+boolean _has_pcmcia = nil;
+
+boolean _is_laptop = nil;
+
+boolean _is_uml = nil;
+
+boolean _has_smp = nil;
+
+// Xen domain (dom0 or domU)
+boolean _is_xen = nil;
+
+// Xen dom0
+boolean _is_xen0 = nil;
+
+/* ************************************************************ */
+/* system architecture */
+
+/**
+ * Returns full architecture type (one of i386, sparc, sparc64, mips, mips64, ppc, ppc64, alpha, s390_32, s390_64, ia64, x86_64)
+ *
+ * @return string architecture
+ */
+global string architecture () {
+ if (_architecture == nil)
+ _architecture = (string)DBus::Read(.probe.architecture);
+ return _architecture;
+}
+
+/**
+ * true for all x86 compatible architectures
+ */
+global boolean i386 () {
+ return architecture () == "i386";
+}
+
+/**
+ * true for all 32bit sparc architectures
+ * @see sparc
+ * @see sparc64
+ */
+global boolean sparc32 () {
+ return architecture () == "sparc";
+}
+
+/**
+ * true for all 64bit sparc architectures
+ * @see sparc
+ * @see sparc32
+ */
+global boolean sparc64 () {
+ return architecture () == "sparc64";
+}
+
+/**
+ * true for all sparc architectures (32 or 64 bit)
+ * @see sparc32
+ * @see sparc64
+ */
+global boolean sparc () {
+ return sparc32 () || sparc64 ();
+}
+
+/**
+ * true for all 32bit mips architectures
+ * @see mips
+ * @see mips64
+ */
+global boolean mips32 () {
+ return architecture () == "mips";
+}
+
+/**
+ * true for all 64bit mips architectures
+ * @see mips
+ * @see mips32
+ */
+global boolean mips64 () {
+ return architecture () == "mips64";
+}
+
+/**
+ * true for all mips architectures (32 or 64 bit)
+ * @see mips32
+ * @see mips64
+ */
+global boolean mips () {
+ return mips32 () || mips64 ();
+}
+
+/**
+ * true for all 32bit ppc architectures
+ * @see ppc
+ * @see ppc64
+ */
+global boolean ppc32 () {
+ return architecture () == "ppc";
+}
+
+/**
+ * true for all 64bit ppc architectures
+ * @see ppc
+ * @see ppc32
+ */
+global boolean ppc64 () {
+ return architecture () == "ppc64";
+}
+
+/**
+ * true for all ppc architectures (32 or 64 bit)
+ * @see ppc32
+ * @see ppc64
+ */
+global boolean ppc () {
+ return ppc32 () || ppc64 ();
+}
+
+/**
+ * true for all alpha architectures
+ */
+global boolean alpha () {
+ return architecture () == "alpha";
+}
+
+/**
+ * true for all 32bit S/390 architectures
+ * @see s390
+ * @see s390_64
+ */
+global boolean s390_32 () {
+ return architecture () == "s390_32";
+}
+
+/**
+ * true for all 64bit S/390 architectures
+ * @see s390
+ * @see s390_32
+ */
+global boolean s390_64 () {
+ return architecture () == "s390_64";
+}
+
+/**
+ * true for all S/390 architectures (32 or 64 bit)
+ * @see s390_32
+ * @see s390_64
+ */
+global boolean s390 () {
+ return s390_32 () || s390_64 ();
+}
+
+/**
+ * true for all IA64 (itanium) architectures
+ */
+global boolean ia64 () {
+ return architecture () == "ia64";
+}
+
+/**
+ * true for all x86-64 (AMD Hammer) architectures
+ */
+global boolean x86_64 () {
+ return architecture () == "x86_64";
+}
+
+/**
+ * Returns general architecture type (one of sparc, mips, ppc, s390, i386, alpha, ia64, x86_64)
+ *
+ * @return string arch_short
+ */
+global string arch_short () {
+ if (sparc ())
+ return "sparc";
+ else if (mips ())
+ return "mips";
+ else if (ppc ())
+ return "ppc";
+ else if (s390 ())
+ return "s390";
+ else
+ return architecture ();
+}
+
+/* ************************************************************ */
+/* general system board types (initialized in constructor) */
+
+global string board_compatible () {
+ if (_board_compatible == nil)
+ {
+ _checkgeneration = "";
+ list<map> systemProbe = (list<map>) DBus::Read(.probe.system);
+ if(systemProbe == nil) systemProbe = [];
+
+ foreach (map systemEntry, systemProbe, ``{
+ string checksys = systemEntry["system"]:"";
+ _checkgeneration = systemEntry["generation"]:"";
+ if (checksys != "")
+ {
+ _board_compatible = checksys;
+ }
+ });
+ y2milestone("_board_compatible '%1' \n", _board_compatible);
+ if (i386 () || x86_64 ())
+ {
+ _board_compatible = "wintel";
+ }
+ // hwinfo expects CHRP/PReP/iSeries/MacRISC* in /proc/cpuinfo
+ // there is no standard for the board identification
+ // Cell and Maple based boards have no CHRP in /proc/cpuinfo
+ // Pegasos and Cell do have CHRP in /proc/cpuinfo, but Pegasos2 should no be handled as CHRP
+ // Efika is handled like Pegasos for the time being
+ if (ppc () && (_board_compatible == nil || _board_compatible == "CHRP"))
+ {
+ map device_type = (map) SCR::Execute (.target.bash_output,
+ "echo -n `cat /proc/device-tree/device_type`" , $[]);
+ map model = (map) SCR::Execute (.target.bash_output,
+ "echo -n `cat /proc/device-tree/model`" , $[]);
+ string board = model["stdout"]:"";
+ y2milestone("model %1 , device_type %2\n", model, device_type);
+ // catch remaining IBM boards
+ if (issubstring (device_type["stdout"]:"", "chrp"))
+ {
+ _board_compatible = "CHRP";
+ }
+ // Maple has its own way of pretenting OF1275 compliance
+ if (board == "Momentum,Maple-D" || board == "Momentum,Maple-L"
+ || board == "Momentum,Maple")
+ {
+ _board_compatible = "CHRP";
+ }
+ // Pegasos has CHRP in /proc/cpuinfo and 'chrp' in /proc/device-tree/device_type
+ if (board == "Pegasos2"
+ || issubstring (tolower (device_type["stdout"]:""), "pegasos2"))
+ {
+ _board_compatible = "Pegasos";
+ }
+ // Efika has CHRP in /proc/cpuinfo and 'efika' in /proc/device-tree/device_type
+ if (issubstring (tolower (board), "efika")
+ || issubstring (tolower (device_type["stdout"]:""), "efika"))
+ {
+ _board_compatible = "Pegasos";
+ }
+ }
+ // avoid future re-probing if probing failed
+ // also avoid passing nil outside the module
+ if (board_compatible == nil)
+ _board_compatible = "";
+ }
+ return _board_compatible;
+}
+/**
+ * true for all PPC "MacRISC" boards
+ */
+global boolean board_mac () {
+ return ppc () && (
+ board_compatible () == "MacRISC" ||
+ board_compatible () == "MacRISC2" ||
+ board_compatible () == "MacRISC3" ||
+ board_compatible () == "MacRISC4"
+ );
+}
+
+/**
+ * true for all "NewWorld" PowerMacs
+ */
+global boolean board_mac_new () {
+ // board_mac calls board_compatible which initializes _checkgeneration
+ return board_mac () && _checkgeneration == "NewWorld";
+}
+
+/**
+ * true for all "OldWorld" powermacs
+ */
+global boolean board_mac_old () {
+ // board_mac calls board_compatible which initializes _checkgeneration
+ return board_mac () && _checkgeneration == "OldWorld";
+}
+
+/**
+ * true for all "CHRP" ppc boards
+ */
+global boolean board_chrp () {
+ return ppc () && board_compatible () == "CHRP";
+}
+
+/**
+ * true for all "iSeries" ppc boards
+ */
+global boolean board_iseries () {
+ return ppc () && board_compatible () == "iSeries";
+}
+
+/**
+ * true for all "PReP" ppc boards
+ */
+global boolean board_prep () {
+ return ppc () && board_compatible () == "PReP";
+}
+
+/**
+ * true for all "Pegasos" and "Efika" ppc boards
+ */
+global boolean board_pegasos () {
+ return ppc () && board_compatible () == "Pegasos";
+}
+
+/**
+ * true for all "Windows/Intel" compliant boards (x86 based)
+ */
+global boolean board_wintel () {
+ return board_compatible () == "wintel";
+
+}
+
+
+/* ************************************************************ */
+/* BIOS stuff */
+
+/**
+ * true if the system supports PCMCIA
+ * But modern notebook computers do not have it. See also Bugzilla #151813#c10
+ * @see is_laptop
+ * @return true if the system supports PCMCIA
+ */
+global boolean has_pcmcia () {
+ if (_has_pcmcia == nil)
+ _has_pcmcia = (boolean)DBus::Read(.probe.has_pcmcia);
+ return _has_pcmcia;
+}
+
+/**
+ * true if the system runs on laptop
+ *
+ * @return if the system is a laptop
+ */
+global boolean is_laptop () {
+ if (_is_laptop == nil) {
+ list<map> system = (list<map>) DBus::Read (.probe.system);
+ string formfactor = system[0, "formfactor"]:"";
+ _is_laptop = formfactor == "laptop";
+ }
+ return _is_laptop;
+}
+
+/* ************************************************************ */
+/* UML stuff */
+
+/**
+ * true if UML
+ * @deprecated
+ * @return true if the system is UML
+ */
+global boolean is_uml () {
+ if (_is_uml == nil)
+ _is_uml = (boolean) DBus::Read(.probe.is_uml);
+ return _is_uml;
+}
+/* ************************************************************ */
+/* XEN stuff */
+
+/**
+ * true if Xen kernel is running (dom0 or domU)
+ * @return true if the Xen kernel is running
+ */
+global boolean is_xen () {
+ if (_is_xen == nil) {
+ // XEN kernel has /proc/xen directory
+ map stat = (map)DBus::ReadArg(.target.stat, "/proc/xen");
+ y2milestone("stat /proc/xen: %1", stat);
+
+ _is_xen = (size(stat) > 0);
+
+ if (_is_xen)
+ {
+ y2milestone("/proc/xen exists");
+
+ // check also the running kernel
+ // a FV machine has also /proc/xen, but the kernel is kernel-default
+ map out = (map)SCR::Execute(.target.bash_output, "uname -r", $[]);
+
+ string kernel_ver = out["stdout"]:"";
+ list<string> l = splitstring(kernel_ver, "\n");
+ kernel_ver = l[0]:"";
+ y2milestone("Kernel version: %1", kernel_ver);
+
+ if (!regexpmatch(kernel_ver, "-xen$") && !regexpmatch(kernel_ver, "-xenpae$"))
+ {
+ // kernel default is running
+ _is_xen = false;
+ }
+
+ y2milestone("kernel-xen is running: %1", _is_xen);
+ }
+ }
+
+ return _is_xen;
+}
+
+/**
+ * true if dom0 Xen kernel is running
+ * @see is_xenU
+ * @see is_xen
+ * @return true if the Xen kernel is running in dom0
+ */
+global boolean is_xen0 () {
+ if (_is_xen0 == nil) {
+ // dom0 Xen kernel has /proc/xen/xsd_port file
+ map stat = (map)DBus::ReadArg(.target.stat, "/proc/xen/xsd_port");
+ y2milestone("stat /proc/xen/xsd_port: %1", stat);
+
+ _is_xen0 = (size(stat) > 0);
+ }
+
+ return _is_xen0;
+}
+
+/**
+ * true if domU Xen kernel is running
+ *
+ * @see is_xen0
+ * @see is_xen
+ * @return true if the Xen kernel is running in another domain than dom0
+ */
+global boolean is_xenU () {
+ return (is_xen() && !is_xen0());
+}
+
+/* ************************************************************ */
+/* SMP stuff */
+
+/**
+ * Set "Arch::has_smp ()". Since Alpha doesn't reliably probe smp,
+ * 'has_smp' must be set later with this function.
+ * @param is_smp true if has_smp should be true
+ * @example setSMP(true);
+ */
+global define void setSMP(boolean is_smp) {
+ _has_smp = is_smp;
+}
+
+/**
+ * true if running on multiprocessor board. This only reflects the
+ * board, not the actual number of CPUs or the running kernel!
+ *
+ * @return true if running on multiprocessor board
+ */
+global boolean has_smp () {
+ if (_has_smp == nil)
+ _has_smp = (boolean)DBus::Read(.probe.has_smp);
+ if (alpha ())
+ {
+ // get smp for alpha from /etc/install.inf
+ setSMP (DBus::Read (.etc.install_inf.SMP) == "1");
+ }
+ return _has_smp;
+}
+
+/**
+ * run X11 configuration after inital boot
+ * this is false in case of:
+ * installation on iSeries,
+ * installation on S390
+ *
+ * @returns true when the X11 configuration is needed after inital boot
+ * @see Installation::x11_setup_needed
+ */
+global boolean x11_setup_needed () {
+ // disable X11 setup after initial boot
+ if (board_iseries () || s390 () || mips ())
+ {
+ return false;
+ }
+ return true;
+}
+
+/* EOF */
+}
Added: branches/tmp/lslezak/workshop/ycp_modules/Directory.ycp
URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/lslezak/workshop/ycp_modules/Directory.ycp?rev=48861&view=auto
==============================================================================
--- branches/tmp/lslezak/workshop/ycp_modules/Directory.ycp (added)
+++ branches/tmp/lslezak/workshop/ycp_modules/Directory.ycp Fri Jul 4 09:35:50 2008
@@ -0,0 +1,135 @@
+/**
+ * File: modules/Directory.ycp
+ * Package: yast2
+ * Summary: Definitions of basic directories
+ * Authors: Michal Svec
+ *
+ * $Id$
+ */
+
+{
+
+module "Directory";
+textdomain "base";
+
+import "DBus";
+
+string yast2dir = "/usr/share/YaST2";
+string execcompdir = "/usr/lib/YaST2";
+
+/**
+ * Directory for binaries and scripts
+ */
+global string bindir = "/usr/lib/YaST2/bin";
+global string ybindir = bindir;
+
+/**
+ * Directory for log files
+ */
+global string logdir = "/var/log/YaST2";
+
+/**
+ * Directory for variable data
+ */
+global string vardir = "/var/lib/YaST2";
+
+/**
+ * Directory for configuration data
+ */
+global string etcdir = "/etc/YaST2";
+
+/**
+ * Directory with agents
+ */
+global string agentdir = execcompdir + "/servers_non_y2";
+
+/**
+ * Directory for data
+ */
+global string datadir = yast2dir + "/data";
+global string ydatadir = datadir;
+
+/**
+ * Directory for schema (RNC,DTD,RNG)
+ */
+global string schemadir = yast2dir + "/schema";
+
+/**
+ * Directory for includes
+ */
+global string includedir = yast2dir + "/include";
+global string yncludedir = includedir;
+
+/**
+ * Directory for images
+ */
+global string imagedir = yast2dir + "/images";
+
+/**
+ * Directory for themes
+ */
+global string themedir = yast2dir + "/theme";
+
+/**
+ * Directory for locales
+ */
+global string localedir = yast2dir + "/locale";
+
+/**
+ * Directory for clients
+ */
+global string clientdir = yast2dir + "/clients";
+
+/**
+ * Directory for modules
+ */
+global string moduledir = yast2dir + "/modules";
+
+/**
+ * Directory for SCR definition files
+ */
+global string scrconfdir = yast2dir + "/scrconf";
+
+/**
+ * Directory for desktop files
+ */
+global string desktopdir = "/usr/share/applications/YaST2";
+
+/**
+ * Base directory for icons
+ **/
+global string icondir = themedir + "/current/icons/";
+
+/**
+ * Directory for temporary files
+ * Must be updated with ResetTmpDir() call after the SCR change!
+ */
+global string tmpdir = "/tmp";
+
+
+/**
+ * Directory needed for custom installation workflows
+ * It can be set to the path containing additional file on a CDROM
+ */
+global string custom_workflow_dir = "";
+
+/**
+ * Set temporary directory
+ */
+global define void ResetTmpDir() ``{
+ tmpdir = (string) DBus::Read(.target.tmpdir);
+ if(tmpdir == "" || tmpdir == nil) {
+ y2error("Failed to set temporary directory: %1", tmpdir);
+ tmpdir = "/tmp";
+ }
+}
+
+/**
+ * Constructor
+ */
+global define void Directory() ``{
+ ResetTmpDir();
+}
+
+/* EOF */
+}
Added: branches/tmp/lslezak/workshop/ycp_modules/Encoding.ycp
URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/lslezak/workshop/ycp_modules/Encoding.ycp?rev=48861&view=auto
==============================================================================
--- branches/tmp/lslezak/workshop/ycp_modules/Encoding.ycp (added)
+++ branches/tmp/lslezak/workshop/ycp_modules/Encoding.ycp Fri Jul 4 09:35:50 2008
@@ -0,0 +1,144 @@
+/**
+ * File: modules/Encoding.ycp
+ * Package: yast2
+ * Summary: Provide the encoding stuff
+ * Authors: Klaus Kaempf
+ *
+ * $Id$
+ */
+
+{
+
+module "Encoding";
+textdomain "base";
+
+import "DBus";
+import "Stage";
+
+/**
+ * Current (ISO) encoding
+ */
+global string console = "ISO-8859-1";
+global string lang = "en_US";
+global boolean utf8 = true;
+
+/**
+ * Restore data to system
+ * @return console encoding
+ */
+global define string Restore() {
+
+ console = (string) DBus::Read (.sysconfig.console.CONSOLE_ENCODING);
+ if(console == nil) console = "";
+
+ map m = (map) DBus::ExecuteArg( .target.bash_output, "locale -k charmap" );
+ if(m == nil) m = $[];
+
+ list<string> out = splitstring(m["stdout"]:"", "\n");
+ y2milestone( "list %1", out );
+
+ out = filter( string e, out, ``(find(e, "charmap=")==0) );
+ y2milestone( "list %1", out );
+
+ if(size(out[0]:"") > 0) {
+ string enc = substring( out[0]:"", 8 );
+ y2milestone( "enc %1", enc );
+ enc = deletechars( enc, "\" " );
+ y2milestone( "enc %1", enc );
+ if(size(enc) > 0)
+ console = enc;
+ }
+ y2milestone( "encoding %1", console );
+ return console;
+}
+
+/**
+ * Set Encoding Language
+ * @param new_lang New Language
+ * @return void
+ */
+global void SetEncLang( string new_lang )
+ ``{
+ lang = new_lang;
+ y2milestone( "SetEncLang %1", lang );
+ }
+
+/**
+ * Get Encoding Language
+ * @return Language
+ */
+global string GetEncLang()
+{
+ string ret = lang;
+ y2milestone( "GetEncLang ret %1", ret );
+ return( ret );
+}
+
+/**
+ * Set UTF8 Language
+ * @param new_utf8 New UTF8 Language
+ * @return void
+ */
+global void SetUtf8Lang( boolean new_utf8 )
+{
+ utf8 = new_utf8;
+ y2milestone( "SetUtf8Lang %1", utf8 );
+}
+
+/**
+ * Get UTF8 Language
+ * @return boolean
+ */
+global boolean GetUtf8Lang()
+ ``{
+ boolean ret = utf8;
+ y2milestone( "GetUtf8Lang ret %1", ret );
+ return( ret );
+ }
+
+map enc_map = $[ "euc-jp" : "932",
+ "sjis" : "932",
+ "gb2312" : "936",
+ "iso8859-2" : "852",
+ "big5" : "950",
+ "euc-kr" : "949" ];
+
+map lang_map = $[ "ja_JP" : "932",
+ "zh_CN" : "936",
+ "zh_TW" : "950",
+ "zh_HK" : "950",
+ "ko_KR" : "949" ];
+
+
+
+/**
+ * Get Code Page
+ * @param enc Encoding
+ * @return string
+ */
+global define string GetCodePage( string enc )
+ ``{
+ string code = enc_map[enc]:"";
+ if( size(code)==0 && lang != nil)
+ {
+ string l = substring( lang, 0, 5 );
+ code = lang_map[l]:"";
+ }
+ y2milestone( "GetCodePage enc %1 lang %2 ret %3", enc, lang, code );
+ return code;
+ }
+
+
+/**
+ * Constructor
+ * does nothing in initial mode
+ * restores console encoding from /etc/sysconfig
+ * in normal mode
+ */
+global define void Encoding() {
+ if(!Stage::initial ()) Restore();
+ return;
+}
+
+/* EOF */
+}
Added: branches/tmp/lslezak/workshop/ycp_modules/Language.ycp
URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/lslezak/workshop/ycp_modules/Language.ycp?rev=48861&view=auto
==============================================================================
--- branches/tmp/lslezak/workshop/ycp_modules/Language.ycp (added)
+++ branches/tmp/lslezak/workshop/ycp_modules/Language.ycp Fri Jul 4 09:35:50 2008
@@ -0,0 +1,1207 @@
+/**
+ * File: modules/Language.ycp
+ * Module: Language
+ * Summary: This module does all language related stuff:
+ * Authors: Klaus Kaempf
+ * Thomas Roelz
+ * Maintainer: Jiri Suchomel
+ *
+ * $Id$
+ */
+
+{
+
+module "Language";
+textdomain "country";
+
+
+import "AsciiFile";
+import "Directory";
+import "Encoding";
+import "FileUtils";
+import "InstExtensionImage";
+import "Linuxrc";
+import "Misc";
+import "Mode";
+import "PackageCallbacks";
+import "PackageSystem";
+import "Popup";
+import "ProductFeatures";
+import "Stage";
+
+import "DBus";
+
+/**
+ * currently selected language
+ */
+global string language = "en_US";
+
+/**
+ * original language
+ */
+global string language_on_entry = "en_US";
+
+/**
+ * language preselected in /etc/install.inf
+ */
+global string preselected = "en_US";
+
+/**
+ * user readable description of language
+ */
+string name = "English (US)";
+
+boolean linuxrc_language_set = false;
+
+/**
+ * Default language to be restored with MakeProposal.
+ */
+string default_language = "en_US";
+
+
+/**
+ * Default settings for ROOT_USES_LANG in /etc/sysconfig/language
+ */
+string rootlang = "ctype";
+
+
+/**
+ * Default settings for INSTALLED_LANGUAGES in /etc/sysconfig/language
+ */
+global string languages = "";
+
+/**
+ * Original value of INSTALLED_LANGUAGES
+ */
+global string languages_on_entry = "";
+
+/**
+ * Use utf8 in locale
+ */
+boolean use_utf8 = true;
+
+/**
+ * ncurses mode
+ */
+boolean text_mode = nil;
+
+global boolean ExpertSettingsChanged = false;
+
+/**
+ * Was the initial language selection skipped? (see bug 223258)
+ * (It can be, if the language was selected in linuxrc)
+ */
+global boolean selection_skipped = false;
+
+/**
+ * level of translation completeness
+ */
+map translation_status = $[];
+
+// map (locale: 1) of available locales
+map locales = $[];
+
+// map with all languages (cached - needs to be reread for retranslation)
+map languages_map = $[];
+
+// mapping of language to its default (proposed) time zone
+map lang2timezone = $[];
+
+// mapping of language to its default (proposed) kbd layout
+map lang2keyboard = $[];
+
+// directory with languages descriptions
+string languages_directory = nil;
+
+// languages that cannot be correctly shown in text mode
+list cjk_languages = [ "ja", "ko", "zh", "hi", "km", "pa", "bn" ];
+
+// FATE #302955: Split translations out of installation system
+// [ "en_US", "en_GB", "de", "cs" ]
+global list <string> available_lang_filenames = nil;
+
+
+/**
+ * Check if the language is "CJK"
+ * (and thus could not be shown in text mode - see bug #102958)
+ */
+global define boolean CJKLanguage (string lang) {
+
+ string l = substring (lang, 0, 2);
+ return contains (cjk_languages, l);
+}
+
+
+/**
+ * return the value of text_mode (true for ncurses)
+ */
+global define boolean GetTextMode () {
+
+ if (text_mode== nil)
+ {
+ map display_info = UI::GetDisplayInfo ();
+ text_mode = display_info["TextMode"]:false;
+ }
+ return text_mode;
+}
+
+/**
+ * Read language DB: translatable strings will be translated to current language
+ */
+define void read_languages_map() {
+
+ if (languages_directory == nil)
+ {
+ languages_directory = Directory::datadir + "/languages";
+ }
+ foreach (string file,
+ (list<string>) DBus::ReadArgs (.target.dir, languages_directory, []),
+ {
+ if (!regexpmatch (file, "language_.+\\.ycp$"))
+ return;
+ map language_map = (map)
+ eval (DBus::ReadArg (.target.yast2, "languages/" + file));
+ if (language_map == nil) language_map = $[];
+ string code = file;
+ foreach (string key, any val, (map) language_map, {
+ if (is (val, list))
+ {
+ languages_map[key] = (list) val;
+ code = key;
+ }
+ });
+ if (!haskey (lang2timezone, code))
+ lang2timezone[code] = language_map["timezone"]:"US/Eastern";
+ if (!haskey (lang2keyboard, code))
+ lang2keyboard[code] = language_map["keyboard"]:"en_US";
+ });
+
+ if (languages_map == nil) languages_map = $[];
+}
+
+/**
+ * Read only the map of one language
+ * @param language code
+ */
+define map ReadLanguageMap (string lang) {
+
+ map ret = $[];
+
+ if (languages_directory == nil)
+ {
+ languages_directory = Directory::datadir + "/languages";
+ }
+ string file = sformat ("language_%1.ycp", lang);
+ if (FileUtils::Exists (languages_directory + "/" + file))
+ {
+ ret = (map) eval (DBus::ReadArg (.target.yast2, "languages/" + file));
+ if (ret == nil)
+ ret = $[];
+ }
+ return ret;
+}
+
+/**
+ * Return the whole map with language descriptions
+ * @param force force new loading of the map from the files (forces the change
+ * of translations to current language)
+ */
+global map GetLanguagesMap (boolean force) {
+
+ if (size (languages_map) == 0 || force)
+ read_languages_map();
+ return languages_map;
+}
+
+// list of items for secondary languages term
+list<term> secondary_items = [];
+
+map english_names = $[];
+
+/**
+ * Return English translation of given language (Fate 301789)
+ */
+string EnglishName (string code, string backup) {
+
+ if (english_names[code]:"" == "")
+ {
+ if (language == "en_US")
+ english_names[code] = backup;
+ else
+ y2warning ("nothing in english_names...");
+ }
+ return english_names[code]:backup;
+}
+
+/**
+ * Fill the map with English names of languages
+ */
+void FillEnglishNames (string lang) {
+
+ if (lang == "en_US")
+ return; // will be filled in on first start
+ if (use_utf8)
+ WFM::SetLanguage ("en_US", "UTF-8");
+ else
+ WFM::SetLanguage ("en_US");
+ foreach (string code, list info, GetLanguagesMap (true),
+ {
+ english_names[code] = info[4]:"";
+ });
+ if (use_utf8)
+ WFM::SetLanguage (lang, "UTF-8");
+ else
+ WFM::SetLanguage (lang);
+}
+
+
+/**
+ * return the content of lang2timezone map
+ * (mapping of languages to their default (proposed) time zones)
+ */
+global define map GetLang2TimezoneMap (boolean force) {
+ if (size (languages_map) == 0 && force)
+ read_languages_map();
+ return lang2timezone;
+}
+
+/**
+ * return the content of lang2keyboard map
+ * (mapping of languages to their default (proposed) keyboard layouts)
+ */
+global define map GetLang2KeyboardMap (boolean force) {
+ if (size (languages_map) == 0 && force)
+ read_languages_map();
+ return lang2keyboard;
+}
+
+/**
+ * return the map of all supported countries and language codes
+ */
+global define map GetLocales () {
+
+ if (locales == nil || locales == $[])
+ {
+ map out = (map)SCR::Execute (.target.bash_output, "/usr/bin/locale -a");
+ foreach (string l, splitstring (out["stdout"]:"", "\n"), {
+ integer pos = findfirstof (l, ".@");
+
+ if (pos != nil && pos >= 0)
+ l = substring (l, 0, pos);
+
+ locales [l] = 1;
+ });
+ }
+
+ return locales;
+}
+
+/**
+ * For given language, return the file name of language extension (image)
+ * to be downloaded to the inst-sys
+ * (FATE #302955: Split translations out of installation system)
+ */
+string GetLanguageExtensionFilename (string language) {
+
+ if (available_lang_filenames == nil) {
+ map lang_numbers = $[];
+ foreach (string code, list data, GetLanguagesMap (false), {
+ string short = splitstring (code, "_")[0]:"";
+ if (lang_numbers[short]:0 == 0)
+ lang_numbers[short] = 1;
+ else
+ lang_numbers[short] = lang_numbers[short]:0 + 1;
+ });
+ available_lang_filenames = maplist (string code, list data,
+ GetLanguagesMap (false), {
+ string short = splitstring (code, "_")[0]:"";
+ if (lang_numbers[short]:0 > 1)
+ return code;
+ else
+ return short;
+ });
+ }
+
+ list <string> check_for_languages = [language];
+
+ // 'en_US' ? add also 'en'
+ if (size (language) > 2) {
+ check_for_languages = add (check_for_languages, splitstring (language, "_")[0]:"");
+ }
+
+ // Default fallback
+ string filename = "yast2-trans-en_US.rpm";
+
+ foreach (string one_language, check_for_languages, {
+ if (contains (available_lang_filenames, one_language)) {
+ filename = sformat ("yast2-trans-%1.rpm", one_language);
+ break;
+ }
+ });
+ // yast2-trans-pt.rpm doesn't fit into the algorithm above, see bnc#386298
+ if (language == "pt_PT")
+ return "yast2-trans-pt.rpm";
+
+ y2milestone ("Using %1 for %2", filename, language);
+ return filename;
+}
+
+
+/**
+ * Set module to selected language.
+ * @param lang language string ISO code of language
+ */
+global define void Set (string lang) {
+
+ y2milestone ("original language: %1; setting to lang:%2", language, lang);
+
+ if (language != lang) // Do it only if different
+ {
+ if (Stage::initial () && !Mode::test () && !Mode::live_installation ())
+ {
+ y2milestone ("integrating translation extension...");
+ // busy message
+ Popup::ShowFeedback ("",_("Downloading installation system language extension..."));
+ InstExtensionImage::DownloadAndIntegrateExtension (GetLanguageExtensionFilename (lang));
+ Popup::ClearFeedback ();
+ y2milestone ("integrating translation extension... done");
+ }
+ if (size (languages_map) == 0)
+ read_languages_map();
+
+ if (size (locales) == 0)
+ GetLocales ();
+
+ if (locales[lang]:0 != 1 && size(lang) > 0)
+ {
+ lang = substring (lang, 0, 2);
+ boolean found = false;
+ foreach (string k, list dummy, languages_map,
+ {
+ if (!found && substring (k, 0, 2) ==lang)
+ {
+ found = true;
+ lang = k;
+ }
+ });
+ }
+ name = languages_map[lang, 0]:lang;
+ if (Mode::config ())
+ name = languages_map[lang, 4]:lang;
+ language = lang;
+ Encoding::SetEncLang (language);
+ }
+
+ if (Stage::initial () && !Mode::test ())
+ {
+ map yinf = $[];
+ AsciiFile::SetDelimiter (yinf, " ");
+ AsciiFile::ReadFile (yinf, "/etc/yast.inf");
+ list lines = AsciiFile::FindLineField (yinf, 0, "Language:");
+ if (size(lines) > 0)
+ {
+ AsciiFile::ChangeLineField (yinf, lines[0]:-1, 1, language);
+ }
+ else
+ {
+ AsciiFile::AppendLine (yinf, ["Language:", language] );
+ }
+ AsciiFile::RewriteFile (yinf, "/etc/yast.inf");
+
+ // update "name" for proposal when it cannot be shown correctly
+ if (GetTextMode () && CJKLanguage (lang) && !CJKLanguage (preselected))
+ {
+ name = languages_map[lang, 1]:lang;
+ }
+ }
+}
+
+
+/**
+ * Set the language that was read from sysconfig,
+ * read only one needed language file
+ */
+global define void QuickSet (string lang) {
+
+ y2milestone ("original language: %1; setting to lang:%2", language, lang);
+
+ if (language != lang)
+ {
+ map lang_map = ReadLanguageMap (lang);
+ name = lang_map[lang, 0]:lang;
+ language = lang;
+ Encoding::SetEncLang (language);
+ }
+}
+
+global define boolean LinuxrcLangSet() {
+
+ return linuxrc_language_set;
+}
+
+/**
+ * generate the whole locale string for given language according to DB
+ * (e.g. de_DE -> de_DE.UTF-8)
+ */
+global define string GetLocaleString (string lang) {
+
+ if (size (languages_map) == 0)
+ read_languages_map();
+
+ list language_info = languages_map[lang]:[];
+ if (!haskey (languages_map, lang))
+ language_info = [ lang, lang, ".UTF-8" ];
+
+ // full language code
+ string val = language;
+ if( use_utf8 )
+ val = val + language_info[2]:"";
+ else
+ val = val + language_info[3]:"";
+
+ y2milestone( "locale %1", val );
+ return val;
+}
+
+
+/**
+ * Store current language as default language.
+ */
+global define void SetDefault() {
+ y2milestone("Setting default language: %1", language);
+ default_language = language;
+ return;
+}
+
+/**
+ * Read the RC_LANG value from sysconfig and exctract language from it
+ * @return language
+ */
+global define string ReadSysconfigLanguage () {
+
+ string local_lang = Misc::SysconfigRead (.sysconfig.language.RC_LANG, language);
+
+ integer pos = findfirstof (local_lang, ".@");
+
+ if (pos != nil && pos >= 0)
+ {
+ local_lang = substring (local_lang, 0, pos);
+ }
+
+ y2milestone ("language from sysconfig: %1", local_lang);
+ return local_lang;
+}
+
+/**
+ * Read the rest of language values from sysconfig
+ */
+global define void ReadSysconfigValues () {
+
+ rootlang = Misc::SysconfigRead (.sysconfig.language.ROOT_USES_LANG, rootlang);
+ // during live installation, we have sysconfig.language.RC_LANG available
+ if (!Stage::initial () || Mode::live_installation ())
+ {
+ string val = toupper (Misc::SysconfigRead (.sysconfig.language.RC_LANG, ""));
+ use_utf8 = search (val, ".UTF-8") != nil;
+ }
+ else
+ {
+ use_utf8 = true;
+ }
+ languages = Misc::SysconfigRead (.sysconfig.language.INSTALLED_LANGUAGES, "");
+}
+
+/**
+ * Constructor
+ *
+ * Initializes module either from /etc/install.inf
+ * or from /etc/sysconfig/language
+ */
+global define void Language() {
+
+ if (Mode::config ())
+ {
+ // read the translated name: bug #180633
+ read_languages_map();
+ name = languages_map[language, 4]:language;
+ return;
+ }
+
+ if (Stage::initial () && !Mode::live_installation ())
+ {
+ string lang = (string)DBus::Read (.content.LANGUAGE);
+ y2milestone ("content LANGUAGE %1", lang);
+
+ preselected = Linuxrc::InstallInf ("Locale");
+ y2milestone ("install_inf Locale %1", preselected);
+ if (preselected != nil && preselected != "")
+ {
+ lang = preselected;
+ if (lang != "en_US")
+ {
+ linuxrc_language_set = true;
+ }
+ }
+ else
+ preselected = "en_US";
+
+ if (lang == nil)
+ lang = "";
+ y2milestone ("lang after checking /etc/install.inf: %1", lang );
+ if (lang == "")
+ {
+ lang = Pkg::GetTextLocale();
+ y2milestone ("setting lang to default language: %1", lang);
+ }
+ // Ignore any previous settings and take language from control file.
+ string l = ProductFeatures::GetStringFeature ("globals","language");
+ if (l != nil && l != "")
+ {
+ lang = l;
+ y2milestone ("setting lang to ProductFeatures::language: %1", lang);
+ }
+ FillEnglishNames (lang);
+ Set (lang); // coming from /etc/install.inf
+ SetDefault (); // also default
+ }
+ else
+ {
+ string local_lang = ReadSysconfigLanguage ();
+ QuickSet (local_lang);
+ SetDefault(); // also default
+ if (Mode::live_installation ())
+ {
+ FillEnglishNames (local_lang);
+ }
+ }
+ if (DBus::ReadArg (.target.size, "/etc/sysconfig/language") > 0)
+ {
+ ReadSysconfigValues ();
+ }
+ Encoding::SetUtf8Lang (use_utf8);
+}
+
+/**
+ * Store the inital values; in normal mode, read from system was done in constructor
+ * @param really: also read the values from the system
+ */
+global define boolean Read (boolean really) {
+
+ if (really)
+ {
+ Set (ReadSysconfigLanguage ());
+ ReadSysconfigValues ();
+ }
+
+ language_on_entry = language;
+ languages_on_entry = languages;
+
+ y2milestone ("language: %1, languages: %2", language_on_entry, languages_on_entry);
+
+ ExpertSettingsChanged = false;
+
+ return true;
+}
+
+/**
+ * was anything modified?
+ */
+global define boolean Modified () {
+
+ return (language != language_on_entry ||
+ ExpertSettingsChanged ||
+ sort (splitstring (languages, ",")) !=
+ sort (splitstring (languages_on_entry, ","))
+ );
+}
+
+/**
+ * Does the modification of language(s) require installation of new packages?
+ * This test compares the list of original languages (primary+secondary) with
+ * the list after user's modifications
+ */
+global define boolean PackagesModified () {
+
+ return
+ sort (union(splitstring(languages, ","), [language])) !=
+ sort (union(splitstring(languages_on_entry, ","), [language_on_entry]));
+}
+
+/**
+ * GetExpertValues()
+ *
+ * Return the values for the various expert settings in a map
+ *
+ * @param -
+ *
+ * @return map with values filled in
+ *
+ */
+global define map GetExpertValues () {
+
+ return $[
+ "rootlang" : rootlang,
+ "use_utf8" : use_utf8,
+ ];
+}
+
+/**
+ * SetExpertValues()
+ *
+ * Set the values of the various expert setting
+ *
+ * @param val map with new values of expert settings
+ *
+ * @return void
+ *
+ */
+global define void SetExpertValues (map val) {
+
+ if (haskey (val,"rootlang") && size (val["rootlang"]:"") >0)
+ {
+ rootlang = val["rootlang"]:"";
+ }
+ if (haskey (val,"use_utf8"))
+ {
+ use_utf8 = val["use_utf8"]:false;
+ Encoding::SetUtf8Lang (use_utf8);
+ }
+}
+
+/**
+ * WfmSetLanguag()
+ *
+ * Set the given language in WFM and UI
+ *
+ * @param language (could be different from current in CJK case)
+ *
+ * @return -
+ */
+global define void WfmSetGivenLanguage (string lang) {
+
+ if (Mode::config ())
+ return;
+
+ string encoding = (use_utf8) ? "UTF-8" : Encoding::console;
+
+ y2milestone ( "language %1 enc %2 utf8:%3", lang, encoding, use_utf8 );
+
+ UI::SetLanguage (lang, encoding);
+
+ if (use_utf8)
+ {
+ WFM::SetLanguage(lang, "UTF-8");
+ }
+ else
+ {
+ WFM::SetLanguage(lang);
+ }
+}
+
+
+/**
+ * WfmSetLanguag()
+ *
+ * Set the current language in WFM and UI
+ *
+ * @param -
+ *
+ * @return -
+ */
+global define void WfmSetLanguage () {
+
+ WfmSetGivenLanguage (language);
+}
+
+
+/**
+ * Return proposal string.
+ *
+ * @return string user readable description.
+ * If force_reset is true reset the module to the language
+ * stored in default_language.
+ */
+global define list<string> MakeProposal (boolean force_reset,boolean language_changed)
+{
+ y2milestone("force_reset: %1", force_reset);
+ y2milestone("language_changed: %1", language_changed);
+
+ if (force_reset)
+ {
+ Set (default_language); // reset
+ }
+ list<string> ret = [
+ // summary label
+ sformat (_("Primary Language: %1"), name)
+ ];
+ if (size (languages_map) == 0 || language_changed)
+ {
+ read_languages_map();
+ }
+ // maybe additional languages were selected in package selector (bnc#393007)
+ list<string> langs = splitstring (languages, ",");
+ list<string> missing = [];
+ foreach (string additional, Pkg::GetAdditionalLocales (), {
+ // add the language for both kind of values ("cs" vs. "pt_PT")
+ if (!contains (langs, additional))
+ {
+ if (additional == "en")
+ additional = "en_US";
+ if (additional == "pt")
+ additional = "pt_PT";
+ if (haskey (languages_map, additional))
+ {
+ missing = add (missing, additional);
+ return;
+ }
+ if (contains (langs, additional)) //en_US or pt_PT already installed
+ return;
+ // now, let's hope there's only one full entry for the short one
+ // (e.g. cs_CZ for cs)
+ foreach (string k, list dummy, languages_map,
+ {
+ if (substring (k, 0, 2) == additional)
+ {
+ missing = add (missing, k);
+ break;
+ }
+ });
+ }
+ });
+ if (size (missing) > 0)
+ {
+ langs = (list<string>) union (langs, missing);
+ languages = mergestring (langs,",");
+ }
+ // now, generate the summary strings
+ if (languages != "" && languages != language)
+ {
+ langs = [];
+ foreach (string lang, splitstring (languages, ","), {
+ if (lang != language)
+ {
+ string l = languages_map[lang,4]:languages_map[lang,0]:"";
+ if (l != "")
+ langs = add (langs, l);
+ }
+ });
+ if (size (langs) > 0)
+ {
+ // summary label
+ ret = add (ret, sformat (_("Additional Languages: %1"),
+ mergestring (langs,", ")));
+ }
+ }
+ return ret;
+}
+
+/**
+ * Return 'simple' proposal string.
+ * @return string preformated description.
+ */
+global define string MakeSimpleProposal ()
+{
+ import "HTML";
+
+ list<string> ret = [
+ // summary label
+ sformat (_("Primary Language: %1"), name)
+ ];
+ if (languages != "" && languages != language)
+ {
+ list<string> langs = [];
+ foreach (string lang, splitstring (languages, ","), {
+ if (lang != language)
+ {
+ string l = languages_map[lang,4]:languages_map[lang,0]:"";
+ if (l != "")
+ langs = add (langs, l);
+ }
+ });
+ if (size (langs) > 0)
+ {
+ // summary label
+ ret = add (ret, sformat (_("Additional Languages: %1"),
+ HTML::List (langs)));
+ }
+ }
+ return HTML::List (ret);
+}
+
+/**
+ * return user readable description of language
+ */
+global define string GetName () {
+
+ return name;
+}
+
+/**
+ * Return a map of ids and names to build up a selection list
+ * for the user. The key is used later in the Set function
+ * to select this language. The name is a translated string.
+ *
+ * @return map of $[ language : [ utf8-name, ascii-name] ...]
+ * for all known languages
+ * 'language' is the (2 or 5 char) ISO language code.
+ * 'utf8-name' is a user-readable (UTF-8 encoded !) string.
+ * 'ascii-name' is an english (ascii encoded !) string.
+ * @see Set
+ */
+global define map Selection() {
+
+ read_languages_map();
+
+ return mapmap (string code, list data, languages_map,
+ ``($[code: [data[0]:"", data[1]:"", data[4]:data[0]:""]]));
+}
+
+
+/**
+ * Save state to target.
+ */
+global define void Save() {
+
+ string loc = GetLocaleString (language);
+
+ SCR::Write (.sysconfig.language.RC_LANG, loc);
+
+ if (find (loc, "zh_HK") == 0)
+ {
+ SCR::Write(.sysconfig.language.RC_LC_MESSAGES,"zh_TW"+substring(loc,5));
+ }
+ else
+ {
+ // FIXME ugly hack: see bug #47711
+ string lc_mess = (string)DBus::Read(.sysconfig.language.RC_LC_MESSAGES);
+ if (find (lc_mess, "zh_TW") == 0)
+ {
+ SCR::Write (.sysconfig.language.RC_LC_MESSAGES, "");
+ }
+ }
+
+ SCR::Write (.sysconfig.language.ROOT_USES_LANG, rootlang);
+ SCR::Write (.sysconfig.language.INSTALLED_LANGUAGES, languages);
+ SCR::Write (.sysconfig.language, nil);
+
+ y2milestone ("Saved data for language: <%1>", loc);
+}
+
+/**
+ * Initializes source and target,
+ * computes the packages necessary to install and uninstall,
+ * checks for disk space (#50745)
+ * @return false when there is not enough disk space for new packages
+ */
+global define boolean PackagesInit (list<string> selected_languages) {
+
+ PackageSystem::EnsureSourceInit ();
+ PackageSystem::EnsureTargetInit ();
+
+ Pkg::SetAdditionalLocales (selected_languages);
+ Pkg::PkgSolve (true);
+
+ boolean ok = true;
+ foreach (string mountpoint, list<integer> usage, Pkg::TargetGetDU (), {
+ if (usage[2]:0 > usage[0]:0)
+ {
+ ok = false;
+ }
+ });
+ return ok;;
+}
+
+/**
+ * Install and uninstall packages selected by Pkg::SetAdditionalLocales
+ *
+global define boolean PackagesCommit () {
+
+ SlideShow::OpenSlideShowDialog ();
+ Pkg::PkgCommit (0);
+ SlideShow::CloseSlideShowDialog();
+ return true;
+}
+*/
+
+/**
+ * de_DE@UTF-8 -> "DE"
+ * @return country part of language
+ */
+global define string GetGivenLanguageCountry (string lang) {
+
+ string country = lang;
+
+ if (country == nil || country == "")
+ country = default_language;
+ if (country != nil && country != "")
+ {
+ if (find (country, "@") != -1)
+ country = splitstring (country, "@") [0]:"";
+ }
+ if (country != nil && country != "")
+ {
+ if (find (country, ".") != -1)
+ country = splitstring (country, ".") [0]:"";
+ }
+ if (country != nil && country != "")
+ {
+ if (find(country, "_") != -1)
+ country = splitstring (country, "_") [1]:"";
+ else
+ country = toupper(country);
+ }
+
+ y2debug("country=%1",country);
+ return country;
+}
+
+
+/**
+ * de_DE@UTF-8 -> "DE"
+ * @return country part of language
+ */
+global define string GetLanguageCountry() {
+
+ return GetGivenLanguageCountry (language);
+}
+
+
+/**
+ * Returns true if translation for given language is not complete
+ */
+global define boolean IncompleteTranslation (string lang) {
+
+ if (!haskey (translation_status,lang))
+ {
+ string file = "/usr/lib/YaST2/trans/" + lang + ".status";
+ if (!FileUtils::Exists (file))
+ {
+ string ll = splitstring (lang, "_") [0]:"";
+ if (ll != "")
+ file = "/usr/lib/YaST2/trans/" + ll + ".status";
+ }
+
+ string status = (string) DBus::ReadArg (.target.string, file);
+
+ if (status != nil && status != "")
+ {
+ integer to_i = tointeger (status);
+ translation_status[lang] = (to_i != nil) ? to_i : 0;
+ }
+ else
+ translation_status[lang] = 100;
+ }
+ integer treshold = tointeger (ProductFeatures::GetStringFeature (
+ "globals", "incomplete_translation_treshold"));
+ if (treshold == nil) treshold = 95;
+
+ return translation_status[lang]:0 < treshold;
+}
+
+/**
+ * Checks if translation is complete and displays
+ * Continue/Cancel popup messsage if it is not
+ * return true if translation is OK or user agrees with the warning
+ */
+global boolean CheckIncompleteTranslation (string lang) {
+ if (IncompleteTranslation (language))
+ {
+ // continue/cancel message
+ return Popup::ContinueCancel (_("Translation of the primary language is not complete.
+Some texts may be displayed in English.
+"));
+ }
+ return true;
+}
+
+/**
+ * AutoYaST interface function: Get the Language configuration from a map.
+ * @param settings imported map
+ * @return success
+ */
+global define boolean Import (map settings) {
+
+ if (languages_on_entry == "")
+ Read (false); // only save original values
+
+ Set (settings["language"]:language);
+ languages = settings["languages"]:languages;
+
+ SetExpertValues (settings);
+
+ list<string> llanguages = splitstring (languages, ",");
+ if (!contains (llanguages, language))
+ {
+ llanguages = add (llanguages, language);
+ languages = mergestring (llanguages, ",");
+ }
+ // set the language dependent packages to install
+ if (Mode::autoinst ())
+ {
+ Pkg::SetPackageLocale (language);
+ Pkg::SetAdditionalLocales (splitstring (languages, ","));
+ }
+
+ return true;
+}
+
+/**
+ * AutoYaST interface function: Return the Language configuration as a map.
+ * @return map with the settings
+ */
+global define map Export () {
+
+ map ret = $[
+ "language" : language,
+ "languages" : languages
+ ];
+ if (rootlang != "ctype")
+ ret["rootlang"] = rootlang;
+ if (!use_utf8)
+ ret["use_utf8"] = use_utf8;
+ return ret;
+}
+
+/**
+ * AutoYaST interface function: Return the summary of Language configuration as a map.
+ * @return summary string
+ */
+global define string Summary () {
+
+ return MakeSimpleProposal ();
+}
+
+// kind: `first_screen, `primary, `secondary
+global list<term> GetLanguageItems (symbol kind) {
+
+ list<term> ret = [];
+
+ // already generated in previous run with `primary
+ if (kind == `secondary && secondary_items != [])
+ {
+ return secondary_items;
+ }
+ secondary_items = [];
+
+ boolean use_ascii = GetTextMode ();
+
+ if (kind == `first_screen)
+ {
+ map en_name_sort =
+ mapmap (string code, list info, Selection(), {
+ string english = EnglishName (code, info[2]:code);
+ return $[
+ english : [
+ info[use_ascii ? 1 : 0]:"",
+ code,
+ ]
+ ];
+ });
+ // fate 301789
+ // English name of language (translated language).
+ // e.g. German (Deutsch)
+ ret = maplist (string name, list codelist, en_name_sort, {
+ string label = substring (codelist[1]:"", 0, 2) == "en" ?
+ codelist[0]:"" : sformat ("%1 - %2", name, codelist[0]:"");
+ return `item (`id (codelist[1]:""), label);
+ });
+ return ret;
+ }
+ // sort language by ASCII with help of a map
+ // $[ "ascii-name" : [ "user-readable-string", "code" ], ...]
+ // the "user-readable-string" is either ascii or utf8, depending
+ // on textmode probed above (workaround because there isn't any
+ // usable console font for all languages).
+
+ map languageselsort = mapmap (
+ string lang_code, list lang_info, Selection(), {
+ string key = lang_info [1]:lang_code;
+ return $[
+ key : [
+ lang_info[use_ascii ? 1 : 0]:"",
+ lang_code,
+ lang_info[2]:key
+ ]
+ ];
+ }
+ );
+
+ // mapping of language name (translated) to language code
+ map lang2code = $[];
+ // list of language names (translated)
+ list<string> lang_list = [];
+ foreach (any name, list codelist, languageselsort, {
+ lang2code [codelist[2]:""] = codelist[1]:"";
+ lang_list = add (lang_list, codelist[2]:"");
+ });
+
+
+ if (Stage::firstboot ())
+ {
+ ret = maplist (string trans_lang, lsort (lang_list), {
+ string code = lang2code [trans_lang]:"";
+ return `item (`id (code), trans_lang, language == code);
+ });
+ return ret;
+ }
+ boolean primary_included = false;
+
+ if (kind == `primary || kind == `secondary)
+ {
+ list<string>languages_l = splitstring (languages, ",");
+ // filter the primary language from the list of secondary ones:
+ languages_l = filter (string l, languages_l, ``(l != language));
+
+ boolean icons = !(Stage::initial () || Stage::firstboot ());
+ list<term> primary_items = [];
+ secondary_items = maplist (string trans_lang, lsort (lang_list),
+ {
+ string code = lang2code [trans_lang]:"";
+ primary_items = add (primary_items, icons ?
+ `item (`id (code), `icon(tolower(Language::GetGivenLanguageCountry(code))+"/flag.png"), trans_lang, language == code) :
+ `item (`id (code), trans_lang, language == code));
+ if (language == code)
+ primary_included = true;
+ return icons ?
+ `item (`id (code), `icon(tolower(Language::GetGivenLanguageCountry(code))+"/flag.png"), trans_lang, contains (languages_l, code)) :
+ `item (`id (code), trans_lang, contains (languages_l, code));
+ });
+ if (!primary_included)
+ primary_items = add (primary_items,
+ `item (`id (language), language, true));
+ ret = (kind == `primary) ? primary_items : secondary_items;
+ }
+ return ret;
+}
+
+/**
+ * check if selected language has support on media (F301238)
+ * show a warning when not
+ */
+global void CheckLanguagesSupport (string selected_language) {
+
+ string linguas = (string) DBus::Read (.content.LINGUAS);
+
+ if (linguas == nil) {
+ y2warning ("No LINGUAS tag defined in content file");
+ return;
+ }
+
+ y2milestone ("content LINGUAS %1", linguas);
+ list <string> all_linguas = splitstring (linguas, " ");
+ string language_short = splitstring (selected_language, "_")[0]:"";
+
+ if (!contains (all_linguas, selected_language) &&
+ !contains (all_linguas, language_short))
+ {
+ y2milestone ("Language %1 is not fully supported", selected_language);
+ // popup message
+ Popup::Message (_("Only minimal support for the selected language is included on the media.
+Add the Language add-on CD as an additional repository in order to get appropriate support
+for this language.
+"));
+ }
+}
+
+/* EOF */
+}
Added: branches/tmp/lslezak/workshop/ycp_modules/Misc.ycp
URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/lslezak/workshop/ycp_modules/Misc.ycp?rev=48861&view=auto
==============================================================================
--- branches/tmp/lslezak/workshop/ycp_modules/Misc.ycp (added)
+++ branches/tmp/lslezak/workshop/ycp_modules/Misc.ycp Fri Jul 4 09:35:50 2008
@@ -0,0 +1,227 @@
+/**
+ * Module:
+ * Misc
+ * File:
+ * Misc.ycp
+ * Purpose:
+ * miscellaneous definitions for installation
+ * Author: Klaus Kaempf
+ * $Id$
+ */
+{
+
+ module "Misc";
+
+ import "DBus";
+
+ /*
+ * Message after finishing installation and before the system
+ * boots for the first time.
+ *
+ */
+ global string boot_msg = "";
+
+ /**
+ * @param first string name of first file to try
+ * @param second string name of second file to try
+ * @return any content of file
+ *
+ * try to read first file, if it doesn't exist, read second
+ * files must reside below /usr/lib/YaST2
+ * files must have ycp syntax
+ */
+
+ global define any ReadAlternateFile ( string first, string second)
+ ``{
+ any result = DBus::ReadArg (.target.yast2, [first, nil]);
+ if (result == nil)
+ result = DBus::ReadArg (.target.yast2, second);
+ return result;
+ }
+
+ /**
+ * @param hardware_entry map map of .probe entry
+ * @return string vendor and device name
+ *
+ * common function to extract 'name' of hardware
+ */
+
+ global define string hardware_name (map hardware_entry)
+ ``{
+ string sub_vendor = "";
+ string sub_device = "";
+
+ sub_vendor = hardware_entry["sub_vendor"]:"";
+ sub_device = hardware_entry["sub_device"]:"";
+
+ if ((sub_vendor != "") && (sub_device != ""))
+ {
+ return (sub_vendor + "\n" + sub_device);
+ }
+ else
+ {
+ string vendor = hardware_entry["vendor"]:"";
+ return (vendor
+ + ((vendor != "") ? "\n" : "")
+ + hardware_entry["device"]:"");
+ }
+ }
+
+
+ /**
+ * @param lmap map map of language codes and translations
+ * e.g. $[ "default" : "Defaultstring", "de" : "German....", ...]
+ * @param lang string language as ISO code, either 2 chars (de)
+ * or 5 chars (de_DE)
+ * @return string translation
+ *
+ * Define a macro that looks up a localized string in a language map
+ * of the form $[ "default" : "Defaultstring", "de" : "German....", ...]
+ */
+
+ global define string translate(map lmap, string lang)
+ ``{
+ string t = lmap[lang]:"";
+ if ((size (t) == 0)
+ && size(lang) > 2)
+ {
+ t = lmap[substring(lang, 0, 2)]:"";
+ }
+ if (size (t) == 0)
+ {
+ t = lmap["default"]:"";
+ }
+
+ return t;
+ }
+
+ /**
+ * SysconfigWrite()
+ * @param path level path behind .sysconfig for all values
+ * @param list values list of [ .NAME, value] lists
+ *
+ * @returns boolean false if SCR::Write reported error
+ *
+ * write list of sysyconfig entries via rcconfig agent
+ */
+
+ global define boolean SysconfigWrite (path level, list<list> values)
+ ``{
+ boolean result = true;
+ if (level == .)
+ level = .sysconfig;
+ else
+ level = .sysconfig + level;
+
+ foreach (list entry, values,
+ ``{
+ if (size (entry) != 2)
+ y2error ("bad entry in rc_write()");
+ else
+ {
+ if (!SCR::Write (level + entry[0]:., entry[1]:""))
+ result = false;
+ }
+ });
+ return result;
+ }
+
+
+
+ /**
+ * MergeOptions
+ * Merges "opt1=val1 opt2=val2 ..." and $["opta":"vala", ..."]
+ * to $["opt1":"val1", "opt2":"val2", "opta":"vala", ...]
+ * as needed by modules.conf agent
+ * @param options string module options, e.g. "opt1=val1 opt2=val2 ..."
+ * @param optmap map possible old options $["opta":"vala", ...]
+ * @returns map $["opt1":"val1", "opt2":"val2", ...]
+ */
+
+ global define map SplitOptions (string options, map optmap)
+ ``{
+ // step 1: split "opt1=val1 opt2=val2 ..."
+ // to ["opt1=val1", "opt2=val2", "..."]
+
+ list<string> options_split = splitstring (options, " ");
+
+ foreach (string options_element, options_split,
+ ``{
+ list options_values = splitstring (options_element, "=");
+
+ if ((size (options_values) == 1)
+ && (optmap[options_element]:"" == ""))
+ {
+ // single argument
+ optmap[options_element] = "";
+ }
+ else if (size (options_values) == 2)
+ {
+ // argument with value
+ optmap[options_values[0]:""] = options_values[1]:"";
+ }
+ });
+ return optmap;
+ }
+
+
+ /**
+ * SysconfigRead()
+ *
+ * Try an DBus::Read(...) and return the result if successful.
+ * On failure return the the second parameter (default value)
+ *
+ * @param sysconfig_path Sysconfig SCR path.
+ * @param defaultv Default value
+ *
+ * @return Success --> Result of DBus::Read<br>
+ * Failure --> Default value
+ *
+ */
+
+ global define string SysconfigRead( path sysconfig_path, string defaultv )
+ ``{
+ string local_ret = (string)DBus::Read( sysconfig_path );
+
+ if ( local_ret == nil )
+ {
+ y2warning("Failed reading '%1', using default value", sysconfig_path );
+ return( defaultv );
+ }
+ else
+ {
+ y2milestone("%1: '%2'", sysconfig_path, local_ret );
+ return( local_ret );
+ }
+ } // SysconfigRead()
+
+ /**
+ * Try to read value from sysconfig file and return the result if successful.
+ * Function reads from arbitrary sysconfig file, for which the agent
+ * doesn't exist: e.g. from different partition like /mnt/etc/sysconfig/file.
+ *
+ * @param key Key of the value we want to read from sysconfig file.
+ * @param defaultv Default value
+ * @param location Full path to target sysconfig file.
+ *
+ * @return Success --> Result of DBus::Read<br>
+ * Failure --> Default value
+ *
+ * @example Misc::CustomSysconfigRead ("INSTALLED_LANGUAGES", "", Installation::destdir + "/etc/sysconfig/language");
+ *
+ */
+ global define string CustomSysconfigRead (string key, string defval,string location)
+ {
+ if (location == "")
+ return defval;
+
+ path custom_path = topath (location);
+ SCR::RegisterAgent (custom_path, `ag_ini(
+ `SysConfigFile (location)
+ ));
+ string ret = SysconfigRead (add (custom_path, key), defval);
+ SCR::UnregisterAgent (custom_path);
+ return ret;
+ }
+
+}
Added: branches/tmp/lslezak/workshop/ycp_modules/Wizard.ycp
URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/lslezak/workshop/ycp_modules/Wizard.ycp?rev=48861&view=auto
==============================================================================
--- branches/tmp/lslezak/workshop/ycp_modules/Wizard.ycp (added)
+++ branches/tmp/lslezak/workshop/ycp_modules/Wizard.ycp Fri Jul 4 09:35:50 2008
@@ -0,0 +1,1742 @@
+/**
+ * File: Wizard.ycp
+ * Package: yast2
+ * Author: Stefan Hundhammer
+ *
+ * Provides the wizard dialog (common screen for all YaST2 installation
+ * modules) and functions to set the contents, to replace and restore
+ * special widgets.
+ */
+
+{
+ module "Wizard";
+ textdomain "base";
+
+ import "Label";
+ import "Popup";
+ import "Directory";
+ import "SuSERelease";
+
+ import "DBus";
+
+ // keep trailing "/" !!
+ string theme_path = Directory::themedir + "/current";
+ string icon_path = theme_path + "/icons/22x22/apps";
+ string default_icon = icon_path + "/yast.png";
+
+ boolean have_fancy_ui_cache = nil;
+
+ // this variable is set from Product:: constructor
+ // to setup correct &product; macro in UI
+ string product_name = "";
+
+
+ boolean haveFancyUI()
+ {
+ if ( have_fancy_ui_cache == nil )
+ {
+ map ui_info = UI::GetDisplayInfo();
+
+ have_fancy_ui_cache = UI::HasSpecialWidget(`Wizard ) == true
+ && ui_info[ "Depth" ]:0 >= 15
+ && ui_info[ "DefaultWidth" ]:0 >= 800
+ && ui_info[ "DefaultHeight"]:0 >= 600;
+
+ // have_fancy_ui_cache = false;
+
+ UI::SetFunctionKeys( Label::DefaultFunctionKeyMap() );
+ }
+
+ return have_fancy_ui_cache;
+ }
+
+
+ /**
+ * Returns a button box with buttons "Back", "Abort", "Next"
+ * @return a widget tree
+ **/
+ global term BackAbortNextButtonBox()
+ {
+ return `HBox(
+ `HWeight(1, `ReplacePoint(`id(`rep_help ), `PushButton(`id(`help ), `opt (`key_F1,`helpButton), Label::HelpButton() ) ) ),
+ `HStretch(),
+ `HWeight(1, `ReplacePoint(`id(`rep_back ), `PushButton(`id(`back ), `opt (`key_F8), Label::BackButton() ) ) ),
+ `HStretch(),
+ `ReplacePoint(`id(`rep_abort), `PushButton(`id(`abort), `opt (`key_F9), Label::AbortButton() ) ),
+ `HStretch(),
+ `HWeight(1, `ReplacePoint(`id(`rep_next ), `PushButton(`id(`next), `opt (`key_F10, `default), Label::NextButton() ) ) )
+ );
+ }
+
+
+ /**
+ * Returns a button box with buttons "Back", "Abort Installation", "Next"
+ * @return a widget tree
+ **/
+ global term BackAbortInstallationNextButtonBox()
+ {
+ return `HBox(
+ `HWeight(1, `ReplacePoint(`id(`rep_help ), `PushButton(`id(`help ), `opt (`key_F1, `helpButton), Label::HelpButton() ) ) ),
+ `HStretch(),
+ `HWeight(1, `ReplacePoint(`id(`rep_back ), `PushButton(`id(`back ), `opt (`key_F8), Label::BackButton() ) ) ),
+ `HStretch(),
+ `ReplacePoint(`id(`rep_abort), `PushButton(`id(`abort), `opt (`key_F9), Label::AbortInstallationButton() ) ),
+ `HStretch(),
+ `HWeight(1, `ReplacePoint(`id(`rep_next ), `PushButton(`id(`next), `opt (`key_F10, `default), Label::NextButton() ) ) )
+ );
+ }
+
+
+ /**
+ * Returns a button box with buttons "Back", "Next"
+ * @return a widget tree
+ **/
+ global term BackNextButtonBox()
+ {
+ return `HBox(
+ `HWeight(1, `ReplacePoint(`id(`rep_back ), `PushButton(`id(`back ), `opt (`key_F8), Label::BackButton() ) ) ),
+ `HStretch(),
+ `HWeight(1, `ReplacePoint(`id(`rep_next ), `PushButton(`id(`next ), `opt (`key_F10, `default), Label::NextButton() ) ) )
+ );
+ }
+
+
+ /**
+ * Returns a button box with buttons "Cancel", "Accept"
+ * @return a widget tree
+ **/
+ global term CancelAcceptButtonBox()
+ {
+ return `HBox(
+ `HWeight(1, `Empty() ), // Layout trick to make sure the center button is centered
+ `HStretch(),
+ `HWeight(1, `PushButton(`id(`cancel ), `opt (`key_F9), Label::CancelButton() ) ),
+ `HStretch(),
+ `HWeight(1, `PushButton(`id(`accept ), `opt (`key_F10, `default), Label::AcceptButton() ) )
+ );
+ }
+
+
+ /**
+ * Returns a button box with buttons "Cancel", "OK"
+ * @return a widget tree
+ **/
+ global term CancelOKButtonBox()
+ {
+ return `HBox(
+ `HWeight(1, `Empty() ), // Layout trick to make sure the center button is centered
+ `HStretch(),
+ `HWeight(1, `PushButton(`id(`cancel ), `opt (`key_F9), Label::CancelButton() ) ),
+ `HStretch(),
+ `HWeight(1, `PushButton(`id(`ok ), `opt (`key_F10, `default), Label::OKButton() ) )
+ );
+ }
+
+
+ /**
+ * Returns a button box with buttons "Abort", "Accept"
+ * @return a widget tree
+ **/
+ global term AbortAcceptButtonBox()
+ {
+ return `HBox(
+ `HWeight(1, `ReplacePoint (`id (`back_rep), `Empty())), // Layout trick to make sure the center button is centered
+ `HStretch(),
+ `PushButton(`id(`abort ), `opt (`key_F9), Label::AbortButton() ),
+ `HStretch(),
+ `HWeight(1, `PushButton(`id(`accept ), `opt (`key_F10, `default), Label::AcceptButton() ) )
+ );
+ }
+
+
+ /**
+ * Returns a button box with buttons "Abort Installation", "Accept"
+ * @return a widget tree
+ **/
+ global term AbortInstallationAcceptButtonBox()
+ {
+ return `HBox(
+ `HWeight(1, `Empty() ), // Layout trick to make sure the center button is centered
+ `HStretch(),
+ `PushButton(`id(`abort ), `opt (`key_F9), Label::AbortInstallationButton() ),
+ `HStretch(),
+ `HWeight(1, `PushButton(`id(`accept ), `opt (`key_F10, `default), Label::AcceptButton() ) )
+ );
+ }
+
+
+ /**
+ * Returns a button box with buttons "Abort", "Apply", "Finish"
+ * @return a widget tree
+ **/
+ global term AbortApplyFinishButtonBox()
+ {
+ return `HBox(
+ `PushButton(`id(`abort ), Label::AbortButton() ),
+ `HStretch(),
+ // button text
+ `PushButton(`id(`apply), _("&Apply") ),
+ `HStretch(),
+ `PushButton(`id(`finish), Label::FinishButton() )
+ );
+ }
+
+
+ /**
+ * @short Create a Generic Dialog
+ *
+ * @descr Returns a term describing a generic wizard dialog with a configurable
+ * button box.
+ *
+ * @stable
+ *
+ * @param button_box term that contains a `HBox() with buttons in it
+ * @return term term describing the dialog.
+ **/
+ global term GenericDialog( term button_box )
+ {
+ return `VBox( `id(`WizardDialog),
+ `ReplacePoint( `id(`topmenu ), `Empty() ),
+ `HBox(
+ `HSpacing(1),
+ `VBox(
+ `VSpacing(0.2),
+ `HBox(
+ // translators: dialog title to appear before any content is initialized
+ `Heading(`id(`title), `opt (`hstretch), _("YaST2\nInitializing ...")),
+ `HStretch()
+ ),
+ `VWeight( 1, // Layout trick: Lower layout priority with weight
+ `HVCenter(`opt(`hvstretch),
+ `ReplacePoint(`id(`contents), `Empty() )
+ )
+ )
+ ),
+ `HSpacing(1)
+ ),
+ `ReplacePoint(`id(`rep_button_box), button_box ),
+ `VSpacing(0.2)
+ );
+ }
+
+
+ /**
+ * @short Create a Generic Tree Dialog
+ *
+ * @descr Returns a term describing a wizard dialog with left menu tree,
+ * right contents and a configurable button box.
+ *
+ *
+ * @stable
+ *
+ * @param button_box term that contains a `HBox() with buttons in it
+ * @return term term describing the dialog.
+ **/
+
+ global term GenericTreeDialog( term button_box )
+ {
+ return `VBox( `id(`WizardDialog),
+ `ReplacePoint( `id(`topmenu ), `Empty() ),
+ `HBox(
+ `HSpacing(1),
+ `HWeight( 30, `ReplacePoint( `id(`helpSpace), `Empty()/*`RichText(`id(`HelpText), "")*/)),
+ `HSpacing(1),
+ `HWeight( 70, `VBox(
+ `VSpacing(0.2),
+ `HBox(
+ // translators: dialog title to appear before any content is initialized
+ `Heading(`id(`title), `opt (`hstretch), _("YaST2\nInitializing ...")),
+ `HStretch()
+ ),
+ `VWeight( 1, // Layout trick: Lower layout priority with weight
+ `HVCenter(`opt(`hvstretch),
+ `ReplacePoint(`id(`contents), `Empty() )
+ )
+ )
+ )),
+ `HSpacing(1)
+ ),
+ `ReplacePoint(`id(`rep_button_box), button_box ),
+ `VSpacing(0.2)
+ );
+ }
+
+
+ /**
+ * Check if the topmost dialog is a wizard dialog
+ * (i.e. has a widget with `id(`WizardDialog) )
+ *
+ * @return boolean True if topmost dialog is a wizard dialog, false otherwise
+ **/
+ global boolean IsWizardDialog()
+ {
+ return
+ UI::WidgetExists(`id(`WizardDialog) ) == true ||
+ UI::WidgetExists(`wizard) == true;
+ }
+
+
+ /**
+ * Open a popup dialog that displays a help text (rich text format).
+ *
+ * @stable
+ *
+ * @param help_text the text to display
+ **/
+ global void ShowHelp( string help_text )
+ {
+ Popup::LongText(
+ // Heading for help popup window
+ _("Help"),
+ `RichText( help_text ),
+ 50, 20 );
+ }
+
+
+ /**
+ * Returns a standard wizard dialog with buttons "Next", "Back", "Abort".
+ *
+ * @stable
+ *
+ * @return term describing the dialog.
+ **/
+ global term NextBackDialog()
+ {
+ return GenericDialog( BackAbortNextButtonBox() );
+ }
+
+
+ /**
+ * Returns a standard wizard dialog with buttons "Cancel", "Accept"
+ *
+ * @stable
+ *
+ * @return term describing the dialog.
+ **/
+ global term AcceptDialog()
+ {
+ return GenericDialog( CancelAcceptButtonBox() );
+ }
+
+ /**
+ * Returns a standard wizard dialog with buttons "Cancel", "OK"
+ *
+ * @stable
+ *
+ * @return term describing the dialog.
+ **/
+ global term OKDialog()
+ {
+ return GenericDialog( CancelOKButtonBox() );
+ }
+
+
+ /**
+ * Open any wizard dialog.
+ *
+ * @stable
+ *
+ * @param dialog a wizard dialog, e.g. Wizard::GenericDialog()
+ **/
+ global void OpenDialog( term dialog )
+ {
+ UI::OpenDialog( `opt(`wizardDialog), dialog );
+ }
+
+
+ /**
+ * Open a dialog with buttons "Next", "Back", "Abort"
+ * and set the keyboard focus to "Next".
+ **/
+ global void OpenNextBackDialog()
+ {
+ if ( haveFancyUI() )
+ {
+ UI::OpenDialog(`opt(`wizardDialog ),
+ `Wizard(`back, Label::BackButton(),
+ `abort, Label::AbortButton(),
+ `next, Label::NextButton() ) );
+
+ UI::WizardCommand(`SetDialogIcon( default_icon ) );
+ }
+ else
+ {
+ Wizard::OpenDialog( NextBackDialog() );
+ UI::SetFocus(`id(`next) );
+ }
+ }
+
+
+ /**
+ * Open a dialog with "Accept", "Cancel"
+ * and set the keyboard focus to "Accept".
+ **/
+ global void OpenAcceptDialog()
+ {
+ if ( haveFancyUI() )
+ {
+ UI::OpenDialog(`opt(`wizardDialog ),
+ `Wizard(`no_back_button, "",
+ `cancel, Label::CancelButton(),
+ `accept, Label::AcceptButton() ) );
+
+ // Don't let sloppy calls to Wizard::SetContents() disable this button by accident
+ UI::WizardCommand(`ProtectNextButton( true ) );
+ UI::WizardCommand(`SetDialogIcon( default_icon ) );
+ }
+ else
+ {
+ Wizard::OpenDialog( AcceptDialog() );
+ UI::SetFocus(`id(`accept) );
+ }
+ }
+
+
+ /**
+ * Open a dialog with "OK", "Cancel"
+ * and set the keyboard focus to "OK".
+ **/
+ global void OpenOKDialog()
+ {
+ if ( haveFancyUI() )
+ {
+ UI::OpenDialog(`opt(`wizardDialog ),
+ `Wizard(`no_back_button, "",
+ `cancel, Label::CancelButton(),
+ `ok, Label::OKButton() ) );
+
+ // Don't let sloppy calls to Wizard::SetContents() disable this button by accident
+ UI::WizardCommand(`ProtectNextButton( true ) );
+ UI::WizardCommand(`SetDialogIcon( default_icon ) );
+ }
+ else
+ {
+ Wizard::OpenDialog( OKDialog() );
+ UI::SetFocus(`id(`ok) );
+ }
+ }
+
+
+ /**
+ * Open a dialog with "Accept", "Cancel"
+ * and set the keyboard focus to "Accept".
+ **/
+ global void OpenAbortApplyFinishDialog()
+ {
+ if ( haveFancyUI() )
+ {
+ UI::OpenDialog(`opt(`wizardDialog ),
+ `Wizard(`apply, _( "&Apply" ),
+ `abort, Label::AbortButton(),
+ `finish, Label::FinishButton() ) );
+
+ UI::WizardCommand(`SetDialogIcon( default_icon ) );
+ }
+ else
+ {
+ Wizard::OpenDialog( GenericDialog( AbortApplyFinishButtonBox() ) );
+ UI::SetFocus(`id(`finish ) );
+ }
+ }
+
+
+ /**
+ * Open a dialog with "Accept", "Cancel" that will also accept workflow steps.
+ **/
+ global void OpenAcceptStepsDialog()
+ {
+ if ( haveFancyUI() )
+ {
+ UI::OpenDialog(`opt(`wizardDialog ),
+ `Wizard(`opt(`stepsEnabled),
+ `no_back_button, "",
+ `cancel, Label::CancelButton(),
+ `accept, Label::AcceptButton() ) );
+
+ // Don't let sloppy calls to Wizard::SetContents() disable this button by accident
+ UI::WizardCommand(`ProtectNextButton( true ) );
+ UI::WizardCommand(`SetDialogIcon( default_icon ) );
+ }
+ else
+ {
+ OpenAcceptDialog();
+ }
+ }
+
+
+ /**
+ * Open a dialog with "Accept", "Cancel" that will also accept workflow steps.
+ **/
+ global void OpenAcceptAbortStepsDialog()
+ {
+ if ( haveFancyUI() )
+ {
+ UI::OpenDialog(`opt(`wizardDialog ),
+ `Wizard(`opt(`stepsEnabled),
+ `no_back_button, "",
+ `abort, Label::AbortButton(),
+ `accept, Label::AcceptButton() ) );
+
+ // Don't let sloppy calls to Wizard::SetContents() disable this button by accident
+ UI::WizardCommand(`ProtectNextButton( true ) );
+ UI::WizardCommand(`SetDialogIcon( default_icon ) );
+ }
+ else
+ {
+ Wizard::OpenDialog( GenericDialog( AbortAcceptButtonBox() ) );
+ }
+ }
+
+
+ /**
+ * Open a dialog with "Back", "Next", "Abort" that will also accept workflow steps.
+ **/
+ global void OpenNextBackStepsDialog()
+ {
+ if ( haveFancyUI() )
+ {
+ UI::OpenDialog(`opt(`wizardDialog ),
+ `Wizard(`opt(`stepsEnabled),
+ `back, Label::BackButton(),
+ `abort, Label::AbortButton(),
+ `next, Label::NextButton() ) );
+
+ UI::WizardCommand(`SetDialogIcon( default_icon ) );
+ }
+ else
+ {
+ OpenNextBackDialog();
+ }
+ }
+
+
+ /**
+ * Open a wizard dialog with simple layout
+ *
+ * no graphics, no steps,
+ * only a help widget buttons (by default "Back", "Abort", "Next").
+ *
+ * This is the only type of wizard dialog which still allows replacing
+ * the help space - either already upon opening it or later with
+ * Wizard::ReplaceCustomHelp().
+ *
+ * If help_space_contents is 'nil', the normal help widget will remain.
+ * If button_box is 'nil', Wizard::BackAbortNextButtonBox() is used.
+ *
+ * @see CloseDialog
+ *
+ * @param help_space_contents Help space contents
+ * @param button_box Buttom Box
+ * @return void
+ **/
+ global void OpenCustomDialog( term help_space_contents,
+ term button_box )
+ {
+ if ( button_box == nil )
+ button_box = BackAbortNextButtonBox();
+
+ UI::OpenDialog(`opt(`wizardDialog),
+ GenericDialog( button_box ) );
+
+ if ( help_space_contents != nil )
+ UI::ReplaceWidget(`id(`helpSpace), help_space_contents );
+ }
+
+
+ /**
+ * Replace the help widget for dialogs opened with Wizard::OpenCustomDialog().
+ * @param contents Replace custom help with supplied contents
+ **/
+ global void ReplaceCustomHelp( term contents )
+ {
+ if ( UI::WidgetExists( `id(`helpSpace ) ) )
+ {
+ UI::ReplaceWidget(`id(`helpSpace), contents);
+ }
+ else
+ {
+ y2error( "Wizard::ReplaceHelpSpace() works only for dialogs opened with Wizard::OpenSimpleDialog() !" );
+ }
+ }
+
+
+ /**
+ * Close a wizard dialog.
+ *
+ * @stable
+ **/
+ global void CloseDialog()
+ {
+ if ( IsWizardDialog() )
+ {
+ UI::CloseDialog();
+ }
+ else
+ {
+ y2error( "Wizard::CloseDialog(): Topmost dialog is not a wizard dialog!" );
+ }
+ }
+
+
+ /**
+ * Substitute for UI::UserInput
+ *
+ * This function transparently handles different variations of the wizard
+ * layout. Returns `next if `next or `accept were clicked, `back if `back
+ * or `cancel were clicked. Simply replace
+ * ret = UI::UserInput()
+ * with
+ * ret = Wizard::UserInput()
+ *
+ * @return (maybe normalized) widget ID
+ **/
+ global any UserInput()
+ {
+ any input = UI::UserInput();
+
+ if ( input == `accept ) return `next;
+ if ( input == `cancel ) return `back;
+
+ return input;
+ }
+
+
+ /**
+ * Substitute for UI::TimeoutUserInput
+ *
+ * Analogical to Wizard::UserInput.
+ **/
+ global any TimeoutUserInput( integer timeout_millisec )
+ {
+ any input = UI::TimeoutUserInput( timeout_millisec );
+
+ if ( input == `accept ) return `next;
+ if ( input == `cancel ) return `back;
+
+ return input;
+ }
+
+
+ /**
+ * Substitute for UI::WaitForEvent
+ *
+ * Analog to Wizard::UserInput.
+ **/
+ global map WaitForEvent( integer timeout_millisec )
+ {
+ map input = UI::WaitForEvent( timeout_millisec );
+
+ if (input["ID"]:nil == `accept) input["ID"] = `next;
+ if (input["ID"]:nil == `cancel) input["ID"] = `back;
+
+ return input;
+ }
+
+
+ /**
+ * Set a new help text.
+ * @param help_text Help text
+ * @example Wizard::SetHelpText("This is a help Text");
+ **/
+ global void SetHelpText( string help_text )
+ {
+ if ( UI::WizardCommand(`SetHelpText( help_text ) ) == false )
+ {
+ UI::ChangeWidget(`id(`WizardDialog), `HelpText, help_text);
+ }
+ }
+
+
+ /**
+ * Replace the wizard help subwindow with a custom widget.
+ *
+ * @deprecated
+ * @param contents Replace Help with contents
+ **/
+ global void ReplaceHelp(term contents)
+ {
+ if ( UI::WidgetExists( `id(`helpSpace ) ) )
+ {
+ y2warning( "Wizard::ReplaceHelp() is deprecated!" );
+ UI::ReplaceWidget(`id(`helpSpace), contents);
+ }
+ else
+ {
+ y2error( "Wizard::ReplaceHelp() is not supported by the new Qt wizard!" );
+ }
+ }
+
+
+ /**
+ * Restore the wizard help subwindow.
+ * @param help_text Help text
+ **/
+ global void RestoreHelp( string help_text )
+ {
+ Wizard::SetHelpText( help_text );
+ }
+
+
+ /**
+ * Create and open a typical installation wizard dialog.
+ *
+ * For backwards compatibility only - don't use this any more in new modules.
+ **/
+ global void CreateDialog()
+ {
+ // Set productname for help text
+ if (product_name == "")
+ product_name = SuSERelease::ReleaseName ();
+ UI::SetProductName(product_name);
+
+ Wizard::OpenNextBackDialog();
+ }
+
+
+ /**
+ * Set the contents of a wizard dialog and define if to move focus to next button
+ *
+ * How the general framework for the installation wizard should
+ * look like. This function creates and shows a dialog.
+ *
+ * @param title Dialog Title
+ * @param contents The Dialog contents
+ * @param help_text Help text
+ * @param has_back Is the Back button enabled?
+ * @param has_next Is the Next button enabled?
+ * @param set_focus Should the focus be set to Next button?
+ **/
+ global void SetContentsFocus( string title,
+ term contents,
+ string help_text,
+ boolean has_back,
+ boolean has_next,
+ boolean set_focus )
+ {
+
+ if ( UI::WizardCommand(`SetDialogHeading( title ) ) == true )
+ {
+ UI::WizardCommand(`SetHelpText( help_text ) );
+ UI::WizardCommand(`EnableNextButton( has_next ) );
+ UI::WizardCommand(`EnableBackButton( has_back ) );
+ if (set_focus)
+ UI::WizardCommand(`SetFocusToNextButton() );
+ }
+ else
+ {
+ if ( UI::WidgetExists(`id(`next ) ) )
+ {
+ UI::ChangeWidget(`id(`next), `Enabled, has_next);
+ UI::SetFocus( `id(`next) );
+ }
+
+ if ( UI::WidgetExists(`id(`back ) ) ) UI::ChangeWidget(`id(`back), `Enabled, has_back);
+ if ( UI::WidgetExists(`id(`abort ) ) ) UI::ChangeWidget(`id(`abort),`Enabled, true);
+ if ( UI::WidgetExists(`id(`title ) ) ) UI::ChangeWidget(`id(`title), `Value, title);
+
+ if ( set_focus )
+ if ( UI::WidgetExists(`id(`accept ) ) ) UI::SetFocus( `id(`accept ) );
+ }
+
+ SetHelpText( help_text );
+ UI::ReplaceWidget(`id(`contents), contents);
+ }
+
+
+ /**
+ * Set the contents of a wizard dialog
+ *
+ * How the general framework for the installation wizard should
+ * look like. This function creates and shows a dialog.
+ *
+ * @stable
+ *
+ * @param title Dialog Title
+ * @param contents The Dialog contents
+ * @param help_text Help text
+ * @param has_back Is the Back button enabled?
+ * @param has_next Is the Next button enabled?
+ * @example_file ../examples/wizard1.ycp
+ * @screenshot screenshots/wizard1.png
+ **/
+ global void SetContents( string title,
+ term contents,
+ string help_text,
+ boolean has_back,
+ boolean has_next )
+ {
+ SetContentsFocus (title, contents, help_text, has_back, has_next, true);
+ }
+
+
+ /**
+ * Clear the wizard contents.
+ *
+ * This may sound silly, but it gives much faster feedback to the
+ * user if used properly: Whenever the user clicks "Next" or
+ * "Back", call ClearContents() prior to any lengthy
+ * operation -> the user notices instant response, even though he
+ * may in fact still have to wait.
+ *
+ * @stable
+ **/
+ global void ClearContents()
+ {
+ Wizard::SetContents("", `Empty(), "", false, false);
+ }
+
+
+ /**
+ * Set contents and Buttons of wizard dialog
+ *
+ * Additionally set its title, help_text and buttons labels. Enables both back and next button.
+ *
+ * @params
+ *
+ * @param title title of window
+ * @param contents contents of dialog
+ * @param help_text help text
+ * @param back_label label of back button
+ * @param next_label label of next button
+ **/
+ global void SetContentsButtons( string title,
+ term contents,
+ string help_text,
+ string back_label,
+ string next_label )
+ {
+ UI::PostponeShortcutCheck ();
+
+ if ( UI::WizardCommand(`SetBackButtonLabel( back_label ) ) == true )
+ {
+ UI::WizardCommand(`SetNextButtonLabel( next_label ) );
+ Wizard::SetContents( title, contents, help_text, true, true );
+ }
+ else
+ {
+ // Set button labels first to avoid geometry problems: SetContents()
+ // calls ReplaceWidget() wich triggers a re-layout.
+
+ if ( UI::WidgetExists(`id(`back ) ) ) UI::ChangeWidget(`id (`back), `Label, back_label);
+ if ( UI::WidgetExists(`id(`next ) ) ) UI::ChangeWidget(`id (`next), `Label, next_label);
+ Wizard::SetContents( title, contents, help_text, true, true );
+ }
+ SetHelpText( help_text );
+ UI::CheckShortcuts ();
+ }
+
+
+ /**
+ * Set the dialog's "Next" button with a new label and a new ID
+ *
+ * @stable
+ *
+ * @param id Button ID
+ * @param label Button Label
+ **/
+ global void SetNextButton( any id, string label )
+ {
+ if ( UI::WizardCommand(`SetNextButtonLabel( label ) ) == true )
+ {
+ UI::WizardCommand(`SetNextButtonID( id ) );
+ }
+ else
+ {
+ if ( UI::WidgetExists(`id(`rep_next ) ) )
+ {
+ UI::ReplaceWidget(`id(`rep_next ),
+ `PushButton( `id( id ), `opt (`key_F10, `default), label ) );
+ }
+ }
+
+ }
+
+
+ /**
+ * Set the dialog's "Back" button with a new label and a new ID
+ *
+ * @stable
+ *
+ * @param id Button ID
+ * @param label Button Label
+ **/
+ global void SetBackButton( any id, string label )
+ {
+ if ( UI::WizardCommand(`SetBackButtonLabel( label ) ) == true )
+ {
+ UI::WizardCommand(`SetBackButtonID( id ) );
+ }
+ else
+ {
+ if ( UI::WidgetExists(`id(`rep_back ) ) )
+ {
+ UI::ReplaceWidget(`id(`rep_back),
+ `PushButton( `id( id ), `opt (`key_F8), label )
+ );
+ }
+ }
+ }
+
+
+ /**
+ * Set the dialog's "Abort" button with a new label and a new ID
+ *
+ * @stable
+ *
+ * @param id Button ID
+ * @param label Button Label
+ **/
+ global void SetAbortButton( any id, string label )
+ {
+ if ( UI::WizardCommand(`SetAbortButtonLabel( label ) ) == true )
+ {
+ UI::WizardCommand(`SetAbortButtonID( id ) );
+ }
+ else
+ {
+ if ( UI::WidgetExists(`id(`rep_abort ) ) )
+ {
+ UI::ReplaceWidget(`id(`rep_abort ),
+ `PushButton( `id( id ), `opt (`key_F9), label )
+ );
+ }
+ }
+ }
+
+
+ /**
+ * Hide the Wizard's "Next" button.
+ * Restore it later with RestoreNextButton():
+ *
+ * @see RestoreNextButton
+ * @stable
+ **/
+ global void HideNextButton()
+ {
+ if ( UI::WizardCommand(`SetNextButtonLabel( "" ) ) == false )
+ {
+ if ( UI::WidgetExists(`id(`rep_next ) ) )
+ UI::ReplaceWidget(`id(`rep_next ), `Empty() );
+ }
+ }
+
+
+ /**
+ * Hide the Wizard's "Back" button.
+ * Restore it later with RestoreBackButton():
+ *
+ * @see RestoreBackButton
+ * @stable
+ **/
+ global void HideBackButton()
+ {
+ if ( UI::WizardCommand(`SetBackButtonLabel( "" ) ) == false )
+ {
+ if ( UI::WidgetExists(`id(`rep_back ) ) )
+ UI::ReplaceWidget(`id(`rep_back), `Empty() );
+ }
+ }
+
+
+ /**
+ * Hide the Wizard's "Abort" button.
+ * Restore it later with RestoreAbortButton():
+ *
+ * @see RestoreAbortButton
+ * @stable
+ **/
+ global void HideAbortButton()
+ {
+ if ( UI::WizardCommand(`SetAbortButtonLabel( "" ) ) == false )
+ {
+ if ( UI::WidgetExists(`id(`rep_abort ) ) )
+ UI::ReplaceWidget(`id(`rep_abort ), `Empty() );
+ }
+ }
+
+
+ /**
+ * Restore the wizard 'back' button.
+ *
+ * @see HideBackButton
+ * @stable
+ **/
+ global void RestoreBackButton()
+ {
+ Wizard::SetBackButton( `back, Label::BackButton() );
+ }
+
+
+ /**
+ * Restore the wizard 'next' button.
+ *
+ * @see HideNextButton
+ * @stable
+ **/
+ global void RestoreNextButton()
+ {
+ Wizard::SetNextButton( `next, Label::NextButton() );
+ }
+
+
+ /**
+ * Restore the wizard 'abort' button.
+ *
+ * @see HideAbortButton
+ * @stable
+ **/
+ global void RestoreAbortButton()
+ {
+ Wizard::SetAbortButton( `abort, Label::AbortButton() );
+ }
+
+
+ /**
+ * Replace the wizard 'next' button with a custom widget.
+ * THIS FUNCTION IS DEPRECATED!
+ *
+ * @deprecated
+ * @see SetNextButton
+ * @param contents a term describing the new contents
+ **/
+ global void ReplaceNextButton( term contents )
+ {
+ if ( UI::WidgetExists(`id(`rep_next ) ) )
+ UI::ReplaceWidget(`id(`rep_next), contents);
+
+ y2warning( "Wizard::ReplaceNextButton() is deprecated!" );
+ }
+
+
+ /**
+ * Replace the wizard 'back' button with a custom widget.
+ * THIS FUNCTION IS DEPRECATED!
+ *
+ * @deprecated
+ * @see SetBackButton
+ * @param contents a term describing the new contents
+ **/
+ global void ReplaceBackButton( term contents )
+ {
+ if ( UI::WidgetExists(`id(`rep_back ) ) )
+ UI::ReplaceWidget(`id(`rep_back), contents);
+
+ y2warning( "Wizard::ReplaceBackButton() is deprecated!" );
+ }
+
+
+ /**
+ * Replace the wizard 'abort' button with a custom widget.
+ * THIS FUNCTION IS DEPRECATED!
+ *
+ * @see SetAbortButton
+ * @deprecated
+ * @param contents a term describing the new contents
+ **/
+ global void ReplaceAbortButton(term contents)
+ {
+ if ( UI::WidgetExists(`id(`rep_abort ) ) )
+ UI::ReplaceWidget(`id(`rep_abort), contents);
+
+ y2warning( "Wizard::ReplaceAbortButton() is deprecated!" );
+ }
+
+
+ /**
+ * Set the wizard 'title' icon
+ *
+ * Set the wizard 'title' icon to the specified icon from the standard icon
+ * directory.
+ *
+ * @stable
+ *
+ * @param icon_name name (without path) of the new icon
+ * @see ClearTitleIcon
+ **/
+ global void SetTitleIcon( string icon_name )
+ {
+ string icon = icon_name == "" ? "" : ( icon_path + "/" + icon_name + ".png" );
+
+ UI::WizardCommand(`SetDialogIcon( icon ) );
+ }
+
+
+ /**
+ * Clear the wizard 'title' icon, i.e. replace it with nothing
+ *
+ * @stable
+ * @see SetTitleIcon
+ **/
+ global void ClearTitleIcon()
+ {
+ UI::WizardCommand(`SetDialogIcon( "" ) );
+ }
+
+
+ /**
+ * Set the icon specified in a .desktop file
+ *
+ * @param file Icon name
+ * @return boolean true on success
+ */
+ global boolean SetDesktopIcon( string file )
+ {
+ string filename = sformat("%1/%2.desktop", Directory::desktopdir, file);
+ // Do not use .yast2.desktop.v.$filename, because ini-agent reads
+ // all the desktop files anyway which is wasteful for setting one icon.
+ // The config is adapted from .yast2.desktop.
+ SCR::RegisterAgent (.yast2.desktop1, `ag_ini(
+ `IniAgent( filename,
+ $[
+ "options" : [ "read_only" ], // rw works but not needed
+ "comments" : [ "^[ \t]*[;#].*", ";.*", "\\{[^}]*\\}", "^[ \t]*$" ],
+ "sections" : [
+ $[ "begin" : [
+ "^[ \t]*\\[[ \t]*(.*[^ \t])[ \t]*\\][ \t]*",
+ "[%s]",
+ ]],
+ ],
+ "params" : [
+ $[ "match" : [
+ "^[ \t]*([^=]*[^ \t=])[ \t]*=[ \t]*(.*[^ \t]|)[ \t]*$" ,
+ "%s=%s",
+ ]],
+ ],
+ ]
+ )
+ )
+ );
+ path filepath = .yast2.desktop1.v."Desktop Entry".Icon;
+ string icon = (string) DBus::Read(filepath);
+ y2debug("icon: %1 (%2)", icon, filepath);
+
+ if (icon == nil)
+ return false;
+
+ SetTitleIcon(icon);
+
+ SCR::UnregisterAgent (.yast2.desktop1);
+ return true;
+ }
+
+
+ /**
+ * PRIVATE - Replace the entire Wizard button box with a new one.
+ * @param button_box Button Box term
+ * @return void
+ **/
+ void ReplaceButtonBox( term button_box )
+ {
+ UI::ReplaceWidget(`id(`rep_button_box ), button_box );
+ }
+
+
+ /**
+ * Enable the wizard's "Abort" button.
+ *
+ * @see DisableAbortButton
+ * @stable
+ **/
+ global void EnableAbortButton()
+ {
+ if ( UI::WizardCommand(`EnableAbortButton( true ) ) == false )
+ UI::ChangeWidget(`id(`abort), `Enabled, true );
+ }
+
+
+ /**
+ * Disable the wizard's "Abort" button.
+ *
+ * @see EnableAbortButton
+ * @stable
+ **/
+ global void DisableAbortButton()
+ {
+ if ( UI::WizardCommand(`EnableAbortButton( false ) ) == false )
+ UI::ChangeWidget(`id(`abort), `Enabled, false );
+ }
+
+
+ /**
+ * Disable the wizard's "Next" (or "Accept") button.
+ *
+ * @see EnableNextButton
+ * @stable
+ **/
+ global void DisableNextButton()
+ {
+ if ( UI::WizardCommand(`EnableNextButton( false ) ) == false )
+ {
+ if (UI::WidgetExists (`id (`next))) {
+ UI::ChangeWidget(`id (`next), `Enabled, false);
+ } else if (UI::WidgetExists (`id (`accept))) {
+ UI::ChangeWidget(`id (`accept), `Enabled, false);
+ } else {
+ y2error (-1, "Neither `next nor `accept widgets exist");
+ }
+ }
+ }
+
+
+ /**
+ * Enable the wizard's "Next" (or "Accept") button.
+ *
+ * @see DisableNextButton
+ * @stable
+ **/
+ global void EnableNextButton()
+ {
+ if ( UI::WizardCommand(`EnableNextButton( true ) ) == false )
+ {
+ if ( UI::WidgetExists(`id(`next ) ) )
+ UI::ChangeWidget(`id(`next), `Enabled, true );
+ else
+ UI::ChangeWidget(`id(`accept), `Enabled, true );
+ }
+ }
+
+
+ /**
+ * Disable the wizard's "Back" button.
+ *
+ * @see EnableBackButton
+ * @stable
+ **/
+ global void DisableBackButton()
+ {
+ if ( UI::WizardCommand(`EnableBackButton( false ) ) == false )
+ UI::ChangeWidget(`id(`back ), `Enabled, false );
+ }
+
+ /**
+ * Enable the wizard's "Back" button.
+ *
+ * @see DisableBackButton
+ * @stable
+ **/
+ global void EnableBackButton()
+ {
+ if ( UI::WizardCommand(`EnableBackButton( true ) ) == false )
+ UI::ChangeWidget(`id(`back ), `Enabled, true );
+ }
+
+
+ /**
+ * Disable the wizard's "Cancel" button.
+ *
+ * @see EnableCancelButton
+ * @stable
+ **/
+ global void DisableCancelButton()
+ {
+ if ( UI::WizardCommand(`EnableCancelButton( false ) ) == false )
+ UI::ChangeWidget(`id(`cancel ), `Enabled, false );
+ }
+
+
+ /**
+ * Enable the wizard's "Cancel" button.
+ *
+ * @see DisableCancelButton
+ * @stable
+ **/
+ global void EnableCancelButton()
+ {
+ if ( UI::WizardCommand(`EnableCancelButton( true ) ) == false )
+ UI::ChangeWidget(`id(`cancel ), `Enabled, true );
+ }
+
+
+ /**
+ * Returns whether the `Wizard widget is available.
+ *
+ * @see bnc #367213.
+ * @return boolean available
+ */
+ boolean HasWidgetWizard () {
+ if (! UI::HasSpecialWidget(`Wizard))
+ {
+ y2milestone ("no Wizard available");
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Show a "Release Notes" button with the specified label and ID if there is a "steps" panel
+ **/
+ global void ShowReleaseNotesButton( string label, string id )
+ {
+ // has wizard? continue
+ // otherwise reuse the back button
+ // show-releasenotes-button failed? continue
+ // reuse the back button
+ if ( (HasWidgetWizard() == false) || (UI::WizardCommand (`ShowReleaseNotesButton (label, id)) == false) )
+ {
+ // Reuse Back button
+ if (UI::WidgetExists (`id (`back_rep))) {
+ UI::ReplaceWidget (`id (`back_rep), `PushButton (`id (id), label));
+ } else {
+ y2warning ("Widget `back_rep does not exist");
+ }
+ }
+ }
+
+
+ /**
+ * Hide the "Release Notes" button, if there is any
+ **/
+ global void HideReleaseNotesButton()
+ {
+ // has wizard? continue
+ // otherwise reuse the back button
+ // hide-releasenotes-button failed? continue
+ // reuse the back button
+ if ((HasWidgetWizard() == false) || (UI::WizardCommand (`HideReleaseNotesButton()) == false))
+ {
+ if (UI::WidgetExists (`id (`back_rep))) {
+ UI::ReplaceWidget (`id (`back_rep), `Empty ());
+ }
+ }
+ }
+
+
+ /**
+ * Retranslate the wizard buttons.
+ *
+ * This will revert button labels and IDs
+ * to the default that were used upon Wizard::CreateDialog(),
+ * Wizard::OpenNextBackDialog(), or Wizard::OpenAcceptDialog().
+ **/
+ global void RetranslateButtons()
+ {
+ if ( UI::WidgetExists(`id(`WizardDialog ) ) == true )
+ {
+ ReplaceButtonBox( UI::WidgetExists(`id(`accept ) ) ?
+ Wizard::AbortAcceptButtonBox() :
+ Wizard::BackAbortNextButtonBox() );
+ }
+ else // Qt wizard
+ {
+ UI::WizardCommand(`RetranslateInternalButtons() );
+
+ if ( UI::WidgetExists(`accept) )
+ {
+ UI::WizardCommand(`SetBackButtonLabel ( "" ) );
+ UI::WizardCommand(`SetAbortButtonLabel( Label::AbortButton() ) );
+ UI::WizardCommand(`SetNextButtonLabel ( Label::AcceptButton() ) );
+ }
+ else
+ {
+ UI::WizardCommand(`SetBackButtonLabel ( Label::BackButton() ) );
+ UI::WizardCommand(`SetAbortButtonLabel( Label::AbortButton() ) );
+ UI::WizardCommand(`SetNextButtonLabel ( Label::NextButton() ) );
+ }
+ }
+ }
+
+
+ /**
+ * Set the keyboard focus to the wizard's "Next" (or "Accept") button.
+ *
+ * @stable
+ **/
+ global void SetFocusToNextButton()
+ {
+ if ( UI::WizardCommand(`SetFocusToNextButton() ) == false )
+ {
+ UI::SetFocus( UI::WidgetExists(`id(`next) ) ? `id(`next) : `id(`accept ) );
+ }
+ }
+
+ /**
+ * Set the keyboard focus to the wizard's "Back" (or "Cancel") button.
+ *
+ * @stable
+ **/
+ global void SetFocusToBackButton()
+ {
+ if ( UI::WizardCommand(`SetFocusToBackButton() ) == false )
+ {
+ UI::SetFocus( UI::WidgetExists(`id(`back) ) ? `id(`back) : `id(`cancel ) );
+ }
+ }
+
+
+
+ //
+ // Screenshot Functions
+ //
+
+
+ /**
+ * Currently used screenshot name.
+ * Initially, it must match the UI default, "yast2"
+ */
+ string screenshot_name = "yast2";
+
+ /**
+ * Screenshot names overriden by nested SetScreenShotName calls
+ */
+ list<string> screenshot_name_stack = [];
+
+
+ /**
+ * Set a name for the current dialog:
+ *
+ * Declare a name for the current dialog to ease making screenshots.
+ * By convention, the name is
+ * {rpm-name-without-yast2}-{sorting-prefix}-{description}
+ * The calls may be nested.
+ * @param s eg. "mail-1-conntype"
+ * @see RestoreScreenShotName
+ */
+ global void SetScreenShotName(string name )
+ {
+ screenshot_name_stack = prepend( screenshot_name_stack, screenshot_name );
+ screenshot_name = name;
+ }
+
+
+ /**
+ * Restore the screenshot name.
+ *
+ * If it does not match a SetScreenShotName, "yast2" is used
+ * and a y2error logged.
+ */
+ global void RestoreScreenShotName ()
+ {
+ screenshot_name = screenshot_name_stack[0]:nil;
+ if (screenshot_name == nil)
+ {
+ screenshot_name = "yast2";
+ y2error (1, "No screenshot name to restore!");
+ }
+ else
+ {
+ screenshot_name_stack = remove (screenshot_name_stack, 0);
+ }
+ }
+
+
+
+ //
+ // Tree & Menu Wizard functions
+ //
+
+ /**
+ * Open a Tree dialog with buttons "Next", "Back", "Abort"
+ * and set the keyboard focus to "Next".
+ **/
+ global void OpenTreeNextBackDialog()
+ {
+ if ( haveFancyUI() )
+ {
+ UI::OpenDialog(`opt(`wizardDialog ),
+ `Wizard(`opt(`treeEnabled),
+ `back, Label::BackButton(),
+ `abort, Label::AbortButton(),
+ `next, Label::NextButton()
+ )
+ );
+
+ UI::WizardCommand(`SetDialogIcon( default_icon ) );
+ }
+ else
+ {
+ Wizard::OpenDialog( GenericTreeDialog( BackAbortNextButtonBox() ) );
+ UI::SetFocus(`id(`next) );
+ }
+ }
+
+
+ /**
+ * Create and open a Tree wizard dialog.
+ *
+ * For backwards compatibility only - don't use this any more in new modules.
+ **/
+ global void CreateTreeDialog()
+ {
+ Wizard::OpenTreeNextBackDialog();
+ return;
+ }
+
+
+ /**
+ * Add Tree Item to tree enabled Wizard
+ * @param Tree Tree Data
+ * @param parent Parent of this item
+ * @param title Item Title
+ * @param id Item ID
+ * @return list<map> Updated Tree Data
+ **/
+ global list<map> AddTreeItem( list<map> Tree, string parent , string title, string id )
+ {
+ if ( haveFancyUI() )
+ {
+ UI::WizardCommand(`AddTreeItem( parent, title , id ) );
+ }
+ else
+ {
+ Tree = add(Tree, $[ "parent": parent, "title":title, "id": id]);
+ }
+ return Tree;
+ }
+
+
+ /**
+ * Create the Tree Items
+ * @param Tree Tree data
+ * @param parent Parent of current Item
+ * @return list Tree Items
+ **/
+ list CreateTreeInternal( list<map> Tree, string parent )
+ {
+ list<map> m = filter(map c, Tree, ``((c["parent"]:"" == parent )));
+ map ccbak = nil; // #38596, broken recursion for iterators
+ list mm = maplist(map cc, m, ``{
+ string TreeEntry = cc["id"]:"";
+ ccbak = cc;
+ list items = CreateTreeInternal(Tree, TreeEntry);
+ cc = ccbak;
+ if (size(items)>0)
+ return(`item(`id(cc["id"]:""), cc["title"]:"", items));
+ else
+ return(`item(`id(cc["id"]:""), cc["title"]:""));
+ });
+ y2debug("items: %1", mm );
+ return mm;
+ }
+
+
+ /**
+ * Query Tree Item
+ * @return Tree Item
+ */
+ global string QueryTreeItem()
+ {
+ if (haveFancyUI() )
+ {
+ return (string)UI::QueryWidget(`id(`wizard), `CurrentItem );
+ }
+ else
+ {
+ return (string)UI::QueryWidget(`id(`wizardTree), `CurrentItem );
+ }
+ }
+
+
+ /**
+ * Create the tree in the dialog, replaces helpspace with new tree widget
+ * @param Tree Tree data
+ * @param title Tree title
+ **/
+ global void CreateTree(list<map> Tree, string title)
+ {
+ if ( !haveFancyUI() )
+ {
+ list items = [];
+ foreach(map i, Tree, ``{
+ if (i["parent"]:"" == "")
+ {
+ items=add(items, `item(`id(i["id"]:""), i["title"]:"",
+ CreateTreeInternal(Tree, i["id"]:"") ));
+ }
+ });
+ y2debug("tree items: %1", items);
+
+ Wizard::ReplaceCustomHelp(
+ `VBox(
+ `Tree(
+ `id(`wizardTree),
+ `opt(`notify, `vstretch),
+ title,
+ items
+ ),
+ `VSpacing(1))
+ );
+ }
+ }
+
+
+ /**
+ * Select Tree item
+ * @param tree_item tree item
+ */
+ global void SelectTreeItem( string tree_item )
+ {
+ if ( haveFancyUI() )
+ {
+ UI::WizardCommand(`SelectTreeItem( tree_item ) );
+ }
+ else
+ {
+ UI::ChangeWidget(`id(`wizardTree), `CurrentItem, tree_item);
+ }
+ }
+
+
+ /**
+ * Delete Tree items
+ */
+ global void DeleteTreeItems()
+ {
+ if ( haveFancyUI() )
+ {
+ UI::WizardCommand(`DeleteTreeItems() );
+ }
+ else
+ {
+ Wizard::ReplaceCustomHelp(`Empty());
+ }
+ }
+
+
+ /**
+ * Delete Menu items
+ */
+ global void DeleteMenus()
+ {
+ if ( haveFancyUI() )
+ {
+ UI::WizardCommand(`DeleteMenus() );
+ }
+ else
+ {
+ UI::ReplaceWidget(`id(`topmenu), `Empty());
+ }
+ }
+
+
+ /**
+ * Add Menu
+ * @param Menu Menu data
+ * @param title Menu Title
+ * @param id Menu ID
+ * @return list<map> Updated Menu Data
+ **/
+ global list<map> AddMenu( list<map> Menu, string title, string id )
+ {
+ if ( haveFancyUI() )
+ {
+ UI::WizardCommand(`AddMenu( title, id ) );
+ }
+ else
+ {
+ Menu = add(Menu, $["type":"Menu", "title":title, "id": id]);
+ }
+ return Menu;
+ }
+
+
+ /**
+ * Add Sub Menu
+ * @param Menu Menu data
+ * @param parent_id Menu Parent
+ * @param title Menu Title
+ * @param id Menu ID
+ * @return list<map> Updated Menu Data
+ **/
+ global list<map> AddSubMenu( list<map> Menu, string parent_id, string title, string id )
+ {
+ if ( haveFancyUI() )
+ {
+ UI::WizardCommand(`AddSubMenu( parent_id, title, id ) );
+ }
+ else
+ {
+ Menu = add(Menu, $["type":"SubMenu", "parent": parent_id, "title":title, "id": id]);
+ }
+ return Menu;
+ }
+
+
+ /**
+ * Add Menu Entry
+ * @param Menu Menu data
+ * @param parent_id Menu Parent
+ * @param title Menu Title
+ * @param id Menu ID
+ * @return list<map> Updated Menu Data
+ **/
+ global list<map> AddMenuEntry(list<map> Menu, string parent_id, string title, string id)
+ {
+ if ( haveFancyUI() )
+ {
+ UI::WizardCommand(`AddMenuEntry( parent_id, title, id ) );
+ }
+ else
+ {
+ Menu = add(Menu, $["type":"MenuEntry", "parent": parent_id, "title":title, "id": id]);
+ }
+ return Menu;
+ }
+
+
+ /**
+ * Create the Menu Items
+ * @param Menu Menu data
+ * @param parent Menu Parent
+ * @return list Menu Items
+ **/
+ list CreateMenuInternal( list<map> Menu, string parent )
+ {
+ list<map> m = filter(map c, Menu, ``((c["parent"]:"" == parent )));
+
+ list mm = maplist(map cc, m, ``{
+ if(cc["type"]:"" == "MenuEntry")
+ {
+ string MenuEntry = cc["id"]:"";
+ return(`item(`id(MenuEntry), cc["title"]:""));
+ }
+ else if (cc["type"]:"" == "SubMenu")
+ {
+ string SubMenu = cc["id"]:"";
+ return(`menu( cc["title"]:"", CreateMenuInternal(Menu,
+ SubMenu)));
+ }
+ });
+ y2debug("items: %1", mm );
+ return mm;
+ }
+
+
+ /**
+ * Create the menu in the dialog
+ * @param Menu Menu data
+ * @return void
+ **/
+ global void CreateMenu( list<map> Menu )
+ {
+ if ( ! haveFancyUI() )
+ {
+ term menu_term = `HBox();
+ foreach(map m, Menu, ``{
+ if (m["type"]:"" == "Menu")
+ {
+ list menu_items = CreateMenuInternal(Menu, m["id"]:"");
+ y2debug("menu_items: %1", menu_items );
+ menu_term=add(menu_term, `MenuButton( m["title"]:"",
+ menu_items));
+ }
+ });
+ y2milestone("menu: %1", menu_term );
+ UI::ReplaceWidget(`id(`topmenu), `Left(menu_term));
+ }
+ return;
+ }
+
+
+ /**
+ * Set the product name for UI
+ * @param name the product name
+ * @return void
+ **/
+ global void SetProductName( string name )
+ {
+ y2milestone ("Setting product name to '%1'", name);
+ product_name = name;
+ }
+
+}
--
To unsubscribe, e-mail: yast-commit+unsubscribe@opensuse.org
For additional commands, e-mail: yast-commit+help@opensuse.org