Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37533757
en ru br
Репозитории ALT
S:2.1.41-alt23
5.1: 2.1.41-alt9
4.1: 2.1.41-alt3.M41.1
4.0: 2.1.35-alt5
3.0: 2.1.25-alt3
+backports:2.1.29-alt4.0.M30
www.altlinux.org/Changes

Группа :: Система/Основа
Пакет: menu

 Главная   Изменения   Спек   Патчи   Sources   Загрузить   Gear   Bugs and FR  Repocop 

Патч: menu-2.1.25-xdginput.patch
Скачать


--- menu-2.1.25/update-menus/common.h~	2005-08-07 21:54:54 +0400
+++ menu-2.1.25/update-menus/common.h	2005-08-07 21:55:38 +0400
@@ -32,6 +32,9 @@ const int MAX_LINE = 10240;
 #define PACKAGEMENUS    "/usr/share/menu/"
 #define MENUMENUS       "/usr/share/menu/default/"
 #define USERMENUS       ".menu/"
+#define XDGMENUS       "/usr/share/applications/"
+#define XDGMENUS_KDE       "/usr/share/applications/kde/"
+#define XDGMENUS_GNOME       "/usr/share/applications/gnome/"
 
 #define MENUMETHODS     "/etc/menu-methods/"
 #define USERMETHODS     ".menu-methods/"
--- menu-2.1.25/update-menus/update-menus.h~	2005-08-07 21:52:18 +0400
+++ menu-2.1.25/update-menus/update-menus.h	2005-08-07 21:52:28 +0400
@@ -122,6 +122,7 @@ public:
   typedef enum { report_quiet, report_normal, report_verbose, report_debug} verbosity_type;
   parsestream::eol_type compat;
   std::vector<std::string> menufilesdir;
+  std::vector<std::string> desktopfilesdir;
   std::string menumethod;
   bool usedefaultmenufilesdirs;
   bool onlyoutput_to_stdout;
--- menu-2.1.25/update-menus/update-menus.cc~	2005-07-24 15:39:26 +0400
+++ menu-2.1.25/update-menus/update-menus.cc	2005-09-11 20:59:10 +0400
@@ -57,6 +57,7 @@ static const char * home_dir;
 
 set<string> installed_packages;
 set<string> menufiles_processed;
+set<string> desktopfiles_processed;
 int total_menuentries;
 
 int verbose=0;
@@ -463,6 +464,234 @@ void read_pkginfo()
   pclose(status);
 }
 
