Index: library/wizard/src/Wizard.ycp
===================================================================
--- library/wizard/src/Wizard.ycp	(revision 65721)
+++ library/wizard/src/Wizard.ycp	(working copy)
@@ -12,6 +12,7 @@
     module "Wizard";
     textdomain "base";
 
+    import "Desktop";
     import "Label";
     import "Popup";
     import "Directory";
@@ -1092,71 +1093,17 @@
      */
     global boolean SetDesktopTitle( string file )
     {
- 	path filepath = .yast2.desktop1.v."Desktop Entry";
-        string name = "";
-	string localizedkey = "";
-	string Language = "";
-	string LanguageFull = "";
-	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 title.
-	// 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",
-		]],
-	    ],
-	]
-	)));
+	map<string,string> description = Desktop::ParseSingleDesktopFile (file);
+	
+	// fallback name for the dialog title
+        string name = description["Name"]:_("Module");
 
-
-	/* read language */
-	LanguageFull = "";
-	Language = UI::GetLanguage(true);
-	if(regexpmatch(Language, "(.*_[^.]*)\\.?.*")) // matches: ll_TT ll_TT.UTF-8
-        LanguageFull = regexpsub(Language, "(.*_[^.]*)\\.?.*", "\\1");
-	if(regexpmatch(Language, "(.*)_"))
-		Language = regexpsub(Language, "(.*)_", "\\1");
-	y2debug("LanguageFull=%1", LanguageFull);
-	y2debug("Language=%1", Language);
-
-	/* get localized Name value from desktop file */
-	if( LanguageFull != nil || LanguageFull != "" )
-	{
-	    localizedkey = sformat("%1[%2]", "Name", LanguageFull);
-	    name = (string) SCR::Read(add(filepath, localizedkey));
-	}
-	if( ( name == nil || name == "" ) && ( Language != nil || Language != "" ))
-	{
-            localizedkey = sformat("%1[%2]", "Name", Language);
-            name = (string) SCR::Read(add(filepath, localizedkey));
-	}
-	if( name == nil || name == "" )
-            name = (string) SCR::Read(add(filepath, "Name"));
-
 	y2debug("Set dialog title: %1", name);
     	SetDialogTitle( name );
 
-	SCR::UnregisterAgent (.yast2.desktop1);
-
-	return ( name != nil && name != "");
+	return ( haskey(description, "Name") );
     }
 
-
-
-
     /**
      * Sets the icon specified in a .desktop file got as parameter.
      * Desktop file is placed in a special directory (/usr/share/applications/YaST2).
@@ -1174,47 +1121,65 @@
      */
     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) SCR::Read(filepath);
-	y2debug("icon: %1 (%2)", icon, filepath);
+	map<string,string> description = Desktop::ParseSingleDesktopFile (file);
+	
+	// fallback name for the dialog title
+        string icon = description["Icon"]:nil;
 
+	y2debug("icon: %1", icon);
+
 	if (icon == nil) 
 	    return false;
 
 	SetTitleIcon(icon);
 
