diff options
Diffstat (limited to 'menu')
114 files changed, 5776 insertions, 0 deletions
diff --git a/menu/.cvsignore b/menu/.cvsignore new file mode 100644 index 0000000..f90eaaf --- /dev/null +++ b/menu/.cvsignore @@ -0,0 +1,11 @@ +config.log +config.status +config.sub +configure +Makefile +Makefile.in +aclocal.m4 +autom4te.cache +config.guess +config.h +config.h.in diff --git a/menu/AUTHORS b/menu/AUTHORS new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/menu/AUTHORS diff --git a/menu/COPYING b/menu/COPYING new file mode 100644 index 0000000..73e7995 --- /dev/null +++ b/menu/COPYING @@ -0,0 +1,2 @@ +FIXME - we need a license for specs + diff --git a/menu/ChangeLog b/menu/ChangeLog new file mode 100644 index 0000000..025e9e1 --- /dev/null +++ b/menu/ChangeLog @@ -0,0 +1,143 @@ +2009-01-10 Vincent Untz <vuntz@gnome.org> + + * menu-spec.xml: bump version to 1.1-draft + +2009-01-10 Vincent Untz <vuntz@gnome.org> + + * menu-spec.xml: add LXDE as registered desktop environment for + OnlyShowIn. + See http://lists.freedesktop.org/archives/xdg/2008-December/010103.html + +2007-08-18 Vincent Untz <vuntz@gnome.org> + + * menu-spec.xml: accept X-Foo for environments in + OnlyShowIn/NotShowIn. + Fix bug #11564. + +2007-07-27 Vincent Untz <vuntz@gnome.org> + + * menu-spec.xml: change sysconfdir/desktop/menus/ to sysconfdir/menus/ + in one place. + Fix bug #8289. + +2007-02-06 Waldo Bastian <waldo.bastian@intel.com> + * Added scondary menu categories + * Bumped version to 1.0 + +2007-01-18 Waldo Bastian <waldo.bastian@intel.com> + + * Added support for LSB's tet testing framework + + * Renamed test to more meaningful names: + 1 -> Category + 2 -> OnlyUnallocated + 3 -> Deleted + 4 -> Move + 5 -> All + 6 -> Filename + 7 -> And + 8 -> Or + 9 -> Exclude + a -> DesktopFileID + b -> menu-multiple-matching + c -> Directory + d -> submenu-collision + e -> LegacyDir-relative + f -> Move-collapsing + g -> AppDir-relative + h -> DirectoryDir-relative + i -> DefaultMergeDirs + j -> MergeDir-relative + k -> MergeFile-relative + l -> MergeFile2 + m -> NoDisplay + n -> NoDisplay2 + o -> boolean-logic + p -> MergeFile3 + q -> MergeFile-parent + r -> MergeFile-path + s -> desktop-name-collision + t -> Move-ordering + u -> MergeFile-recursive + v -> NotOnlyUnallocated-default + w -> LegacyDir-Move + x -> Move-submenu + y -> Merge-combined + + * Added the following new tests: + AppDir + DirectoryDir + MergeDir-absolute + MergeFile-absolute + official-categories + +2006-03-28 Waldo Bastian <waldo.bastian@intel.com> + + * menu-spec.xml: Added example for installing sub-menu. + +2006-03-21 Waldo Bastian <waldo.bastian@intel.com> + + * menu-spec.xml: Recommend to use /usr/share for datadir + +2005-03-30 Waldo Bastian <bastian@kde.org> + + * menu-spec.xml: Change semantics and remove restrictions on <Move> + element to facilitate menu editing. + +2005-03-23 Waldo Bastian <bastian@kde.org> + + * menu-spec.xml: Clearify DTD conformance and version compatibility + +2005-03-22 Waldo Bastian <bastian@kde.org> + + * menu-spec.xml, menu.dtd: Added type attribute to <MergeFile> + element to facilitate menu-editing. + +2005-02-24 Waldo Bastian <bastian@kde.org> + + * menu-spec.xml: Fixed links to www.freedesktop.org + +2004-12-13 Mark McLoughlin <mark@skynet.ie> + + * menu-spec.xml: elaboration from Waldo. + +2004-12-08 Mark McLoughlin <mark@skynet.ie> + + * menu-spec.xml: make <OnlyUnallocated/> be for entries + which don't match any <Include> rule rather than entries + which don't appear in any menu. + +2004-09-03 Mark McLoughlin <mark@skynet.ie> + + * menu-spec.xml: minor typo - "This specification adds two + new fields to desktop entries" - s/two/three/ + +2004-05-07 Mark McLoughlin <mark@skynet.ie> + + * menu-spec.xml: fix typo in <Menuname> description. Its + inline_header rather than inline_title according to the DTD. + +2004-04-18 Mark McLoughlin <mark@skynet.ie> + + Patch from Ville Skyttä <ville.skytta@iki.fi> + + * menu-spec.xml: editorial changes and typo fixes. + +2003-12-12 Waldo Bastian <bastian@kde.org> + * menu-spec.xml: Correct example in "Legacy Menu Hierarchies" + +2003-11-09 Heinrich Wendel <h_wendel@cojobo.net> + * menu-spec.xml: patch for categories based on Suse 9.0 + * menu-spec.xml: Grahpics -> Graphics + * menu-spec.xml: DTD fix + * menu.dtd: added dtd + * testsuite: fixed errors highlighted by havoc + +2003-10-23 Havoc Pennington <hp@redhat.com> + + * menu-spec.xml: clarify how <Move> elements are resolved + +2003-10-21 Havoc Pennington <hp@redhat.com> + + * create autotools setup + diff --git a/menu/Makefile.am b/menu/Makefile.am new file mode 100644 index 0000000..92448da --- /dev/null +++ b/menu/Makefile.am @@ -0,0 +1,16 @@ +HTML_FILES= menu-spec.html + +XML_FILES= menu-spec.xml + +EXTRA_DIST= $(HTML_FILES) $(XML_FILES) + +if XML_DOCS_ENABLED +all-local: $(HTML_FILES) +endif + +%.html: %.xml + $(XMLTO) html-nochunks $< + +maintainer-clean-local: + rm -f $(HTML_FILES) + diff --git a/menu/NEWS b/menu/NEWS new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/menu/NEWS diff --git a/menu/README b/menu/README new file mode 100644 index 0000000..0edf632 --- /dev/null +++ b/menu/README @@ -0,0 +1 @@ +This is the specification and test suite for the menu system. diff --git a/menu/autogen.sh b/menu/autogen.sh new file mode 100755 index 0000000..b1376df --- /dev/null +++ b/menu/autogen.sh @@ -0,0 +1,3 @@ +#! /bin/sh +autoreconf -v --install || exit 1 +./configure --enable-maintainer-mode "$@" diff --git a/menu/configure.in b/menu/configure.in new file mode 100644 index 0000000..7a5a76c --- /dev/null +++ b/menu/configure.in @@ -0,0 +1,61 @@ +dnl -*- mode: m4 -*- +AC_PREREQ(2.52) + +AC_INIT(menu-spec.xml) + +AM_INIT_AUTOMAKE(desktop-menu-spec, 0.7) + +# Honor aclocal flags +ACLOCAL="$ACLOCAL $ACLOCAL_FLAGS" + + ## must come before we use the $USE_MAINTAINER_MODE variable later +AM_MAINTAINER_MODE + +AC_ARG_ENABLE(xml-docs, [ --enable-xml-docs build XML into HTML (requires xmlto)],enable_xml_docs=$enableval,enable_xml_docs=auto) + +### XML tools + +AC_PATH_PROG(XMLTO, xmlto, no) + +AC_MSG_CHECKING([whether to build XML documentation]) + +if test x$XMLTO = xno ; then + have_xmlto=no +else + have_xmlto=yes +fi + +if test x$enable_xml_docs = xauto ; then + if test x$have_xmlto = xno ; then + enable_xml_docs=no + else + enable_xml_docs=yes + fi +fi + +if test x$enable_xml_docs = xyes; then + if test x$have_xmlto = xno; then + AC_MSG_ERROR([Building XML docs explicitly required, but xmlto not found]) + fi +fi + +AM_CONDITIONAL(XML_DOCS_ENABLED, test x$enable_xml_docs = xyes) +AC_MSG_RESULT(yes) + +AC_OUTPUT([ +Makefile +]) + +dnl ========================================================================== +echo " + Menu specification $VERSION + ============== + + prefix: ${prefix} + source code location: ${srcdir} + xmlto: ${XMLTO}" + +echo " + Maintainer mode: ${USE_MAINTAINER_MODE} + Building XML docs: ${enable_xml_docs} +" diff --git a/menu/menu-spec.xml b/menu/menu-spec.xml new file mode 100644 index 0000000..28c0097 --- /dev/null +++ b/menu/menu-spec.xml @@ -0,0 +1,2383 @@ +<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" + "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [ + <!ENTITY version "1.1-draft"> + <!ENTITY dtd-version "1.0"> + ]> + +<article id="index"> + <articleinfo> + <title>Desktop Menu Specification</title> + <releaseinfo>Version &version;</releaseinfo> + <date>31 March 2011</date> + <authorgroup> + <author> + <firstname>Waldo</firstname> + <surname>Bastian</surname> + <affiliation> + <address> + <email>waldo.bastian@intel.com</email> + </address> + </affiliation> + </author> + <author> + <firstname>Francois</firstname> + <surname>Gouget</surname> + <affiliation> + <address> + <email>fgouget@codeweavers.com</email> + </address> + </affiliation> + </author> + <author> + <firstname>Alex</firstname> + <surname>Graveley</surname> + <affiliation> + <address> + <email>alex@ximian.com</email> + </address> + </affiliation> + </author> + <author> + <firstname>George</firstname> + <surname>Lebl</surname> + <affiliation> + <address> + <email>jirka@5z.com</email> + </address> + </affiliation> + </author> + <author> + <firstname>Havoc</firstname> + <surname>Pennington</surname> + <affiliation> + <address> + <email>hp@pobox.com</email> + </address> + </affiliation> + </author> + <author> + <firstname>Heinrich</firstname> + <surname>Wendel</surname> + <affiliation> + <address> + <email>h_wendel@cojobo.net</email> + </address> + </affiliation> + </author> + </authorgroup> + </articleinfo> + + <sect1 id="introduction"> + <title>Introduction</title> + <para> + This document defines how to construct a user-visible hierarchy of + applications, typically displayed as a menu. It allows third-party + software to add menu items that work for all desktops, and allows system + administrators to edit menus in a way that affects all desktops. + </para> + <para> + The basic scheme is very simple. Information about each application (menu + item) is stored in a desktop entry (see <ulink + url="http://www.freedesktop.org/Standards/desktop-entry-spec">Desktop + Entry Standard</ulink>). Then an XML configuration file defines the + hierarchical arrangement (layout) of menu items, and which menu items are + actually displayed. + </para> + <para> + Things are complicated somewhat by the need to support legacy desktop + entry hierarchies, and the need to allow third parties to extend the menu + layout. Both of these issues are addressed by the idea of + <firstterm>merging</firstterm> two menu layouts. + </para> + <para> + In addition to a strict definition of the contents of each menu this + specification also foresees in a number of layout / presentation hints. + This part of the specification is optional, implementations may chose to + ignore these hints. + </para> + </sect1> + <sect1 id="paths"> + <title>File locations</title> + <para> + Files involved in this specification are located according to the <ulink + url="http://www.freedesktop.org/Standards/basedir-spec">"desktop + base directory specification"</ulink>. + </para> + <para> + Here are the files defined by this specification: + <variablelist> + <varlistentry> + +<term><varname>$XDG_CONFIG_DIRS</varname>/menus/<varname>${XDG_MENU_PREFIX}</varname>applications.menu</term> + <listitem> + <para> + This file contains the XML definition of the main application + menu layout. The first file found in the search path should be + used; other files are ignored. This implies that if the user + has their own <varname>${XDG_MENU_PREFIX}</varname>applications.menu, + it replaces the system wide one. + (Though the user's menu may explicitly merge the system wide + one.) + </para> + <para> + Systems that offer multiple desktop environments and that want + to use distinct menu layouts in the different environments can + use differently prefixed .menu files. In this case the + <varname>$XDG_MENU_PREFIX</varname> environment variable must + be set by the system to reflect the .menu file that is being + used. + </para> + <para> + For example if a system contains both the GNOME and the KDE + desktop environments it can decide to use + gnome-applications.menu as the menu layout in GNOME sessions + and kde-applications.menu as the menu layout in KDE sessions. + To correctly reflect this, it should set the + <varname>$XDG_MENU_PREFIX</varname> environment variable to + "gnome-" respectively "kde-". + </para> + <para> + Implementations may chose to use .menu files with other names + for tasks or menus other than the main application menu. Such + usage is not covered by this specification. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><varname>$XDG_CONFIG_DIRS</varname>/menus/applications-merged/</term> + <listitem> + <para> + The default merge directories included in the + <DefaultMergeDirs> element. By convention, third parties + may add new <Menu> files in this location to create their + own sub-menus. + </para> + <para> + Note that a system that uses either gnome-applications.menu or + kde-applications.menu depending on the desktop environment in + use must still use applications-merged as the default merge + directory in both cases. + </para> + <para> + Implementations may chose to use .menu files with names other + than application.menu for tasks or menus other than the main + application menu. In that case the first part of the name of + the default merge directory is derived from the name of the + .menu file. + </para> + <para> + For example in a system that uses a preferences.menu file to + describe an additional menu, the default merge directories + included in the <DefaultMergeDirs> element in the + preferences.menu file would become + <varname>$XDG_CONFIG_DIRS</varname>/menus/preferences-merged/ + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><varname>$XDG_DATA_DIRS</varname>/applications/</term> + <listitem> + <para> + This directory contains a .desktop file for each possible menu + item. Each directory in the <varname>$XDG_DATA_DIRS</varname> + search path should be used (i.e. desktop entries are collected + from all of them, not just the first one that exists). When two + desktop entries have the same name, the one appearing earlier in + the path is used. + </para> + <para> + The <DefaultAppDirs> element in a menu file indicates that + this default list of desktop entry locations should be scanned at + that point. If a menu file does not contain + <DefaultAppDirs>, then these locations are not scanned. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><varname>$XDG_DATA_DIRS</varname>/desktop-directories/</term> + <listitem> + <para> + This directory contains directory entries which may be associated + with folders in the menu layout. Each directory + in the search path should be used. Only files ending in + .directory are used; other files are ignored. + </para> + <para> + The <DefaultDirectoryDirs> element in a menu file indicates that + this default list of directory entry locations should be scanned at + that point. If a menu file does not contain + <DefaultDirectoryDirs>, then these locations are not scanned. + </para> + </listitem> + </varlistentry> + </variablelist> + </para> + </sect1> + <sect1 id="desktop-entry-extensions"> + <title>Extensions to the desktop entry format</title> + <para> + This specification adds three new fields to <ulink + url="http://www.freedesktop.org/Standards/desktop-entry-spec">desktop + entries</ulink>: <varname>Categories</varname>, + <varname>OnlyShowIn</varname> and <varname>NotShowIn</varname>. + </para> + <para> + The <varname>Categories</varname> field is a list of strings used to + classify menu items. For example, applications in the + <literal>AudioVideo</literal> category might end up in the + "Sound & Video" submenu. <xref linkend="category-registry"/> + enumerates the standard categories. Categories not in this document + must be prefixed by the string "X-" indicating that they are extensions. + Categories are case-sensitive. + </para> + <para> + Desktop entries should list all categories that clearly apply. They should + not list categories that only vaguely or possibly apply, because the user + will end up seeing the same desktop entry in a half-dozen places. But + it's typical that several categories will apply to a given desktop entry. + </para> + <para> + The <varname>OnlyShowIn</varname> field is a list of strings identifying + the environments that should display a given menu item. If an + <varname>OnlyShowIn</varname> field is present, a given environment should + only display the menu item if the string identifying that environment is + present. The strings are case-sensitive. <xref + linkend="onlyshowin-registry"/> enumerates the strings to use for + some common environments. + </para> + <para> + The <varname>NotShowIn</varname> field is a list of strings identifying + the environments that should not display a given menu item. If an + <varname>NotShowIn</varname> field is present, a given environment should + only display the menu item if the string identifying that environment is + not present. The strings are case-sensitive. <xref + linkend="onlyshowin-registry"/> enumerates the strings to use for + some common environments. + </para> + <para> + Environments not in this document must be prefixed by the string "X-" + indicating that they are extensions. Environments are case-sensitive. + </para> + <sect2 id="desktop-entry-extensions-examples"> + <title>Examples of using <varname>Categories</varname> and <varname>OnlyShowIn</varname></title> + <para> + A desktop entry for a Qt-based image viewer might contain + this <varname>Categories</varname> line: + <informalexample> + <programlisting> + Categories=Qt;Graphics;RasterGraphics;Viewer; + </programlisting> + </informalexample> + </para> + <para> + A desktop entry for Octave, a command-line mathematics program (which + would also have the field <literal>Terminal=true</literal>), might have: + <informalexample> + <programlisting> + Categories=ConsoleOnly;Math; + </programlisting> + </informalexample> + </para> + <para> + A desktop entry for a GNOME-specific calculator program + that should only appear in GNOME might have: + <informalexample> + <programlisting> + Categories=GNOME;Utility; + OnlyShowIn=GNOME; + </programlisting> + </informalexample> + Note that the <varname>OnlyShowIn</varname> field is a + <emphasis>list</emphasis> and thus ends in a semicolon. + </para> + </sect2> + </sect1> + <sect1 id="menu-file-format"> + <title>Format of menu files</title> + <para> + Menu files must be well-formed XML files and end in the extension + ".menu". They should also conform to the menu file DTD which implies + that implementation-specific extensions to the file format are not + allowed. Implementations may stop processing if they encounter a menu + file which does not comply with the associated DTD. Note that the + associated DTD may differ in version from the one defined in this document. + </para> + <para> + When an implementation updates an existing menu file it may need to + update the identifier to a newer version of the DTD. Implementations + should never update the identifier of an existing menu file to an + older version. In order to remain compatible with newer versions, + implementations should ignore and preserve any XML elements, + attributes and attribute values that it does not know how to handle. + </para> + <sect2 id="menu-file-doctype"> + <title>Document Type Declaration</title> + <para> + Menu files for this version of the specification must use the following + namespace, public and system identifiers: + <variablelist> + <varlistentry> + <term>Namespace</term> + <listitem> + <para> + <literal>http://www.freedesktop.org/standards/menu</literal> + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>Public Identifier for &version;</term> + <listitem> + <para> + <literal>PUBLIC "-//freedesktop//DTD Menu &dtd-version;//EN"</literal> + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>System Identifier for &version;</term> + <listitem> + <para> +<literal>http://www.freedesktop.org/standards/menu-spec/menu-&dtd-version;.dtd</literal> + </para> + </listitem> + </varlistentry> + </variablelist> + + Here is a sample document type declaration: + <informalexample> + <programlisting> + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu &dtd-version;//EN" + "http://www.freedesktop.org/standards/menu-spec/menu-&dtd-version;.dtd"> + </programlisting> + </informalexample> + + All menu files MUST include the document type declaration, so that + implementations can adapt to different versions of this specification + (and so implementations can validate the menu file against + the DTD). + </para> + </sect2> + <sect2 id="menu-file-elements"> + <title>Elements</title> + <para> + <variablelist> + <varlistentry> + <term><Menu></term> + <listitem> + <para> + The root element is <Menu>. Each <Menu> element may + contain any number of nested <Menu> elements, indicating submenus. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><AppDir></term> + <listitem> + <para> + This element may only appear below <Menu>. The + content of this element is a directory name. Desktop entries + in this directory are scanned and added to the pool of entries + which can be included in this <Menu> and its submenus. + Only files ending in ".desktop" should be used, other files are + ignored. + </para> + <para> + Desktop entries in the pool of available entries are identified + by their <firstterm>desktop-file id</firstterm> (see <xref + linkend="term-desktop-file-id"/>). + The desktop-file id of a desktop entry is equal to its filename, + with any path components removed. + So given a <AppDir> + <filename>/foo/bar</filename> and desktop entry + <filename>/foo/bar/Hello.desktop</filename> the desktop + entry would get a desktop-file id of <filename>Hello.desktop</filename> + </para> + <para> + If the directory contains sub-directories then these sub-directories + should be (recursively) scanned as well. The name of the subdirectory + should be added as prefix to the desktop-file id together with a dash character ("-") + So given a <AppDir> + <filename>/foo/bar</filename> and desktop entry + <filename>/foo/bar/booz/Hello.desktop</filename> the desktop + entry would get a desktop-file id of <filename>booz-Hello.desktop</filename> + A desktop entry <filename>/foo/bar/bo/oz/Hello.desktop</filename> would result + in a desktop-file id of <filename>bo-oz-Hello.desktop</filename> + </para> + <para> + <AppDir> elements appearing later in the menu file have + priority in case of collisions between desktop-file ids. + </para> + <para> + If the filename given as an <AppDir> is not an absolute + path, it should be located relative to the location of the menu + file being parsed. + </para> + <para> + Duplicate <AppDir> elements (that specify the same + directory) should be ignored, but the <emphasis>last</emphasis> + duplicate in the file should be used when establishing the order + in which to scan the directories. This is important when merging + (see <xref linkend="merge-algorithm"/>). The order of + <AppDir> elements with respect to <Include> and + <Exclude> elements is not relevant, also to facilitate + merging. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><DefaultAppDirs></term> + <listitem> + <para> + This element may only appear below <Menu>. The element has + no content. The element should be treated as if it were a list + of <AppDir> elements containing the default app dir + locations + (<replaceable>datadir</replaceable>/applications/ etc.). When expanding + <DefaultAppDirs> to a list of <AppDir>, the default + locations that are earlier in the search path go later in the + <Menu> so that they have priority. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><DirectoryDir></term> + <listitem> + <para> + This element may only appear below <Menu>. The content of + this element is a directory name. Each directory listed in a + <DirectoryDir> element will be searched for directory + entries to be used when resolving the <Directory> element + for this menu and its submenus. + If the filename given as a <DirectoryDir> is not an absolute path, + it should be located relative to the location + of the menu file being parsed. + </para> + <para> + Directory entries in the pool of available entries are identified + by their <firstterm>relative path</firstterm> (see <xref + linkend="term-relative-path"/>). + </para> + <para> + If two directory entries have duplicate relative paths, the one from + the last (furthest down) element in the menu file must be used. + Only files ending in the extension ".directory" should be + loaded, other files should be ignored. + </para> + <para> + Duplicate <DirectoryDir> elements (that specify the same + directory) are handled as with duplicate <AppDir> + elements (the last duplicate is used). + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><DefaultDirectoryDirs></term> + <listitem> + <para> + This element may only appear below <Menu>. The element has + no content. The element should be treated as if it were a list + of <DirectoryDir> elements containing the default desktop dir + locations + (<replaceable>datadir</replaceable>/desktop-directories/ etc.). The default + locations that are earlier in the search path go later in the + <Menu> so that they have priority. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><Name></term> + <listitem> + <para> + Each <Menu> element must have a single <Name> + element. The content of the <Name> element is a name to + be used when referring to the given menu. Each submenu of a + given <Menu> must have a unique name. <Menu> + elements can thus be referenced by a menu path, for example + "Applications/Graphics." The <Name> field must not contain + the slash character ("/"); implementations should discard + any name containing a slash. See also <xref linkend="term-menu-path"/>. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><Directory></term> + <listitem> + <para> + Each <Menu> element has any number of <Directory> + elements. The content of the <Directory> element + is the relative path of a directory entry containing meta information + about the <Menu>, such as its icon and localized name. + If no <Directory> is specified for a <Menu>, + its <Name> field should be used as the user-visible + name of the menu. + </para> + <para> + Duplicate <Directory> elements are allowed in order + to simplify menu merging, and allow user menus to override + system menus. The last <Directory> element to appear + in the menu file "wins" and other elements are ignored, + unless the last element points to a nonexistent directory + entry, in which case the previous element should be tried instead, + and so on. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><OnlyUnallocated> and <NotOnlyUnallocated></term> + <listitem> + <para> + Each <Menu> may contain any number of + <OnlyUnallocated> and <NotOnlyUnallocated> + elements. Only the last such element to appear is relevant, as + it determines whether the <Menu> can contain any desktop + entries, or only those desktop entries that do not match other + menus. If neither <OnlyUnallocated> nor + <NotOnlyUnallocated> elements are present, the default + is <NotOnlyUnallocated>. + </para> + <para> + To handle <OnlyUnallocated>, the menu file must be + analyzed in two conceptual passes. The first pass processes + <Menu> elements that can match any desktop entry. During + this pass, each desktop entry is marked as allocated according + to whether it was matched by an <Include> rule in some + <Menu>. The second pass processes only <Menu> + elements that are restricted to unallocated desktop entries. + During the second pass, queries may only match desktop entries + that were not marked as allocated during the first pass. + See <xref linkend="query-algorithm"/>. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><Deleted> and <NotDeleted></term> + <listitem> + <para> + Each <Menu> may contain any number of <Deleted> and + <NotDeleted> elements. Only the last such element to + appear is relevant, as it determines whether the <Menu> + has been deleted. If neither <Deleted> nor + <NotDeleted> elements are present, the default is + <NotDeleted>. The purpose of this element is to support + menu editing. If a menu contains a <Deleted> element + not followed by a <NotDeleted> element, that menu + should be ignored. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><Include></term> + <listitem> + <para> + An <Include> element is a set of rules attempting to match + some of the known desktop entries. The <Include> element + contains a list of any number of matching rules. Matching rules + are specified using the elements <And>, <Or>, + <Not>, <All>, <Filename>, and + <Category>. Each rule in a list of rules has a logical OR + relationship, that is, desktop entries which match any rule + are included in the menu. + </para> + <para> + <Include> elements must appear immediately under + <Menu> elements. The desktop entries they match are + included in the menu. <Include> and <Exclude> + elements for a given <Menu> are processed in order, + with queries earlier in the file handled first. This has + implications for merging, see <xref linkend="merge-algorithm"/>. + See <xref linkend="query-algorithm"/> for full details on + how to process <Include> and <Exclude> elements. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><Exclude></term> + <listitem> + <para> + Any number of <Exclude> elements may appear below a + <Menu> element. The content of an <Exclude> element + is a list of matching rules, just as with an + <Include>. However, the desktop entries matched are + removed from the list of desktop entries included so far. (Thus + an <Exclude> element that appears before any + <Include> elements will have no effect, for example, as no + desktop entries have been included yet.) + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><Filename></term> + <listitem> + <para> + The <Filename> element is the most basic matching rule. + It matches a desktop entry if the desktop entry has the given + desktop-file id. See <xref linkend="term-desktop-file-id"/>. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><Category></term> + <listitem> + <para> + The <Category> element is another basic matching + predicate. It matches a desktop entry if the desktop entry has + the given category in its <varname>Categories</varname> field. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><All></term> + <listitem> + <para> + The <All> element is a matching rule that matches + all desktop entries. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><And></term> + <listitem> + <para> + The <And> element contains a list of matching rules. + If each of the matching rules inside the <And> + element match a desktop entry, then the entire + <And> rule matches the desktop entry. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><Or></term> + <listitem> + <para> + The <Or> element contains a list of matching rules. + If any of the matching rules inside the <Or> + element match a desktop entry, then the entire + <Or> rule matches the desktop entry. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><Not></term> + <listitem> + <para> + The <Not> element contains a list of matching rules. If + any of the matching rules inside the <Not> element matches + a desktop entry, then the entire <Not> rule does + <emphasis>not</emphasis> match the desktop entry. That is, + matching rules below <Not> have a logical OR relationship. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><MergeFile [type="path"|"parent"] ></term> + <listitem> + <para> + Any number of <MergeFile> elements may be listed below a + <Menu> element, giving the name of another menu file to + be merged into this one. <xref linkend="merge-algorithm"/> + specifies how merging is done. The root <Menu> of the + merged file will be merged into the immediate parent of the + <MergeFile> element. The <Name> element of the + root <Menu> of the merged file are ignored. + </para> + <para> + If the type attribute is missing or set to "path" then the + contents of the <MergeFile> element indicates the + file to be merged. If this is not an absolute path then the + file to be merged should be located relative to the location + of the menu file that contains this <MergeFile> element. + </para> + <para> + Duplicate <MergeFile> elements (that specify the same + file) are handled as with duplicate <AppDir> + elements (the last duplicate is used). + </para> + <para> + If the type attribute is set to "parent" and the file that + contains this <MergeFile> element is located under one + of the paths specified by <varname>$XDG_CONFIG_DIRS</varname>, + the contents of the element should be ignored and the remaining + paths specified by <varname>$XDG_CONFIG_DIRS</varname> are + searched for a file with the same relative filename. The first + file encountered should be merged. There should be no + merging at all if no matching file is found. + </para> + <para> + Compatibility note: The filename specified inside the <MergeFile> + element should be ignored if the type attribute is set to "parent", + it should however be expected that implementations based on + previous versions of this specification will ignore the + type attribute and that such implementations will use the + filename inside the <MergeFile> element instead. + </para> + <para> + Example 1: If <varname>$XDG_CONFIG_HOME</varname> is "~/.config/" and + <varname>$XDG_CONFIG_DIRS</varname> is "/opt/gnome/:/etc/xdg/" + and the file ~/.config/menus/applications.menu contains + <MergeFile type="parent">/opt/kde3/etc/xdg/menus/applications.menu</MergeFile> + then the file /opt/gnome/menus/applications.menu + should be merged if it exists. If that file does not exists + then the file /etc/xdg/menus/applications.menu + should be merged instead. + </para> + <para> + Example 2: If <varname>$XDG_CONFIG_HOME</varname> is "~/.config/" and + <varname>$XDG_CONFIG_DIRS</varname> is "/opt/gnome/:/etc/xdg/" + and the file /opt/gnome/menus/applications.menu contains + <MergeFile type="parent">/opt/kde3/etc/xdg/menus/applications.menu</MergeFile> + then the file /etc/xdg/menus/applications.menu should be merged + if it exists. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><MergeDir></term> + <listitem> + <para> + Any number of <MergeDir> elements may be listed below a + <Menu> element. A <MergeDir> contains the name of a + directory. Each file in the given directory which ends in the + ".menu" extension should be merged in the same way that a + <MergeFile> would be. If the filename given as a + <MergeDir> is not an absolute path, it should be located + relative to the location of the menu file being parsed. + The files inside the merged directory are not merged in any + specified order. + </para> + <para> + Duplicate <MergeDir> elements (that specify the same + directory) are handled as with duplicate <AppDir> + elements (the last duplicate is used). + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><DefaultMergeDirs></term> + <listitem> + <para> + This element may only appear below <Menu>. The element has + no content. The element should be treated as if it were a list + of <MergeDir> elements containing the default merge + directory locations. When expanding <DefaultMergeDirs> to a + list of <MergeDir>, the default locations that are earlier + in the search path go later in the <Menu> so that they + have priority. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><LegacyDir></term> + <listitem> + <para> + This element may only appear below <Menu>. The text + content of this element is a directory name. Each directory + listed in a <LegacyDir> element will be an old-style + legacy hierarchy of desktop entries, see <xref + linkend="legacy-hierarchies"/> for how to load such a + hierarchy. Implementations must not load legacy hierarchies that + are not explicitly specified in the menu file (because for + example the menu file may not be the main menu). If the + filename given as a <LegacyDir> is not an absolute path, + it should be located relative to the location of the menu file + being parsed. + </para> + <para> + Duplicate <LegacyDir> elements (that specify the same + directory) are handled as with duplicate <AppDir> + elements (the last duplicate is used). + </para> + <para> + The <LegacyDir> element may have one attribute, + <literal>prefix</literal>. Normally, given a <LegacyDir> + <filename>/foo/bar</filename> and desktop entry + <filename>/foo/bar/baz/Hello.desktop</filename> the desktop + entry would get a desktop-file id of <filename>Hello.desktop</filename>. + Given a prefix of <literal>boo-</literal>, it would instead be + assigned the desktop-file id <filename>boo-Hello.desktop</filename>. + The prefix should not contain path separator ('/') characters. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><KDELegacyDirs></term> + <listitem> + <para> + This element may only appear below <Menu>. The element has + no content. The element should be treated as if it were a list + of <LegacyDir> elements containing the traditional desktop + file locations supported by KDE with a hard coded prefix of "kde-". + When expanding <KDELegacyDirs> to a list of <LegacyDir>, the + locations that are earlier in the search path go later in the + <Menu> so that they have priority. + The search path can be obtained by running <filename>kde-config --path apps</filename> + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><Move></term> + <listitem> + <para> + This element may only appear below <Menu>. The + <Move> element contains pairs of <Old>/<New> + elements indicating how to rename a descendant of the current + <Menu>. If the destination path already exists, the moved + menu is merged with the destination menu (see <xref + linkend="merge-algorithm"/> for details). + </para> + <para> + <Move> is used primarily to fix up legacy directories. + For example, say you are merging a <LegacyDir> with folder + names that don't match the current hierarchy; the legacy folder + names can be moved to the new names, where they will be merged + with the new folders. + </para> + <para> + <Move> is also useful for implementing menu + editing, see <xref linkend="menu-editing"/>. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><Old></term> + <listitem> + <para> + This element may only appear below <Move>, and + must be followed by a <New> element. The content of both + <Old> and <New> should be a menu path + (slash-separated concatenation of <Name> fields, see + <xref linkend="term-menu-path"/>). + Paths are interpreted relative to the menu containing + the <Move> element. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><New></term> + <listitem> + <para> + This element may only appear below <Move>, and must + be preceded by an <Old> element. The <New> element + specifies the new path for the preceding <Old> element. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><Layout></term> + <listitem> + <para> + The <Layout> element is an optional part of this specification. + Implementations that do not support the <Layout> element should + preserve any <Layout> elements and their contents as far as + possible. + Each <Menu> may optionally contain a <Layout> element. + If multiple elements appear then only the last such element is relevant. + The purpose of this element is to offer suggestions for the presentation + of the menu. + If a menu does not contain a <Layout> element or if it contains + an empty <Layout> element then the default layout should be used. + The <Layout> element may contain <Filename>, <Menuname>, + <Separator> and <Merge> elements. The <Layout> element + defines a suggested layout for the menu starting from top to bottom. + References to desktop entries that are not contained in this + menu as defined by the <Include> and <Exclude> elements should + be ignored. References to sub-menus that are not directly contained in this + menu as defined by the <Menu> elements should be ignored. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><DefaultLayout [show_empty="false"] [inline="false"] [inline_limit="4"] [inline_header="true"] [inline_alias="false"]></term> + <listitem> + <para> + The <DefaultLayout> element is an optional part of this specification. + Implementations that do not support the <DefaultLayout> element should + preserve any <DefaultLayout> elements and their contents as far as + possible. + Each <Menu> may optionally contain a <DefaultLayout> element + which defines the default-layout for the current menu and all its sub-menus. + If a menu has a <DefaultLayout> element then this will override + any default-layout specified by a parent menu. + The default-layout defines the suggested layout if a <Menu> element + does either not have <Layout> element or if it has an empty <Layout> element. + For explanations of the various attributes see the <Menuname> element. + If no default-layout has been specified then the layout as specified by the following + elements should be assumed: + <DefaultLayout show_empty="false" inline="false" inline_limit="4" inline_header="true" inline_alias="false"><Merge type="menus"/><Merge type="files"/></DefaultLayout> + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><Menuname [show_empty="..."] [inline="..."] [inline_limit="..."] [inline_header="..."] [inline_alias="..."]></term> + <listitem> + <para> + This element may only appear as a child of a <Layout> or <DefaultLayout> + menu. Its contents references an immediate sub-menu of the current menu as defined + with the <Menu> element, as such it should never contain a slash. + If no such sub-menu exists the element should be ignored. + This element may have various attributes, the default values are taken from the DefaultLayout key. + The show_empty attribute defines whether a menu that contains no desktop + entries and no sub-menus should be shown at all. The show_empty attribute + can be "true" or "false". + It may have an inline attribute that can be either "true" or "false". + If the inline attribute is "true" the menu that is referenced may be copied into the + current menu at the current point instead of being inserted as sub-menu of the current menu. + The optional inline_limit attribute defines the maximum number of entries that can be inlined. + If the sub-menu has more entries than inline_limit, the sub-menu will not be inlined. + If the inline_limit is 0 (zero) there is no limit. + The optional inline_header attribute defines whether an inlined menu should be preceded with + a header entry listing the caption of the sub-menu. + The inline_header attribute can be either "true" or "false". + The optional inline_alias attribute defines whether a single inlined entry should adopt the + caption of the inlined menu. In such case no additional header entry will be added regardless + of the value of the inline_header attribute. + The inline_alias attribute can be either "true" or "false". + Example: if a menu has a sub-menu titled "WordProcessor" with a single entry "OpenOffice 4.2", + and both inline="true" and inline_alias="true" are specified then this would result in the + "OpenOffice 4.2" entry being inlined in the current menu but the "OpenOffice 4.2" caption + of the entry would be replaced with "WordProcessor". + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><Separator></term> + <listitem> + <para> + This element may only appear as a child of a <Layout> or <DefaultLayout> + menu. It indicates a suggestion to draw a visual separator at this point in the menu. + <Separator> elements at the start of a menu, at the end of a menu or that directly + follow other <Separator> elements may be ignored. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><Merge type="menus"|"files"|"all"/></term> + <listitem> + <para> + This element may only appear as a child of a <Layout> or <DefaultLayout> + menu. It indicates the point where desktop entries and sub-menus that are not explicitly + mentioned within the <Layout> or <DefaultLayout> element are to be inserted. + It has a type attribute that indicates which elements should be inserted: + type="menus" + means that all sub-menus that are not explicitly mentioned should be inserted in + alphabetical order of their visual caption at this point. + type="files" + means that all desktop entries + contained in this menu that are not explicitly mentioned should be inserted in + alphabetical order of their visual caption at this point. + type="all" means that a mix of all sub-menus + and all desktop entries that are not explicitly mentioned should be inserted in + alphabetical order of their visual caption at this point. + Each <Layout> or <DefaultLayout> element shall have exactly one <Merge type="all"> + element or it shall have exactly one <Merge type="files"> and exactly one + <Merge type="menus"> element. An exception is made for a completely empty <Layout> + element which may be used to indicate that the default-layout should be used instead. + </para> + </listitem> + </varlistentry> + </variablelist> + </para> + </sect2> + </sect1> + + <sect1 id="merge-algorithm"> + <title>Merging</title> + <para> + Sometimes two menu layouts need to be merged. This is done when folding in + legacy menu hierarchies (see <xref linkend="legacy-hierarchies"/>) and also + for files specified in <MergeFile> elements. A common case is that + per-user menu files might merge the system menu file. Merging is also used + to avoid cut-and-paste, for example to include a common submenu in + multiple menu files. + </para> + <para> + Merging involves a base <Menu> and a merged <Menu>. The base + is the "target" menu and the merged <Menu> is being added to it. The + result of the merge is termed the "combined menu." + </para> + <para> + As a preparatory step, the goal is to resolve all files into + XML elements. To do so, traverse the entire menu tree. For each + <MergeFile>, <MergeDir>, or <LegacyDir> element, replace + the <MergeFile>, <MergeDir>, or <LegacyDir> element with + the child elements of the root <Menu> of the file(s) being + merged. As a special exception, remove the <Name> element from the + root element of each file being merged. To generate a + <Menu> based on a <LegacyDir>, see + <xref linkend="legacy-hierarchies"/>. + </para> + <para> + Continue processing until no <MergeFile>, <MergeDir>, or + <LegacyDir> elements remain, taking care to avoid infinite loops + caused by files that reference one another. + </para> + <para> + Once all files have been loaded into a single tree, scan the tree + recursively performing these steps to remove duplicates: + <orderedlist> + <listitem> + <para> + Consolidate child menus. Each group of child <Menu>s with the same + name must be consolidated into a single child menu with that name. + Concatenate the child elements of all menus with the same name, in + the order that they appear, and insert those elements as the + children of the <emphasis>last</emphasis> menu with that name. + Delete all the newly empty <Menu> elements, keeping the + last one. + </para> + </listitem> + <listitem> + <para> + Expand <DefaultAppDirs> and <DefaultDirectoryDirs> + elements to <AppDir> and <DirectoryDir> elements. + Consolidate duplicate <AppDir>, <DirectoryDir>, + and <Directory> elements by keeping the last one. + For <Directory> elements that refer to distinct directory + entries, all of them should be kept - if the last one points + to a nonexistent file, the one before that can be used instead, + and so forth. + </para> + </listitem> + <listitem> + <para> + Recurse into each child <Menu>, performing this list of + steps for each child in order. + </para> + </listitem> + </orderedlist> + </para> + <para> + After recursing once to remove duplicates, recurse a second time to + resolve <Move> elements for each menu starting with any child + menu before handling the more top level menus. + So the deepest menus have their <Move> operations performed first. + Within each <Menu>, execute <Move> operations in the order + that they appear. If the destination path does not exist, simply relocate + the origin <Menu> element, and change its <Name> field to + match the destination path. If the origin path does not exist, do + nothing. If both paths exist, take the origin <Menu> element, + delete its <Name> element, and prepend its remaining child elements + to the destination <Menu> element. + </para> + <para> + If any <Move> operations affect a menu, then re-run the + steps to resolve duplicates in case any duplicates have been + created. + </para> + <para> + Finally, for each <Menu> containing a <Deleted> element which + is not followed by a <NotDeleted> element, remove that menu and all + its child menus. + </para> + + <para> + Merged menu elements are kept in order because <Include> and + <Exclude> elements later in the file override <Include> and + <Exclude> elements earlier in the file. This means that if the user's + menu file merges the system menu file, the user can always override what + the system menu specifies by placing elements after the <MergeFile> + that incorporates the system file. + </para> + <para> + To prevent that a desktop entry from one party inadvertently cancels out + the desktop entry from another party because both happen to get the same + desktop-file id it is recommended that providers of desktop-files ensure that + all desktop-file ids start with a vendor prefix. A vendor prefix + consists of [a-zA-Z] and is terminated with a dash ("-"). Open Source + projects and commercial parties are encouraged to use a word or phrase, + preferably their name, as prefix for which they hold a trademark. Open Source + applications can also ask to make use of the vendor prefix of another open + source project (such as GNOME or KDE) they consider themselves affiliated + with, at the discretion of these projects. + </para> + <para> + For example, to ensure that GNOME applications start with a vendor prefix of "gnome-", + it could either add "gnome-" to all the desktop files it installs in + <filename><replaceable>datadir</replaceable>/applications/</filename> or it could + install desktop files in a <filename><replaceable>datadir</replaceable>/applications/gnome</filename> + subdirectory. When including legacy menu hierarchies the <literal>prefix</literal> argument + of the <LegacyDir> element can be used to specify a prefix. + </para> + </sect1> + + <sect1 id="query-algorithm"> + <title>Generating the menus</title> + <para> + After merging the menus, the result should be a single menu layout + description. For each <Menu>, we have a list of directories where + desktop entries can be found, a list of directories where directory + entries can be found, and a series of <Include> and <Exclude> + directives. + </para> + <para> + For each <Menu> element, build a pool of desktop entries by + collecting entries found in each <AppDir> for the menu element. If + two entries have the same desktop-file id, the entry for the earlier (closer + to the top of the file) <AppDir> must be discarded. Next, add to the + pool the entries for any <AppDir>s specified by ancestor + <Menu> elements. If a parent menu has a duplicate entry (same + desktop-file id), the entry for the child menu has priority. + </para> + <para> + Next, walk through all <Include> and <Exclude> statements. + For each <Include>, match the rules against the pool of all desktop + entries. For each desktop entry that matches one of the rules, + add it to the menu to be displayed and mark it as having been allocated. + For each <Exclude>, match the rules against the currently-included + desktop entries. For each desktop entry that matches, remove it again + from the menu. Note that an entry that is included in a menu but excluded + again by a later <Exclude> is still considered allocated (for the + purposes of <OnlyUnallocated>) even though that entry no longer + appears in the menu. + </para> + <para> + Two passes are necessary, once for regular menus where any entry may + be matched, and once for <OnlyUnallocated> menus where only entries + which have not been marked as allocated may be matched. + </para> + <para> + The result is a tree of desktop entries, of course. + </para> + </sect1> + + <sect1 id="legacy-hierarchies"> + <title>Legacy Menu Hierarchies</title> + <para> + Traditionally, menus were defined as a filesystem hierarchy, with each + filesystem directory corresponding to a submenu. Implementations of this + specification must be able to load these old-style hierarchies + as specified in this section. + </para> + <para> + The general approach is: the legacy hierarchy is converted into a + <Menu>, and then this menu layout is merged with the menu that + specified <LegacyDir>. + </para> + <para> + Desktop entries in the legacy hierarchy should be added to the pool of + desktop entries as if the <LegacyDir> were an + <AppDir>. Directory entries in the legacy hierarchy should be added + to the pool of directory entries as if the <LegacyDir> were a + <DirectoryDir>. This can be trivially implemented by adding + appropriate <AppDir> and <DirectoryDir> statements to the root + legacy <Menu>. There is one slight complexity, namely the + "prefix" attribute of <LegacyDir>. + </para> + <para> + The menu layout corresponds conceptually to the following, though actually + generating the XML is not necessary: + <itemizedlist> + <listitem> + <para> + For each directory in the legacy hierarchy, a + <Menu> is created with the same <Name> + as the directory on disk. + </para> + </listitem> + <listitem> + <para> + This menu then contains an <Include> element that includes + each desktop entry in the directory. That is, it should have a + + <Filename><replaceable>Foo/Bar/foo.desktop</replaceable></Filename> + for each desktop entry in the directory. + </para> + <para> + As a special exception, if a desktop entry in a directory contains + a <varname>Categories</varname> field, that desktop entry should + <emphasis>not</emphasis> be included in the legacy menu. + That is, no <Include> element should be generated for + the entry. This allows a desktop entry to be installed + in a legacy location but still work optimally with the + menu system specified in this document. + </para> + </listitem> + <listitem> + <para> + If the legacy directory contains a ".directory" file, then + a <Directory> element should be generated that points to said + ".directory" file. + </para> + </listitem> + <listitem> + <para> + Legacy desktop entries should not be assigned any + <varname>Categories</varname> fields if they didn't have them + already, except that all legacy entries should have the + "Legacy" category added to allow menu files to treat them + specially. (If the same directory is given as both + a <LegacyDir> and an <AppDir>, its desktop + entries should be labeled "Legacy" only if the <LegacyDir> + appears later in the file than the <AppDir>.) + </para> + </listitem> + </itemizedlist> + </para> + <para> + For example, say we have the following legacy directory hierarchy: + <informalexample> + <programlisting> + /usr/share/applnk + /usr/share/applnk/.directory + /usr/share/applnk/bar.desktop + /usr/share/applnk/System + /usr/share/applnk/System/.directory + /usr/share/applnk/System/foo.desktop + </programlisting> + </informalexample> + Conceptually that is converted to the following <Menu>: + <informalexample> + <programlisting> + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu &dtd-version;//EN" + "http://www.freedesktop.org/standards/menu-spec/menu-&dtd-version;.dtd"> + + <Menu> + <Name>Applications</Name> + <AppDir>/usr/share/applnk</AppDir> + <DirectoryDir>/usr/share/applnk</DirectoryDir> + <Directory>.directory</Directory> + <Include> + <Filename>bar.desktop</Filename> + </Include> + <Menu> + <Name>System</Name> + <AppDir>/usr/share/applnk/System</AppDir> + <DirectoryDir>/usr/share/applnk/System</DirectoryDir> + <Directory>.directory</Directory> + <Include> + <Filename>foo.desktop</Filename> + </Include> + </Menu> + </Menu> + </programlisting> + </informalexample> + This <Menu> is then merged as if it were in a file + and loaded with <MergeFile>. + </para> + </sect1> + + <sect1 id="example"> + <title>Example Menu File</title> + <para> + <informalexample> + <programlisting> + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu &dtd-version;//EN" + "http://www.freedesktop.org/standards/menu-spec/menu-&dtd-version;.dtd"> + + <Menu> + <Name>Applications</Name> + <Directory>Applications.directory</Directory> + + <-- Search the default locations --> + <DefaultAppDirs/> + <DefaultDirectoryDirs/> + + <-- Merge third-party submenus --> + <MergeDir>applications-merged</MergeDir> + + <-- Merge legacy hierarchy --> + <LegacyDir>/usr/share/applnk</LegacyDir> + + <-- Define default layout --> + <DefaultLayout> + <Merge type="menus"/> + <Merge type="files"/> + <Separator/> + <Menuname>More</Menuname> + </DefaultLayout> + + <-- some random moves, maybe to clean up legacy dirs, + maybe from menu editing --> + <Move> + <Old>Foo</Old> + <New>Bar</New> + <Old>Foo2</Old> + <New>Bar2</New> + </Move> + + <-- A preferences submenu, kept in a separate file + so it can also be used standalone --> + <Menu> + <Name>Preferences</Name> + <Directory>Preferences.directory</Directory> + <MergeFile>preferences.menu</MergeFile> + </Menu> + + <-- An Office submenu, specified inline --> + <Menu> + <Name>Office</Name> + <Directory>Office.directory</Directory> + <Include> + <Category>Office</Category> + </Include> + <Exclude> + <Filename>foo.desktop</Filename> + </Exclude> + </Menu> + + </Menu> + </programlisting> + </informalexample> + </para> + </sect1> + + <appendix id="category-registry"> + <title>Registered Categories</title> + <para> + This section contains a number of well known categories and + suggestions on how to use them. The list of Main Categories consist + of those categories that every conforming desktop environment MUST + support. By including one of these categories in an application's + desktop entry file the application will be ensured that it will + show up in a section of the application menu dedicated to this + category. The list of Additional Categories provides categories + that can be used to provide more fine grained information about + the application. Additional Categories should always be used in + combination with one of the Main Categories. + </para> + <para> + The table below lists all Main Categories. + Note that category names are case-sensitive. + <informaltable> + <tgroup cols="3"> + <thead> + <row> + <entry>Main Category</entry> + <entry>Description</entry> + <entry>Notes</entry> + </row> + </thead> + <tbody> + <row> + <entry>AudioVideo</entry> + <entry>Application for presenting, creating, or processing multimedia (audio/video)</entry> + </row><row> + <entry>Audio</entry> + <entry>An audio application</entry> + <entry>Desktop entry must include AudioVideo as well</entry> + </row><row> + <entry>Video</entry> + <entry>A video application</entry> + <entry>Desktop entry must include AudioVideo as well</entry> + </row><row> + <entry>Development</entry> + <entry>An application for development</entry> + </row><row> + <entry>Education</entry> + <entry>Educational software</entry> + </row><row> + <entry>Game</entry> + <entry>A game</entry> + </row><row> + <entry>Graphics</entry> + <entry>Application for viewing, creating, or processing graphics</entry> + </row><row> + <entry>Network</entry> + <entry>Network application such as a web browser</entry> + </row><row> + <entry>Office</entry> + <entry>An office type application</entry> + </row><row> + <entry>Settings</entry> + <entry>Settings applications</entry> + <entry>Entries may appear in a separate menu or as part of a + "Control Center"</entry> + </row><row> + <entry>System</entry> + <entry>System application, "System Tools" such as say a log viewer or network monitor</entry> + </row><row> + <entry>Utility</entry> + <entry>Small utility application, "Accessories"</entry> + </row> + </tbody> + </tgroup> + </informaltable> + </para> + <para> + The table below describes Additional Categories. The Related + Categories column lists one or more categories that are suggested + to be used in conjunction with the Additional Category. Note that at + least one Main Category must be included in the desktop entry's list + of categories. If multiple Main Categories are included in a single + desktop entry file, the entry may appear more than once in the menu. + If the Related Categories column is blank, the + Additional Category can be used with any Main Category. + <informaltable> + <tgroup cols="3"> + <thead> + <row> + <entry>Additional Category</entry> + <entry>Description</entry> + <entry>Related Categories</entry> + </row> + </thead> + <tbody> + <row> + <entry>Building</entry> + <entry>A tool to build applications</entry> + <entry>Development</entry> + + </row><row> + <entry>Debugger</entry> + <entry>A tool to debug applications</entry> + <entry>Development</entry> + + </row><row> + <entry>IDE</entry> + <entry>IDE application</entry> + <entry>Development</entry> + + </row><row> + <entry>GUIDesigner</entry> + <entry>A GUI designer application</entry> + <entry>Development</entry> + + </row><row> + <entry>Profiling</entry> + <entry>A profiling tool</entry> + <entry>Development</entry> + + </row><row> + <entry>RevisionControl</entry> + <entry>Applications like cvs or subversion</entry> + <entry>Development</entry> + + </row><row> + <entry>Translation</entry> + <entry>A translation tool</entry> + <entry>Development</entry> + + </row><row> + <entry>Calendar</entry> + <entry>Calendar application</entry> + <entry>Office</entry> + + </row><row> + <entry>ContactManagement</entry> + <entry>E.g. an address book</entry> + <entry>Office</entry> + + </row><row> + <entry>Database</entry> + <entry>Application to manage a database</entry> + <entry>Office or Development or AudioVideo</entry> + + </row><row> + <entry>Dictionary</entry> + <entry>A dictionary</entry> + <entry>Office;TextTools</entry> + + </row><row> + <entry>Chart</entry> + <entry>Chart application</entry> + <entry>Office</entry> + + </row><row> + <entry>Email</entry> + <entry>Email application</entry> + <entry>Office;Network</entry> + + </row><row> + <entry>Finance</entry> + <entry>Application to manage your finance</entry> + <entry>Office</entry> + + </row><row> + <entry>FlowChart</entry> + <entry>A flowchart application</entry> + <entry>Office</entry> + + </row><row> + <entry>PDA</entry> + <entry>Tool to manage your PDA</entry> + <entry>Office</entry> + + </row><row> + <entry>ProjectManagement</entry> + <entry>Project management application</entry> + <entry>Office;Development</entry> + + </row><row> + <entry>Presentation</entry> + <entry>Presentation software</entry> + <entry>Office</entry> + + </row><row> + <entry>Spreadsheet</entry> + <entry>A spreadsheet</entry> + <entry>Office</entry> + + </row><row> + <entry>WordProcessor</entry> + <entry>A word processor</entry> + <entry>Office</entry> + + </row><row> + <entry>2DGraphics</entry> + <entry>2D based graphical application</entry> + <entry>Graphics</entry> + + </row><row> + <entry>VectorGraphics</entry> + <entry>Application for viewing, creating, or processing vector graphics</entry> + <entry>Graphics;2DGraphics</entry> + + </row><row> + <entry>RasterGraphics</entry> + <entry>Application for viewing, creating, or processing raster (bitmap) graphics</entry> + <entry>Graphics;2DGraphics</entry> + + </row><row> + <entry>3DGraphics</entry> + <entry>Application for viewing, creating, or processing 3-D graphics</entry> + <entry>Graphics</entry> + + </row><row> + <entry>Scanning</entry> + <entry>Tool to scan a file/text</entry> + <entry>Graphics</entry> + + </row><row> + <entry>OCR</entry> + <entry>Optical character recognition application</entry> + <entry>Graphics;Scanning</entry> + + </row><row> + <entry>Photography</entry> + <entry>Camera tools, etc.</entry> + <entry>Graphics or Office</entry> + + </row><row> + <entry>Publishing</entry> + <entry>Desktop Publishing applications and Color Management tools</entry> + <entry>Graphics or Office</entry> + + </row><row> + <entry>Viewer</entry> + <entry>Tool to view e.g. a graphic or pdf file</entry> + <entry>Graphics or Office</entry> + + </row><row> + <entry>TextTools</entry> + <entry>A text tool utiliy</entry> + <entry>Utility</entry> + + </row><row> + <entry>DesktopSettings</entry> + <entry>Configuration tool for the GUI</entry> + <entry>Settings</entry> + + </row><row> + <entry>HardwareSettings</entry> + <entry>A tool to manage hardware components, like sound cards, video cards or printers</entry> + <entry>Settings</entry> + + </row><row> + <entry>Printing</entry> + <entry>A tool to manage printers</entry> + <entry>HardwareSettings;Settings</entry> + + </row><row> + <entry>PackageManager</entry> + <entry>A package manager application</entry> + <entry>Settings</entry> + + </row><row> + <entry>Dialup</entry> + <entry>A dial-up program</entry> + <entry>Network</entry> + + </row><row> + <entry>InstantMessaging</entry> + <entry>An instant messaging client</entry> + <entry>Network</entry> + + </row><row> + <entry>Chat</entry> + <entry>A chat client</entry> + <entry>Network</entry> + + </row><row> + <entry>IRCClient</entry> + <entry>An IRC client</entry> + <entry>Network</entry> + + </row><row> + <entry>FileTransfer</entry> + <entry>Tools like FTP or P2P programs</entry> + <entry>Network</entry> + + </row><row> + <entry>HamRadio</entry> + <entry>HAM radio software</entry> + <entry>Network or Audio</entry> + + </row><row> + <entry>News</entry> + <entry>A news reader or a news ticker</entry> + <entry>Network</entry> + + </row><row> + <entry>P2P</entry> + <entry>A P2P program</entry> + <entry>Network</entry> + + </row><row> + <entry>RemoteAccess</entry> + <entry>A tool to remotely manage your PC</entry> + <entry>Network</entry> + + </row><row> + <entry>Telephony</entry> + <entry>Telephony via PC</entry> + <entry>Network</entry> + + </row><row> + <entry>TelephonyTools</entry> + <entry>Telephony tools, to dial a number, manage PBX, ...</entry> + <entry>Utility</entry> + + </row><row> + <entry>VideoConference</entry> + <entry>Video Conference software</entry> + <entry>Network</entry> + + </row><row> + <entry>WebBrowser</entry> + <entry>A web browser</entry> + <entry>Network</entry> + + </row><row> + <entry>WebDevelopment</entry> + <entry>A tool for web developers</entry> + <entry>Network or Development</entry> + + </row><row> + <entry>Midi</entry> + <entry>An app related to MIDI</entry> + <entry>AudioVideo;Audio</entry> + + </row><row> + <entry>Mixer</entry> + <entry>Just a mixer</entry> + <entry>AudioVideo;Audio</entry> + + </row><row> + <entry>Sequencer</entry> + <entry>A sequencer</entry> + <entry>AudioVideo;Audio</entry> + + </row><row> + <entry>Tuner</entry> + <entry>A tuner</entry> + <entry>AudioVideo;Audio</entry> + + </row><row> + <entry>TV</entry> + <entry>A TV application</entry> + <entry>AudioVideo;Video</entry> + + </row><row> + <entry>AudioVideoEditing</entry> + <entry>Application to edit audio/video files</entry> + <entry>Audio or Video or AudioVideo</entry> + + </row><row> + <entry>Player</entry> + <entry>Application to play audio/video files</entry> + <entry>Audio or Video or AudioVideo</entry> + + </row><row> + <entry>Recorder</entry> + <entry>Application to record audio/video files</entry> + <entry>Audio or Video or AudioVideo</entry> + + </row><row> + <entry>DiscBurning</entry> + <entry>Application to burn a disc</entry> + <entry>AudioVideo</entry> + + </row><row> + <entry>ActionGame</entry> + <entry>An action game</entry> + <entry>Game</entry> + + </row><row> + <entry>AdventureGame</entry> + <entry>Adventure style game</entry> + <entry>Game</entry> + + </row><row> + <entry>ArcadeGame</entry> + <entry>Arcade style game</entry> + <entry>Game</entry> + + </row><row> + <entry>BoardGame</entry> + <entry>A board game</entry> + <entry>Game</entry> + + </row><row> + <entry>BlocksGame</entry> + <entry>Falling blocks game</entry> + <entry>Game</entry> + + </row><row> + <entry>CardGame</entry> + <entry>A card game</entry> + <entry>Game</entry> + + </row><row> + <entry>KidsGame</entry> + <entry>A game for kids</entry> + <entry>Game</entry> + + </row><row> + <entry>LogicGame</entry> + <entry>Logic games like puzzles, etc</entry> + <entry>Game</entry> + + </row><row> + <entry>RolePlaying</entry> + <entry>A role playing game</entry> + <entry>Game</entry> + + </row><row> + <entry>Simulation</entry> + <entry>A simulation game</entry> + <entry>Game</entry> + + </row><row> + <entry>SportsGame</entry> + <entry>A sports game</entry> + <entry>Game</entry> + + </row><row> + <entry>StrategyGame</entry> + <entry>A strategy game</entry> + <entry>Game</entry> + + </row><row> + <entry>Art</entry> + <entry>Software to teach arts</entry> + <entry>Education</entry> + + </row><row> + <entry>Construction</entry> + <entry></entry> + <entry>Education</entry> + + </row><row> + <entry>Music</entry> + <entry>Musical software</entry> + <entry>AudioVideo;Education</entry> + + </row><row> + <entry>Languages</entry> + <entry>Software to learn foreign languages</entry> + <entry>Education</entry> + + </row><row> + <entry>Science</entry> + <entry>Scientific software</entry> + <entry>Education</entry> + + </row><row> + <entry>ArtificialIntelligence</entry> + <entry>Artificial Intelligence software</entry> + <entry>Education;Science</entry> + + </row><row> + <entry>Astronomy</entry> + <entry>Astronomy software</entry> + <entry>Education;Science</entry> + + </row><row> + <entry>Biology</entry> + <entry>Biology software</entry> + <entry>Education;Science</entry> + + </row><row> + <entry>Chemistry</entry> + <entry>Chemistry software</entry> + <entry>Education;Science</entry> + + </row><row> + <entry>ComputerScience</entry> + <entry>ComputerSience software</entry> + <entry>Education;Science</entry> + + </row><row> + <entry>DataVisualization</entry> + <entry>Data visualization software</entry> + <entry>Education;Science</entry> + + </row><row> + <entry>Economy</entry> + <entry>Economy software</entry> + <entry>Education</entry> + + </row><row> + <entry>Electricity</entry> + <entry>Electricity software</entry> + <entry>Education;Science</entry> + + </row><row> + <entry>Geography</entry> + <entry>Geography software</entry> + <entry>Education</entry> + + </row><row> + <entry>Geology</entry> + <entry>Geology software</entry> + <entry>Education;Science</entry> + + </row><row> + <entry>Geoscience</entry> + <entry>Geoscience software</entry> + <entry>Education;Science</entry> + + </row><row> + <entry>History</entry> + <entry>History software</entry> + <entry>Education</entry> + + </row><row> + <entry>ImageProcessing</entry> + <entry>Image Processing software</entry> + <entry>Education;Science</entry> + + </row><row> + <entry>Literature</entry> + <entry>Literature software</entry> + <entry>Education</entry> + + </row><row> + <entry>Math</entry> + <entry>Math software</entry> + <entry>Education;Science</entry> + + </row><row> + <entry>NumericalAnalysis</entry> + <entry>Numerical analysis software</entry> + <entry>Education;Science;Math</entry> + + </row><row> + <entry>MedicalSoftware</entry> + <entry>Medical software</entry> + <entry>Education;Science</entry> + + </row><row> + <entry>Physics</entry> + <entry>Physics software</entry> + <entry>Education;Science</entry> + + </row><row> + <entry>Robotics</entry> + <entry>Robotics software</entry> + <entry>Education;Science</entry> + + </row><row> + <entry>Sports</entry> + <entry>Sports software</entry> + <entry>Education</entry> + + </row><row> + <entry>ParallelComputing</entry> + <entry>Parallel computing software</entry> + <entry>Education;Science;ComputerScience</entry> + + </row><row> + <entry>Amusement</entry> + <entry>A simple amusement</entry> + <entry></entry> + + + </row><row> + <entry>Archiving</entry> + <entry>A tool to archive/backup data</entry> + <entry>Utility</entry> + + </row><row> + <entry>Compression</entry> + <entry>A tool to manage compressed data/archives</entry> + <entry>Utility;Archiving</entry> + + </row><row> + <entry>Electronics</entry> + <entry>Electronics software, e.g. a circuit designer</entry> + <entry></entry> + + </row><row> + <entry>Emulator</entry> + <entry>Emulator of another platform, such as a DOS emulator</entry> + <entry>System or Game</entry> + + </row><row> + <entry>Engineering</entry> + <entry>Engineering software, e.g. CAD programs</entry> + <entry></entry> + + </row><row> + <entry>FileTools</entry> + <entry>A file tool utility</entry> + <entry>Utility or System</entry> + + </row><row> + <entry>FileManager</entry> + <entry>A file manager</entry> + <entry>System;FileTools</entry> + + </row><row> + <entry>TerminalEmulator</entry> + <entry>A terminal emulator application</entry> + <entry>System</entry> + + </row><row> + <entry>Filesystem</entry> + <entry>A file system tool</entry> + <entry>System</entry> + + </row><row> + <entry>Monitor</entry> + <entry>Monitor application/applet that monitors some resource or activity</entry> + <entry>System</entry> + + </row><row> + <entry>Security</entry> + <entry>A security tool</entry> + <entry>Settings or System</entry> + + </row><row> + <entry>Accessibility</entry> + <entry>Accessibility</entry> + <entry>Settings or Utility</entry> + + </row><row> + <entry>Calculator</entry> + <entry>A calculator</entry> + <entry>Utility</entry> + + </row><row> + <entry>Clock</entry> + <entry>A clock application/applet</entry> + <entry>Utility</entry> + + </row><row> + <entry>TextEditor</entry> + <entry>A text editor</entry> + <entry>Utility</entry> + + </row><row> + <entry>Documentation</entry> + <entry>Help or documentation</entry> + <entry></entry> + + </row><row> + <entry>Adult</entry> + <entry>Application handles adult or explicit material</entry> + <entry></entry> + + </row><row> + <entry>Core</entry> + <entry>Important application, core to the desktop such as a file manager or a help browser</entry> + <entry></entry> + + </row><row> + <entry>KDE</entry> + <entry>Application based on KDE libraries</entry> + <entry>QT</entry> + + </row><row> + <entry>GNOME</entry> + <entry>Application based on GNOME libraries</entry> + <entry>GTK</entry> + + </row><row> + <entry>GTK</entry> + <entry>Application based on GTK+ libraries</entry> + <entry></entry> + + </row><row> + <entry>Qt</entry> + <entry>Application based on Qt libraries</entry> + <entry></entry> + + </row><row> + <entry>Motif</entry> + <entry>Application based on Motif libraries</entry> + <entry></entry> + + </row><row> + <entry>Java</entry> + <entry>Application based on Java GUI libraries, such as AWT or Swing</entry> + <entry></entry> + + </row><row> + <entry>ConsoleOnly</entry> + <entry>Application that only works inside a terminal (text-based or command line application)</entry> + <entry></entry> + + </row> + </tbody> + </tgroup> + </informaltable> + + </para> + <para> + The table below describes Reserved Categories. + Reserved Categories have a specific desktop specific meaning + that has not been standardized (yet). Desktop entry files that use + a reserved category MUST also include an appropriate OnlyShowIn= entry + to restrict themselves to those environments that properly support the + reserved category as used. + <informaltable> + <tgroup cols="2"> + <thead> + <row> + <entry>Reserved Category</entry> + <entry>Description</entry> + </row> + </thead> + <tbody> + <row> + <entry>Screensaver</entry> + <entry>A screen saver (launching this desktop entry should activate the screen saver)</entry> + </row><row> + <entry>TrayIcon</entry> + <entry>An application that is primarily an icon for the "system tray" or "notification area" (apps that open a normal window and just happen to have a tray icon as well should not list this category)</entry> + </row><row> + <entry>Applet</entry> + <entry>An applet that will run inside a panel or another such application, likely desktop specific</entry> + </row><row> + <entry>Shell</entry> + <entry>A shell (an actual specific shell such as + <filename>bash</filename> or <filename>tcsh</filename>, not a TerminalEmulator)</entry> + </row> + </tbody> + </tgroup> + </informaltable> + + </para> + </appendix> + <appendix id="onlyshowin-registry"> + <title>Registered OnlyShowIn Environments</title> + <para> + Remember, these are case-sensitive. "KDE" not "kde" should be + used. + <informaltable> + <tgroup cols="2"> + <thead> + <row> + <entry>OnlyShowIn Value</entry> + <entry>Environment</entry> + </row> + </thead> + <tbody> + <row> + <entry>GNOME</entry><entry>GNOME Desktop</entry> + </row><row> + <entry>KDE</entry><entry>KDE Desktop</entry> + </row><row> + <entry>LXDE</entry><entry>LXDE Desktop</entry> + </row><row> + <entry>ROX</entry><entry>ROX Desktop</entry> + </row><row> + <entry>Unity</entry><entry>Unity Shell</entry> + </row><row> + <entry>XFCE</entry><entry>XFCE Desktop</entry> + </row><row> + <entry>Old</entry><entry>Legacy menu systems</entry> + </row> + </tbody> + </tgroup> + </informaltable> + </para> + </appendix> + <appendix id="third-party-howto"> + <title>Integrating your application in the menus</title> + <sect1 id="adding-items"> + <title>Adding menu items</title> + <para> + The following steps describe how a third party application can add + menu items to the menu system: + <itemizedlist> + <listitem> + <para> + Install desktop entries to + <replaceable>datadir</replaceable>/applications/ for each menu + item. Please namespace the filename, as in "vendor-foo.desktop", or + use a subdirectory of + <replaceable>datadir</replaceable>/applications/ so you have + "vendor/foo.desktop." Please be sure all desktop entries are valid + (see the <ulink + url="http://www.freedesktop.org/software/desktop-file-utils/"> + desktop-file-utils</ulink> package for a validation utility). + </para> + </listitem> + <listitem> + <para> + Install an XML menu file to <replaceable>sysconfdir</replaceable>/menus/applications-merged/ to add any submenus, if your desktop entries aren't already + included in some common categories. + </para> + </listitem> + <listitem> + <para> + Install any directory entries needed for your submenus to <replaceable>datadir</replaceable>/desktop-directories/, taking care to namespace and validate + the directory entries. + </para> + </listitem> + </itemizedlist> + </para> + </sect1> + <sect1 id="locations"> + <title>Install Locations</title> + <para> + If an application is intended to be installed by root on a system wide + basis then /usr/share is recommended to be used as value for + <replaceable>datadir</replaceable> and /etc/xdg is recommended to be + used as value for <replaceable>sysconfdir</replaceable>. + In case the /usr/share hierarchy is not writable it is recommended to + use /usr/local/share as value for <replaceable>datadir</replaceable> + instead. + </para> + <para> + If an application is intended to be installed by an unprivileged user + for exclusive use by that user only then + <varname>$XDG_DATA_HOME</varname> should be used as value + for <replaceable>datadir</replaceable> and + <varname>$XDG_CONFIG_HOME</varname> should be used as value + for <replaceable>sysconfdir</replaceable>. + If <varname>$XDG_DATA_HOME</varname> is not set, the default value of + $HOME/.local/share should be used for it. + If <varname>$XDG_CONFIG_HOME</varname> is not set, the default value of + $HOME/.config should be used for it. + </para> + </sect1> + <sect1 id="menu-add-example"> + <title>Example</title> + <para> + The company ShinyThings Inc. has developed an application named + <emphasis>WebMirror 1.0</emphasis> and would like to add its own + submenu to the system menus consisting of a <emphasis>WebMirror</emphasis> + menu item and a <emphasis>WebMirror Admin Tool</emphasis> + menu item. The company will use "shinythings" as its vendor id. + For the purpose of this example all menu items will be available + in two languages, English and Dutch. + The language code for Dutch is <emphasis>nl</emphasis>. + </para> + <para> + First the company needs to create two .desktop files that describe + the two menu items: + <informalexample> + <programlisting> + <replaceable>datadir</replaceable>/applications/shinythings-webmirror.desktop: + + [Desktop Entry] + Encoding=UTF-8 + Type=Application + + Exec=webmirror + Icon=webmirror + + Name=WebMirror + Name[nl]=WebSpiegel + </programlisting> + </informalexample> + and + <informalexample> + <programlisting> + <replaceable>datadir</replaceable>/applications/shinythings-webmirror-admin.desktop: + + [Desktop Entry] + Encoding=UTF-8 + Type=Application + + Exec=webmirror-admintool + Icon=webmirror-admintool + + Name=WebMirror Admin Tool + Name[nl]=WebSpiegel Administratie Tool + </programlisting> + </informalexample> + A .directory file needs to be installed to provide a title and icon + for the sub-menu itself: + <informalexample> + <programlisting> + <replaceable>datadir</replaceable>/desktop-directories/shinythings-webmirror.directory: + + [Desktop Entry] + Encoding=UTF-8 + + Icon=webmirror + + Name=WebMirror + Name[nl]=WebSpiegel + </programlisting> + </informalexample> + And finally, a .menu file needs to be provided that links it all + togther: + <informalexample> + <programlisting> + <replaceable>sysconfdir</replaceable>/menus/application-merged/shinythings-webmirror.menu: + + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu &dtd-version;//EN" + "http://www.freedesktop.org/standards/menu-spec/menu-&dtd-version;.dtd"> + <Menu> + <Name>Applications</Name> + <Menu> + <Name>WebMirror</Name> + <Directory>shinythings-webmirror.directory</Directory> + <Include> + <Filename>shinythings-webmirror.desktop</Filename> + <Filename>shinythings-webmirror-admin.desktop</Filename> + </Include> + </Menu> + </programlisting> + </informalexample> + + </para> + </sect1> + <sect1 id="compatibility"> + <title>Backward Compatibility</title> + <para> + For a limited time, installing a directory hierarchy to + the old GNOME/KDE specific locations such as /usr/share/applnk and + /usr/share/gnome/apps will continue to work as way to add your + application to the menu system as well. There are two ways to support + both the old and new menu systems at the same time: + <itemizedlist> + <listitem> + <para> + If you add a <varname>Categories</varname> line to the desktop + entries in the legacy hierarchy, implementations of this + specification will ignore their location in the legacy hierarchy, + and arrange them according to <varname>Categories</varname> instead. + This allows you to install a single desktop file that works in all + cases, though on the down side it's in a legacy location. + </para> + </listitem> + <listitem> + <para> + If you add the line <literal>OnlyShowIn=Old;</literal> to a desktop + entry, then old legacy implementations that ignore + <varname>OnlyShowIn</varname> will still show the desktop entry, but + implementations of this specification will not. Thus you can + add an "<literal>OnlyShowIn=Old;</literal>" entry to the legacy + hierarchy, and a new-style desktop entry to + <replaceable>datadir</replaceable>/applications/, and still get + only one entry in the menus. + </para> + </listitem> + </itemizedlist> + </para> + </sect1> + </appendix> + <appendix id="implementation-notes"> + <title>Implementation notes</title> + <sect1 id="menu-editing"> + <title>Menu editing</title> + <para> + To implement menu editing, the intent is that a per-user file is + created. The per-user file should specify a <MergeFile> with the + system wide file, so that system changes are inherited. When the user + deletes a menu item, you add + <literal><Exclude><Filename>foo.desktop</Filename></Exclude></literal>. If + the user adds a menu item, you use + <literal><Include><Filename>foo.desktop</Filename></Include></literal>. + </para> + <para> + If the user moves a folder you can use <Move> elements + to represent the move. <Move> elements used for menu-editing + should always be added to the most top-level menu to ensure that moves + are performed in the order in which they are specified; moves specified + in child menus are always performed before moves specified in a more + top level menu regardless of their location in the menu file. + </para> + <para> + To delete a folder, simply append the <Deleted> element. + </para> + <para> + When adding a new folder or moving an existing folder, menu editing + implementations are advised not to re-use the menu path of a previously + deleted folder. + </para> + <para> + Menu editors probably need to do some kind of consolidation/compression + to avoid an XML tree that grows infinitely over time. + </para> + </sect1> + </appendix> + <glossary><title>Glossary</title> + <para> + This glossary defines some of the terms used in this specification. + </para> + + <glossentry id="term-desktop-entry"><glossterm>Desktop entry</glossterm> + <glossdef> + <para> + A desktop entry is a file with a name ending in the ".desktop" + extension which conforms to the <ulink + url="http://www.freedesktop.org/Standards/desktop-entry-spec">desktop + entry specification</ulink> with <literal>Type=Application</literal>. + It describes a menu item, including a name, an icon, and what to do when the item is selected. + Desktop entries are also known as ".desktop files." + </para> + </glossdef> + </glossentry> + + <glossentry id="term-desktop-file-id"><glossterm>Desktop-File Id</glossterm> + <glossdef> + <para> + The id to identify a desktop entry with. + For example, if <filename>/usr/share/applications</filename> is + specified as an <AppDir>, and <filename>/opt/ude</filename> + as <LegacyDir prefix="foo-"> + then + <filename>/usr/share/applications/foo/bar.desktop</filename>, + <filename>/usr/share/applications/foo-bar.desktop</filename> + and + <filename>/opt/ude/Settings/bar.desktop</filename> all have + the same desktop-file id <literal>foo-bar.desktop</literal> + </para> + </glossdef> + </glossentry> + + <glossentry id="term-directory-entry"><glossterm>Directory entry</glossterm> + <glossdef> + <para> + A directory entry is a file with a name ending in the ".directory" + extension which conforms to the <ulink + url="http://www.freedesktop.org/Standards/desktop-entry-spec">desktop + entry specification</ulink> with <literal>Type=Directory</literal>. + It provides a localized name and an icon for a submenu. + Directory entries are also known as ".directory files." + </para> + </glossdef> + </glossentry> + + <glossentry id="term-menu-path"><glossterm>Menu path</glossterm> + <glossdef> + <para> + A "menu path" is the path to a particular menu. Menu paths are + always "relative" so never start with a slash character. + The path to a menu is simply the <Name> of each parent + of the menu, followed by the <Name> of the menu itself. + For example, "Foo/Bar/Baz" is a valid menu path. + </para> + </glossdef> + </glossentry> + + <glossentry id="term-relative-path"><glossterm>Relative path</glossterm> + <glossdef> + <para> + The canonical path to a directory entry, relative to the + <DirectoryDir> containing the + entry. For example, if <filename>/usr/share/desktop-directories</filename> is + specified as an <DirectoryDir>, the relative path to + <filename>/usr/share/desktop-directories/foo/bar.directory</filename> is + <filename>foo/bar.directory</filename>. + </para> + </glossdef> + </glossentry> + </glossary> +</article> + diff --git a/menu/menu.dtd b/menu/menu.dtd new file mode 100644 index 0000000..1bca3ed --- /dev/null +++ b/menu/menu.dtd @@ -0,0 +1,84 @@ +<!-- For explanations see http://www.freedesktop.org/standards/menu-spec --> +<!ELEMENT Menu ( + Name, ( + Directory + | DefaultAppDirs + | AppDir + | DefaultDirectoryDirs + | DirectoryDir + | LegacyDir + | KDELegacyDirs + | MergeFile + | DefaultMergeDirs + | MergeDir + | OnlyUnallocated + | NotOnlyUnallocated + | Deleted + | NotDeleted + | Include + | Exclude + | Move + | Menu + | Layout + | DefaultLayout + )* +)> + +<!ELEMENT Name (#PCDATA)> + +<!ELEMENT Directory (#PCDATA)> + +<!ELEMENT DefaultAppDirs EMPTY> +<!ELEMENT AppDir (#PCDATA)> + +<!ELEMENT DefaultDirectoryDirs EMPTY> +<!ELEMENT DirectoryDir (#PCDATA)> + +<!ELEMENT LegacyDir (#PCDATA)> +<!ATTLIST LegacyDir prefix CDATA #IMPLIED> +<!ELEMENT KDELegacyDirs EMPTY> + +<!ELEMENT MergeFile (#PCDATA)> +<!ATTLIST MergeFile type (path|parent) #IMPLIED> + +<!ELEMENT DefaultMergeDirs EMPTY> +<!ELEMENT MergeDir (#PCDATA)> + +<!ELEMENT OnlyUnallocated EMPTY> +<!ELEMENT NotOnlyUnallocated EMPTY> + +<!ELEMENT Deleted EMPTY> +<!ELEMENT NotDeleted EMPTY> + +<!ELEMENT Exclude ((Category|Filename|And|Or|Not|All)*)> +<!ELEMENT Include ((Category|Filename|And|Or|Not|All)*)> + +<!ELEMENT And ((Category|Filename|And|Or|Not|All)*)> +<!ELEMENT Or ((Category|Filename|And|Or|Not|All)*)> +<!ELEMENT Not ((Category|Filename|And|Or|Not|All)*)> +<!ELEMENT Filename (#PCDATA)> +<!ELEMENT Category (#PCDATA)> +<!ELEMENT All EMPTY> + +<!ELEMENT Move ((Old,New)*)> +<!ELEMENT Old (#PCDATA)> +<!ELEMENT New (#PCDATA)> + +<!ELEMENT Layout ((Filename|Menuname|Separator|Merge)*)> +<!ELEMENT DefaultLayout ((Filename|Menuname|Separator|Merge)*)> +<!ATTLIST DefaultLayout show_empty (true|false) #IMPLIED> +<!ATTLIST DefaultLayout inline (true|false) #IMPLIED> +<!ATTLIST DefaultLayout inline_limit CDATA #IMPLIED> +<!ATTLIST DefaultLayout inline_header (true|false) #IMPLIED> +<!ATTLIST DefaultLayout inline_alias (true|false) #IMPLIED> + +<!ELEMENT Menuname (#PCDATA)> +<!ATTLIST Menuname inline (true|false) #IMPLIED> +<!ATTLIST Menuname inline_limit CDATA #IMPLIED> +<!ATTLIST Menuname inline_header (true|false) #IMPLIED> +<!ATTLIST Menuname inline_alias (true|false) #IMPLIED> + +<!ELEMENT Separator EMPTY> + +<!ELEMENT Merge EMPTY> +<!ATTLIST Merge type (menus|files|all) #REQUIRED> diff --git a/menu/tests/ChangeLog b/menu/tests/ChangeLog new file mode 100644 index 0000000..ac55e4f --- /dev/null +++ b/menu/tests/ChangeLog @@ -0,0 +1,70 @@ +2005-04-25 Mark McLoughlin <mark@skynet.ie> + + * tests/u: add test for recursive inclusion of .menu files. + Also know as the "get really hosed and eat all the RAM + you can find" test. + +2005-04-20 Waldo Bastian <bastian@kde.org> + + * tests/s/result, + tests/s/test: Test that .desktop files under $HOME correctly + override .desktop files at system level + + * tests/t/result, + tests/t/test: Test order in which <Move> elements are processed + +2005-02-18 Mark McLoughlin <mark@skynet.ie> + + Make it a bit more difficult in order to catch: + http://bugzilla.gnome.org/show_bug.cgi?id=167758 + Thanks to Chris Lahey for the test case. + + * tests/o/test: put freecell.desktop in a subdirectory. + +2005-02-18 Mark McLoughlin <mark@skynet.ie> + + * tests/o/result, + tests/o/test: test that + <And><Category>foo</Category><Not><Category>foo</Category></Not></And> + doesn't match anything. + + * README: add bit about how to test the GNOME impl. + +2005-02-18 Mark McLoughlin <mark@skynet.ie> + + Problem pointed out by Waldo. + + * menutest: don't try and run the "CVS" test :) + + * tests/m/result, + tests/n/result: items in a hidden or deleted menu + should be considered allocated. + +2004-12-08 Mark McLoughlin <mark@skynet.ie> + + * tests/2/result, + tests/2/test: test the new <OnlyUnallocated> behaviour. + +2004-08-29 Mark McLoughlin <mark@skynet.ie> + + * tests/m: test for NoDisplay=true behavious in .desktop and + .directory files. + + * data/hidden.desktop, + data/hidden.directory: add. + + * data/apps.directory: add Type=Directory. + + * menutest: actually generate a test result if one doesn't + exist - makes it easier to write new tests. + +2003-10-23 Havoc Pennington <hp@redhat.com> + + * tests/f/test: remove <OnlyUnallocated/> from inside <Include> + statement, not allowed. + +2003-10-16 Havoc Pennington <hp@redhat.com> + + * menutest: cat log file on failure; print list of failed tests + when we're done + diff --git a/menu/tests/README b/menu/tests/README new file mode 100644 index 0000000..b003dc0 --- /dev/null +++ b/menu/tests/README @@ -0,0 +1,44 @@ +This directory contains regression tests for the menu-spec. + +To run these tests your menu-spec implementation should be +able to generate a menu in the following text format: + +<Full Menu Name><tab><Desktop File Id><tab><Full Path to Desktop File> + +Example: + +Editors/ kde-kwrite.desktop /home/bastian/.local/share/applications/kde-kwrite.desktop +Editors/ kde-kate.desktop /home/bastian/.local/share/applications/kde-kate.desktop +Editors/ kde-KEdit.desktop /home/bastian/.local/share/applications/kde-KEdit.desktop +Development/ kde-gideon.desktop /opt/kde3/share/applnk/Development/gideon.desktop +Development/ kde-kbabel.desktop /opt/kde3/share/applnk/Development/kbabel.desktop +Development/ kde-quanta.desktop /opt/kde3/share/applnk/Development/quanta.desktop +/ kde-Kfind.desktop /opt/kde3/share/applnk/Kfind.desktop +/ kde-Home.desktop /opt/kde3/share/applnk/Home.desktop +/ kde-Help.desktop /opt/kde3/share/applnk/Help.desktop + + + +The environment variable $MENUTEST should point to a command that is +able to generate the menu in the above format. + +To test KDE one can use: + MENUTEST="kbuildsycoca --menutest" + +With GNOME, you can use: + MENUTEST=gnome-menu-spec-test + +The menutest script should be used to run the tests. The following commands can +be used: + + MENUTEST="foo -bar" ./menutest + +to run all tests + + MENUTEST="foo -bar" TESTS="Deleted Directory" ./menutest + +to run the tests named "Deleted" and "Directory" only + +All tests contain of a test setup script named "test" and a file describing +the expected menu named "result". + diff --git a/menu/tests/TODO b/menu/tests/TODO new file mode 100644 index 0000000..6e178bf --- /dev/null +++ b/menu/tests/TODO @@ -0,0 +1,5 @@ +I hope you understand what i mean ;) + +desktop-file-id stuff & overwrite stuff absolute path + +onlyshowin - notshowin diff --git a/menu/tests/data/Help.desktop b/menu/tests/data/Help.desktop new file mode 100644 index 0000000..dc867cd --- /dev/null +++ b/menu/tests/data/Help.desktop @@ -0,0 +1,68 @@ +[Desktop Entry] +Encoding=UTF-8 +Exec=khelpcenter +Icon=khelpcenter +DocPath=khelpcenter/index.html +Type=Application +Terminal=0 + +Name=Help +Name[af]=Hulp +Name[az]=Yardım +Name[be]=Дапамога +Name[bg]=Помощ +Name[br]=Skoazell +Name[bs]=Pomoć +Name[ca]=Ajuda +Name[cs]=Nápověda +Name[cy]=Cymorth +Name[da]=Hjælp +Name[de]=Hilfe +Name[el]=Βοήθεια +Name[eo]=Helpo +Name[es]=Ayuda +Name[et]=Abiinfo +Name[eu]=Laguntza +Name[fa]=راهنما +Name[fi]=Ohje +Name[fr]=Aide +Name[gl]=Axuda +Name[he]=עזרה +Name[hr]=Pomoć +Name[hu]=Segítség +Name[id]=Keterangan bantu +Name[is]=Hjálp +Name[it]=Aiuto +Name[ja]=ヘルプ +Name[ko]=도움말 +Name[lo]=ລະບົບຊ່ວຍເຫືລອ +Name[lt]=Pagalba +Name[lv]=Palīdzība +Name[mn]=Тусламж +Name[mt]=Għajnuna +Name[nb]=Hjelp +Name[nn]=Hjelp +Name[nso]=Thuso +Name[oc]=Ajuda +Name[pl]=Pomoc +Name[pt]=Ajuda +Name[pt_BR]=Ajuda +Name[ro]=Ajutor +Name[ru]=Справка +Name[sk]=Pomocník +Name[sl]=Pomoč +Name[sr]=Pomoć +Name[ss]=Sita +Name[sv]=Hjälp +Name[ta]=¯¾Å¢ +Name[th]=ระบบช่วยเหลือ +Name[tr]=Yardım +Name[uk]=Довідка +Name[ven]=Thuso +Name[vi]=Trợ giúp +Name[wa]=Aidance +Name[xh]=Uncedo +Name[zh_CN]=帮助 +Name[zh_TW]=求助 +Name[zu]=Usizo + diff --git a/menu/tests/data/Home.desktop b/menu/tests/data/Home.desktop new file mode 100644 index 0000000..2bf8178 --- /dev/null +++ b/menu/tests/data/Home.desktop @@ -0,0 +1,127 @@ +[Desktop Entry] +Encoding=UTF-8 +Type=Application +Exec=kfmclient openProfile filemanagement +Icon=folder_home +Terminal=0 + +Name=Home +Name[af]=Huis +Name[az]=Başlanğıc +Name[be]=Хатні +Name[bg]=Домашна директория +Name[br]=Er-gêr +Name[bs]=Početak +Name[ca]=Inici +Name[cs]=Můj adresář +Name[cy]=Cartref +Name[da]=Hjem +Name[de]=Persönliches Verzeichnis +Name[el]=Σπίτι +Name[eo]=Hejmo +Name[es]=Personal +Name[et]=Kodukataloog +Name[eu]=Etxea +Name[fa]=خانه +Name[fi]=Koti +Name[fr]=Dossier personnel +Name[gl]=Persoal +Name[he]=בית +Name[hr]=Početak +Name[hu]=Saját könyvtár +Name[id]=Rumah +Name[is]=Heimasvæðið þitt +Name[ja]=ホーム +Name[ko]=홈 +Name[lo]=ພື້ນທີ່ສ່ວນຕົວ +Name[lt]=Pradžia +Name[lv]=Mājas +Name[mn]=Хувийн лавлах +Name[mt]=Direttorju Personali +Name[nb]=Hjem +Name[nl]=Persoonlijke map +Name[nn]=Heim +Name[nso]=Gae +Name[oc]=Inici +Name[pl]=Katalog domowy +Name[pt]=Casa +Name[ro]=Acasă +Name[ru]=Домой +Name[sk]=Domov +Name[sl]=Domov +Name[sr]=Кориснички директоријум +Name[ss]=Ekhaya +Name[sv]=Hem +Name[ta]=¦¾¡¼ì¸õ +Name[th]=พื้นที่ส่วนตัว +Name[tr]=Başlangıç +Name[uk]=Домівка +Name[ven]=Haya +Name[wa]=Måjhon +Name[xh]=Ikhaya +Name[xx]=xxHomexx +Name[zh_CN]=起点 +Name[zh_TW]=家目錄 +Name[zu]=Ikhaya + +GenericName=Personal Files +GenericName[af]=Persoonlike Lêers +GenericName[az]=Şəxsi Fayllar +GenericName[be]=Пэрсанальныя файлы +GenericName[bg]=Лични файлове +GenericName[br]=Restroù deoc'h +GenericName[bs]=Osobne datoteke +GenericName[ca]=Fitxers personals +GenericName[cs]=Osobní soubory +GenericName[cy]=Ffeiliau Personol +GenericName[da]=Personlige filer +GenericName[de]=Eigene Dateien +GenericName[el]=Προσωπικά Αρχεία +GenericName[eo]=Personaj dosieroj +GenericName[es]=Archivos personales +GenericName[et]=Isiklikud failid +GenericName[eu]=Fitxategi Pertsonalak +GenericName[fa]=پروندههای شخصی +GenericName[fi]=Omat tiedostot +GenericName[fr]=Fichiers personnels +GenericName[gl]=Ficheiros Persoais +GenericName[he]=קבצים אישיים +GenericName[hr]=Osobne datoteke +GenericName[hu]=személyes fájlok +GenericName[id]=File Pribadi +GenericName[is]=Skrárnar þÃnar +GenericName[it]=File personali +GenericName[ja]=個人のファイル +GenericName[ko]=혼자만 쓰는 파일 +GenericName[lo]=ທີ່ເກັບແຟ້ມແລະເອກະສານສວ່ນຕົວຫລືອື່ນຯ +GenericName[lt]=Asmeninės Bylos +GenericName[lv]=Personālie Faili +GenericName[mn]=Өөрийн файлууд +GenericName[mt]=Fajls Personali +GenericName[nb]=Personlige filer +GenericName[nl]=persoonlijke bestanden +GenericName[nn]=Personlege filer +GenericName[nso]=Difaele tsa Botho +GenericName[oc]=FiquièRs personals +GenericName[pl]=Pliki osobiste +GenericName[pt]=Ficheiros Pessoais +GenericName[pt_BR]=Arquivos Pessoais +GenericName[ro]=Fişiere personale +GenericName[ru]=Личные файлы +GenericName[sk]=Osobné súbory +GenericName[sl]=Osebne datoteke +GenericName[sr]=Овај директоријум садржи ваше личне фајлове +GenericName[sv]=Personliga filer +GenericName[ta]=¦º¡ó¾ì §¸¡ôÒì¸û +GenericName[th]=ที่เก็บแฟ้มและเอกสารส่วนตัว หรืออื่น ๆ +GenericName[tr]=Kişisel Dosyalar +GenericName[uk]=Особисті файли +GenericName[ven]=Dzifaela dza vhune +GenericName[vi]=File cá nhân +GenericName[wa]=Fitchîs da vosse +GenericName[xh]=Iifayile Zobuqu +GenericName[xx]=xxPersonal Filesxx +GenericName[zh_CN]=个人文件 +GenericName[zh_TW]=個人檔案 +GenericName[zu]=Amafayela Omuntu siqu + diff --git a/menu/tests/data/KEdit.desktop b/menu/tests/data/KEdit.desktop new file mode 100644 index 0000000..4274a2b --- /dev/null +++ b/menu/tests/data/KEdit.desktop @@ -0,0 +1,34 @@ +[Desktop Entry] +Encoding=UTF-8 +BinaryPattern=kedit; +MimeType=text/english;text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-c;text/x-c++; +GenericName=Simple Text Editor +GenericName[ca]=Editor de text +GenericName[cs]=Jednoduchý textový editor +GenericName[da]=Simpel teksteditor +GenericName[es]=Editor de texto sencillo +GenericName[fr]=Éditeur de texte élémentaire +GenericName[pt_BR]=Editor de Texto Simples +GenericName[sv]=Enkel texteditor +GenericName[wa]=Simpe aspougneu di tecse +Exec=kedit -caption "%c" %i %m %u +Icon=kedit +TerminalOptions= +Path= +DocPath=kedit/index.html +Type=Application +Terminal=0 +Name=KEdit +Name[af]=Kredigeer +Name[eo]=Redaktilo +Name[hr]=Uređivač +Name[lv]=KRediģēt +Name[pl]=Edytor +Name[sv]=Kedit +Name[th]=แก้ไขข้อความ +Name[ven]=U sengulusa ha K +Name[xh]=Abahleli Be K +Name[zh_TW]=KDE 編輯器 +X-KDE-StartupNotify=true +X-DCOP-ServiceType=Multi +Categories=Qt;KDE;TextEditor diff --git a/menu/tests/data/Kfind.desktop b/menu/tests/data/Kfind.desktop new file mode 100644 index 0000000..8984f18 --- /dev/null +++ b/menu/tests/data/Kfind.desktop @@ -0,0 +1,66 @@ +[Desktop Entry] +Encoding=UTF-8 +Exec=kfind %f +Icon=kfind +DocPath=kfind/index.html +TerminalOptions= +Path= +Type=Application +Terminal=0 +Name=Find Files +Name[af]=Soek Lêers +Name[be]=Шукаць файлы +Name[bg]=Търсене на файлове +Name[br]=Klask restroù +Name[bs]=Pronađi datoteke +Name[ca]=Cerca fitxers +Name[cs]=Najít soubory +Name[cy]=Canfod Ffeiliau +Name[da]=Find filer +Name[de]=Dateien suchen +Name[el]=Εύρεση αρχείων +Name[eo]=Trovu dosierojn +Name[es]=KFind +Name[et]=Failide otsimine +Name[eu]=Fitxategiak Bilatu +Name[fa]=یافتن پروندهها +Name[fi]=Etsi tiedostoja +Name[fr]=Recherche de fichiers +Name[gl]=Buscar Ficheiros +Name[he]=חפש קבצים +Name[hr]=Nađi datoteke +Name[hu]=Fájlkeresés +Name[id]=Cari Berkas +Name[it]=Trova file +Name[ja]=ファイルを検索 +Name[ko]=파일 찾기 +Name[lo]=ຄົ້ນຫາແຟ້ມ +Name[lt]=Rasti bylas +Name[lv]=Meklēt Failus +Name[mn]=Файл хайх +Name[mt]=Sib Fajls +Name[nb]=Finn filer +Name[nl]=Bestanden zoeken +Name[nn]=Finn filer +Name[nso]=Hwetsa Difaele +Name[oc]=Cerca fiquièrs +Name[pl]=Znajdź pliki +Name[pt]=Procurar Ficheiros +Name[pt_BR]=Encontrar arquivos +Name[ro]=Caută fişiere +Name[ru]=Поиск файлов +Name[sk]=Hľadať súbory +Name[sl]=Poišči datoteke +Name[sr]=Pretraga fajlova +Name[sv]=Hitta filer +Name[ta]=§¸¡ôÒì ¸ñÎÀ¢Ê +Name[th]=ค้นหาแฟ้ม +Name[tr]=Dosyalarda Bul +Name[uk]=Знайти файли +Name[ven]=Todani faela +Name[vi]=Tìm file +Name[xh]=Fumana Iifayile +Name[zh_CN]=查找文件 +Name[zh_TW]=尋找檔案 +Name[zu]=Thola Amafayela +X-KDE-StartupNotify=true diff --git a/menu/tests/data/apps.directory b/menu/tests/data/apps.directory new file mode 100644 index 0000000..d54b4bd --- /dev/null +++ b/menu/tests/data/apps.directory @@ -0,0 +1,66 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=Apps +Name[af]=Programme +Name[ar]=تطبيقات +Name[az]=Proqram Tə'minatları +Name[be]=Дастасаваньні +Name[bg]=Приложения +Name[br]=Arloadoù +Name[bs]=Aplikacije +Name[ca]=Aplicacions +Name[cs]=Aplikace +Name[da]=Øvrige programmer +Name[de]=Programme +Name[el]=Εφαρμογές +Name[eo]=Aplikaĵoj +Name[es]=Aplicaciones +Name[et]=Rakendused +Name[eu]=Aplikazioak +Name[fa]=برنامههای کاربردی +Name[fi]=Sovellukset +Name[fo]=Nýtsluskipanir +Name[gl]=Aplicacións +Name[he]=יישומים +Name[hr]=Programi +Name[hu]=Alkalmazások +Name[id]=Aplikasi +Name[is]=Forrit +Name[it]=Applicazioni +Name[ja]=アプリケーション +Name[ko]=응용 프로그램 +Name[lo]=ອັບພລິກເຄເຊິນ +Name[lt]=Programos +Name[lv]=Aplikācijas +Name[mk]=Апликации +Name[mt]=Applikazzjonijiet +Name[nb]=Programmer +Name[nl]=Programma's +Name[nn]=Program +Name[nso]=Ditshomiso +Name[oc]=Aplicacions +Name[pl]=Aplikacje +Name[pt]=Aplicações +Name[pt_BR]=Aplicativos +Name[ro]=Aplicaţii +Name[ru]=Приложения +Name[se]=Prográmmat +Name[sk]=Aplikácie +Name[sl]=Uporabniški programi +Name[sr]=Aplikacije +Name[ss]=Ticelo +Name[sv]=Program +Name[ta]=ÀÂýÀ¡Î¸û +Name[th]=แอพพลิเคชัน +Name[tr]=Uygulamalar +Name[uk]=Програми +Name[ven]=Apulikhesheni +Name[vi]=Chương trình +Name[wa]=Programes +Name[xh]=Izicelo +Name[zh_CN]=应用程序 +Name[zh_TW]=應用程式 +Name[zu]=Abayaleli +Type=Directory +Icon=package_applications + diff --git a/menu/tests/data/freecell.desktop b/menu/tests/data/freecell.desktop new file mode 100644 index 0000000..da6d251 --- /dev/null +++ b/menu/tests/data/freecell.desktop @@ -0,0 +1,83 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=FreeCell +Name[be]=Вольная ячэя +Name[bg]=Свободна Клетка +Name[bn]=ফ্রীসেল +Name[ca]=FreeCell +Name[cs]=FreeCell +Name[da]=Napoleon +Name[de]=FreeCell +Name[el]=FreeCell +Name[es]=FreeCell +Name[et]=Freecell +Name[fi]=Vapaakenttä +Name[fr]=Freecell +Name[ga]=FreeCell +Name[gl]=FreeCell +Name[he]=פריסל +Name[hu]=FreeCell +Name[it]=FreeCell +Name[ja]=フリーセル +Name[ko]=프리셀 +Name[lt]=FreeCell +Name[lv]=FreeCell +Name[mn]=Фриселл +Name[ms]=FreeCell +Name[nl]=FreeCell +Name[no]=Freecell +Name[pl]=FreeCell +Name[pt]=Freecell +Name[pt_BR]=FreeCell +Name[ru]=Фриселл +Name[sk]=FreeCell +Name[sl]=FreeCell +Name[sv]=Napoleon på S:t Helena +Name[tr]=İskambil falı +Name[uk]=Вільна комірка +Name[vi]=FreeCell +Name[wa]=Freecell +Name[zh_CN]=空当接龙 +Name[zh_TW]=Freecell +Comment=FreeCell game +Comment[be]=Гульня ў Вольную ячэю +Comment[bg]=игра Свободна Клетка +Comment[bn]=ফ্রীসেল খেলা +Comment[ca]=Joc del FreeCell +Comment[cs]=Hra FreeCell +Comment[da]=Kortspillet Napoleon +Comment[de]=FreeCell-Spiel +Comment[el]=Το παιχνίδι FreeCell +Comment[es]=Juego FreeCell +Comment[et]=Kaardimäng FreeCell +Comment[fi]=Vapaakenttä-peli +Comment[fr]=Jeu de cartes Freecell +Comment[he]=משחק פריסל +Comment[hu]=FreeCell játék +Comment[it]=FreeCell +Comment[ja]=フリーセルの GNOME 版 +Comment[lv]=FreeCell spēle +Comment[mn]=GNOME Фриселл тоглоом +Comment[ms]=Permainan FreeCell +Comment[nl]=FreeCell Spel +Comment[no]=Spillet FreeCell +Comment[pl]=Gra FreeCell +Comment[pt]=Jogo FreeCell +Comment[pt_BR]=Jogo de FreeCell +Comment[ru]=Пасьянс "Ячейка" +Comment[sk]=Hra FreeCell +Comment[sl]=Igra Freecell +Comment[sv]=Spelet Napoleon på S:t Helena +Comment[tr]=İskambil falı oyunu +Comment[uk]=Гра "Вільна комірка" +Comment[vi]=Trò chơi FreeCell +Comment[zh_TW]=Freecell 紙牌接龍遊戲 +Exec=freecell +Icon=gnome-cardgame.png +Terminal=false +Type=Application +Categories=GNOME;Application;Game;CardGame; +X-GNOME-Bugzilla-Bugzilla=GNOME +X-GNOME-Bugzilla-Product=gnome-games +X-GNOME-Bugzilla-Component=freecell +StartupNotify=true diff --git a/menu/tests/data/gataxx.desktop b/menu/tests/data/gataxx.desktop new file mode 100644 index 0000000..10dfec6 --- /dev/null +++ b/menu/tests/data/gataxx.desktop @@ -0,0 +1,81 @@ +[Desktop Entry] +Encoding=UTF-8 +Icon=gataxx.png +Name=Gataxx +Name[am]=Gataxx +Name[be]=Gataxx +Name[bg]=Гатаксс +Name[bn]=জীঅ্যাটাক্স +Name[ca]=Gataxx +Name[cs]=Gataxx +Name[da]=Ataxx +Name[de]=Gataxx +Name[el]=Gataxx +Name[es]=Gataxx +Name[et]=Gataxx +Name[fi]=Gataxx +Name[fr]=Gataxx +Name[he]=Gataxx +Name[hu]=Gataxx +Name[it]=Gataxx +Name[ja]=Gataxx +Name[ko]=Gataxx +Name[lv]=Gataxx +Name[mn]=Gataxx +Name[ms]=Gataxx +Name[nl]=Gataxx +Name[no]=Gataxx +Name[pl]=Gataxx +Name[pt]=Gataxx +Name[pt_BR]=Gataxx +Name[ru]=Gataxx +Name[sk]=Gataxx +Name[sl]=Gataxx +Name[sv]=Gataxx +Name[tr]=Gataxx +Name[uk]=Атаки +Name[vi]=Gataxx +Name[wa]=Gataxx +Name[zh_CN]=Gataxx +Name[zh_TW]=Gataxx +Comment=Ataxx game +Comment[be]=Гульня Ataxx +Comment[bg]=Игра атаксс +Comment[bn]=অ্যাটাক্স খেলা +Comment[ca]=Joc del Ataxx +Comment[cs]=Hra Ataxx +Comment[da]=Spillet Ataxx +Comment[de]=Ataxx-Spiel +Comment[el]=Παιχνίδι Ataxx +Comment[es]=Un juego tipo Ataxx. +Comment[et]=Mäng nimega ataxx +Comment[fi]=Ataxx-peli +Comment[fr]=Jeu Ataxx +Comment[he]=משחק Ataxx +Comment[hu]=Ataxx játék +Comment[it]=Gioco Ataxx +Comment[ja]=Ataxx ゲーム +Comment[lv]=Ataxx spēle +Comment[mn]=Ataxx тоглоом. +Comment[ms]=Permainan Ataxx +Comment[nl]=Ataxx +Comment[no]=Ataxx-spill +Comment[pl]=Gra Ataxx +Comment[pt]=Jogo Ataxx +Comment[pt_BR]=Jogo Ataxx +Comment[ru]=Игра ataxx +Comment[sk]=Hra Ataxx +Comment[sl]=Igra Ataxx +Comment[sv]=Spelet Ataxx +Comment[tr]=Ataxx oyunu +Comment[uk]=Гра "Атаки" +Comment[vi]=Trò chơi Ataxx. +Comment[zh_TW]=Ataxx 遊戲 +Exec=gataxx +Terminal=false +Type=Application +Categories=GNOME;Application;Game;BoardGame; +X-GNOME-Bugzilla-Bugzilla=GNOME +X-GNOME-Bugzilla-Product=gnome-games +X-GNOME-Bugzilla-Component=gataxx +StartupNotify=true diff --git a/menu/tests/data/gideon-legacy.desktop b/menu/tests/data/gideon-legacy.desktop new file mode 100644 index 0000000..4595087 --- /dev/null +++ b/menu/tests/data/gideon-legacy.desktop @@ -0,0 +1,12 @@ +[KDE Desktop Entry] +Encoding=UTF-8 +BinaryPattern=kdevelop; +Type=Application +Exec=gideon %u +MimeType=application/x-kdevelop; +Icon=gideon +DocPath=kdevelop/index.html +Terminal=0 +Name=KDevelop 3.0 +Comment=IDE for C++/Qt/KDE +X-DCOP-ServiceType=Multi diff --git a/menu/tests/data/gideon.desktop b/menu/tests/data/gideon.desktop new file mode 100644 index 0000000..1e11dc1 --- /dev/null +++ b/menu/tests/data/gideon.desktop @@ -0,0 +1,13 @@ +[Desktop Entry] +Encoding=UTF-8 +BinaryPattern=kdevelop; +Type=Application +Exec=gideon %u +MimeType=application/x-kdevelop; +Icon=gideon +DocPath=kdevelop/index.html +Terminal=0 +Name=KDevelop 3.0 +Comment=IDE for C++/Qt/KDE +X-DCOP-ServiceType=Multi +Categories=Qt;KDE;Development diff --git a/menu/tests/data/glines-2.desktop b/menu/tests/data/glines-2.desktop new file mode 100644 index 0000000..266747d --- /dev/null +++ b/menu/tests/data/glines-2.desktop @@ -0,0 +1,83 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=Glines +Name[be]=Glines +Name[bg]=ГЛинии +Name[bn]=জীলাইন্স +Name[ca]=Glines +Name[cs]=Glines +Name[da]=Linjer +Name[de]=Glines +Name[el]=Glines +Name[es]=Glines +Name[et]=Glines +Name[eu]=Glines +Name[fi]=Glines +Name[fr]=Glines +Name[he]=Glines +Name[hu]=Glines +Name[it]=Glines +Name[ja]=Glines +Name[ko]=Glines +Name[lt]=Glines +Name[lv]=Glines +Name[mn]=Glines +Name[ms]=Glines +Name[nl]=GLines +Name[no]=Glines +Name[pl]=Glines +Name[pt]=GLinhas +Name[pt_BR]=Glines +Name[ro]=Glines +Name[ru]=Glines +Name[sk]=GČiary +Name[sl]=Glines +Name[sv]=Glinjer +Name[tr]=Sıradaki toplar +Name[uk]=Ряди +Name[vi]=Glines +Name[wa]=GRoyes +Name[zh_CN]=Glines +Name[zh_TW]=Glines +Comment=Color lines game +Comment[be]=Гульня "Каляровыя лініі" +Comment[bg]=Игра Цветни линии +Comment[bn]=কালার লাইন্স খেলা +Comment[ca]=Joc de línies de color +Comment[cs]=Hra Barevné linie +Comment[da]=Farvede linjer-spil +Comment[de]=Farblinienspiel +Comment[el]=Παιχνίδι γραμμών χρώματος +Comment[es]=Juego del tipo líneas de colores. +Comment[fi]=Väriviivapeli +Comment[fr]=Jeu de lignes colorées +Comment[he]=משחק שורות צבעוניות +Comment[hu]=Color lines játék +Comment[it]=Gioco Color Lines +Comment[ja]=カラーラインのゲーム +Comment[lv]=Krāsu līniju spēle +Comment[mn]=Өнгөт бөмбөлөг тоглоом +Comment[ms]=Permainan garisan warna +Comment[nl]=Kleurlijnen +Comment[no]=Spill med fargelinjer +Comment[pl]=Gra w kolorowe linie +Comment[pt]=Jogo das linhas coloridas +Comment[pt_BR]=Jogo de linhas coloridas +Comment[ru]=Игра "Цветные линии" +Comment[sk]=Hra Farebné čiary +Comment[sl]=Igra barvnih črt +Comment[sv]=Färglinjespel +Comment[tr]=Color lines oyunu +Comment[uk]=Гра "Кольорові ряди" +Comment[vi]=Trò chơi ColorLines +Comment[zh_TW]=Color lines 遊戲 +Exec=glines +Icon=glines.png +Terminal=false +Type=Application +Categories=GNOME;Application;Game;PuzzleGame; +X-GNOME-Bugzilla-Bugzilla=GNOME +X-GNOME-Bugzilla-Product=gnome-games +X-GNOME-Bugzilla-Component=glines +StartupNotify=true +NoDisplay=true diff --git a/menu/tests/data/glines.desktop b/menu/tests/data/glines.desktop new file mode 100644 index 0000000..5e5b465 --- /dev/null +++ b/menu/tests/data/glines.desktop @@ -0,0 +1,82 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=Glines +Name[be]=Glines +Name[bg]=ГЛинии +Name[bn]=জীলাইন্স +Name[ca]=Glines +Name[cs]=Glines +Name[da]=Linjer +Name[de]=Glines +Name[el]=Glines +Name[es]=Glines +Name[et]=Glines +Name[eu]=Glines +Name[fi]=Glines +Name[fr]=Glines +Name[he]=Glines +Name[hu]=Glines +Name[it]=Glines +Name[ja]=Glines +Name[ko]=Glines +Name[lt]=Glines +Name[lv]=Glines +Name[mn]=Glines +Name[ms]=Glines +Name[nl]=GLines +Name[no]=Glines +Name[pl]=Glines +Name[pt]=GLinhas +Name[pt_BR]=Glines +Name[ro]=Glines +Name[ru]=Glines +Name[sk]=GČiary +Name[sl]=Glines +Name[sv]=Glinjer +Name[tr]=Sıradaki toplar +Name[uk]=Ряди +Name[vi]=Glines +Name[wa]=GRoyes +Name[zh_CN]=Glines +Name[zh_TW]=Glines +Comment=Color lines game +Comment[be]=Гульня "Каляровыя лініі" +Comment[bg]=Игра Цветни линии +Comment[bn]=কালার লাইন্স খেলা +Comment[ca]=Joc de línies de color +Comment[cs]=Hra Barevné linie +Comment[da]=Farvede linjer-spil +Comment[de]=Farblinienspiel +Comment[el]=Παιχνίδι γραμμών χρώματος +Comment[es]=Juego del tipo líneas de colores. +Comment[fi]=Väriviivapeli +Comment[fr]=Jeu de lignes colorées +Comment[he]=משחק שורות צבעוניות +Comment[hu]=Color lines játék +Comment[it]=Gioco Color Lines +Comment[ja]=カラーラインのゲーム +Comment[lv]=Krāsu līniju spēle +Comment[mn]=Өнгөт бөмбөлөг тоглоом +Comment[ms]=Permainan garisan warna +Comment[nl]=Kleurlijnen +Comment[no]=Spill med fargelinjer +Comment[pl]=Gra w kolorowe linie +Comment[pt]=Jogo das linhas coloridas +Comment[pt_BR]=Jogo de linhas coloridas +Comment[ru]=Игра "Цветные линии" +Comment[sk]=Hra Farebné čiary +Comment[sl]=Igra barvnih črt +Comment[sv]=Färglinjespel +Comment[tr]=Color lines oyunu +Comment[uk]=Гра "Кольорові ряди" +Comment[vi]=Trò chơi ColorLines +Comment[zh_TW]=Color lines 遊戲 +Exec=glines +Icon=glines.png +Terminal=false +Type=Application +Categories=GNOME;Application;Game;PuzzleGame; +X-GNOME-Bugzilla-Bugzilla=GNOME +X-GNOME-Bugzilla-Product=gnome-games +X-GNOME-Bugzilla-Component=glines +StartupNotify=true diff --git a/menu/tests/data/hidden.desktop b/menu/tests/data/hidden.desktop new file mode 100644 index 0000000..dbbbff9 --- /dev/null +++ b/menu/tests/data/hidden.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=Hidden +Comment=You shouldn't see this +Exec=hidden +Type=Application +Categories=GNOME;Application;TextEditor; +NoDisplay=true diff --git a/menu/tests/data/hidden.directory b/menu/tests/data/hidden.directory new file mode 100644 index 0000000..5f1e776 --- /dev/null +++ b/menu/tests/data/hidden.directory @@ -0,0 +1,5 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=Hidden +Type=Directory +NoDisplay=true diff --git a/menu/tests/data/kate.desktop b/menu/tests/data/kate.desktop new file mode 100644 index 0000000..3ca1c5d --- /dev/null +++ b/menu/tests/data/kate.desktop @@ -0,0 +1,30 @@ +[Desktop Entry] +Encoding=UTF-8 +GenericName=Advanced Text Editor +GenericName[cy]=Golygydd Testun Uwch +GenericName[da]= Avanceret teksteditor +GenericName[el]=Προχωρημένος διορθωτής κειμένου +GenericName[es]=Editor de texto avanzado +GenericName[fa]=ویرایشگر متن پیشرفته +GenericName[hu]=szövegszerkesztő +GenericName[pt_BR]=Editor de Texto Avançado +GenericName[sr]=Napredni editor teksta +GenericName[sv]=Avancerad texteditor +BinaryPattern= +Name=Kate +Name[ar]=كيت +Name[bg]=Редактор Kate +Name[eo]=Kodredaktilo +Name[fa]=کِیت +Name[ko]=카테 +Name[ru]=Редактор Kate +MimeType=text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-c;text/x-c++;text/rdf; +Exec=kate %u +TerminalOptions= +Icon=kate +Path= +DocPath=kate/index.html +Type=Application +Terminal=0 +X-DCOP-ServiceType=Multi +Categories=Qt;KDE;TextEditor diff --git a/menu/tests/data/kbabel.desktop b/menu/tests/data/kbabel.desktop new file mode 100644 index 0000000..2892cb8 --- /dev/null +++ b/menu/tests/data/kbabel.desktop @@ -0,0 +1,69 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=KBabel +Name[af]=Kbabel +Name[ar]=المترجم +Name[eo]=Babelo-tradukilo +Name[ko]=K바벨 +Name[pt_BR]=Editor de POTFiles +Name[sv]=Kbabel +Name[xx]=xxKBabelxx +Exec=kbabel %i %m -caption "%c" %U +Icon=kbabel +MiniIcon=kbabel +Type=Application +DocPath=kbabel/index.html +MimeType=application/x-gettext; +GenericName=Translation Tool +GenericName[af]=Vertaling Program +GenericName[ar]=أداة الترجمة +GenericName[bg]=Инструменти за Превод +GenericName[bs]=Alat za prevođenje +GenericName[ca]=Eina de traducció +GenericName[cs]=Překladatelský nástroj +GenericName[cy]=Erfyn Cyfieithu +GenericName[da]=Oversættelsesværktøj +GenericName[de]=Übersetzungsprogramm +GenericName[el]=Εργαλείο μετάφρασης +GenericName[eo]=Tradukilo por Qt-programoj +GenericName[es]=Herramienta de traducción +GenericName[et]=Tõlkimise rakendus +GenericName[eu]=Itzulpenerako Tresnak +GenericName[fi]=Käännöstyökalu +GenericName[fo]=Umsetingaramboð +GenericName[fr]=Outil de traduction +GenericName[he]=כלי תרגום +GenericName[hr]=Uslužni program za prevođenje +GenericName[hu]=segédprogram fordítóknak +GenericName[it]=Strumento per le traduzioni +GenericName[ja]=翻訳ツール +GenericName[lt]=Vertimo įrankis +GenericName[lv]=Tulkošanas Rīks +GenericName[mt]=Għodda tat-traduzzjoni +GenericName[nb]=Oversettingsverktøy +GenericName[nl]=vertaalprogramma +GenericName[nn]=Omsetjingsverktøy +GenericName[nso]=Sebereka sa Thlathollo +GenericName[pl]=Narzędzie dla tłumaczy +GenericName[pt]=Ferramenta de Tradução +GenericName[pt_BR]=Ferramenta de Tradução +GenericName[ro]=Utilitar de traducere +GenericName[ru]=Утилита локализации приложений +GenericName[sk]=Prekladací nástroj +GenericName[sl]=Orodje za prevajanje +GenericName[sv]=Översättningsverktyg +GenericName[ta]=¦Á¡Æ¢¦ÀÂ÷ôÒì ¸ÕÅ¢ +GenericName[th]=เครื่องมือแปลภาษา +GenericName[tr]=Çeviri Aracı +GenericName[uk]=Засіб для перекладів +GenericName[ven]=Zwishumiswa zwau Dologa +GenericName[vi]=Công cụ dịch +GenericName[xh]=Isixhobo Soguqulelo lomsebenzi kolunye ulwimi +GenericName[xx]=xxTranslation Toolxx +GenericName[zh_CN]=翻译工具 +GenericName[zh_TW]=翻譯工具 +GenericName[zu]=Ithuluzi Lokuguqulela +Terminal=0 +X-KDE-StartupNotify=true +X-DCOP-ServiceType=Unique +Categories=Qt;KDE;Development diff --git a/menu/tests/data/kedit-legacy.desktop b/menu/tests/data/kedit-legacy.desktop new file mode 100644 index 0000000..fa9700e --- /dev/null +++ b/menu/tests/data/kedit-legacy.desktop @@ -0,0 +1,33 @@ +[Desktop Entry] +Encoding=UTF-8 +BinaryPattern=kedit; +MimeType=text/english;text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-c;text/x-c++; +GenericName=Simple Text Editor +GenericName[ca]=Editor de text +GenericName[cs]=Jednoduchý textový editor +GenericName[da]=Simpel teksteditor +GenericName[es]=Editor de texto sencillo +GenericName[fr]=Éditeur de texte élémentaire +GenericName[pt_BR]=Editor de Texto Simples +GenericName[sv]=Enkel texteditor +GenericName[wa]=Simpe aspougneu di tecse +Exec=kedit -caption "%c" %i %m %u +Icon=kedit +TerminalOptions= +Path= +DocPath=kedit/index.html +Type=Application +Terminal=0 +Name=KEdit +Name[af]=Kredigeer +Name[eo]=Redaktilo +Name[hr]=Uređivač +Name[lv]=KRediģēt +Name[pl]=Edytor +Name[sv]=Kedit +Name[th]=แก้ไขข้อความ +Name[ven]=U sengulusa ha K +Name[xh]=Abahleli Be K +Name[zh_TW]=KDE 編輯器 +X-KDE-StartupNotify=true +X-DCOP-ServiceType=Multi diff --git a/menu/tests/data/kwrite.desktop b/menu/tests/data/kwrite.desktop new file mode 100644 index 0000000..9804fa6 --- /dev/null +++ b/menu/tests/data/kwrite.desktop @@ -0,0 +1,84 @@ +[Desktop Entry] +Encoding=UTF-8 +GenericName=Text Editor +GenericName[af]=Teks Redigeerder +GenericName[ar]=محرر نصوص +GenericName[be]=Тэкставы рэдактар +GenericName[bg]=Текстов Редактор +GenericName[bs]=Tekst editor +GenericName[ca]=Editor de text +GenericName[cs]=Textový editor +GenericName[cy]=Golygydd Testun +GenericName[da]= Teksteditor +GenericName[de]=Texteditor +GenericName[el]=Διορθωτής Κειμένου +GenericName[eo]=Tekstredaktilo +GenericName[es]=Editor de texto +GenericName[et]=Tekstiredaktor +GenericName[eu]=Testu Editorea +GenericName[fa]=ویرایشگر متن +GenericName[fi]=Tekstieditori +GenericName[fo]=Tekstritil +GenericName[fr]=Éditeur de texte +GenericName[he]=עורך טקסט +GenericName[hr]=Uređivač teksta +GenericName[hu]=szövegszerkesztő +GenericName[is]=Textaritill +GenericName[it]=Editor di testi +GenericName[ja]=テキストエディタ +GenericName[ko]=글월 편집기 +GenericName[lo]=ເຄື່ອງມືແກ້ໄຂຂໍ້ຄວາມ +GenericName[lt]=Teksto redaktorius +GenericName[lv]=Teksta Redaktors +GenericName[mn]=Текст боловсруулагч +GenericName[mt]=Editur tat-test +GenericName[nb]=Skriveprogram +GenericName[nl]=teksteditor +GenericName[nn]=Skriveprogram +GenericName[nso]=Mofetosi wa Sengwalwana +GenericName[pl]=Edytor tekstowy +GenericName[pt]=Editor de Texto +GenericName[pt_BR]=Editor de Texto +GenericName[ro]=Editor de text +GenericName[ru]=Текстовый редактор +GenericName[sk]=Textový editor +GenericName[sl]=Urejevalnik besedil +GenericName[sr]=Editor teksta +GenericName[ss]=Sihleli sembhalo +GenericName[sv]=Texteditor +GenericName[ta]=¯¨Ã ¦¾¡ÌôÀ¡Ç÷ +GenericName[th]=เครื่องมือแก้ไขข้อความ +GenericName[tr]=Metin Düzenleyici +GenericName[uk]=Редактор текстів +GenericName[ven]=Musengulusi wa Manwalwa +GenericName[vi]=Trình soạn văn bản +GenericName[wa]=Aspougneu di tecse +GenericName[xh]=Umhleli Wombhalo +GenericName[zh_CN]=文本编辑器 +GenericName[zh_TW]=文字編輯器 +GenericName[zu]=Umlungisi wombhalo +BinaryPattern= +Name=KWrite +Name[af]=Kskryf +Name[ar]=كاتب كيدي +Name[eo]=Simpla kodredaktilo +Name[fa]=نوشتار K +Name[fo]=KSkriva +Name[lo]=Kwrite +Name[lv]=KRakstīt +Name[nso]=KNgwala +Name[ru]=Редактор KWrite +Name[sv]=Kwrite +Name[ven]=Nwala ha K +MimeType=text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-c;text/x-c++;text/x-diff;text/rdf; +Exec=kwrite %u +X-KDE-StartupNotify=true +TerminalOptions= +Icon=kwrite +Path= +DocPath=kwrite/index.html +Type=Application +Terminal=0 +InitialPreference=8 +X-DCOP-ServiceType=Multi +Categories=Qt;KDE;TextEditor diff --git a/menu/tests/data/mahjongg-2.desktop b/menu/tests/data/mahjongg-2.desktop new file mode 100644 index 0000000..95cfe27 --- /dev/null +++ b/menu/tests/data/mahjongg-2.desktop @@ -0,0 +1,86 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=Mahjongg +Name[am]=ማህጆንግ +Name[be]=Маджонг +Name[bg]=Махджонг +Name[bn]=মাহজং +Name[ca]=Mahjongg +Name[cs]=Mahjongg +Name[da]=Mahjongg +Name[de]=Mahjongg +Name[el]=Mahjongg +Name[es]=Mahjongg +Name[et]=Mahjongg +Name[fa]=ماهجونگ +Name[fi]=Mahjongg +Name[fr]=Mahjongg +Name[gl]=Mahjongg +Name[he]=Mahjongg +Name[hu]=Mahjongg +Name[it]=Mahjongg +Name[ja]=GNOME 上海 +Name[ko]=그놈 마작 +Name[lt]=Mahjongg +Name[lv]=Mahjongg +Name[mn]=Маджонг +Name[ms]=Mahjongg +Name[nl]=Mahjongg +Name[no]=Mahjongg +Name[pl]=Mahjongg +Name[pt]=Mahjongg +Name[pt_BR]=Mahjongg +Name[ru]=Маджонг +Name[sk]=Mahjongg +Name[sl]=Mahjongg +Name[sv]=Mah Jong +Name[tr]=Mahjongg +Name[uk]=Магджонґ +Name[vi]=Mahjongg +Name[wa]=Mahjongg +Name[zh_CN]=堆麻将 +Name[zh_TW]=上海麻將 +Comment=Mahjongg game +Comment[am]=የማህጆንግ ጨዋታ +Comment[be]=Гульня Маджонг +Comment[bg]=Игра на Махджонг +Comment[bn]=মাহজং খেলা +Comment[ca]=Joc del Mahjongg +Comment[cs]=Hra Mahjongg +Comment[da]=Mahjonggspil +Comment[de]=Mahjongg-Spiel +Comment[el]=Παιχνίδι Mahjongg +Comment[es]=Juego Mahjongg +Comment[et]=Mäng nimega mahjongg +Comment[fa]=بازی ماهجونگ +Comment[fi]=Mahjongg-peli +Comment[fr]=Jeu de Mahjongg +Comment[he]=משחק Mahjongg +Comment[hu]=Mahjongg játék +Comment[it]=Gioco Mahjongg +Comment[ja]=麻雀ゲーム +Comment[lv]=Mahjongg spēle +Comment[mn]=Mahjongg тоглоом +Comment[ms]=Permainan Mahjongg +Comment[nl]=Mahjongg +Comment[no]=Mahjongg-spill +Comment[pl]=Gra Mahjongg +Comment[pt]=Jogo Mahjongg +Comment[pt_BR]=Jogo Mahjongg +Comment[ru]=Игра Маджонг +Comment[sk]=Hra Mahjongg +Comment[sl]=Igra Mahjongg +Comment[sv]=Mah Jong-spel +Comment[tr]=Mahjongg oyunu +Comment[uk]=Гра "Магджонґ" +Comment[vi]=Trò chơi Mahjongg +Comment[zh_TW]=上海麻將遊戲 +Exec=mahjongg +Icon=gnome-mahjongg.png +Terminal=false +Type=Application +Categories=GNOME;Application;Development; +X-GNOME-Bugzilla-Bugzilla=GNOME +X-GNOME-Bugzilla-Product=gnome-games +X-GNOME-Bugzilla-Component=mahjongg +StartupNotify=true diff --git a/menu/tests/data/mahjongg.desktop b/menu/tests/data/mahjongg.desktop new file mode 100644 index 0000000..0d5f5de --- /dev/null +++ b/menu/tests/data/mahjongg.desktop @@ -0,0 +1,86 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=Mahjongg +Name[am]=ማህጆንግ +Name[be]=Маджонг +Name[bg]=Махджонг +Name[bn]=মাহজং +Name[ca]=Mahjongg +Name[cs]=Mahjongg +Name[da]=Mahjongg +Name[de]=Mahjongg +Name[el]=Mahjongg +Name[es]=Mahjongg +Name[et]=Mahjongg +Name[fa]=ماهجونگ +Name[fi]=Mahjongg +Name[fr]=Mahjongg +Name[gl]=Mahjongg +Name[he]=Mahjongg +Name[hu]=Mahjongg +Name[it]=Mahjongg +Name[ja]=GNOME 上海 +Name[ko]=그놈 마작 +Name[lt]=Mahjongg +Name[lv]=Mahjongg +Name[mn]=Маджонг +Name[ms]=Mahjongg +Name[nl]=Mahjongg +Name[no]=Mahjongg +Name[pl]=Mahjongg +Name[pt]=Mahjongg +Name[pt_BR]=Mahjongg +Name[ru]=Маджонг +Name[sk]=Mahjongg +Name[sl]=Mahjongg +Name[sv]=Mah Jong +Name[tr]=Mahjongg +Name[uk]=Магджонґ +Name[vi]=Mahjongg +Name[wa]=Mahjongg +Name[zh_CN]=堆麻将 +Name[zh_TW]=上海麻將 +Comment=Mahjongg game +Comment[am]=የማህጆንግ ጨዋታ +Comment[be]=Гульня Маджонг +Comment[bg]=Игра на Махджонг +Comment[bn]=মাহজং খেলা +Comment[ca]=Joc del Mahjongg +Comment[cs]=Hra Mahjongg +Comment[da]=Mahjonggspil +Comment[de]=Mahjongg-Spiel +Comment[el]=Παιχνίδι Mahjongg +Comment[es]=Juego Mahjongg +Comment[et]=Mäng nimega mahjongg +Comment[fa]=بازی ماهجونگ +Comment[fi]=Mahjongg-peli +Comment[fr]=Jeu de Mahjongg +Comment[he]=משחק Mahjongg +Comment[hu]=Mahjongg játék +Comment[it]=Gioco Mahjongg +Comment[ja]=麻雀ゲーム +Comment[lv]=Mahjongg spēle +Comment[mn]=Mahjongg тоглоом +Comment[ms]=Permainan Mahjongg +Comment[nl]=Mahjongg +Comment[no]=Mahjongg-spill +Comment[pl]=Gra Mahjongg +Comment[pt]=Jogo Mahjongg +Comment[pt_BR]=Jogo Mahjongg +Comment[ru]=Игра Маджонг +Comment[sk]=Hra Mahjongg +Comment[sl]=Igra Mahjongg +Comment[sv]=Mah Jong-spel +Comment[tr]=Mahjongg oyunu +Comment[uk]=Гра "Магджонґ" +Comment[vi]=Trò chơi Mahjongg +Comment[zh_TW]=上海麻將遊戲 +Exec=mahjongg +Icon=gnome-mahjongg.png +Terminal=false +Type=Application +Categories=GNOME;Application;Game;BoardGame; +X-GNOME-Bugzilla-Bugzilla=GNOME +X-GNOME-Bugzilla-Product=gnome-games +X-GNOME-Bugzilla-Component=mahjongg +StartupNotify=true diff --git a/menu/tests/data/quanta.desktop b/menu/tests/data/quanta.desktop new file mode 100644 index 0000000..4b23aef --- /dev/null +++ b/menu/tests/data/quanta.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=Quanta Plus +Exec=quanta +Icon=quanta +Type=Application +MimeType=text/html +DocPath=quanta/index.html +Comment=Web Development Environment +Categories=Qt;KDE;Development diff --git a/menu/tests/expand b/menu/tests/expand new file mode 100755 index 0000000..5dbaac8 --- /dev/null +++ b/menu/tests/expand @@ -0,0 +1,12 @@ +#!/usr/bin/perl + +# This script performs expansion of environment variables of the form ${HOME} + +while(<>) +{ + while (($a) = ($_ =~ /[^\$]*\$\{([^\}]*)\}.*/)) + { + s/([^\$]*)(\$\{$a\})(.*)/$1$ENV{$a}$3/; + } + printf $_; +}
\ No newline at end of file diff --git a/menu/tests/menutest b/menu/tests/menutest new file mode 100755 index 0000000..9d37246 --- /dev/null +++ b/menu/tests/menutest @@ -0,0 +1,200 @@ +#!/bin/bash +# these vars are usable *only* for debugging purposes; they're not allowed as part of the spec, thus don't use them. +# set MENU_FAKE_PREFIX to a non empty val to force testing for if things would succeed if XDG_MENU_PREFIX were +# implemented +# set MENU_FAKE_APPLICATIONS to force a work around for applications-merged postfixing. +# +function installData() +{ + local DIR="$1" + shift + mkdir -p "${DIR}" + for file in $*; do + cp "data/${file}" "${DIR}" + WIPE[$WIPE_IDX]="${DIR}/${file}" + WIPE_IDX=$(( $WIPE_IDX + 1 )) + done +} + +function installDataAs() +{ + local DIR="$1" + mkdir -p "${DIR}" + cp "data/$2" "${DIR}/$3" + WIPE[${WIPE_IDX}]="${DIR}/${3}" + WIPE_IDX=$(( $WIPE_IDX + 1 )) +} + +setup_local_xdg_vars() { + export XDG_CONFIG_HOME="${MENUTESTDIR}/xdg_config_home" + export XDG_DATA_HOME="${MENUTESTDIR}/xdg_data_home" + export XDG_CONFIG_DIR="${MENUTESTDIR}/xdg_config_dir" + export XDG_CONFIG_DIRS="$XDG_CONFIG_DIR:${XDG_CONFIG_DIRS}2" + export XDG_DATA_DIR="${MENUTESTDIR}/xdg_data_dir" + export XDG_DATA_DIRS="$XDG_DATA_DIR:${XDG_DATA_DIR}2" + export XDG_CACHE_HOME="${MENUTESTDIR}/xdg_cache_home" +} + +setup_xdg_system_data_vars() +{ + export XDG_CACHE_HOME="${XDG_DATA_HOME:-${HOME}/.cache}" + export XDG_DATA_HOME="${XDG_DATA_HOME:-${HOME}/.local/share}" + export XDG_CONFIG_DIR="${XDG_CONFIG_DIR:-/etc/xdg}" + if [ -z "${XDG_DATA_DIRS}" ]; then + export XDG_DATA_DIRS="/usr/local/share:/usr/share" + fi + export XDG_DATA_DIRS="${XDG_DATA_DIRS}:${MENUTESTDIR}/xdg_cache_dir" + export XDG_DATA_DIR="${XDG_DATA_DIRS//*:}" + if [ -z "${XDG_CONFIG_DIRS}" ]; then + export XDG_CONFIG_DIRS="/etc/xdg" + fi + export XDG_CONFIG_DIR="${XDG_CONFIG_DIRS/:*}" +} + +run_test() { + if [ -z "$1" ]; then + echo "requires name of test directory to run" + exit 1 + fi + local TEST="$1" + rm -rf "${MENUTESTDIR}" 2> /dev/null + mkdir "${MENUTESTDIR}" + RESULT="${TEST}/result" + + ( + unset WIPE WIPE_IDX + declare -a WIPE + declare -i WIPE_IDX=0 + unset MODE + + . ${TEST}/test + echo ">>> Running test ${TEST}, purpose $TEST_PURPOSE" + + if [ "${MODE:-local}" == "local" ]; then + setup_local_xdg_vars + elif [ "${MODE}" == "system_data" ]; then + setup_xdg_system_data_vars + else + echo "!!! unknown MODE from $TEST, bailing" + exit -1 + fi + + test_code + + declare -i IDX=0 + while [ $WIPE_IDX -gt $IDX ]; do + echo "${WIPE[$IDX]}" >> "${MENUTESTDIR}/wipe" + IDX=$(( $IDX + 1 )) + done + + DEBUG_OVERRIDES='' + [ -n "$MENU_FAKE_PREFIX" ] && DEBUG_OVERRIDES=.menu + [ -n "$MENU_FAKE_APPLICATIONS" ] && DEBUG_OVERIDES="${DEBUG_OVERRIDES} -merged" + + for x in dir home; do + for y in ${DEBUG_OVERRIDES}; do + if [ -e "${MENUTESTDIR}/xdg_config_${x}/menus/applications${y}" ]; then + ln -s applications${y} "${MENUTESTDIR}/xdg_config_${x}/menus/kde-applications${y}" + ln -s applications${y} "${MENUTESTDIR}/xdg_config_${x}/menus/gnome-applications${y}" + fi + done + unset y + done + unset x DEBUG_OVERRIDES + + $MENUTEST > ${MENUTESTDIR}/run-result 2> ${MENUTESTDIR}/log + + if [ -e "${RESULT}" ]; then + ./expand "${RESULT}" > "${MENUTESTDIR}/required-result" + fi + + if [ "$(type -t interpret_results)" == "function" ]; then + interpret_results + else + default_interpret_results + fi + ret=$? + if [ -e "${MENUTESTDIR}/wipe" ]; then + cat "${MENUTESTDIR}/wipe" | while read l; do + [ -z "$l" ] && continue + rm "$l" + done + fi + return $ret + ) +} + +default_interpret_results() { + if [ ! -e "${RESULT}" ]; then + echo "!!! Result file (${RESULT}) for ${TEST} missing" + echo '>>> Failed' + return 1 + elif diff -q "${MENUTESTDIR}/run-result" "${MENUTESTDIR}/required-result" > /dev/null; then + echo '>>> OK' + return 0 + fi + sort "${MENUTESTDIR}/run-result" > "${MENUTESTDIR}/run-result.sorted" + sort "${MENUTESTDIR}/required-result" > "${MENUTESTDIR}/required-result.sorted" + if diff -u "${MENUTESTDIR}/run-result.sorted" "${MENUTESTDIR}/required-result.sorted" > "${MENUTESTDIR}/result.diff"; then + echo '>>> OK (different order)' + return 0 + fi + grep "${MENUTESTDIR}" "${MENUTESTDIR}/run-result" > "${MENUTESTDIR}/run-result.filtered" 2> /dev/null + if diff -q "${MENUTESTDIR}/run-result.filtered" "${MENUTESTDIR}/required-result" > /dev/null; then + echo '>>> OK (additional system items)' + return 0 + fi + grep "${MENUTESTDIR}" "${MENUTESTDIR}/run-result.sorted" > "${MENUTESTDIR}/required-result.filtered" 2> /dev/null + if diff -u "${MENUTESTDIR}/run-result.filtered" "${MENUTESTDIR}/required-result.sorted" > "${MENUTESTDIR}/result.diff"; then + echo '>>> OK (different order, additional system items)' + return 0 + fi + echo '>>> Failed' + cat "${MENUTESTDIR}/result.diff" + cat "${MENUTESTDIR}/log" + return 1 +} + +if [ -z "${TESTS}" ]; then + export TESTS=`ls tests/*/test | sed -e 's:^\(\./\)\?tests/\+::' -e 's:/\+test$::'` +fi + +if [ -z "$TET_RUN" ]; then + + if [ "x${MENUTEST}" == "x" ]; then + echo 'To run the test set $MENUTEST to your menu-spec implementation.' + exit 1 + fi + + if [ "x${MENUTESTDIR}" == "x" ]; then + MENUTESTDIR=/tmp/menutestdir + echo Using ${MENUTESTDIR} as test directory, override with \$MENUTESTDIR. + else + echo Using ${MENUTESTDIR} as test directory. + fi + + export MENUTESTDIR + export USER=${USER:-test} + + + FAILED= + SUCCEEDED= + + for TESTCASE in ${TESTS}; do + if [ "${TESTCASE}" == "CVS" ]; then + continue + fi + echo + if ! run_test "tests/${TESTCASE}" ${MODE}; then + FAILED="${FAILED} ${TESTCASE}" + else + SUCCEEDED="${SUCCEEDED} ${TESTCASE}" + fi + done + + echo "OK tests: ${SUCCEEDED}" + [ -n "${FAILED}" ] && echo "Failed tests: ${FAILED}" + echo "$(echo ${SUCCEEDED} | wc -w) tests passed, $(echo ${FAILED} | wc -w) tests failed" + [ -z "${FAILED}" ] && exit 0 + exit 1 +fi diff --git a/menu/tests/tests/All/result b/menu/tests/tests/All/result new file mode 100644 index 0000000..fc75a82 --- /dev/null +++ b/menu/tests/tests/All/result @@ -0,0 +1,4 @@ +Applications/ freecell.desktop ${XDG_DATA_DIR}/applications/freecell.desktop +Applications/ gataxx.desktop ${XDG_DATA_DIR}/applications/gataxx.desktop +Applications/ glines.desktop ${XDG_DATA_DIR}/applications/glines.desktop +Applications/ mahjongg.desktop ${XDG_DATA_DIR}/applications/mahjongg.desktop diff --git a/menu/tests/tests/All/test b/menu/tests/tests/All/test new file mode 100644 index 0000000..e97bddc --- /dev/null +++ b/menu/tests/tests/All/test @@ -0,0 +1,26 @@ +TEST_PURPOSE="<All> Keyword" + +test_code() { + # Generate applications.menu + mkdir -p ${XDG_CONFIG_DIR}/menus + ./expand > ${XDG_CONFIG_DIR}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + <!-- Search the default locations --> + <DefaultAppDirs/> + + <Menu> + <Name>Applications</Name> + <Include> + <All/> + </Include> + </Menu> +</Menu> +EOF + + # Install .desktop files + installData ${XDG_DATA_DIR}/applications gataxx.desktop mahjongg.desktop freecell.desktop glines.desktop +} diff --git a/menu/tests/tests/And/result b/menu/tests/tests/And/result new file mode 100644 index 0000000..dc159fa --- /dev/null +++ b/menu/tests/tests/And/result @@ -0,0 +1 @@ +Applications/ freecell.desktop ${XDG_DATA_DIR}/applications/freecell.desktop diff --git a/menu/tests/tests/And/test b/menu/tests/tests/And/test new file mode 100644 index 0000000..31571db --- /dev/null +++ b/menu/tests/tests/And/test @@ -0,0 +1,29 @@ +TEST_PURPOSE="<And> Keyword" + +test_code() { + # Generate applications.menu + mkdir -p ${XDG_CONFIG_DIR}/menus + ./expand > ${XDG_CONFIG_DIR}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + <!-- Search the default locations --> + <DefaultAppDirs/> + + <Menu> + <Name>Applications</Name> + <Include> + <And> + <Filename>freecell.desktop</Filename> + <Category>Game</Category> + </And> + </Include> + </Menu> +</Menu> +EOF + + # Install .desktop files + installData ${XDG_DATA_DIR}/applications gataxx.desktop mahjongg.desktop freecell.desktop glines.desktop +} diff --git a/menu/tests/tests/AppDir-relative/result b/menu/tests/tests/AppDir-relative/result new file mode 100644 index 0000000..9e1d622 --- /dev/null +++ b/menu/tests/tests/AppDir-relative/result @@ -0,0 +1,3 @@ +Applications/ KEdit.desktop ${XDG_CONFIG_DIR}/menus/apps/KEdit.desktop +Applications/ kate.desktop ${XDG_CONFIG_DIR}/menus/apps/kate.desktop +Applications/ kwrite.desktop ${XDG_CONFIG_DIR}/menus/apps/kwrite.desktop diff --git a/menu/tests/tests/AppDir-relative/test b/menu/tests/tests/AppDir-relative/test new file mode 100644 index 0000000..75bd201 --- /dev/null +++ b/menu/tests/tests/AppDir-relative/test @@ -0,0 +1,27 @@ +TEST_PURPOSE="<AppDir> relative path tag ..." + +test_code() { + # Generate applications.menu + mkdir -p ${XDG_CONFIG_DIR}/menus + ./expand > ${XDG_CONFIG_DIR}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + <!-- Search the default locations --> + <AppDir>apps</AppDir> + + <Menu> + <Name>Applications</Name> + <Include> + <Category>TextEditor</Category> + </Include> + </Menu> +</Menu> +EOF + + # Install .desktop files + installData "${XDG_CONFIG_DIR}/menus/apps" kwrite.desktop KEdit.desktop quanta.desktop kate.desktop kbabel.desktop + installDataAs "${XDG_CONFIG_DIR}/menus/apps" kwrite.desktop should_be_ignored.notdesktop +} diff --git a/menu/tests/tests/AppDir/test b/menu/tests/tests/AppDir/test new file mode 100644 index 0000000..8faff91 --- /dev/null +++ b/menu/tests/tests/AppDir/test @@ -0,0 +1,4 @@ +. tests/AppDir-relative/test +export PATH_EXPANSION='${XDG_CONFIG_DIR}/menus/' +TEST_PURPOSE="<AppDir> absolute path" + diff --git a/menu/tests/tests/Category/result b/menu/tests/tests/Category/result new file mode 100644 index 0000000..73b00c9 --- /dev/null +++ b/menu/tests/tests/Category/result @@ -0,0 +1,3 @@ +Editors/ KEdit.desktop ${XDG_DATA_DIR}/applications/KEdit.desktop +Editors/ kate.desktop ${XDG_DATA_DIR}/applications/kate.desktop +Editors/ kwrite.desktop ${XDG_DATA_DIR}/applications/kwrite.desktop diff --git a/menu/tests/tests/Category/test b/menu/tests/tests/Category/test new file mode 100644 index 0000000..3ee0777 --- /dev/null +++ b/menu/tests/tests/Category/test @@ -0,0 +1,29 @@ +TEST_PURPOSE="<Category> tag" + +test_code() { + # Generate applications.menu + mkdir -p ${XDG_CONFIG_DIR}/menus + ./expand > ${XDG_CONFIG_DIR}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + <!-- Search the default locations --> + <DefaultAppDirs/> + + <Menu> + <Name>Editors</Name> + <Include> + <Category>TextEditor</Category> + <!-- note it's lowercase, this is intentional to verify + it's a case sensitive implementation --> + <Category>application</Category> + </Include> + </Menu> +</Menu> +EOF + +# Install .desktop files, freecell is daft but intentional to verify category support is case sensitive +installData ${XDG_DATA_DIR}/applications kwrite.desktop KEdit.desktop kate.desktop freecell.desktop +} diff --git a/menu/tests/tests/DefaultMergeDirs/result b/menu/tests/tests/DefaultMergeDirs/result new file mode 100644 index 0000000..9e17189 --- /dev/null +++ b/menu/tests/tests/DefaultMergeDirs/result @@ -0,0 +1,5 @@ +Applications/ KEdit.desktop ${XDG_DATA_DIR}/applications/KEdit.desktop +Applications/ kate.desktop ${XDG_DATA_DIR}/applications/kate.desktop +Applications/ kwrite.desktop ${XDG_DATA_DIR}/applications/kwrite.desktop +Development/ kbabel.desktop ${XDG_DATA_DIR}/applications/kbabel.desktop +Development/ quanta.desktop ${XDG_DATA_DIR}/applications/quanta.desktop diff --git a/menu/tests/tests/DefaultMergeDirs/test b/menu/tests/tests/DefaultMergeDirs/test new file mode 100644 index 0000000..3b570f2 --- /dev/null +++ b/menu/tests/tests/DefaultMergeDirs/test @@ -0,0 +1,43 @@ +TEST_PURPOSE="<DefaultMergeDirs> tag ..." + +test_code() { + # Generate applications.menu + mkdir -p ${XDG_CONFIG_DIR}/menus + ./expand > ${XDG_CONFIG_DIR}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + <DefaultAppDirs/> + <DefaultMergeDirs/> + + <Menu> + <Name>Applications</Name> + <Include> + <Category>TextEditor</Category> + </Include> + </Menu> +</Menu> +EOF + + mkdir ${XDG_CONFIG_DIR}/menus/applications-merged/ + ./expand > ${XDG_CONFIG_DIR}/menus/applications-merged/test.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + + <Menu> + <Name>Development</Name> + <Include> + <Category>Development</Category> + </Include> + </Menu> +</Menu> +EOF + + # Install .desktop files + installData ${XDG_DATA_DIR}/applications kwrite.desktop KEdit.desktop quanta.desktop kate.desktop kbabel.desktop +} diff --git a/menu/tests/tests/Deleted/result b/menu/tests/tests/Deleted/result new file mode 100644 index 0000000..c121419 --- /dev/null +++ b/menu/tests/tests/Deleted/result @@ -0,0 +1,2 @@ +BoardGames/ gataxx.desktop ${XDG_DATA_DIR}/applications/gataxx.desktop +BoardGames/ mahjongg.desktop ${XDG_DATA_DIR}/applications/mahjongg.desktop diff --git a/menu/tests/tests/Deleted/test b/menu/tests/tests/Deleted/test new file mode 100644 index 0000000..db7a413 --- /dev/null +++ b/menu/tests/tests/Deleted/test @@ -0,0 +1,35 @@ +TEST_PURPOSE="<Deleted> tag" + +test_code() { + # Generate applications.menu + mkdir -p ${XDG_CONFIG_DIR}/menus + ./expand > ${XDG_CONFIG_DIR}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + <!-- Search the default locations --> + <DefaultAppDirs/> + + <Menu> + <Name>BoardGames</Name> + <Include> + <Category>BoardGame</Category> + </Include> + </Menu> + <Menu> + <Name>Games</Name> + <Include> + <Category>Game</Category> + </Include> + <Deleted/> + <NotDeleted/> + <Deleted/> + </Menu> +</Menu> +EOF + + # Install .desktop files + installData ${XDG_DATA_DIR}/applications gataxx.desktop mahjongg.desktop freecell.desktop glines.desktop +} diff --git a/menu/tests/tests/DesktopFileID/result b/menu/tests/tests/DesktopFileID/result new file mode 100644 index 0000000..9629384 --- /dev/null +++ b/menu/tests/tests/DesktopFileID/result @@ -0,0 +1,4 @@ +Applications/ company-games-freecell.desktop ${XDG_DATA_DIR}/applications/company/games/freecell.desktop +Applications/ company-games-gataxx.desktop ${XDG_DATA_DIR}/applications/company/games/gataxx.desktop +Applications/ company-games-glines.desktop ${XDG_DATA_DIR}/applications/company/games/glines.desktop +Applications/ company-games-mahjongg.desktop ${XDG_DATA_DIR}/applications/company/games/mahjongg.desktop diff --git a/menu/tests/tests/DesktopFileID/test b/menu/tests/tests/DesktopFileID/test new file mode 100644 index 0000000..ae2c679 --- /dev/null +++ b/menu/tests/tests/DesktopFileID/test @@ -0,0 +1,26 @@ +TEST_PURPOSE="DesktopFileIDs in submenus" + +test_code() { + # Generate applications.menu + mkdir -p ${XDG_CONFIG_DIR}/menus + ./expand > ${XDG_CONFIG_DIR}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + <!-- Search the default locations --> + <DefaultAppDirs/> + + <Menu> + <Name>Applications</Name> + <Include> + <Category>Game</Category> + </Include> + </Menu> +</Menu> +EOF + + # Install .desktop files + installData ${XDG_DATA_DIR}/applications/company/games gataxx.desktop mahjongg.desktop freecell.desktop glines.desktop +} diff --git a/menu/tests/tests/Directory/result b/menu/tests/tests/Directory/result new file mode 100644 index 0000000..2cd1d1f --- /dev/null +++ b/menu/tests/tests/Directory/result @@ -0,0 +1,3 @@ +Apps/ KEdit.desktop ${XDG_DATA_DIR}/applications/KEdit.desktop +Apps/ kate.desktop ${XDG_DATA_DIR}/applications/kate.desktop +Apps/ kwrite.desktop ${XDG_DATA_DIR}/applications/kwrite.desktop diff --git a/menu/tests/tests/Directory/test b/menu/tests/tests/Directory/test new file mode 100644 index 0000000..fe7e126 --- /dev/null +++ b/menu/tests/tests/Directory/test @@ -0,0 +1,29 @@ +TEST_PURPOSE="<Directory> tag ..." + +test_code() { + # Generate applications.menu + mkdir -p ${XDG_CONFIG_DIR}/menus + ./expand > ${XDG_CONFIG_DIR}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + <!-- Search the default locations --> + <DefaultAppDirs/> + <DefaultDirectoryDirs/> + + <Menu> + <Name>Applications</Name> + <Directory>apps.directory</Directory> + <Include> + <Category>TextEditor</Category> + </Include> + </Menu> +</Menu> +EOF + + # Install .desktop files + installData ${XDG_DATA_DIR}/applications kwrite.desktop KEdit.desktop quanta.desktop kate.desktop kbabel.desktop + installData ${XDG_DATA_DIR}/desktop-directories apps.directory +} diff --git a/menu/tests/tests/DirectoryDir-relative/result b/menu/tests/tests/DirectoryDir-relative/result new file mode 100644 index 0000000..2cd1d1f --- /dev/null +++ b/menu/tests/tests/DirectoryDir-relative/result @@ -0,0 +1,3 @@ +Apps/ KEdit.desktop ${XDG_DATA_DIR}/applications/KEdit.desktop +Apps/ kate.desktop ${XDG_DATA_DIR}/applications/kate.desktop +Apps/ kwrite.desktop ${XDG_DATA_DIR}/applications/kwrite.desktop diff --git a/menu/tests/tests/DirectoryDir-relative/test b/menu/tests/tests/DirectoryDir-relative/test new file mode 100644 index 0000000..4a5e039 --- /dev/null +++ b/menu/tests/tests/DirectoryDir-relative/test @@ -0,0 +1,28 @@ +TEST_PURPOSE="relative <DirectoryDir> tag ..." + +test_code() { + # Generate applications.menu + mkdir -p ${XDG_CONFIG_DIR}/menus + ./expand > ${XDG_CONFIG_DIR}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + <!-- Search the default locations --> + <DefaultAppDirs/> + <DirectoryDir>${PATH_EXPANSION}desktop-directories</DirectoryDir> + + <Menu> + <Name>Applications</Name> + <Directory>apps.directory</Directory> + <Include> + <Category>TextEditor</Category> + </Include> + </Menu> +</Menu> +EOF + # Install .desktop files + installData ${XDG_DATA_DIR}/applications kwrite.desktop KEdit.desktop quanta.desktop kate.desktop kbabel.desktop + installData ${XDG_CONFIG_DIR}/menus/desktop-directories apps.directory +} diff --git a/menu/tests/tests/DirectoryDir/test b/menu/tests/tests/DirectoryDir/test new file mode 100644 index 0000000..dc8bb3b --- /dev/null +++ b/menu/tests/tests/DirectoryDir/test @@ -0,0 +1,4 @@ +. tests/DirectoryDir-relative/test +export PATH_EXPANSION='${XDG_CONFIG_DIR}/menus/' +TEST_PURPOSE="<DirectoryDir> absolute path" + diff --git a/menu/tests/tests/Exclude/result b/menu/tests/tests/Exclude/result new file mode 100644 index 0000000..dfbb122 --- /dev/null +++ b/menu/tests/tests/Exclude/result @@ -0,0 +1,3 @@ +Applications/ freecell.desktop ${XDG_DATA_DIR}/applications/freecell.desktop +Applications/ gataxx.desktop ${XDG_DATA_DIR}/applications/gataxx.desktop +Applications/ mahjongg.desktop ${XDG_DATA_DIR}/applications/mahjongg.desktop diff --git a/menu/tests/tests/Exclude/test b/menu/tests/tests/Exclude/test new file mode 100644 index 0000000..728ec99 --- /dev/null +++ b/menu/tests/tests/Exclude/test @@ -0,0 +1,32 @@ +TEST_PURPOSE="<Exclude> Keyword" + +test_code() { + # Generate applications.menu + mkdir -p ${XDG_CONFIG_DIR}/menus + ./expand > ${XDG_CONFIG_DIR}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + <!-- Search the default locations --> + <DefaultAppDirs/> + + <Menu> + <Name>Applications</Name> + <Include> + <Or> + <Filename>freecell.desktop</Filename> + <Category>Game</Category> + </Or> + </Include> + <Exclude> + <Filename>glines.desktop</Filename> + </Exclude> + </Menu> +</Menu> +EOF + + # Install .desktop files + installData ${XDG_DATA_DIR}/applications gataxx.desktop mahjongg.desktop freecell.desktop glines.desktop +} diff --git a/menu/tests/tests/Filename/result b/menu/tests/tests/Filename/result new file mode 100644 index 0000000..dc159fa --- /dev/null +++ b/menu/tests/tests/Filename/result @@ -0,0 +1 @@ +Applications/ freecell.desktop ${XDG_DATA_DIR}/applications/freecell.desktop diff --git a/menu/tests/tests/Filename/test b/menu/tests/tests/Filename/test new file mode 100644 index 0000000..b9d021d --- /dev/null +++ b/menu/tests/tests/Filename/test @@ -0,0 +1,26 @@ +TEST_PURPOSE="<Filename> tag" + +test_code() { + # Generate applications.menu + mkdir -p ${XDG_CONFIG_DIR}/menus + ./expand > ${XDG_CONFIG_DIR}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + <!-- Search the default locations --> + <DefaultAppDirs/> + + <Menu> + <Name>Applications</Name> + <Include> + <Filename>freecell.desktop</Filename> + </Include> + </Menu> +</Menu> +EOF + + # Install .desktop files + installData ${XDG_DATA_DIR}/applications gataxx.desktop mahjongg.desktop freecell.desktop glines.desktop +} diff --git a/menu/tests/tests/LegacyDir-Move/result b/menu/tests/tests/LegacyDir-Move/result new file mode 100644 index 0000000..9a2b9db --- /dev/null +++ b/menu/tests/tests/LegacyDir-Move/result @@ -0,0 +1,2 @@ +Editors/ gideon-legacy.desktop ${LEGACY_DIR}/Development/gideon-legacy.desktop +/ Home.desktop ${LEGACY_DIR}/Home.desktop diff --git a/menu/tests/tests/LegacyDir-Move/test b/menu/tests/tests/LegacyDir-Move/test new file mode 100644 index 0000000..7e6e85e --- /dev/null +++ b/menu/tests/tests/LegacyDir-Move/test @@ -0,0 +1,39 @@ +TEST_PURPOSE="move entries from <LegacyDir>" + +test_code() { + LEGACY_DIR=${MENUTESTDIR}/legacy_applnk + export LEGACY_DIR + + # Generate applications.menu + mkdir -p ${XDG_CONFIG_DIR}/menus + ./expand > ${XDG_CONFIG_DIR}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + <!-- Search the default locations --> + <LegacyDir>${LEGACY_DIR}</LegacyDir> + <DefaultAppDirs/> + <DefaultDirectoryDirs/> + + <Menu> + <Name>Development</Name> + <Exclude> + <Filename>gideon-legacy.desktop</Filename> + </Exclude> + </Menu> + <Menu> + <Name>Editors</Name> + <Include> + <Filename>gideon-legacy.desktop</Filename> + </Include> + </Menu> +</Menu> +EOF + + # Install .desktop files + + installData ${LEGACY_DIR} Home.desktop + installData ${LEGACY_DIR}/Development gideon-legacy.desktop +} diff --git a/menu/tests/tests/LegacyDir-relative/result b/menu/tests/tests/LegacyDir-relative/result new file mode 100644 index 0000000..0c2af9b --- /dev/null +++ b/menu/tests/tests/LegacyDir-relative/result @@ -0,0 +1,9 @@ +Development/ gideon-legacy.desktop ${LEGACY_DIR}/Development/gideon-legacy.desktop +Development/ kbabel.desktop ${LEGACY_DIR}/Development/kbabel.desktop +Development/ quanta.desktop ${LEGACY_DIR}/Development/quanta.desktop +Editors/ KEdit.desktop ${XDG_DATA_DIR}/applications/KEdit.desktop +Editors/ kate.desktop ${XDG_DATA_DIR}/applications/kate.desktop +Editors/ kwrite.desktop ${XDG_DATA_DIR}/applications/kwrite.desktop +/ Help.desktop ${LEGACY_DIR}/Help.desktop +/ Home.desktop ${LEGACY_DIR}/Home.desktop +/ Kfind.desktop ${LEGACY_DIR}/Kfind.desktop diff --git a/menu/tests/tests/LegacyDir-relative/test b/menu/tests/tests/LegacyDir-relative/test new file mode 100644 index 0000000..5082590 --- /dev/null +++ b/menu/tests/tests/LegacyDir-relative/test @@ -0,0 +1,42 @@ +TEST_PURPOSE="Simple <LegacyDir> test" + +test_code() { + LEGACY_DIR=${MENUTESTDIR}/legacy_applnk + export LEGACY_DIR + + # Generate applications.menu + mkdir -p ${XDG_CONFIG_DIR}/menus + ./expand > ${XDG_CONFIG_DIR}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + <!-- Search the default locations --> + <LegacyDir>${LEGACY_DIR}</LegacyDir> + <DefaultAppDirs/> + <DefaultDirectoryDirs/> + + <Menu> + <Name>Editors</Name> + <Directory>kde-editors.directory</Directory> + <Include> + <Category>TextEditor</Category> + </Include> + </Menu> + <Menu> + <Name>Development</Name> + <Directory>kde-development.directory</Directory> + <Include> + <Category>Development</Category> + </Include> + </Menu> +</Menu> +EOF + + # Install .desktop files + installData ${XDG_DATA_DIR}/applications kwrite.desktop KEdit.desktop kate.desktop + installData ${LEGACY_DIR}/Development gideon-legacy.desktop kbabel.desktop quanta.desktop + installData ${LEGACY_DIR} Kfind.desktop Home.desktop Help.desktop +} + diff --git a/menu/tests/tests/Merge-combined/result b/menu/tests/tests/Merge-combined/result new file mode 100644 index 0000000..999bd1e --- /dev/null +++ b/menu/tests/tests/Merge-combined/result @@ -0,0 +1 @@ +Editors/ kwrite.desktop ${XDG_DATA_DIR}/applications/kwrite.desktop diff --git a/menu/tests/tests/Merge-combined/test b/menu/tests/tests/Merge-combined/test new file mode 100644 index 0000000..07cfab3 --- /dev/null +++ b/menu/tests/tests/Merge-combined/test @@ -0,0 +1,46 @@ +TEST_PURPOSE="Merge Two Menus and a Legacy Menu" + +test_code() { + LEGACY_DIR=${MENUTESTDIR}/legacy_applnk + export LEGACY_DIR + + # Generate applications.menu + mkdir -p ${XDG_CONFIG_DIR}/menus + ./expand > ${XDG_CONFIG_DIR}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + <!-- Search the default locations --> + <DefaultAppDirs/> + <DefaultDirectoryDirs/> + <LegacyDir>${LEGACY_DIR}</LegacyDir> + + <Menu> + <Name>Development</Name> + <Include> + <Filename>kate.desktop</Filename> + </Include> + </Menu> + <Menu> + <Name>Development</Name> + <Include> + <Filename>KEdit.desktop</Filename> + </Include> + <Deleted/> + </Menu> + <Menu> + <Name>Editors</Name> + <Include> + <Filename>kwrite.desktop</Filename> + </Include> + </Menu> +</Menu> +EOF + + # Install .desktop files + + installData ${LEGACY_DIR}/Development gideon-legacy.desktop + installData ${XDG_DATA_DIR}/applications kate.desktop kwrite.desktop KEdit.desktop +} diff --git a/menu/tests/tests/MergeDir-absolute/test b/menu/tests/tests/MergeDir-absolute/test new file mode 100644 index 0000000..db6c895 --- /dev/null +++ b/menu/tests/tests/MergeDir-absolute/test @@ -0,0 +1,3 @@ +. tests/MergeDir-relative/test +export PATH_EXPANSION='${XDG_CONFIG_DIR}/menus/' +export TEST_PURPOSE="<MergeDir> absolute path test" diff --git a/menu/tests/tests/MergeDir-relative/result b/menu/tests/tests/MergeDir-relative/result new file mode 100644 index 0000000..9e17189 --- /dev/null +++ b/menu/tests/tests/MergeDir-relative/result @@ -0,0 +1,5 @@ +Applications/ KEdit.desktop ${XDG_DATA_DIR}/applications/KEdit.desktop +Applications/ kate.desktop ${XDG_DATA_DIR}/applications/kate.desktop +Applications/ kwrite.desktop ${XDG_DATA_DIR}/applications/kwrite.desktop +Development/ kbabel.desktop ${XDG_DATA_DIR}/applications/kbabel.desktop +Development/ quanta.desktop ${XDG_DATA_DIR}/applications/quanta.desktop diff --git a/menu/tests/tests/MergeDir-relative/test b/menu/tests/tests/MergeDir-relative/test new file mode 100644 index 0000000..ba96b1a --- /dev/null +++ b/menu/tests/tests/MergeDir-relative/test @@ -0,0 +1,61 @@ +TEST_PURPOSE="<MergeDir> relative path ..." + +test_code() { + # Generate applications.menu + mkdir -p "${XDG_CONFIG_DIR}/menus" + ./expand > "${XDG_CONFIG_DIR}/menus/applications.menu" <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + <DefaultAppDirs/> + <MergeDir>${PATH_EXPANSION}applications-merged</MergeDir> + + <Menu> + <Name>Applications</Name> + <Include> + <Category>TextEditor</Category> + </Include> + </Menu> +</Menu> +EOF + + mkdir "${XDG_CONFIG_DIR}/menus/applications-merged/" + ./expand > "${XDG_CONFIG_DIR}/menus/applications-merged/test.menu" <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + + <Menu> + <Name>Development</Name> + <Include> + <Category>Development</Category> + </Include> + </Menu> +</Menu> +EOF + + # intentional crap entry to verify it does _not_ get picked up + ./expand > "${XDG_CONFIG_DIR}/menus/applications-merged/dar.notmenu" <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + + <Menu> + <Name>testing</Name> + <Include> + <All/> + </Include> + </Menu> +</Menu> +EOF + + + # Install .desktop files + installData "${XDG_DATA_DIR}/applications" kwrite.desktop KEdit.desktop quanta.desktop kate.desktop kbabel.desktop +} diff --git a/menu/tests/tests/MergeFile-absolute/test b/menu/tests/tests/MergeFile-absolute/test new file mode 100644 index 0000000..24cf669 --- /dev/null +++ b/menu/tests/tests/MergeFile-absolute/test @@ -0,0 +1,3 @@ +. tests/MergeFile-relative/test +export PATH_EXPANSION='${XDG_CONFIG_DIR}/menus/' +export TEST_PURPOSE="<MergeFile> absolute path" diff --git a/menu/tests/tests/MergeFile-parent/result b/menu/tests/tests/MergeFile-parent/result new file mode 100644 index 0000000..9e17189 --- /dev/null +++ b/menu/tests/tests/MergeFile-parent/result @@ -0,0 +1,5 @@ +Applications/ KEdit.desktop ${XDG_DATA_DIR}/applications/KEdit.desktop +Applications/ kate.desktop ${XDG_DATA_DIR}/applications/kate.desktop +Applications/ kwrite.desktop ${XDG_DATA_DIR}/applications/kwrite.desktop +Development/ kbabel.desktop ${XDG_DATA_DIR}/applications/kbabel.desktop +Development/ quanta.desktop ${XDG_DATA_DIR}/applications/quanta.desktop diff --git a/menu/tests/tests/MergeFile-parent/test b/menu/tests/tests/MergeFile-parent/test new file mode 100644 index 0000000..00ed006 --- /dev/null +++ b/menu/tests/tests/MergeFile-parent/test @@ -0,0 +1,61 @@ +TEST_PURPOSE="<MergeFile> tag ..." + +test_code() { + # Tests the type attribute in <MergeFile> + + # Generate applications.menu + mkdir -p ${XDG_CONFIG_HOME}/menus + ./expand > ${XDG_CONFIG_HOME}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + <DefaultAppDirs/> + <MergeFile type="parent">${XDG_CONFIG_DIR}/menus/test.menu</MergeFile> + + <Menu> + <Name>Applications</Name> + <Include> + <Category>TextEditor</Category> + </Include> + </Menu> +</Menu> +EOF + + mkdir -p ${XDG_CONFIG_DIR}/menus + ./expand > ${XDG_CONFIG_DIR}/menus/test.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + + <Menu> + <Name>Games</Name> + <Include> + <Category>Game</Category> + </Include> + </Menu> +</Menu> +EOF + + ./expand > ${XDG_CONFIG_DIR}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + + <Menu> + <Name>Development</Name> + <Include> + <Category>Development</Category> + </Include> + </Menu> +</Menu> +EOF + + # Install .desktop files + installData ${XDG_DATA_DIR}/applications kwrite.desktop KEdit.desktop quanta.desktop kate.desktop kbabel.desktop freecell.desktop glines.desktop +} diff --git a/menu/tests/tests/MergeFile-path/result b/menu/tests/tests/MergeFile-path/result new file mode 100644 index 0000000..fbe635e --- /dev/null +++ b/menu/tests/tests/MergeFile-path/result @@ -0,0 +1,5 @@ +Applications/ KEdit.desktop ${XDG_DATA_DIR}/applications/KEdit.desktop +Applications/ kate.desktop ${XDG_DATA_DIR}/applications/kate.desktop +Applications/ kwrite.desktop ${XDG_DATA_DIR}/applications/kwrite.desktop +Games/ freecell.desktop ${XDG_DATA_DIR}/applications/freecell.desktop +Games/ glines.desktop ${XDG_DATA_DIR}/applications/glines.desktop diff --git a/menu/tests/tests/MergeFile-path/test b/menu/tests/tests/MergeFile-path/test new file mode 100644 index 0000000..97daa5c --- /dev/null +++ b/menu/tests/tests/MergeFile-path/test @@ -0,0 +1,61 @@ +TEST_PURPOSE="<MergeFile> tag ..." + +test_code() { + # Tests the type attribute in <MergeFile> + + # Generate applications.menu + mkdir -p ${XDG_CONFIG_HOME}/menus + ./expand > ${XDG_CONFIG_HOME}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + <DefaultAppDirs/> + <MergeFile type="path">${XDG_CONFIG_DIR}/menus/test.menu</MergeFile> + + <Menu> + <Name>Applications</Name> + <Include> + <Category>TextEditor</Category> + </Include> + </Menu> +</Menu> +EOF + + mkdir -p ${XDG_CONFIG_DIR}/menus + ./expand > ${XDG_CONFIG_DIR}/menus/test.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + + <Menu> + <Name>Games</Name> + <Include> + <Category>Game</Category> + </Include> + </Menu> +</Menu> +EOF + + ./expand > ${XDG_CONFIG_DIR}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + + <Menu> + <Name>Development</Name> + <Include> + <Category>Development</Category> + </Include> + </Menu> +</Menu> +EOF + + # Install .desktop files + installData ${XDG_DATA_DIR}/applications kwrite.desktop KEdit.desktop quanta.desktop kate.desktop kbabel.desktop freecell.desktop glines.desktop +} diff --git a/menu/tests/tests/MergeFile-recursive/result b/menu/tests/tests/MergeFile-recursive/result new file mode 100644 index 0000000..9e17189 --- /dev/null +++ b/menu/tests/tests/MergeFile-recursive/result @@ -0,0 +1,5 @@ +Applications/ KEdit.desktop ${XDG_DATA_DIR}/applications/KEdit.desktop +Applications/ kate.desktop ${XDG_DATA_DIR}/applications/kate.desktop +Applications/ kwrite.desktop ${XDG_DATA_DIR}/applications/kwrite.desktop +Development/ kbabel.desktop ${XDG_DATA_DIR}/applications/kbabel.desktop +Development/ quanta.desktop ${XDG_DATA_DIR}/applications/quanta.desktop diff --git a/menu/tests/tests/MergeFile-recursive/test b/menu/tests/tests/MergeFile-recursive/test new file mode 100644 index 0000000..4dbab21 --- /dev/null +++ b/menu/tests/tests/MergeFile-recursive/test @@ -0,0 +1,58 @@ +TEST_PURPOSE="test elaborate recursive look in <MergeFile>s" + +test_code(){ + # Generate applications.menu + mkdir -p ${XDG_CONFIG_DIR}/menus + ./expand > ${XDG_CONFIG_DIR}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + <DefaultAppDirs/> + <MergeFile>applications-merged/test.menu</MergeFile> + + <Menu> + <Name>Applications</Name> + <Include> + <Category>TextEditor</Category> + </Include> + </Menu> +</Menu> +EOF + + + mkdir ${XDG_CONFIG_DIR}/menus/applications-merged/ + ./expand > ${XDG_CONFIG_DIR}/menus/applications-merged/test.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + + <MergeFile>extra/test.menu</MergeFile> +</Menu> +EOF + + mkdir ${XDG_CONFIG_DIR}/menus/applications-merged/extra/ + ./expand > ${XDG_CONFIG_DIR}/menus/applications-merged/extra/test.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + + <Menu> + <Name>Development</Name> + <Include> + <Category>Development</Category> + </Include> + </Menu> + + <MergeFile>../test.menu</MergeFile> +</Menu> +EOF + + # Install .desktop files + installData ${XDG_DATA_DIR}/applications kwrite.desktop KEdit.desktop quanta.desktop kate.desktop kbabel.desktop +} diff --git a/menu/tests/tests/MergeFile-relative/result b/menu/tests/tests/MergeFile-relative/result new file mode 100644 index 0000000..9e17189 --- /dev/null +++ b/menu/tests/tests/MergeFile-relative/result @@ -0,0 +1,5 @@ +Applications/ KEdit.desktop ${XDG_DATA_DIR}/applications/KEdit.desktop +Applications/ kate.desktop ${XDG_DATA_DIR}/applications/kate.desktop +Applications/ kwrite.desktop ${XDG_DATA_DIR}/applications/kwrite.desktop +Development/ kbabel.desktop ${XDG_DATA_DIR}/applications/kbabel.desktop +Development/ quanta.desktop ${XDG_DATA_DIR}/applications/quanta.desktop diff --git a/menu/tests/tests/MergeFile-relative/test b/menu/tests/tests/MergeFile-relative/test new file mode 100644 index 0000000..c3478db --- /dev/null +++ b/menu/tests/tests/MergeFile-relative/test @@ -0,0 +1,44 @@ +TEST_PURPOSE="<MergeFile> tag relative path" + +test_code(){ + # Generate applications.menu + mkdir -p ${XDG_CONFIG_DIR}/menus + ./expand > ${XDG_CONFIG_DIR}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + <DefaultAppDirs/> + <MergeFile>${PATH_EXPANSION}applications-merged/test.menu</MergeFile> + + <Menu> + <Name>Applications</Name> + <Include> + <Category>TextEditor</Category> + </Include> + </Menu> +</Menu> +EOF + + mkdir ${XDG_CONFIG_DIR}/menus/applications-merged/ + ./expand > ${XDG_CONFIG_DIR}/menus/applications-merged/test.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> +<!-- test --> + +<Menu> + <Name>KDE</Name> + + <Menu> + <Name>Development</Name> + <Include> + <Category>Development</Category> + </Include> + </Menu> +</Menu> +EOF + + # Install .desktop files + installData ${XDG_DATA_DIR}/applications kwrite.desktop KEdit.desktop quanta.desktop kate.desktop kbabel.desktop +} diff --git a/menu/tests/tests/MergeFile2/result b/menu/tests/tests/MergeFile2/result new file mode 100644 index 0000000..9e17189 --- /dev/null +++ b/menu/tests/tests/MergeFile2/result @@ -0,0 +1,5 @@ +Applications/ KEdit.desktop ${XDG_DATA_DIR}/applications/KEdit.desktop +Applications/ kate.desktop ${XDG_DATA_DIR}/applications/kate.desktop +Applications/ kwrite.desktop ${XDG_DATA_DIR}/applications/kwrite.desktop +Development/ kbabel.desktop ${XDG_DATA_DIR}/applications/kbabel.desktop +Development/ quanta.desktop ${XDG_DATA_DIR}/applications/quanta.desktop diff --git a/menu/tests/tests/MergeFile2/test b/menu/tests/tests/MergeFile2/test new file mode 100644 index 0000000..e5b1591 --- /dev/null +++ b/menu/tests/tests/MergeFile2/test @@ -0,0 +1,57 @@ +TEST_PURPOSE="<MergeFile> tag ..." + +test_code() { + # Tests the use of relative paths in <MergeFile> + + # Generate applications.menu + mkdir -p ${XDG_CONFIG_DIR}/menus + ./expand > ${XDG_CONFIG_DIR}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + <DefaultAppDirs/> + <MergeFile>applications-merged/test.menu</MergeFile> + + <Menu> + <Name>Applications</Name> + <Include> + <Category>TextEditor</Category> + </Include> + </Menu> +</Menu> +EOF + + mkdir ${XDG_CONFIG_DIR}/menus/applications-merged/ + ./expand > ${XDG_CONFIG_DIR}/menus/applications-merged/test.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + + <MergeFile>extra/test.menu</MergeFile> +</Menu> +EOF + + mkdir ${XDG_CONFIG_DIR}/menus/applications-merged/extra/ + ./expand > ${XDG_CONFIG_DIR}/menus/applications-merged/extra/test.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + + <Menu> + <Name>Development</Name> + <Include> + <Category>Development</Category> + </Include> + </Menu> +</Menu> +EOF + + # Install .desktop files + installData ${XDG_DATA_DIR}/applications kwrite.desktop KEdit.desktop quanta.desktop kate.desktop kbabel.desktop +} diff --git a/menu/tests/tests/MergeFile3/result b/menu/tests/tests/MergeFile3/result new file mode 100644 index 0000000..9e17189 --- /dev/null +++ b/menu/tests/tests/MergeFile3/result @@ -0,0 +1,5 @@ +Applications/ KEdit.desktop ${XDG_DATA_DIR}/applications/KEdit.desktop +Applications/ kate.desktop ${XDG_DATA_DIR}/applications/kate.desktop +Applications/ kwrite.desktop ${XDG_DATA_DIR}/applications/kwrite.desktop +Development/ kbabel.desktop ${XDG_DATA_DIR}/applications/kbabel.desktop +Development/ quanta.desktop ${XDG_DATA_DIR}/applications/quanta.desktop diff --git a/menu/tests/tests/MergeFile3/test b/menu/tests/tests/MergeFile3/test new file mode 100644 index 0000000..8781888 --- /dev/null +++ b/menu/tests/tests/MergeFile3/test @@ -0,0 +1,56 @@ +TEST_PURPOSE="<MergeFile> tag ..." + +test_code() { + # Tests the use of relative paths in <MergeFile> + + # Generate applications.menu + mkdir -p ${XDG_CONFIG_DIR}/menus + ./expand > ${XDG_CONFIG_DIR}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + <DefaultAppDirs/> + <MergeFile>test.menu</MergeFile> + + <Menu> + <Name>Applications</Name> + <Include> + <Category>TextEditor</Category> + </Include> + </Menu> +</Menu> +EOF + + ./expand > ${XDG_CONFIG_DIR}/menus/test.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + + <MergeFile>extra/test.menu</MergeFile> +</Menu> +EOF + + mkdir ${XDG_CONFIG_DIR}/menus/extra/ + ./expand > ${XDG_CONFIG_DIR}/menus/extra/test.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + + <Menu> + <Name>Development</Name> + <Include> + <Category>Development</Category> + </Include> + </Menu> +</Menu> +EOF + + # Install .desktop files + installData ${XDG_DATA_DIR}/applications kwrite.desktop KEdit.desktop quanta.desktop kate.desktop kbabel.desktop +} diff --git a/menu/tests/tests/Move-collapsing/result b/menu/tests/tests/Move-collapsing/result new file mode 100644 index 0000000..10ccec6 --- /dev/null +++ b/menu/tests/tests/Move-collapsing/result @@ -0,0 +1,4 @@ +Games/BoardGame/ gataxx.desktop ${XDG_DATA_DIR}/applications/gataxx.desktop +Games/BoardGame/ mahjongg.desktop ${XDG_DATA_DIR}/applications/mahjongg.desktop +Games/ freecell.desktop ${XDG_DATA_DIR}/applications/freecell.desktop +Games/ glines.desktop ${XDG_DATA_DIR}/applications/glines.desktop diff --git a/menu/tests/tests/Move-collapsing/test b/menu/tests/tests/Move-collapsing/test new file mode 100644 index 0000000..b842b0a --- /dev/null +++ b/menu/tests/tests/Move-collapsing/test @@ -0,0 +1,40 @@ +TEST_PURPOSE="complicated <Move> operation" + +test_code() { + # Generate applications.menu + mkdir -p ${XDG_CONFIG_DIR}/menus + ./expand > ${XDG_CONFIG_DIR}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + <!-- Search the default locations --> + <DefaultAppDirs/> + <Move> + <Old>Games1</Old> + <New>Games</New> + </Move> + + <Menu> + <Name>Games1</Name> + <Menu> + <Name>BoardGame</Name> + <Include> + <Category>BoardGame</Category> + </Include> + </Menu> + </Menu> + <Menu> + <Name>Games</Name> + <Include> + <Category>Game</Category> + </Include> + <OnlyUnallocated/> + </Menu> +</Menu> +EOF + + # Install .desktop files + installData ${XDG_DATA_DIR}/applications gataxx.desktop mahjongg.desktop freecell.desktop glines.desktop +} diff --git a/menu/tests/tests/Move-ordering/result b/menu/tests/tests/Move-ordering/result new file mode 100644 index 0000000..b941f58 --- /dev/null +++ b/menu/tests/tests/Move-ordering/result @@ -0,0 +1,3 @@ +Development/ gideon.desktop ${XDG_DATA_DIR}/applications/gideon.desktop +Games-Correct/ freecell.desktop ${XDG_DATA_DIR}/applications/freecell.desktop +Games-Correct/ glines.desktop ${XDG_DATA_DIR}/applications/glines.desktop diff --git a/menu/tests/tests/Move-ordering/test b/menu/tests/tests/Move-ordering/test new file mode 100644 index 0000000..f8883b9 --- /dev/null +++ b/menu/tests/tests/Move-ordering/test @@ -0,0 +1,49 @@ +TEST_PURPOSE="Order of <Move> operations ..." + +test_code() { + # Tests the type attribute in <MergeFile> + + # Generate applications.menu + mkdir -p ${XDG_CONFIG_DIR}/menus + ./expand > ${XDG_CONFIG_DIR}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + <DefaultAppDirs/> + <Menu> + <Name>Development</Name> + <Menu> + <Name>Games</Name> + <Include> + <Category>Game</Category> + </Include> + </Menu> + <Include> + <Category>Development</Category> + </Include> + </Menu> + <Move> + <Old>Development/Games-New</Old> + <New>Games-Correct</New> + </Move> + <Move> + <Old>Development/Games</Old> + <New>Games-Wrong</New> + </Move> + <Menu> + <Name>Development</Name> + <Move> + <Old>Games</Old> + <New>Games-New</New> + </Move> + </Menu> +</Menu> +EOF + + # Move operations in sub-menus should be performed first + + # Install .desktop files + installData ${XDG_DATA_DIR}/applications freecell.desktop glines.desktop gideon.desktop +} diff --git a/menu/tests/tests/Move-submenu/result b/menu/tests/tests/Move-submenu/result new file mode 100644 index 0000000..f1c44ef --- /dev/null +++ b/menu/tests/tests/Move-submenu/result @@ -0,0 +1 @@ +A/B/Development/ gideon-legacy.desktop ${XDG_DATA_DIR}/applications/gideon-legacy.desktop diff --git a/menu/tests/tests/Move-submenu/test b/menu/tests/tests/Move-submenu/test new file mode 100644 index 0000000..2751983 --- /dev/null +++ b/menu/tests/tests/Move-submenu/test @@ -0,0 +1,32 @@ +TEST_PURPOSE="Move into a new Submenu" + +test_code() { + # Generate applications.menu + mkdir -p ${XDG_CONFIG_DIR}/menus + ./expand > ${XDG_CONFIG_DIR}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + <!-- Search the default locations --> + <DefaultAppDirs/> + <DefaultDirectoryDirs/> + + <Menu> + <Name>Development</Name> + <Include> + <Filename>gideon-legacy.desktop</Filename> + </Include> + </Menu> + <Move> + <Old>Development</Old> + <New>A/B/Development</New> + </Move> +</Menu> +EOF + + # Install .desktop files + + installData ${XDG_DATA_DIR}/applications gideon-legacy.desktop +} diff --git a/menu/tests/tests/Move/result b/menu/tests/tests/Move/result new file mode 100644 index 0000000..d9a802d --- /dev/null +++ b/menu/tests/tests/Move/result @@ -0,0 +1,2 @@ +Games/ gataxx.desktop ${XDG_DATA_DIR}/applications/gataxx.desktop +Games/ mahjongg.desktop ${XDG_DATA_DIR}/applications/mahjongg.desktop diff --git a/menu/tests/tests/Move/test b/menu/tests/tests/Move/test new file mode 100644 index 0000000..9f2d162 --- /dev/null +++ b/menu/tests/tests/Move/test @@ -0,0 +1,34 @@ +TEST_PURPOSE="simple <Move> operation" + +test_code() { + # Generate applications.menu + mkdir -p ${XDG_CONFIG_DIR}/menus + ./expand > ${XDG_CONFIG_DIR}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + <!-- Search the default locations --> + <DefaultAppDirs/> + <Move> + <Old>Foo</Old> + <New>Bar</New> + <Old>BoardGames</Old> + <New>Apps</New> + <Old>BoardGames</Old> + <New>Games</New> + </Move> + + <Menu> + <Name>BoardGames</Name> + <Include> + <Category>BoardGame</Category> + </Include> + </Menu> +</Menu> +EOF + + # Install .desktop files + installData ${XDG_DATA_DIR}/applications gataxx.desktop mahjongg.desktop freecell.desktop glines.desktop +} diff --git a/menu/tests/tests/NoDisplay/result b/menu/tests/tests/NoDisplay/result new file mode 100644 index 0000000..7ed7169 --- /dev/null +++ b/menu/tests/tests/NoDisplay/result @@ -0,0 +1 @@ +Other/ freecell.desktop ${XDG_DATA_DIR}/applications/freecell.desktop diff --git a/menu/tests/tests/NoDisplay/test b/menu/tests/tests/NoDisplay/test new file mode 100644 index 0000000..48e94ea --- /dev/null +++ b/menu/tests/tests/NoDisplay/test @@ -0,0 +1,37 @@ +TEST_PURPOSE="NoDisplay desktop entry values" + +test_code() { + # Generate applications.menu + mkdir -p ${XDG_CONFIG_DIR}/menus + ./expand > ${XDG_CONFIG_DIR}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + + <DefaultAppDirs/> + <DefaultDirectoryDirs/> + + <Menu> + <Name>Shouldn't see this</Name> + <Directory>hidden.directory</Directory> + <Include> + <Category>TextEditor</Category> + </Include> + </Menu> + + <Menu> + <Name>Other</Name> + <OnlyUnallocated/> + <Include> + <All/> + </Include> + </Menu> +</Menu> +EOF + + # Install .desktop files + installData ${XDG_DATA_DIR}/applications kwrite.desktop KEdit.desktop kate.desktop freecell.desktop hidden.desktop + installData ${XDG_DATA_DIR}/desktop-directories hidden.directory +} diff --git a/menu/tests/tests/NoDisplay2/result b/menu/tests/tests/NoDisplay2/result new file mode 100644 index 0000000..7ed7169 --- /dev/null +++ b/menu/tests/tests/NoDisplay2/result @@ -0,0 +1 @@ +Other/ freecell.desktop ${XDG_DATA_DIR}/applications/freecell.desktop diff --git a/menu/tests/tests/NoDisplay2/test b/menu/tests/tests/NoDisplay2/test new file mode 100644 index 0000000..62ba5a7 --- /dev/null +++ b/menu/tests/tests/NoDisplay2/test @@ -0,0 +1,38 @@ +TEST_PURPOSE="Allocation of desktop entry values from deleted menus" + +test_code() { + # Generate applications.menu + mkdir -p ${XDG_CONFIG_DIR}/menus +./expand > ${XDG_CONFIG_DIR}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + + <DefaultAppDirs/> + <DefaultDirectoryDirs/> + + <Menu> + <Name>Shouldn't see this</Name> + <Directory>apps.directory</Directory> + <Include> + <Category>TextEditor</Category> + </Include> + <Deleted/> + </Menu> + + <Menu> + <Name>Other</Name> + <OnlyUnallocated/> + <Include> + <All/> + </Include> + </Menu> +</Menu> +EOF + + # Install .desktop files + installData ${XDG_DATA_DIR}/applications kwrite.desktop KEdit.desktop kate.desktop freecell.desktop hidden.desktop + installData ${XDG_DATA_DIR}/desktop-directories apps.directory +} diff --git a/menu/tests/tests/NotOnlyUnallocated-default/result b/menu/tests/tests/NotOnlyUnallocated-default/result new file mode 100644 index 0000000..0c398b7 --- /dev/null +++ b/menu/tests/tests/NotOnlyUnallocated-default/result @@ -0,0 +1,2 @@ +Applications/ kwrite.desktop ${XDG_DATA_DIR}/applications/kwrite.desktop +Editors/ kwrite.desktop ${XDG_DATA_DIR}/applications/kwrite.desktop diff --git a/menu/tests/tests/NotOnlyUnallocated-default/test b/menu/tests/tests/NotOnlyUnallocated-default/test new file mode 100644 index 0000000..2f4956e --- /dev/null +++ b/menu/tests/tests/NotOnlyUnallocated-default/test @@ -0,0 +1,33 @@ +TEST_PURPOSE="Another <OnlyUnallocated> test" + +test_code() { + # Tests <OnlyUnallocated> + + # Generate applications.menu + mkdir -p ${XDG_CONFIG_DIR}/menus + ./expand > ${XDG_CONFIG_DIR}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + <DefaultAppDirs/> + + <Menu> + <Name>Applications</Name> + <Include> + <Filename>kwrite.desktop</Filename> + </Include> + </Menu> + <Menu> + <Name>Editors</Name> + <Include> + <Filename>kwrite.desktop</Filename> + </Include> + </Menu> +</Menu> +EOF + + # Install .desktop files + installData ${XDG_DATA_DIR}/applications kwrite.desktop +} diff --git a/menu/tests/tests/OnlyUnallocated/result b/menu/tests/tests/OnlyUnallocated/result new file mode 100644 index 0000000..8be4bc7 --- /dev/null +++ b/menu/tests/tests/OnlyUnallocated/result @@ -0,0 +1,3 @@ +BoardGames/ gataxx.desktop ${XDG_DATA_DIR}/applications/gataxx.desktop +BoardGames/ mahjongg.desktop ${XDG_DATA_DIR}/applications/mahjongg.desktop +Games/ freecell.desktop ${XDG_DATA_DIR}/applications/freecell.desktop diff --git a/menu/tests/tests/OnlyUnallocated/test b/menu/tests/tests/OnlyUnallocated/test new file mode 100644 index 0000000..efda0ff --- /dev/null +++ b/menu/tests/tests/OnlyUnallocated/test @@ -0,0 +1,44 @@ +TEST_PURPOSE="<OnlyAllocated> tag" + +test_code() { + # Generate applications.menu + mkdir -p ${XDG_CONFIG_DIR}/menus + ./expand > ${XDG_CONFIG_DIR}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + <!-- Search the default locations --> + <DefaultAppDirs/> + + <Menu> + <Name>BoardGames</Name> + <Include> + <And> + <Category>Game</Category> + <Not> + <Category>CardGame</Category> + </Not> + </And> + </Include> + <Exclude> + <Category>PuzzleGame</Category> + </Exclude> + </Menu> + <Menu> + <Name>Games</Name> + <Include> + <Category>Game</Category> + </Include> + <OnlyUnallocated/> + <NotOnlyUnallocated/> + <OnlyUnallocated/> + </Menu> +</Menu> +EOF + + + # Install .desktop files + installData ${XDG_DATA_DIR}/applications gataxx.desktop mahjongg.desktop freecell.desktop glines.desktop +} diff --git a/menu/tests/tests/Or/result b/menu/tests/tests/Or/result new file mode 100644 index 0000000..fc75a82 --- /dev/null +++ b/menu/tests/tests/Or/result @@ -0,0 +1,4 @@ +Applications/ freecell.desktop ${XDG_DATA_DIR}/applications/freecell.desktop +Applications/ gataxx.desktop ${XDG_DATA_DIR}/applications/gataxx.desktop +Applications/ glines.desktop ${XDG_DATA_DIR}/applications/glines.desktop +Applications/ mahjongg.desktop ${XDG_DATA_DIR}/applications/mahjongg.desktop diff --git a/menu/tests/tests/Or/test b/menu/tests/tests/Or/test new file mode 100644 index 0000000..cd10cfd --- /dev/null +++ b/menu/tests/tests/Or/test @@ -0,0 +1,29 @@ +TEST_PURPOSE="<Or> Keyword" + +test_code() { + # Generate applications.menu + mkdir -p ${XDG_CONFIG_DIR}/menus + ./expand > ${XDG_CONFIG_DIR}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + <!-- Search the default locations --> + <DefaultAppDirs/> + + <Menu> + <Name>Applications</Name> + <Include> + <Or> + <Filename>freecell.desktop</Filename> + <Category>Game</Category> + </Or> + </Include> + </Menu> +</Menu> +EOF + + # Install .desktop files + installData ${XDG_DATA_DIR}/applications gataxx.desktop mahjongg.desktop freecell.desktop glines.desktop +} diff --git a/menu/tests/tests/boolean-logic/result b/menu/tests/tests/boolean-logic/result new file mode 100644 index 0000000..ea47f01 --- /dev/null +++ b/menu/tests/tests/boolean-logic/result @@ -0,0 +1,3 @@ +Apps/ KEdit.desktop ${XDG_DATA_DIR}/applications/KEdit.desktop +Apps/ kwrite.desktop ${XDG_DATA_DIR}/applications/kwrite.desktop +Apps/ kate.desktop ${XDG_DATA_DIR}/applications/kate.desktop diff --git a/menu/tests/tests/boolean-logic/test b/menu/tests/tests/boolean-logic/test new file mode 100644 index 0000000..dc045c4 --- /dev/null +++ b/menu/tests/tests/boolean-logic/test @@ -0,0 +1,36 @@ +TEST_PURPOSE="<And><Category>foo</Category><Not><Category>foo</Category></Not></And> shouldn't match anything" + +test_code() { + # Generate applications.menu + mkdir -p ${XDG_CONFIG_DIR}/menus + ./expand > ${XDG_CONFIG_DIR}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + + <DefaultAppDirs/> + <DefaultDirectoryDirs/> + + <Menu> + <Name>Applications</Name> + <Directory>apps.directory</Directory> + <Include> + <Or> + <Category>TextEditor</Category> + <And> + <Category>Game</Category> + <Not><Category>Game</Category></Not> + </And> + </Or> + </Include> + </Menu> +</Menu> +EOF + + # Install .desktop files + installData ${XDG_DATA_DIR}/applications kwrite.desktop KEdit.desktop kate.desktop + installData ${XDG_DATA_DIR}/applications/test freecell.desktop + installData ${XDG_DATA_DIR}/desktop-directories apps.directory +} diff --git a/menu/tests/tests/desktop-name-collision/result b/menu/tests/tests/desktop-name-collision/result new file mode 100644 index 0000000..e1e9221 --- /dev/null +++ b/menu/tests/tests/desktop-name-collision/result @@ -0,0 +1,3 @@ +Development/ kde-gideon.desktop ${XDG_DATA_HOME}/applications/kde-gideon.desktop +Development/ mahjongg.desktop ${XDG_DATA_HOME}/applications/mahjongg.desktop +Games/ freecell.desktop ${XDG_DATA_HOME}/applications/freecell.desktop diff --git a/menu/tests/tests/desktop-name-collision/test b/menu/tests/tests/desktop-name-collision/test new file mode 100644 index 0000000..46b5ded --- /dev/null +++ b/menu/tests/tests/desktop-name-collision/test @@ -0,0 +1,53 @@ +TEST_PURPOSE=".desktop files with same name ..." + +test_code() { + # Tests the type attribute in <MergeFile> + + # Generate applications.menu + mkdir -p ${XDG_CONFIG_DIR}/menus + ./expand > ${XDG_CONFIG_DIR}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + <DefaultAppDirs/> + <Menu> + <Name>Games</Name> + <Include> + <Category>Game</Category> + </Include> + </Menu> + <Menu> + <Name>Development</Name> + <Include> + <Category>Development</Category> + </Include> + </Menu> +</Menu> +EOF + + # Install .desktop files + installData ${XDG_DATA_DIR}/applications freecell.desktop glines.desktop mahjongg.desktop + + # freecell.desktop is installed twice, only the version under ${XDG_DATA_HOME}/applications + # should show up in the menu + # freecell.desktop in ${XDG_DATA_DIR}/applications should be ignored. + installData ${XDG_DATA_HOME}/applications freecell.desktop + + # ${XDG_DATA_HOME}/applications/glines.desktop has NoDisplay=true + # glines.desktop should not be shown + # glines.desktop in ${XDG_DATA_DIR}/applications should be ignored. + installDataAs ${XDG_DATA_HOME}/applications glines-2.desktop glines.desktop + + # ${XDG_DATA_HOME}/applications/mahjongg.desktop has Categories=Development + # mahjongg.desktop should be shown under the Development menu + # mahjongg.desktop in ${XDG_DATA_DIR}/applications should be ignored. + installDataAs ${XDG_DATA_HOME}/applications mahjongg-2.desktop mahjongg.desktop + + # kde/gideon.desktop and kde-gideon.desktop are equivalent + # only the version under ${XDG_DATA_HOME}/applications should show up in the menu + # gideon.desktop in ${XDG_DATA_DIR}/applications/kde should be ignored. + installDataAs ${XDG_DATA_DIR}/applications/kde gideon.desktop + installDataAs ${XDG_DATA_HOME}/applications gideon.desktop kde-gideon.desktop +} diff --git a/menu/tests/tests/menu-multiple-matching/result b/menu/tests/tests/menu-multiple-matching/result new file mode 100644 index 0000000..986c873 --- /dev/null +++ b/menu/tests/tests/menu-multiple-matching/result @@ -0,0 +1,5 @@ +Applications/ KEdit.desktop ${XDG_DATA_DIR}/applications/KEdit.desktop +Applications/ gataxx.desktop ${XDG_DATA_DIR}/applications/gataxx.desktop +Applications/ kate.desktop ${XDG_DATA_DIR}/applications/kate.desktop +Applications/ kwrite.desktop ${XDG_DATA_DIR}/applications/kwrite.desktop +Applications/ quanta.desktop ${XDG_DATA_DIR}/applications/quanta.desktop diff --git a/menu/tests/tests/menu-multiple-matching/test b/menu/tests/tests/menu-multiple-matching/test new file mode 100644 index 0000000..d8914ab --- /dev/null +++ b/menu/tests/tests/menu-multiple-matching/test @@ -0,0 +1,36 @@ +TEST_PURPOSE="complicated rule ..." + +test_code() { + # Generate applications.menu + mkdir -p ${XDG_CONFIG_DIR}/menus + ./expand > ${XDG_CONFIG_DIR}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + <!-- Search the default locations --> + <DefaultAppDirs/> + + <Menu> + <Name>Applications</Name> + <Include> + <And> + <Category>Game</Category> + <Category>BoardGame</Category> + </And> + <Or> + <Category>TextEditor</Category> + <Filename>quanta.desktop</Filename> + </Or> + </Include> + <Exclude> + <Filename>mahjongg.desktop</Filename> + </Exclude> + </Menu> +</Menu> +EOF + + # Install .desktop files + installData ${XDG_DATA_DIR}/applications gataxx.desktop mahjongg.desktop freecell.desktop glines.desktop kwrite.desktop KEdit.desktop quanta.desktop kate.desktop kbabel.desktop +} diff --git a/menu/tests/tests/official-categories/categories.list b/menu/tests/tests/official-categories/categories.list new file mode 100644 index 0000000..6e2198d --- /dev/null +++ b/menu/tests/tests/official-categories/categories.list @@ -0,0 +1,10 @@ +AudioVideo +Development +Education +Game +Graphics +Network +Office +Settings +System +Utility diff --git a/menu/tests/tests/official-categories/test b/menu/tests/tests/official-categories/test new file mode 100644 index 0000000..09621cd --- /dev/null +++ b/menu/tests/tests/official-categories/test @@ -0,0 +1,73 @@ +TEST_PURPOSE="verify all required categories are supported" + +base_loc="tests/official-categories" + +test_code() +{ + local category + for category in $(< "${base_loc}/categories.list"); do + CATEGORY="${category}" ./expand "${base_loc}/unique-entry.desktop" > "data/${category}.desktop" + installData "${XDG_DATA_DIR}/applications" "${category}.desktop" + rm "data/${category}.desktop" + done +} + +query() +{ + echo "$@" + ret='' + while [ -z "$ret" ]; do + echo -n "y/n? :" + read ret + if ! [ "$ret" == "y" -o "$ret" == "n" ]; then + echo "invalid response; must be 'y' or 'n'" + ret='' + fi + done + [ "$ret" == "y" ] && return 0 + return 1 +} + +interpret_results() +{ + # inefficient, but works. + local missed='' + local correct='' + for category in $(< "${base_loc}/categories.list"); do + if grep "/${category}\.desktop" "${MENUTESTDIR}/run-result" > /dev/null; then + correct="${correct} ${category}" + else + missed="${missed} ${category}" + fi + done + if [ -z "${missed}" ]; then + echo ">>> OK" + return 0 + fi + if [ "$(echo $missed)" != "Settings" ]; then + # failures. + cat "${MENUTESTDIR}/run-result" + echo "missed categories $missed" + echo "matched ${correct}" + echo ">>> Failed (missed $(echo $missed | wc -w) out of $(wc -l "${base_loc}/categories.list")" + return 1 + fi + echo ">>> Settings failed; checking interactively" + local ret + if [ "$(id -u)" != "0" ]; then + echo ">>> Cannot go interactive due to test being ran as non-root; re-run as root" + return 1; + elif ! which xdg-desktop-menu &> /dev/null; then + echo ">>> xdg-desktop-menu is not available; cannot do interactive test" + return 1; + fi + xdg-desktop-menu install --mode system --novendor "${XDG_DATA_DIR}/applications/Settings.desktop" + ( + query "Please check for a 'menu-spec-testing' in any gnome/kde system settings panel" + ) + ret=$? + xdg-desktop-menu uninstall --mode system "${XDG_DATA_DIR}/applications/Settings.desktop" + return $(($ret)) +} + +MODE=system_data diff --git a/menu/tests/tests/official-categories/unique-entry.desktop b/menu/tests/tests/official-categories/unique-entry.desktop new file mode 100644 index 0000000..6ee3b88 --- /dev/null +++ b/menu/tests/tests/official-categories/unique-entry.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=menu-spec-testing +Exec=true +Icon=quanta +Type=Application +MimeType=text/html +Comment=menu-spec testing +Categories=${CATEGORY}; diff --git a/menu/tests/tests/submenu-collision/result b/menu/tests/tests/submenu-collision/result new file mode 100644 index 0000000..6aa47d7 --- /dev/null +++ b/menu/tests/tests/submenu-collision/result @@ -0,0 +1,5 @@ +Applications/ KEdit.desktop ${XDG_DATA_DIR}/applications/KEdit.desktop +Applications/ kate.desktop ${XDG_DATA_DIR}/applications/kate.desktop +Applications/ kbabel.desktop ${XDG_DATA_DIR}/applications/kbabel.desktop +Applications/ kwrite.desktop ${XDG_DATA_DIR}/applications/kwrite.desktop +Applications/ quanta.desktop ${XDG_DATA_DIR}/applications/quanta.desktop diff --git a/menu/tests/tests/submenu-collision/test b/menu/tests/tests/submenu-collision/test new file mode 100644 index 0000000..7d29896 --- /dev/null +++ b/menu/tests/tests/submenu-collision/test @@ -0,0 +1,32 @@ +TEST_PURPOSE="two submenus with the same name ..." + +test_code() { + # Generate applications.menu + mkdir -p ${XDG_CONFIG_DIR}/menus + ./expand > ${XDG_CONFIG_DIR}/menus/applications.menu <<EOF + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" + "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> + +<Menu> + <Name>KDE</Name> + <!-- Search the default locations --> + <DefaultAppDirs/> + + <Menu> + <Name>Applications</Name> + <Include> + <Category>TextEditor</Category> + </Include> + </Menu> + <Menu> + <Name>Applications</Name> + <Include> + <Category>Development</Category> + </Include> + </Menu> +</Menu> +EOF + + # Install .desktop files + installData ${XDG_DATA_DIR}/applications kwrite.desktop KEdit.desktop quanta.desktop kate.desktop kbabel.desktop +} diff --git a/menu/tests/tet_menutest b/menu/tests/tet_menutest new file mode 100755 index 0000000..1aae67e --- /dev/null +++ b/menu/tests/tet_menutest @@ -0,0 +1,39 @@ +#!/bin/bash +TET_RUN="asdf" +export MENUTESTDIR="${MENUTESTDIR:-/tmp/menutest}" +. menutest +# hack, figure out the var to use here + +tpstart() { + tet_infoline "$*" + FAIL=N +} + +tet_startup='' +tet_cleanup='' +declare -i count=1 +iclist='' +echo $TESTS +for TESTCASE in ${TESTS}; do + [ ! -e "tests/${TESTCASE}/test" ] && continue; + # this basically curries the arg to run_test. + eval "tp${count}() { + . tests/${TESTCASE}/test + tpstart \"$(. tests/${TESTCASE}/test; echo ${TEST_PURPOSE-none stated})\"; + if ! run_test tests/\"$TESTCASE\"; then + tet_result FAIL; + else + tet_result PASS; + fi + set +x + }"; + iclist="${iclist} ic${count}" + eval "ic${count}=tp${count}" + # force subshelling, so that it doesn't pull a die on us + ((count+=1)) +done +tet_iclist=iclist +. /opt/lsb-tet3-lite/lib/posix_sh/tcm.sh +tet_outputline 100 "xdg menu test" +tet_tcm_main $tet_iclist + diff --git a/menu/tet_scen b/menu/tet_scen new file mode 100644 index 0000000..4fe544e --- /dev/null +++ b/menu/tet_scen @@ -0,0 +1,5 @@ +all + "Starting menu tests" + /tests/tet_menutest + "finished menu tests" + diff --git a/menu/tetexec.cfg b/menu/tetexec.cfg new file mode 100644 index 0000000..ea150c9 --- /dev/null +++ b/menu/tetexec.cfg @@ -0,0 +1 @@ +TET_PASS_TC_NAME=True |