+/** Read a XDG desktopfile and create one menu entry for it.
+ *
+ * Returns 0 or 1 of menu entries read. */
+int read_desktopfile(const string &filename, const string &shortfilename,
+                  vector<string> &menudata)
+{
+  FILE *desktop_file = fopen(filename.c_str(), "r");
+  if (desktop_file == NULL)  return 0;
+
+      char firstline[MAX_LINE];
+      if (fgets(firstline, MAX_LINE, desktop_file) == NULL)
+      {
+        pclose(desktop_file);
+        return 0;
+      }
+      if (strcmp(firstline, "[Desktop Entry]\n") != 0)
+      {
+        pclose(desktop_file);
+        return 0;
+      }
+//      cerr << __FUNCTION__ << " read " << filename << std::endl;
+
+      bool have_section = false;
+      bool have_title = false;
+      std::string d_onlyshowin;
+      std::string d_terminal;
+      std::string d_extra;
+      std::string menu_line;
+
+      // create menu entry start
+      menu_line += "package=\"_local.xdg_desktop_files\" xdg_desktopfile=\"true\"";
+//      int n_line = 2;
+      while (!feof(desktop_file))
+      {
+        std::string line;
+        char tmp[MAX_LINE];
+        fgets(tmp, MAX_LINE, desktop_file);
+	int len = strlen(tmp);
+
+	// ignore empty lines
+	if ( len <= 1) continue;
+
+	// quote
+	for(int i=0; i < MAX_LINE; i++)
+	{
+	  if( tmp[i] == '\"' )
+	    line += "\\\"";
+	  else if( tmp[i] == '\n' )
+	    break;
+	  else
+	    line += tmp[i];
+	}
+
+//	if( tmp[len-1] == '\n' )
+//	    line = std::string(tmp, 0, len-1);
+//	else
+//	    line = tmp;
+//	cerr << " line " << n_line++ << ":" << line << std::endl;
+	
+	int sz = line.size();
+
+	if( line.compare(0, 5, "Name=") == 0 )
+	{
+	  // take title
+//	  cerr << __FUNCTION__ << " take title" << std::endl;
+	  if(sz > 5)
+	  {
+	    menu_line += " title=\""+line.substr(5, sz-5)+"\"";
+	    have_title = true;
+	  }
+	}
+	else if( line.compare(0, 11, "Categories=") == 0 )
+	{
+	  // take section
+//	  cerr << __FUNCTION__ << " take section" << std::endl;
+	  if(sz > 11)
+	  {
+	    std::string categories( line.substr(11, sz-11) );
+	    std::list<string> ctglist;
+	    for(std::string::iterator it = categories.begin(); it != categories.end(); ++it)
+	    {
+    	      std::string ctg;
+
+    	      while( it != categories.end() && *it != ';' )
+    	      {
+		ctg += *it;
+		++it;
+	      }
+	      if( it == categories.end() ) --it;
+
+	      if( ctg.size() > 0 )
+		ctglist.push_front(ctg);
+	    }
+	    for(std::list<string>::iterator it = ctglist.begin(); it != ctglist.end(); ++it)
+	    {
+		if( *it != "X-KDE-More" )
+		{
+		    menu_line += " section=\""+*it+"\"";
+		    have_section = true;
+		    break;
+		}
+	    }
+	  }
+	}
+	else if( line.compare(0, 8, "Comment=") == 0 )
+	{
+	  // take longtitle
+	  if(sz > 8)
+	  {
+	    menu_line += " longtitle=\""+line.substr(8, sz-8)+"\"";
+	  }
+	}
+	else if( line.compare(0, 5, "Icon=") == 0 )
+	{
+	  // take icon
+	  if(sz > 5)
+	  {
+	    menu_line += " icon=\""+line.substr(5, sz-5)+"\"";
+	  }
+	}
+	else if( line.compare(0, 9, "MimeType=") == 0 )
+	{
+	  // take mimetypes
+	  // FIXME? replace ; by ,
+	  if(sz > 9)
+	  {
+	    menu_line += " mimetypes=\""+line.substr(9, sz-9)+"\"";
+	  }
+	}
+	else if( line.compare(0, 5, "Exec=") == 0 )
+	{
+	  // take command && xdg_command
+	  if(sz > 5)
+	  {
+	    menu_line += " xdg_command=\""+line.substr(5, sz-5)+"\"";
+	    int sps_pos = line.find(' ');
+	    if( sps_pos > 5 )
+		menu_line += " command=\""+line.substr(5, sps_pos-5)+"\"";
+	    else
+		menu_line += " command=\""+line.substr(5, sz-5)+"\"";
+	  }
+	}
+	else if( line.compare(0, 12, "GenericName=") == 0 )
+	{
+	  if(sz > 12)
+	  {
+	    menu_line += " xdg_genericname=\""+line.substr(12, sz-12)+"\"";
+	  }
+	}
+	else if( line.compare(0, 9, "Terminal=") == 0 )
+	{
+	  // fill d_terminal
+	  if(sz > 9)
+	  {
+	    d_terminal = line.substr(9, sz-9);
+	  }
+	}
+	else if( line.compare(0, 11, "OnlyShowIn=") == 0 )
+	{
+	  // fill d_onlyshowin
+	  if(sz > 11)
+	  {
+	    int start = sz - 3;
+	    int end = sz - 1 ;
+	    while( line[start] != ';' && line[start] != '=' && start >= 0 )
+		start--;
+	    start++;
+	    end = start;
+	    while( line[end] != ';' && line[end] != '\n' && end < sz )
+		end++;
+	    std::string onlyshowin(line.substr(start, end-start));
+	    d_onlyshowin = onlyshowin;
+	  }
+	}
+	else
+	{
+	    if( line.compare(0, 9, "Encoding=") != 0 )
+	    {
+		// fill xdg_extra
+		d_extra += line+"\\n";
+	    }
+	}
+
+      }
+//      cerr << __FUNCTION__ << " end while" << std::endl;
+
+      // skip wrong entries
+      if ( !have_section || !have_title )
+      {
+//	cerr << __FUNCTION__ << " !have_section || !have_title " << filename << std::endl;
+        pclose(desktop_file);
+        return 0;
+      }
+
+      // take needs
+      if( d_terminal.size() > 0 || d_onlyshowin.size() > 0 )
+      {
+	if( d_terminal == "1" || d_terminal == "true" )
+	  menu_line += " needs=\"text\"";
+	else if( d_onlyshowin.size() > 0 )
+	  menu_line += " needs=\""+d_onlyshowin+"\"";
+	else
+	  menu_line += " needs=\"X11\"";
+      }
+      else
+	menu_line += " needs=\"X11\"";
+
+      // take xdg_filename
+      {
+	int slash_pos = shortfilename.rfind("/");
+	if( slash_pos >= 0 )
+	  menu_line += " xdg_filename=\""+shortfilename.substr(slash_pos+1, shortfilename.size()-slash_pos-1)+"\"";
+	else
+	  menu_line += " xdg_filename=\""+shortfilename+"\"";
+      }
+
+      // add xdg_extra
+      if( d_extra.size() > 0 )
+        menu_line += " xdg_extra=\""+d_extra+"\"";
+
+      menudata.push_back(string("!F ") + filename + '\n');
+      menudata.push_back(menu_line + '\n');
+//      cerr << __FUNCTION__ << " add " << filename << std::endl;
+
+      pclose(desktop_file);
+      return 1;
+}
+
 /** Read a menufile and create one (or more) menu entries for it.
  *
  * Returns the number of menu entries read. */
