-----------------------------------------------------------------------------
-- |
-- Module      : System.Taffybar.Widget.XDGMenu.Menu
-- Copyright   : 2017 Ulf Jasper
-- License     : BSD3-style (see LICENSE)
--
-- Maintainer  : Ulf Jasper <ulf.jasper@web.de>
-- Stability   : unstable
-- Portability : unportable
--
-- Implementation of version 1.1 of the freedesktop "Desktop Menu
-- Specification", see
-- https://specifications.freedesktop.org/menu-spec/menu-spec-1.1.html
--
-- See also 'MenuWidget'.
-----------------------------------------------------------------------------

module System.Taffybar.Widget.XDGMenu.Menu
  ( Menu(..)
  , MenuEntry(..)
  , buildMenu
  , getApplicationEntries
  ) where

import Data.Char (toLower)
import Data.List
import Data.Maybe
import qualified Data.Text as T
import System.Environment.XDG.DesktopEntry
import System.Taffybar.Information.XDG.Protocol

-- | Displayable menu
data Menu = Menu
  { Menu -> String
fmName :: String
  , Menu -> String
fmComment :: String
  , Menu -> Maybe String
fmIcon :: Maybe String
  , Menu -> [Menu]
fmSubmenus :: [Menu]
  , Menu -> [MenuEntry]
fmEntries :: [MenuEntry]
  , Menu -> Bool
fmOnlyUnallocated :: Bool
  } deriving (Menu -> Menu -> Bool
(Menu -> Menu -> Bool) -> (Menu -> Menu -> Bool) -> Eq Menu
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Menu -> Menu -> Bool
$c/= :: Menu -> Menu -> Bool
== :: Menu -> Menu -> Bool
$c== :: Menu -> Menu -> Bool
Eq, Int -> Menu -> ShowS
[Menu] -> ShowS
Menu -> String
(Int -> Menu -> ShowS)
-> (Menu -> String) -> ([Menu] -> ShowS) -> Show Menu
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Menu] -> ShowS
$cshowList :: [Menu] -> ShowS
show :: Menu -> String
$cshow :: Menu -> String
showsPrec :: Int -> Menu -> ShowS
$cshowsPrec :: Int -> Menu -> ShowS
Show)

-- | Displayable menu entry
data MenuEntry = MenuEntry
  { MenuEntry -> Text
feName :: T.Text
  , MenuEntry -> Text
feComment :: T.Text
  , MenuEntry -> String
feCommand :: String
  , MenuEntry -> Maybe Text
feIcon :: Maybe T.Text
  } deriving (MenuEntry -> MenuEntry -> Bool
(MenuEntry -> MenuEntry -> Bool)
-> (MenuEntry -> MenuEntry -> Bool) -> Eq MenuEntry
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MenuEntry -> MenuEntry -> Bool
$c/= :: MenuEntry -> MenuEntry -> Bool
== :: MenuEntry -> MenuEntry -> Bool
$c== :: MenuEntry -> MenuEntry -> Bool
Eq, Int -> MenuEntry -> ShowS
[MenuEntry] -> ShowS
MenuEntry -> String
(Int -> MenuEntry -> ShowS)
-> (MenuEntry -> String)
-> ([MenuEntry] -> ShowS)
-> Show MenuEntry
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MenuEntry] -> ShowS
$cshowList :: [MenuEntry] -> ShowS
show :: MenuEntry -> String
$cshow :: MenuEntry -> String
showsPrec :: Int -> MenuEntry -> ShowS
$cshowsPrec :: Int -> MenuEntry -> ShowS
Show)

-- | Fetch menus and desktop entries and assemble the menu.
buildMenu :: Maybe String -> IO Menu
buildMenu :: Maybe String -> IO Menu
buildMenu mMenuPrefix :: Maybe String
mMenuPrefix = do
  Maybe (XDGMenu, [DesktopEntry])
mMenuDes <- Maybe String -> IO (Maybe (XDGMenu, [DesktopEntry]))
readXDGMenu Maybe String
mMenuPrefix
  case Maybe (XDGMenu, [DesktopEntry])
mMenuDes of
    Nothing -> Menu -> IO Menu
forall (m :: * -> *) a. Monad m => a -> m a
return (Menu -> IO Menu) -> Menu -> IO Menu
forall a b. (a -> b) -> a -> b
$ String
-> String -> Maybe String -> [Menu] -> [MenuEntry] -> Bool -> Menu
Menu "???" "Parsing failed" Maybe String
forall a. Maybe a
Nothing [] [] Bool
False
    Just (menu :: XDGMenu
menu, des :: [DesktopEntry]
des) -> do
      String
dt <- IO String
getXDGDesktop
      [String]
dirDirs <- IO [String]
getDirectoryDirs
      [String]
langs <- IO [String]
getPreferredLanguages
      (fm :: Menu
fm, ae :: [MenuEntry]
ae) <- String
-> [String]
-> [String]
-> [DesktopEntry]
-> XDGMenu
-> IO (Menu, [MenuEntry])
xdgToMenu String
dt [String]
langs [String]
dirDirs [DesktopEntry]
des XDGMenu
menu
      let fm' :: Menu
fm' = [MenuEntry] -> Menu -> Menu
fixOnlyUnallocated [MenuEntry]
ae<(m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
get href="#local-6989586621679653684">ae<(m :: * -&s.html#workspacesConfig">workspacesConfigworkspacesConfigworkspacesConfigWorkspacesConfig -> Maybe Int
(\langs [String]
dirDirs [DesktopEntry]
show<-identifier hs-voer hs-var">show<-identifier hs-voer hs-var">show<-identifiecoding -> IO ()
setLocaleEncodinget.="hs-spennottext">String
urlbaseUrl :: <- <-identifier hs-voer hs-var">show [String]
"???" "Parsing failed"         }showu :: XDGMenu
menun>menun>showu ::(XDGMenu
menun>menu [DesktopEntry]
Menu -> Maybe String
Priority
,(\langs [St
  • B
  • C
  • <>show
    <-identifier hs-voer hs-var">show<-identnfig -> Bool $c<= :: ClockConfig -> ClockConfig -> Bool < :: ClockConfig -&g/span> getParse< Bool < :: Clgt; c menun>B
  • C
  • <> { var hs-var">fmName ::ate -> Text folass="hs-glyph">= ReaderTgetDirectoryDirs import 21679653693">mindex-C.html">C<>::ate -> Text folass="hs-glyph">= menun>import Data.Uniqun> ::ate -> Text folass="hs-glyph">=fmName ::ate -> Text folass="hs-glyph">=n>i#t:Maybe" title="Data.GI.Base.ShortPrelude">Maybe =n>import 21679653693">(==) :: Dimodoion, CInt) Bool , Maybe getParseName ::ate -> Text folaial">, (de (= menun>WeatherConfig ) i#t:Maybe" title="Data.GI.Base.łkspace workspace(IO [DesktopEntry] -> MaybeT IO [DesktopEntry]ph">::ate -> Text folass="hs-glyph">= , forkIO ,