-	SCR::UnregisterAgent (.yast2.desktop1);
-
 	return true;
     }
 
 
     /**
+     * Convenience function to avoid 2 calls if application needs to set
+     * both dialog title and icon from desktop file specified as parameter.
+     * Desktop file is placed in a special directory (/usr/share/applications/YaST2).
+     * Parameter file is realative to that directory without ".desktop" suffix.
+     * Warning: There are no desktop files in inst-sys.
+     *
+     * @param file desktop file name
+     * @return boolean true on success
+     *
+     * @example
+     *	// Opens /usr/share/applications/YaST2/lan.desktop
+     *	// Reads "Icon" and "Name" entries from there
+     *	// Sets the icon, sets the dialog title
+     *	SetDialogTitleAndIcon ("lan")
+     */
+    global boolean SetDesktopTitleAndIcon( string file )
+    {
+	boolean result = true;
+	
+	map<string,string> description = Desktop::ParseSingleDesktopFile (file);
+	
+	// fallback name for the dialog title
+        string icon = description["Icon"]:nil;
+
+	y2debug("icon: %1", icon);
+
+	if (icon != nil) 
+	    SetTitleIcon(icon);
+	else
+	    result = false;
+
+	// fallback name for the dialog title
+        string name = description["Name"]:_("Module");
+
+	y2debug("Set dialog title: %1", name);
+    	SetDialogTitle( name );
+
+	return result && ( haskey(description, "Name") );
+    }
+
+
+    /**
      * PRIVATE - Replace the entire Wizard button box with a new one.
      * @param button_box Button Box term
      * @return void
Index: library/desktop/src/Desktop.ycp
===================================================================
--- library/desktop/src/Desktop.ycp	(revision 65721)
+++ library/desktop/src/Desktop.ycp	(working copy)
@@ -12,6 +12,7 @@
 module "Desktop";
 textdomain "base";
 import "Map";
+import "Directory";
 
 /**
  * YaST configuration modules
@@ -74,6 +75,7 @@
 
     //no translations in .desktop, check desktop_translations.mo then
     string msgid = sformat("%1(%2): %3", key, fname, fallback );
+    y2debug( "Looking for key: %1", msgid );
     ret = dpgettext( "desktop_translations", "/usr/share/locale", msgid );
 
     //probably untranslated - return english name
@@ -86,6 +88,21 @@
 }
 
 /**
+ * Internal function: set up the language variables.
+ */
+void ReadLanguage() {
+    /* read language */
+    LanguageFull = "";
+    Language = UI::GetLanguage(true);
+    if(regexpmatch(Language, "(.*_[^.]*)\\.?.*")) // matches: ll_TT ll_TT.UTF-8
+	LanguageFull = regexpsub(Language, "(.*_[^.]*)\\.?.*", "\\1");
+    if(regexpmatch(Language, "(.*)_"))
+	Language = regexpsub(Language, "(.*)_", "\\1");
+    y2debug("LanguageFull=%1", LanguageFull);
+    y2debug("Language=%1", Language);
+}
+
+/**
  * Read module and group data from desktop files
  * @param Values list of values to be parsed (empty to read all)
  */
@@ -103,20 +120,12 @@
     map filemap = $[];
     path filepath = nil;
     string name = nil;
+    
+    ReadLanguage();
 
     path ps = add(AgentPath, "s");
     list<string> files = (list<string>) SCR::Dir(ps);
 
-    /* read language */
-    LanguageFull = "";
-    Language = WFM::GetLanguage();
-    if(regexpmatch(Language, "(.*_[^.]*)\\.?.*")) // matches: ll_TT ll_TT.UTF-8
-	LanguageFull = regexpsub(Language, "(.*_[^.]*)\\.?.*", "\\1");
-    if(regexpmatch(Language, "(.*)_"))
-	Language = regexpsub(Language, "(.*)_", "\\1");
-    y2debug("LanguageFull=%1", LanguageFull);
-    y2debug("Language=%1", Language);
-
     /* read groups */
     list<string> groups = (list<string>) SCR::Dir(.yast2.groups.s);
     y2debug("groups=%1", groups);
@@ -249,5 +258,71 @@
 	    content);
 }
 
+/**
+ * Parses the a .desktop file it gets as a parameter without trying to use
+ * already cached information or agent to access all desktop files. This is
+ * optimized version to be used for rapid start of modules.
+ * Desktop file is placed in a special directory (/usr/share/applications/YaST2).
+ * Parameter file is relative to that directory without ".desktop" suffix.
+ * Warning: There are no desktop files in inst-sys.
+ *
+ * @param file desktop file name
+ * @return map filled with data, or nil
+ *
+ * @example
+ *	// Opens /usr/share/applications/YaST2/lan.desktop
+ *	map<string,string> description = Desktop::ParseSingleDesktopFile ("lan");
+ *	Wizard::SetDialogTitle (description["Name"]:_("None));
+ */
+global map<string,string> ParseSingleDesktopFile( 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",
+		]],
+	    ],
+	]
+	))
+    );
+    
+    //non-existent file requested
+    if (SCR::Dir( .yast2.desktop1.v."Desktop Entry" ) == nil)
+    {
+	y2error ("Unknown desktop file: %1", file);
+	SCR::UnregisterAgent (.yast2.desktop1);   
+	return nil;
+    }
+    
+    // we need localized keys
+    ReadLanguage ();
+    
+    map<string, string> result = $[
+	"Icon" : (string) SCR::Read(.yast2.desktop1.v."Desktop Entry".Icon),
+	"Name" : ReadLocalizedKey (file + ".desktop", .yast2.desktop1.v."Desktop Entry", "Name"),
+	"GenericName" : ReadLocalizedKey (file + ".desktop", .yast2.desktop1.v."Desktop Entry", "GenericName")
+    ];
+    
+    SCR::UnregisterAgent (.yast2.desktop1);
+
+    return result;
+}
+
+
 /* EOF */
 }