@@ -591,6 +820,47 @@ void read_menufilesdir(vector<string> &m
   }
 }
 
+/** Read a XDG directory full of desktop files */
+void read_desktopfilesdir(vector<string> &menudata)
+{
+  int menuentries = 0;
+  for(vector<string>::const_iterator method_i = config.desktopfilesdir.begin();
+      method_i != config.desktopfilesdir.end();
+      ++method_i)
+  {
+    string dirname = *method_i;
+    config.report(String::compose(_("Reading menu-entry files in %1."), dirname),
+        configinfo::report_verbose);
+    try {
+      struct dirent *entry;
+      DIR *dir = open_dir_check(dirname);
+      while((entry = readdir(dir)))
+      {
+        string name = entry->d_name;
+        if ((name != "README") && (name != "core") && (name[0] != '.') &&
+            (name.find(".bak") == string::npos) &&
+            (name[name.length()-1] != '~'))
+
+            if (desktopfiles_processed.find(name) == desktopfiles_processed.end()) {
+              desktopfiles_processed.insert(name);
+              name = dirname+name;
+              struct stat st;
+              int r = stat(name.c_str(),&st);
+              try {
+                if ((!r) && (S_ISREG(st.st_mode)||S_ISLNK(st.st_mode)) && (st.st_size < 30720))
+                    menuentries += read_desktopfile(name,entry->d_name, menudata);
+              }
+              catch (endofline p) {
+                cerr << String::compose(_("Error reading %1.\n"), name);
+              }
+            }
+      }
+    } catch (dir_error_read p) { }
+    total_menuentries += menuentries;
+    config.report(String::compose(_("%1 menu entries found (%2 total)."), menuentries, total_menuentries), configinfo::report_verbose);
+  }
+}
+
 /** Run a menu method */
 void run_menumethod(string methodname, const vector<string> &menudata)
 {
@@ -1037,7 +1307,12 @@ int main (int argc, char **argv)
       config.menufilesdir.push_back(MENUMENUS);
     }
 
+    config.desktopfilesdir.push_back(XDGMENUS);
+    config.desktopfilesdir.push_back(XDGMENUS_KDE);
+    config.desktopfilesdir.push_back(XDGMENUS_GNOME);
+
     read_menufilesdir(menudata);
+    read_desktopfilesdir(menudata);
 
     if (config.onlyoutput_to_stdout) {
         for(vector<string>::const_iterator i = menudata.begin(); i != menudata.end(); ++i)
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin