vision 0.0.3.0 → 0.0.4.0
raw patch · 25 files changed
+1336/−1070 lines, 25 files
Files
- src/Collection.hs +5/−5
- src/Collection/List/View.hs +6/−4
- src/Collection/UI.hs +66/−283
- src/Collection/View.hs +6/−5
- src/Environment.hs +2/−0
- src/Location.hs +6/−4
- src/Location/UI.hs +83/−176
- src/Location/View.hs +6/−6
- src/Playlist.hs +9/−4
- src/Playlist/Model.hs +14/−9
- src/Playlist/UI.hs +73/−275
- src/Playlist/Update.hs +25/−5
- src/Playlist/View.hs +20/−14
- src/Playtime.hs +2/−1
- src/Properties/View.hs +55/−31
- src/UI.hs +55/−81
- src/Utils.hs +23/−0
- src/XMMS.hs +0/−4
- ui/collection-browser.glade +352/−0
- ui/collection-browser.xml +0/−59
- ui/location-browser.glade +210/−0
- ui/location-browser.xml +0/−39
- ui/playlist.glade +314/−0
- ui/playlist.xml +0/−62
- vision.cabal +4/−3
src/Collection.hs view
@@ -45,20 +45,20 @@ browseCollection maybeName = do- let f = browseCollection+ builder <- makeBuilder "collection-browser" - context <- initUI- let ?context = context+ let f = browseCollection context <- initModel let ?context = context - context <- initView+ context <- initView builder let ?context = context - context <- initCollectionUI f+ context <- initUI builder let ?context = context + setupUI builder f setupDnD widgetShowAll window
src/Collection/List/View.hs view
@@ -48,12 +48,14 @@ listSel = vSel context -initListView = do- context <- initContext+initListView builder = do+ context <- initContext builder let ?context = context treeSelectionSetMode listSel SelectionBrowse + treeViewSetModel listView listStore+ treeViewSetHeadersVisible listView False widgetSetSizeRequest listView 200 (-1) @@ -80,8 +82,8 @@ treeViewSetCursor listView [0] Nothing -initContext = do- view <- treeViewNewWithModel listStore+initContext builder = do+ view <- builderGetObject builder castToTreeView "list-view" sel <- treeViewGetSelection view return $ augmentContext View { vView = view
src/Collection/UI.hs view
@@ -18,7 +18,7 @@ -- module Collection.UI- ( initCollectionUI+ ( setupUI ) where import Control.Applicative@@ -34,11 +34,9 @@ import XMMS import Handler import Utils-import Context import Properties ( showPropertyImport , showPropertyManager- , OrderDialog , makeOrderDialog , showOrderDialog ) import Compound@@ -47,65 +45,71 @@ import Collection.Control -data CollectionUI- = CollectionUI { cOrderDialog :: OrderDialog }--orderDialog = cOrderDialog context---initCollectionUI browse = do- context <- initContext+setupUI builder browse = do+ context <- initListView builder let ?context = context - addUIActions $ uiActions browse+ setupActions builder browse+ setupConnection builder - srvAG <- actionGroupNew "server"- actionGroupAddActions srvAG $ srvActions browse- onServerConnectionAdd . ever $ actionGroupSetSensitive srvAG- insertActionGroup srvAG 1+ collFilter `onEntryActivate` applyFilter+ collFilter `onIconPress` \icon ->+ case icon of+ PrimaryIcon -> entrySetText collFilter ""+ SecondaryIcon -> applyFilter - addUIFromFile "collection-browser"+ popup <- getWidget castToMenu "ui/collection-popup"+ setupTreeViewPopup collView popup onCollectionActivated loadSelected onCollectionListMidClick $ browseSelected browse onCollectionListCR $ browseSelected browse - paned <- hPanedNew- boxPackStartDefaults contents paned-- scroll <- scrolledWindowNew Nothing Nothing- scrolledWindowSetPolicy scroll PolicyAutomatic PolicyAutomatic- scrolledWindowSetShadowType scroll ShadowIn- containerAdd scroll listView- panedAdd1 paned scroll-- box <- vBoxNew False 5- panedAdd2 paned box-- boxPackStart box collFilter PackNatural 0- collFilter `onEntryActivate` applyFilter+ popup <- getWidget castToMenu "ui/list-popup"+ setupTreeViewPopup listView popup - scroll <- scrolledWindowNew Nothing Nothing- scrolledWindowSetPolicy scroll PolicyAutomatic PolicyAutomatic- scrolledWindowSetShadowType scroll ShadowIn- containerAdd scroll collView- boxPackStartDefaults box scroll+ return () - popup <- getWidget castToMenu "ui/collection-popup"- setupTreeViewPopup collView popup+setupActions builder browse = do+ orderDialog <- unsafeInterleaveIO $ makeOrderDialog $ \v -> do+ let outerw = outer v+ windowSetTitle outerw "Configure ordering"+ windowSetDefaultSize outerw 500 400 - popup <- getWidget castToMenu "ui/list-popup"- setupTreeViewPopup listView popup+ bindActions builder+ [ ("new-window" , newWindow browse )+ , ("edit-filter" , editFilter )+ , ("all-media" , allMedia )+ , ("configure-columns" , showViewConfigDialog )+ , ("configure-ordering" , showOrderDialog orderDialog getOrder setOrder)+ , ("manage-properties" , showPropertyManager )+ , ("browse-in-new-window" , browseSelected browse )+ , ("save-collection" , saveCollection )+ , ("rename-collection" , renameCollection )+ , ("delete-collection" , removeCollection )+ , ("add-to-playlist" , addToPlaylist False )+ , ("replace-playlist" , addToPlaylist True )+ , ("coll-add-to-playlist" , collAddToPlaylist False )+ , ("coll-replace-playlist" , collAddToPlaylist True )+ , ("list-add-to-playlist" , listAddToPlaylist False )+ , ("list-replace-playlist" , listAddToPlaylist True )+ , ("copy" , editCopy )+ , ("select-all" , editSelectAll )+ , ("invert-selection" , editInvertSelection )+ , ("edit-properties" , showPropertyEditor )+ , ("export-properties" , showPropertyExport )+ , ("import-properties" , showPropertyImport )+ ] - acts <- mapM (getAction srvAG)+ acts <- actions builder [ "rename-collection"- , "remove-collection"+ , "delete-collection" ] onCollectionSelectionChanged $ do en <- isJust <$> getSelectedCollection mapM_ (`actionSetSensitive` en) acts - acts <- mapM (getAction srvAG)+ acts <- actions builder [ "add-to-playlist" , "replace-playlist" ]@@ -119,254 +123,33 @@ w `on` focusOutEvent $ updatePA setupPA listView setupPA collView- updatePA - acts <- mapM (getAction srvAG)- ["copy", "edit-properties", "export-properties"]- let updateE = do+ acts <- actions builder+ [ "copy"+ , "edit-properties"+ , "export-properties"+ ]+ let updateEdit = do en <- (/= 0) <$> treeSelectionCountSelectedRows collSel mapM_ (`actionSetSensitive` en) acts- collSel `onSelectionChanged` updateE- updateE-- updateWindowTitle- return ?context---initContext = do- context <- initListView- let ?context = context+ collSel `onSelectionChanged` updateEdit - orderDialog <- unsafeInterleaveIO $ makeOrderDialog $ \v -> do- let outerw = outer v- windowSetTitle outerw "Configure ordering"- windowSetDefaultSize outerw 500 400+ flip timeoutAdd 0 $ do+ updatePA+ updateEdit+ updateWindowTitle+ return False - return $ augmentContext- CollectionUI { cOrderDialog = orderDialog }+ return () +setupConnection builder = do+ ag <- builderGetObject builder castToActionGroup "server-actions" -uiActions browse =- [ ActionEntry- { actionEntryName = "collection"- , actionEntryLabel = "_Collection"- , actionEntryStockId = Nothing- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = return ()- }- , ActionEntry- { actionEntryName = "new-window"- , actionEntryLabel = "_New window"- , actionEntryStockId = Just stockNew- , actionEntryAccelerator = Just "<Control>n"- , actionEntryTooltip = Nothing- , actionEntryCallback = newWindow browse- }- , ActionEntry- { actionEntryName = "edit-filter"- , actionEntryLabel = "_Edit filter"- , actionEntryStockId = Just stockEdit- , actionEntryAccelerator = Just "<Control>l"- , actionEntryTooltip = Nothing- , actionEntryCallback = editFilter- }- , ActionEntry- { actionEntryName = "all-media"- , actionEntryLabel = "A_ll media"- , actionEntryStockId = Just stockNew- , actionEntryAccelerator = Just "<Control>u"- , actionEntryTooltip = Nothing- , actionEntryCallback = allMedia- }- , ActionEntry- { actionEntryName = "edit"- , actionEntryLabel = "_Edit"- , actionEntryStockId = Nothing- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = return ()- }- , ActionEntry- { actionEntryName = "view"- , actionEntryLabel = "_View"- , actionEntryStockId = Nothing- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = return ()- }- , ActionEntry- { actionEntryName = "configure-columns"- , actionEntryLabel = "Configure _columns"- , actionEntryStockId = Nothing- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = showViewConfigDialog- }- , ActionEntry- { actionEntryName = "configure-ordering"- , actionEntryLabel = "Configure _ordering"- , actionEntryStockId = Nothing- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = showOrderDialog orderDialog getOrder setOrder- }- , ActionEntry- { actionEntryName = "properties"- , actionEntryLabel = "P_roperties"- , actionEntryStockId = Nothing- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = return ()- }- , ActionEntry- { actionEntryName = "manage-properties"- , actionEntryLabel = "_Manage properties"- , actionEntryStockId = Just stockPreferences- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = showPropertyManager- }- , ActionEntry- { actionEntryName = "collection-popup"- , actionEntryLabel = ""- , actionEntryStockId = Nothing- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = return ()- }- ]+ onServerConnectionAdd . ever $ \conn -> do+ actionGroupSetSensitive ag conn+ collFilter `set` [ secondaryIconSensitive := conn ] -srvActions browse =- [ ActionEntry- { actionEntryName = "browse-in-new-window"- , actionEntryLabel = "_Browse in new window"- , actionEntryStockId = Just stockOpen- , actionEntryAccelerator = Just "<Control>Return"- , actionEntryTooltip = Nothing- , actionEntryCallback = browseSelected browse- }- , ActionEntry- { actionEntryName = "save-collection"- , actionEntryLabel = "_Save collection"- , actionEntryStockId = Just stockSave- , actionEntryAccelerator = Just "<Control>s"- , actionEntryTooltip = Nothing- , actionEntryCallback = saveCollection- }- , ActionEntry- { actionEntryName = "rename-collection"- , actionEntryLabel = "Rena_me collection"- , actionEntryStockId = Nothing- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = renameCollection- }- , ActionEntry- { actionEntryName = "remove-collection"- , actionEntryLabel = "Remo_ve collection"- , actionEntryStockId = Just stockDelete- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = removeCollection- }- , ActionEntry- { actionEntryName = "add-to-playlist"- , actionEntryLabel = "_Add to playlist"- , actionEntryStockId = Just stockAdd- , actionEntryAccelerator = Just "<Control>p"- , actionEntryTooltip = Nothing- , actionEntryCallback = addToPlaylist False- }- , ActionEntry- { actionEntryName = "replace-playlist"- , actionEntryLabel = "_Replace playlist"- , actionEntryStockId = Nothing- , actionEntryAccelerator = Just "<Control><Shift>p"- , actionEntryTooltip = Nothing- , actionEntryCallback = addToPlaylist True- }- , ActionEntry- { actionEntryName = "coll-add-to-playlist"- , actionEntryLabel = "_Add to playlist"- , actionEntryStockId = Just stockAdd- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = collAddToPlaylist False- }- , ActionEntry- { actionEntryName = "coll-replace-playlist"- , actionEntryLabel = "_Replace playlist"- , actionEntryStockId = Nothing- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = collAddToPlaylist True- }- , ActionEntry- { actionEntryName = "list-add-to-playlist"- , actionEntryLabel = "_Add to playlist"- , actionEntryStockId = Just stockAdd- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = listAddToPlaylist False- }- , ActionEntry- { actionEntryName = "list-replace-playlist"- , actionEntryLabel = "_Replace playlist"- , actionEntryStockId = Nothing- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = listAddToPlaylist True- }- , ActionEntry- { actionEntryName = "copy"- , actionEntryLabel = "_Copy"- , actionEntryStockId = Just stockCopy- , actionEntryAccelerator = Just "<Control>c"- , actionEntryTooltip = Nothing- , actionEntryCallback = editCopy- }- , ActionEntry- { actionEntryName = "select-all"- , actionEntryLabel = "_Select all"- , actionEntryStockId = Just stockSelectAll- , actionEntryAccelerator = Just "<Control>a"- , actionEntryTooltip = Nothing- , actionEntryCallback = editSelectAll- }- , ActionEntry- { actionEntryName = "invert-selection"- , actionEntryLabel = "_Invert selection"- , actionEntryStockId = Just stockSelectAll- , actionEntryAccelerator = Just "<Control><Shift>a"- , actionEntryTooltip = Nothing- , actionEntryCallback = editInvertSelection- }- , ActionEntry- { actionEntryName = "edit-properties"- , actionEntryLabel = "_Edit properties"- , actionEntryStockId = Just stockEdit- , actionEntryAccelerator = Just "<Alt>Return"- , actionEntryTooltip = Nothing- , actionEntryCallback = showPropertyEditor- }- , ActionEntry- { actionEntryName = "export-properties"- , actionEntryLabel = "E_xport properties"- , actionEntryStockId = Just stockSave- , actionEntryAccelerator = Just ""- , actionEntryTooltip = Nothing- , actionEntryCallback = showPropertyExport- }- , ActionEntry- { actionEntryName = "import-properties"- , actionEntryLabel = "_Import properties"- , actionEntryStockId = Just stockOpen- , actionEntryAccelerator = Just ""- , actionEntryTooltip = Nothing- , actionEntryCallback = showPropertyImport- }- ]+ return () newWindow browse =
src/Collection/View.hs view
@@ -64,10 +64,11 @@ columns = vColumns context -initView = do- context <- initContext+initView builder = do+ context <- initContext builder let ?context = context + treeViewSetModel collView collStore treeViewSetRulesHint collView True treeSelectionSetMode collSel SelectionMultiple @@ -81,10 +82,10 @@ (setColumns True . map fst) False window -initContext = do- view <- treeViewNewWithModel collStore+initContext builder = do+ view <- builderGetObject builder castToTreeView "collection-view" sel <- treeViewGetSelection view- filter <- entryNew+ filter <- builderGetObject builder castToEntry "filter-entry" configDlg <- unsafeInterleaveIO makeConfigDlg columns <- newIORef [] return $ augmentContext
src/Environment.hs view
@@ -25,6 +25,7 @@ , homeDir , dataDir , uiFilePath+ , gladeFilePath , xmmsPath , maybeGetEnv ) where@@ -64,4 +65,5 @@ (Just <$> getEnv var) `catch` \_ -> return Nothing uiFilePath name = dataDir </> "ui" </> name <.> "xml"+gladeFilePath name = dataDir </> "ui" </> name <.> "glade"
src/Location.hs view
@@ -40,16 +40,18 @@ browseLocation order maybeURL = do let f = browseLocation - context <- initUI- let ?context = context+ builder <- makeBuilder "location-browser" context <- initModel order let ?context = context - context <- initView+ context <- initView builder let ?context = context - setupUI f+ context <- initUI builder+ let ?context = context++ setupUI builder f setupDnD widgetShowAll window
src/Location/UI.hs view
@@ -36,41 +36,37 @@ import Location.Control -setupUI browse = do- addUIActions $ uiActions browse-- srvAG <- actionGroupNew "server"- actionGroupAddActions srvAG $ srvActions browse- onServerConnectionAdd . ever $ actionGroupSetSensitive srvAG- insertActionGroup srvAG 1-- addUIFromFile "location-browser"-- toolbar <- getWidget castToToolbar "ui/toolbar"- toolbarSetStyle toolbar ToolbarIcons- boxPackStart contents toolbar PackNatural 0-- item <- toolItemNew- toolItemSetHomogeneous item False- toolItemSetExpand item True- containerAdd item locationEntry- toolbarInsert toolbar item 6-- load <- getAction srvAG "load"- locationEntry `onEntryActivate` actionActivate load+setupUI builder browse = do+ setupActions builder browse+ setupToolbar builder+ setupLocationEntry builder+ setupLocationView builder+ setupConnection builder - scroll <- scrolledWindowNew Nothing Nothing- scrolledWindowSetPolicy scroll PolicyAutomatic PolicyAutomatic- containerAdd scroll locationView- boxPackStartDefaults contents scroll+setupActions builder browse = do+ bindActions builder+ [ ("new-window" , newWindow browse )+ , ("open-location" , openLocation )+ , ("load" , loadCurrentLocation )+ , ("down" , loadAtCursor (loadLocation . Go))+ , ("browse-in-new-window" , browseInNewWindow browse )+ , ("add-to-playlist" , addToPlaylist )+ , ("replace-playlist" , replacePlaylist )+ , ("back" , loadLocation Back )+ , ("forward" , loadLocation Forward )+ , ("up" , loadLocation Up )+ , ("refresh" , loadLocation Refresh )+ ] - popup <- getWidget castToMenu "ui/location-popup"- setupTreeViewPopup locationView popup+ down <- action builder "down"+ binw <- action builder "browse-in-new-window"+ addp <- action builder "add-to-playlist"+ repp <- action builder "replace-playlist"+ back <- action builder "back"+ forward <- action builder "forward"+ up <- action builder "up"+ refresh <- action builder "refresh" - down <- getAction srvAG "down"- binw <- getAction srvAG "browse-in-new-window"- addp <- getAction srvAG "add-to-playlist"- repp <- getAction srvAG "replace-playlist" let updateB = do rows <- treeSelectionGetSelectedRows locationSel (enp, enn) <- case rows of@@ -83,12 +79,59 @@ return (True, False) mapM_ (`actionSetSensitive` enp) [addp, repp] mapM_ (`actionSetSensitive` enn) [down, binw]+ updateN = do+ (eb, ef, eu, er) <- canGo+ actionSetSensitive back eb+ actionSetSensitive forward ef+ actionSetSensitive up eu+ actionSetSensitive refresh er+ locationSel `onSelectionChanged` updateB- updateB+ onLocation . add . ever . const $ updateN+ flip timeoutAdd 0 $ do+ updateB+ updateN+ updateWindowTitle+ return False + return ()++setupToolbar builder = do+ toolbar <- builderGetObject builder castToToolbar "toolbar"++ item <- separatorToolItemNew+ separatorToolItemSetDraw item False+ toolbarInsert toolbar item 4++ item <- toolItemNew+ toolItemSetHomogeneous item False+ toolItemSetExpand item True+ containerAdd item locationEntry+ toolbarInsert toolbar item 5++ item <- separatorToolItemNew+ separatorToolItemSetDraw item False+ toolbarInsert toolbar item 6++setupLocationEntry builder = do+ load <- action builder "load"+ locationEntry `onEntryActivate` actionActivate load+ locationEntry `onIconPress` \icon ->+ case icon of+ PrimaryIcon -> entrySetText locationEntry ""+ SecondaryIcon -> actionActivate load++ return ()++setupLocationView builder = do+ popup <- getWidget castToMenu "ui/location-popup"+ setupTreeViewPopup locationView popup++ down <- action builder "down" locationView `onRowActivated` \_ _ -> actionActivate down + binw <- action builder "browse-in-new-window" locationView `on` buttonPressEvent $ tryEvent $ do MiddleButton <- eventButton SingleClick <- eventClick@@ -102,150 +145,18 @@ Nothing -> return () - back <- getAction srvAG "back"- forward <- getAction srvAG "forward"- up <- getAction srvAG "up"- refresh <- getAction srvAG "refresh"- let updateN = do- (eb, ef, eu, er) <- canGo- actionSetSensitive back eb- actionSetSensitive forward ef- actionSetSensitive up eu- actionSetSensitive refresh er- onLocation . add . ever . const $ updateN- updateN-- updateWindowTitle- return () +setupConnection builder = do+ ag <- builderGetObject builder castToActionGroup "server-actions" -uiActions browse =- [ ActionEntry- { actionEntryName = "location"- , actionEntryLabel = "_Location"- , actionEntryStockId = Nothing- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = return ()- }- , ActionEntry- { actionEntryName = "new-window"- , actionEntryLabel = "_New window"- , actionEntryStockId = Just stockNew- , actionEntryAccelerator = Just "<Control>n"- , actionEntryTooltip = Nothing- , actionEntryCallback = newWindow browse- }- , ActionEntry- { actionEntryName = "open-location"- , actionEntryLabel = "_Open location"- , actionEntryStockId = Nothing- , actionEntryAccelerator = Just "<Control>l"- , actionEntryTooltip = Nothing- , actionEntryCallback = openLocation- }- , ActionEntry- { actionEntryName = "go"- , actionEntryLabel = "_Go"- , actionEntryStockId = Nothing- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = return ()- }- , ActionEntry- { actionEntryName = "location-popup"- , actionEntryLabel = ""- , actionEntryStockId = Nothing- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = return ()- }- , ActionEntry- { actionEntryName = "clear"- , actionEntryLabel = ""- , actionEntryStockId = Just stockClear- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = clearLocationEntry- }- ]+ onServerConnectionAdd . ever $ \conn -> do+ actionGroupSetSensitive ag conn+ locationEntry `set` [secondaryIconSensitive := conn] -srvActions browse =- [ ActionEntry- { actionEntryName = "load"- , actionEntryLabel = ""- , actionEntryStockId = Just stockJumpTo- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = loadCurrentLocation- }- , ActionEntry- { actionEntryName = "down"- , actionEntryLabel = ""- , actionEntryStockId = Nothing- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = loadAtCursor (loadLocation . Go)- }- , ActionEntry- { actionEntryName = "browse-in-new-window"- , actionEntryLabel = "_Browse in new window"- , actionEntryStockId = Just stockOpen- , actionEntryAccelerator = Just "<Control>Return"- , actionEntryTooltip = Nothing- , actionEntryCallback = browseInNewWindow browse- }- , ActionEntry- { actionEntryName = "add-to-playlist"- , actionEntryLabel = "_Add to playlist"- , actionEntryStockId = Just stockAdd- , actionEntryAccelerator = Just "<Control>p"- , actionEntryTooltip = Nothing- , actionEntryCallback = addToPlaylist- }- , ActionEntry- { actionEntryName = "replace-playlist"- , actionEntryLabel = "_Replace playlist"- , actionEntryStockId = Nothing- , actionEntryAccelerator = Just "<Control><Shift>p"- , actionEntryTooltip = Nothing- , actionEntryCallback = replacePlaylist- }- , ActionEntry- { actionEntryName = "back"- , actionEntryLabel = "Go _back"- , actionEntryStockId = Just stockGoBack- , actionEntryAccelerator = Just "<Alt>Left"- , actionEntryTooltip = Nothing- , actionEntryCallback = loadLocation Back- }- , ActionEntry- { actionEntryName = "forward"- , actionEntryLabel = "Go _forward"- , actionEntryStockId = Just stockGoForward- , actionEntryAccelerator = Just "<Alt>Right"- , actionEntryTooltip = Nothing- , actionEntryCallback = loadLocation Forward- }- , ActionEntry- { actionEntryName = "up"- , actionEntryLabel = "Go _up"- , actionEntryStockId = Just stockGoUp- , actionEntryAccelerator = Just "<Alt>Up"- , actionEntryTooltip = Nothing- , actionEntryCallback = loadLocation Up- }- , ActionEntry- { actionEntryName = "refresh"- , actionEntryLabel = "_Refresh"- , actionEntryStockId = Just stockRefresh- , actionEntryAccelerator = Just "F5"- , actionEntryTooltip = Nothing- , actionEntryCallback = loadLocation Refresh- }- ]+ return () + loadCurrentLocation = do text <- trim <$> entryGetText locationEntry case text of@@ -266,10 +177,6 @@ when (iIsDir item) $ func $ iPath item _ -> return ()--clearLocationEntry = do- entrySetText locationEntry ""- widgetGrabFocus locationEntry browseInNewWindow browse = do order <- getSortOrder
src/Location/View.hs view
@@ -45,11 +45,11 @@ locationEntry = vEntry context -initView = do- context <- initContext+initView builder = do+ context <- initContext builder let ?context = context - treeViewSetRulesHint locationView True+ treeViewSetModel locationView sortModel treeSelectionSetMode locationSel SelectionMultiple @@ -93,10 +93,10 @@ return ?context -initContext = do- view <- treeViewNewWithModel sortModel+initContext builder = do+ view <- builderGetObject builder castToTreeView "location-view" sel <- treeViewGetSelection view- entry <- entryNew+ entry <- builderGetObject builder castToEntry "location-entry" return $ augmentContext View { vView = view , vSel = sel
src/Playlist.hs view
@@ -41,7 +41,9 @@ initFormat showPlaylist = do- context <- initUI+ builder <- makeBuilder "playlist"++ context <- initUI builder let ?context = context context <- initModel@@ -50,15 +52,18 @@ context <- initIndex let ?context = context - context <- initView+ context <- initView builder let ?context = context context <- initPlaylistConfig let ?context = context + context <- initUpdate+ let ?context = context+ setupSearch- setupUpdate setupDnD- setupUI+ setupUI builder widgetShowAll window+
src/Playlist/Model.hs view
@@ -26,6 +26,7 @@ , getPlaylistSize , touchPlaylist , onPlaylistUpdated+ , beforeDeletingTrack , playlistGetIds ) where @@ -43,13 +44,15 @@ = State { sName :: Maybe String } data Model- = Model { mStore :: ListStore Int32- , mOnPlaylistUpdated :: HandlerMVar ()- , mState :: MVar State+ = Model { mStore :: ListStore Int32+ , mOnPlaylistUpdated :: HandlerMVar ()+ , mBeforeDeletingTrack :: HandlerMVar Int+ , mState :: MVar State } playlistStore = mStore context onPlaylistUpdated = onHandler (mOnPlaylistUpdated context)+beforeDeletingTrack = onHandler (mBeforeDeletingTrack context) state = mState context getPlaylistName = withMVar state (return . sName)@@ -77,13 +80,15 @@ initContext = do- store <- listStoreNewDND [] Nothing Nothing- onPlaylistUpdated <- makeHandlerMVar- state <- newMVar makeState+ store <- listStoreNewDND [] Nothing Nothing+ onPlaylistUpdated <- makeHandlerMVar+ beforeDeletingTrack <- makeHandlerMVar+ state <- newMVar makeState return $ augmentContext- Model { mStore = store- , mOnPlaylistUpdated = onPlaylistUpdated- , mState = state+ Model { mStore = store+ , mOnPlaylistUpdated = onPlaylistUpdated+ , mBeforeDeletingTrack = beforeDeletingTrack+ , mState = state } makeState =
src/Playlist/UI.hs view
@@ -49,9 +49,24 @@ import Playlist.Control -setupUI = do- addUIActions uiActions+setupUI builder = do+ setupActions builder+ setupPlaybar builder + playlistView `onRowActivated` \[n] _ ->+ playTrack n++ popup <- getWidget castToMenu "ui/playlist-popup"+ setupTreeViewPopup playlistView popup++ window `onDestroy` mainQuit++ return ()+++setupActions builder = do+ urlEntryDialog <- unsafeInterleaveIO $ makeURLEntryDialog+ orderDialog <- unsafeInterleaveIO $ makeOrderDialog $ \v -> do let outerw = outer v updateTitle = do@@ -63,16 +78,48 @@ updateTitle windowSetDefaultSize outerw 500 400 - urlEntryDialog <- unsafeInterleaveIO $ makeURLEntryDialog+ ag <- builderGetObject builder castToActionGroup "server-actions"+ onServerConnectionAdd . ever $ actionGroupSetSensitive ag - srvAG <- actionGroupNew "server"- actionGroupAddActions srvAG $ srvActions orderDialog urlEntryDialog- onServerConnectionAdd . ever $ actionGroupSetSensitive srvAG- insertActionGroup srvAG 1+ bindActions builder+ [ ("play", startPlayback False)+ , ("pause", pausePlayback)+ , ("stop", stopPlayback)+ , ("prev", prevTrack)+ , ("next", nextTrack)+ , ("quit", mainQuit)+ , ("cut", editDelete True)+ , ("copy", editCopy)+ , ("paste", editPaste False)+ , ("append", editPaste True)+ , ("delete", editDelete False)+ , ("select-all", editSelectAll)+ , ("invert-selection", editInvertSelection)+ , ("browse-location", browseLocation SortAscending Nothing)+ , ("browse-collection", browseCollection Nothing)+ , ("add-media", runURLEntryDialog urlEntryDialog)+ , ("clear-playlist", clearPlaylist)+ , ("sort-by", showOrderDialog orderDialog getOrder setOrder)+ , ("configure-playlist", showPlaylistConfigDialog)+ , ("edit-properties", showPropertyEditor)+ , ("export-properties", showPropertyExport)+ , ("import-properties", showPropertyImport)+ , ("manage-properties", showPropertyManager)+ ] - play <- getAction srvAG "play"- pause <- getAction srvAG "pause"- stop <- getAction srvAG "stop"+ play <- action builder "play"+ pause <- action builder "pause"+ stop <- action builder "stop"+ prev <- action builder "prev"+ next <- action builder "next"+ cut <- action builder "cut"+ copy <- action builder "copy"+ paste <- action builder "paste"+ append <- action builder "append"+ delete <- action builder "delete"+ editp <- action builder "edit-properties"+ export <- action builder "export-properties"+ let setupPPS = do ps <- getPlaybackStatus let (ePlay, ePause, eStop) = case ps of@@ -84,10 +131,7 @@ actionSetSensitive pause ePause actionSetVisible pause ePause actionSetSensitive stop eStop-- prev <- getAction srvAG "prev"- next <- getAction srvAG "next"- let setupPN = do+ setupPN = do size <- getPlaylistSize name <- getPlaylistName cpos <- getCurrentTrack@@ -98,49 +142,31 @@ (False, False) actionSetSensitive prev ep actionSetSensitive next en-- cut <- getAction srvAG "cut"- copy <- getAction srvAG "copy"- delete <- getAction srvAG "delete"- editp <- getAction srvAG "edit-properties"- expp <- getAction srvAG "export-properties"- let setupSel = do+ setupSel = do n <- treeSelectionCountSelectedRows playlistSel mapM_ (`actionSetSensitive` (n /= 0))- [cut, copy, delete, editp, expp]-- paste <- getAction srvAG "paste"- append <- getAction srvAG "append"- let setupPA = do+ [cut, copy, delete, editp, export]+ setupPA = do en <- editCheckClipboard mapM_ (`actionSetSensitive` en) [paste, append] onPlaybackStatus . add . ever . const $ setupPPS onCurrentTrack . add . ever . const $ setupPN- onPlaylistUpdated . add . ever . const $ setupPN+ onPlaylistUpdated . add . ever . const $ (setupPN >> updateWindowTitle) onClipboardTargets . add . ever . const $ setupPA playlistSel `onSelectionChanged` setupSel flip timeoutAdd 0 $ do setupPPS setupPN- setupSel setupPA+ setupSel+ updateWindowTitle return False - addUIFromFile "playlist"-- playlistView `onRowActivated` \[n] _ ->- playTrack n-- scroll <- scrolledWindowNew Nothing Nothing- scrolledWindowSetPolicy scroll PolicyAutomatic PolicyAutomatic- scrolledWindowSetShadowType scroll ShadowIn- containerAdd scroll playlistView- boxPackStartDefaults contents scroll+ return () - playbar <- getWidget castToToolbar "ui/playbar"- toolbarSetStyle playbar ToolbarIcons- boxPackEnd contents playbar PackNatural 0+setupPlaybar builder = do+ playbar <- builderGetObject builder castToToolbar "playbar" sep <- separatorToolItemNew separatorToolItemSetDraw sep False@@ -165,241 +191,13 @@ containerAdd volumeItem volView toolbarInsert playbar volumeItem (-1) - popup <- getWidget castToMenu "ui/playlist-popup"- setupTreeViewPopup playlistView popup-- window `onDestroy` mainQuit---uiActions =- [ ActionEntry- { actionEntryName = "music"- , actionEntryLabel = "_Music"- , actionEntryStockId = Nothing- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = return ()- }- , ActionEntry- { actionEntryName = "edit"- , actionEntryLabel = "_Edit"- , actionEntryStockId = Nothing- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = return ()- }- , ActionEntry- { actionEntryName = "browse"- , actionEntryLabel = "_Browse"- , actionEntryStockId = Nothing- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = return ()- }- , ActionEntry- { actionEntryName = "playlist"- , actionEntryLabel = "_Playlist"- , actionEntryStockId = Nothing- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = return ()- }- , ActionEntry- { actionEntryName = "configure-playlist"- , actionEntryLabel = "C_onfigure playlist"- , actionEntryStockId = Just stockPreferences- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = showPlaylistConfigDialog- }- , ActionEntry- { actionEntryName = "properties"- , actionEntryLabel = "P_roperties"- , actionEntryStockId = Nothing- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = return ()- }- , ActionEntry- { actionEntryName = "manage-properties"- , actionEntryLabel = "_Manage properties"- , actionEntryStockId = Just stockPreferences- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = showPropertyManager- }- , ActionEntry- { actionEntryName = "playlist-popup"- , actionEntryLabel = ""- , actionEntryStockId = Nothing- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = return ()- }- ]+ return () -srvActions orderDialog urlEntryDialog =- [ ActionEntry- { actionEntryName = "play"- , actionEntryLabel = "_Play"- , actionEntryStockId = Just stockMediaPlay- , actionEntryAccelerator = Just "<Control>Return"- , actionEntryTooltip = Nothing- , actionEntryCallback = startPlayback False- }- , ActionEntry- { actionEntryName = "pause"- , actionEntryLabel = "_Pause"- , actionEntryStockId = Just stockMediaPause- , actionEntryAccelerator = Just "<Control>Return"- , actionEntryTooltip = Nothing- , actionEntryCallback = pausePlayback- }- , ActionEntry- { actionEntryName = "stop"- , actionEntryLabel = "_Stop"- , actionEntryStockId = Just stockMediaStop- , actionEntryAccelerator = Just "<Control>s"- , actionEntryTooltip = Nothing- , actionEntryCallback = stopPlayback- }- , ActionEntry- { actionEntryName = "prev"- , actionEntryLabel = "P_revious track"- , actionEntryStockId = Just stockMediaPrevious- , actionEntryAccelerator = Just "<Control>p"- , actionEntryTooltip = Nothing- , actionEntryCallback = prevTrack- }- , ActionEntry- { actionEntryName = "next"- , actionEntryLabel = "_Next track"- , actionEntryStockId = Just stockMediaNext- , actionEntryAccelerator = Just "<Control>n"- , actionEntryTooltip = Nothing- , actionEntryCallback = nextTrack- }- , ActionEntry- { actionEntryName = "cut"- , actionEntryLabel = "Cu_t"- , actionEntryStockId = Just stockCut- , actionEntryAccelerator = Just "<Control>x"- , actionEntryTooltip = Nothing- , actionEntryCallback = editDelete True- }- , ActionEntry- { actionEntryName = "copy"- , actionEntryLabel = "_Copy"- , actionEntryStockId = Just stockCopy- , actionEntryAccelerator = Just "<Control>c"- , actionEntryTooltip = Nothing- , actionEntryCallback = editCopy- }- , ActionEntry- { actionEntryName = "paste"- , actionEntryLabel = "_Paste"- , actionEntryStockId = Just stockPaste- , actionEntryAccelerator = Just "<Control>v"- , actionEntryTooltip = Nothing- , actionEntryCallback = editPaste False- }- , ActionEntry- { actionEntryName = "append"- , actionEntryLabel = "_Append"- , actionEntryStockId = Just stockPaste- , actionEntryAccelerator = Just "<Control><Shift>v"- , actionEntryTooltip = Nothing- , actionEntryCallback = editPaste True- }- , ActionEntry- { actionEntryName = "delete"- , actionEntryLabel = "_Delete"- , actionEntryStockId = Just stockDelete- , actionEntryAccelerator = Just "Delete"- , actionEntryTooltip = Nothing- , actionEntryCallback = editDelete False- }- , ActionEntry- { actionEntryName = "select-all"- , actionEntryLabel = "_Select all"- , actionEntryStockId = Just stockSelectAll- , actionEntryAccelerator = Just "<Control>a"- , actionEntryTooltip = Nothing- , actionEntryCallback = editSelectAll- }- , ActionEntry- { actionEntryName = "invert-selection"- , actionEntryLabel = "_Invert selection"- , actionEntryStockId = Just stockSelectAll- , actionEntryAccelerator = Just "<Control><Shift>a"- , actionEntryTooltip = Nothing- , actionEntryCallback = editInvertSelection- }- , ActionEntry- { actionEntryName = "browse-location"- , actionEntryLabel = "Browse _location"- , actionEntryStockId = Nothing- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = browseLocation SortAscending Nothing- }- , ActionEntry- { actionEntryName = "browse-collection"- , actionEntryLabel = "Browse _collection"- , actionEntryStockId = Nothing- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = browseCollection Nothing- }- , ActionEntry- { actionEntryName = "add-media"- , actionEntryLabel = "_Add media"- , actionEntryStockId = Just stockAdd- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = runURLEntryDialog urlEntryDialog- }- , ActionEntry- { actionEntryName = "clear-playlist"- , actionEntryLabel = "_Clear playlist"- , actionEntryStockId = Just stockClear- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = clearPlaylist- }- , ActionEntry- { actionEntryName = "sort-by"- , actionEntryLabel = "_Sort by…"- , actionEntryStockId = Nothing- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = showOrderDialog orderDialog getOrder setOrder- }- , ActionEntry- { actionEntryName = "edit-properties"- , actionEntryLabel = "_Edit properties"- , actionEntryStockId = Just stockEdit- , actionEntryAccelerator = Just "<Alt>Return"- , actionEntryTooltip = Nothing- , actionEntryCallback = showPropertyEditor- }- , ActionEntry- { actionEntryName = "export-properties"- , actionEntryLabel = "E_xport properties"- , actionEntryStockId = Just stockSave- , actionEntryAccelerator = Just ""- , actionEntryTooltip = Nothing- , actionEntryCallback = showPropertyExport- }- , ActionEntry- { actionEntryName = "import-properties"- , actionEntryLabel = "_Import properties"- , actionEntryStockId = Just stockOpen- , actionEntryAccelerator = Just ""- , actionEntryTooltip = Nothing- , actionEntryCallback = showPropertyImport- }- ]+updateWindowTitle = do+ maybeName <- getPlaylistName+ setWindowTitle $ case maybeName of+ Nothing -> "Vision playlist"+ Just name -> name ++ " - Vision playlist" data URLEntry =
src/Playlist/Update.hs view
@@ -18,7 +18,8 @@ -- module Playlist.Update- ( setupUpdate+ ( initUpdate+ , onPlaylistLoaded ) where import Control.Applicative@@ -32,13 +33,23 @@ import XMMS import Handler+import Utils+import Context import Playback import Playlist.Model import Playlist.Index-import Playlist.View -setupUpdate = do+data Context+ = Context { cOnPlaylistLoaded :: HandlerMVar () }++onPlaylistLoaded = onHandler $ cOnPlaylistLoaded context+++initUpdate = do+ context <- initContext+ let ?context = context+ onServerConnectionAdd . ever $ \conn -> if conn then do@@ -50,8 +61,8 @@ persist else do setPlaylistName Nothing- updateWindowTitle clearModel+ onPlaylistLoaded $ invoke () onPlaybackStatus . add . ever . const $ do maybeCT <- getCurrentTrack@@ -78,12 +89,19 @@ _ -> return () + return ?context++initContext = do+ onPlaylistLoaded <- makeHandlerMVar+ return $ augmentContext+ Context { cOnPlaylistLoaded = onPlaylistLoaded }+ setupPlaylist = do name <- result liftIO $ do setPlaylistName $ Just name- updateWindowTitle requestPlaylist name+ onPlaylistLoaded $ invoke () requestPlaylist name = playlistListEntries xmms (Just name) >>* handlePlaylist@@ -107,6 +125,7 @@ when (name == playlist change) $ case change of PlaylistRemove { position = p } -> do+ beforeDeletingTrack $ invoke p listStoreRemove playlistStore p onPlaylistUpdated $ invoke () PlaylistAdd { mlibId = id } -> do@@ -118,6 +137,7 @@ addToIndex id n onPlaylistUpdated $ invoke () PlaylistMove { mlibId = id, position = o, newPosition = n } -> do+ beforeDeletingTrack $ invoke o listStoreRemove playlistStore o listStoreInsert playlistStore n id addToIndex id n
src/Playlist/View.hs view
@@ -17,11 +17,12 @@ -- General Public License for more details. -- +{-# LANGUAGE TupleSections #-}+ module Playlist.View ( initView , playlistView , playlistSel- , updateWindowTitle , getSelectedTracks ) where @@ -29,17 +30,16 @@ import Data.Maybe -import Graphics.UI.Gtk+import Graphics.UI.Gtk hiding (add) import XMMS2.Client import Context-import UI+import Handler import Playback import Playlist.Model import Playlist.Index import Playlist.Format---import Playlist.Control data View@@ -50,10 +50,12 @@ playlistSel = vSel context -initView = do- context <- initContext+initView builder = do+ context <- initContext builder let ?context = context + treeViewSetModel playlistView playlistStore+ treeViewSetRulesHint playlistView True treeViewSetReorderable playlistView True treeViewSetHeadersVisible playlistView False@@ -95,6 +97,16 @@ info <- getInfoIfNeeded iter cell `set` [ cellText := trackInfoDuration info ] + beforeDeletingTrack . add . ever $ \t -> do+ cursor <- treeViewGetCursor playlistView+ case cursor of+ ([p], c) | p == t -> do+ s <- getPlaylistSize+ let p' = if p + 1 < s then p + 1 else max (p - 1) 0+ c' = maybe Nothing (Just . (, False)) c+ treeViewSetCursor playlistView [p'] c'+ _ -> return ()+ return ?context @@ -107,14 +119,8 @@ _ -> False -updateWindowTitle = do- maybeName <- getPlaylistName- setWindowTitle $ case maybeName of- Nothing -> "Vision playlist"- Just name -> name ++ " - Vision playlist"--initContext = do- view <- treeViewNewWithModel playlistStore+initContext builder = do+ view <- builderGetObject builder castToTreeView "playlist-view" sel <- treeViewGetSelection view return $ augmentContext View { vView = view
src/Playtime.hs view
@@ -107,6 +107,8 @@ handleCurrentId = do cid <- result liftIO $ do+ setValue 0+ setUpper bigNum setCurrentId $ if cid == 0 then Nothing@@ -123,7 +125,6 @@ bigNum = 10000000000.0 seek pos = do- putStrLn $ "seek to " ++ show pos eid <- disableUpdate playbackSeekMs xmms (round pos) SeekSet >>* liftIO (scheduleEnableUpdate eid)
src/Properties/View.hs view
@@ -162,33 +162,48 @@ let updFilter func props = do modifyIORef selected $ func (Set.fromList $ map propName props) treeModelFilterRefilter filter- addProps = do- sel <- treeViewGetSelection left- rows <- treeSelectionGetSelectedRows sel- rows <- mapM (treeModelFilterConvertPathToChildPath filter) rows- props <- mapM (listStoreGetValue propertyStore . head) rows- mapM (listStoreAppend store . make) props+ takeProps = do+ sel <- treeViewGetSelection left+ rows <- treeSelectionGetSelectedRows sel+ rows <- mapM (liftM head . treeModelFilterConvertPathToChildPath filter) rows+ props <- mapM (listStoreGetValue propertyStore) rows+ cursor <- treeViewGetCursor left updFilter Set.union props+ case cursor of+ ([n], c) -> do+ size1 <- listStoreGetSize propertyStore+ size2 <- Set.size <$> readIORef selected+ let up = length $ takeWhile (n >) rows+ n' = min (n - up) $ max 0 (size1 - size2 - 1)+ c' = maybe Nothing (Just . (, False)) c+ treeViewSetCursor left [n'] c'+ _ -> return ()+ return props+ addProps =+ mapM_ (listStoreAppend store . make) =<< takeProps - left `onRowActivated` \_ _ -> addProps+ left `onRowActivated` \_ _ ->+ addProps left `on` keyPressEvent $ tryEvent $ do [] <- eventModifier "Return" <- eventKeyName liftIO addProps - setupLeftDnD filter left+ setupLeftDnD left takeProps - right `on` keyPressEvent $ tryEvent $ do- [] <- eventModifier- "Delete" <- eventKeyName- liftIO $ do- sel <- treeViewGetSelection right- rows <- treeSelectionGetSelectedRows sel- props <- mapM (listStoreGetValue store . head) rows- mapM_ (listStoreRemove store . head) $ reverse rows- updFilter (flip Set.difference) $ map fst props+ right `onRowActivated` \_ _ ->+ deleteSelectedRows store right updFilter + right `on` keyPressEvent $ do+ m <- eventModifier+ k <- eventKeyName+ case (m, k) of+ ([], "Delete") -> do+ liftIO $ deleteSelectedRows store right updFilter+ return True+ (_, "Return") -> return True+ _ -> return False setupRightDnD store right make updFilter @@ -201,21 +216,16 @@ , vSelected = selected } --setupLeftDnD filter left = do+setupLeftDnD left takeProps = do targetList <- targetListNew targetListAdd targetList propertyNameListTarget [TargetSameApp] 0 dragSourceSet left [Button1] [ActionCopy] dragSourceSetTargetList left targetList - sel <- treeViewGetSelection left- left `on` dragDataGet $ \_ _ _ -> do- names <- liftIO $ do- rows <- treeSelectionGetSelectedRows sel- rows <- mapM (treeModelFilterConvertPathToChildPath filter) rows- mapM (liftM propName . listStoreGetValue propertyStore . head) rows- selectionDataSetStringList names+ left `on` dragDataGet $ \_ _ _ ->+ selectionDataSetStringList =<<+ liftIO (map propName <$> takeProps) setupDragDest left [DestDefaultMotion, DestDefaultHighlight]@@ -259,8 +269,22 @@ return (True, False) ] - view `on` dragDataDelete $ \_ -> do- rows <- treeSelectionGetSelectedRows sel- props <- mapM (listStoreGetValue store . head) rows- mapM_ (listStoreRemove store . head) $ reverse rows- updFilter (flip Set.difference) $ map fst props+ view `on` dragDataDelete $ const $+ deleteSelectedRows store view updFilter+++deleteSelectedRows store view updFilter = do+ sel <- treeViewGetSelection view+ rows <- map head <$> treeSelectionGetSelectedRows sel+ props <- mapM (listStoreGetValue store) rows+ cursor <- treeViewGetCursor view+ mapM_ (listStoreRemove store) $ reverse rows+ updFilter (flip Set.difference) $ map fst props+ case cursor of+ ([n], c) -> do+ size <- listStoreGetSize store+ let up = length $ takeWhile (n >) rows+ n' = min (n - up) $ max 0 (size - 1)+ c' = maybe Nothing (Just . (, False)) c+ treeViewSetCursor view [n'] c'+ _ -> return ()
src/UI.hs view
@@ -30,6 +30,12 @@ , addUIActions , getAction , windowGroup+ , makeUI+ , makeBuilder+ , action+ , actions+ , bindAction+ , bindActions ) where import Control.Applicative@@ -57,93 +63,61 @@ uiActionGroup = uActionGroup context windowGroup = uWindowGroup context -initUI = do- context <- initContext+setWindowTitle = windowSetTitle window+addUIActions = actionGroupAddActions uiActionGroup+insertActionGroup = uiManagerInsertActionGroup uiManager+addUIFromFile = uiManagerAddUiFromFile uiManager . uiFilePath+maybeGetWidget cast name = fmap cast <$> uiManagerGetWidget uiManager name+getWidget cast name = fromJust <$> maybeGetWidget cast name+getAction group name = fromJust <$> actionGroupGetAction group name+++initUI builder = do+ context <- augmentContext <$> makeUI builder let ?context = context - windowGroupAddWindow windowGroup window- containerAdd window contents+ mapM_ (uncurry $ maybeBindAction builder)+ [ ("close", widgetDestroy window)+ , ("quit", mainQuit)+ , ("about", showAbout window)+ ] - windowAddAccelGroup window =<< uiManagerGetAccelGroup uiManager- insertActionGroup uiActionGroup 1- addUIActions uiActions- addUIFromFile "common"+ return context - menubar <- getWidget castToMenuBar "ui/menubar"- boxPackStart contents menubar PackNatural 0+makeUI builder = do+ window <- builderGetObject builder castToWindow "main-window"+ contents <- builderGetObject builder castToVBox "contents"+ uiManager <- builderGetObject builder castToUIManager "ui-manager"+ uiActionGroup <- builderGetObject builder castToActionGroup "ui-actions"+ windowGroup <- windowGroupNew+ return UI { uWindow = window+ , uContents = contents+ , uManager = uiManager+ , uActionGroup = uiActionGroup+ , uWindowGroup = windowGroup+ } - return ?context+makeBuilder name = do+ builder <- builderNew+ builderAddFromFile builder $ gladeFilePath name+ return builder +action builder name =+ builderGetObject builder castToAction name -initContext = do- window <- windowNew- contents <- vBoxNew False 0- uiManager <- uiManagerNew- uiActionGroup <- actionGroupNew "ui"- windowGroup <- windowGroupNew- return $ augmentContext- UI { uWindow = window- , uContents = contents- , uManager = uiManager- , uActionGroup = uiActionGroup- , uWindowGroup = windowGroup- }+actions builder =+ mapM (action builder) -setWindowTitle = windowSetTitle window-addUIActions = actionGroupAddActions uiActionGroup-insertActionGroup = uiManagerInsertActionGroup uiManager-addUIFromFile = uiManagerAddUiFromFile uiManager . uiFilePath-maybeGetWidget cast name = fmap cast <$> uiManagerGetWidget uiManager name-getWidget cast name = fromJust <$> maybeGetWidget cast name-getAction group name = fromJust <$> actionGroupGetAction group name+bindAction builder name func = do+ a <- action builder name+ a `on` actionActivated $ func -uiActions =- [ ActionEntry- { actionEntryName = "menubar"- , actionEntryLabel = ""- , actionEntryStockId = Nothing- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = return ()- }- , ActionEntry- { actionEntryName = "toolbar"- , actionEntryLabel = ""- , actionEntryStockId = Nothing- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = return ()- }- , ActionEntry- { actionEntryName = "quit"- , actionEntryLabel = "_Quit"- , actionEntryStockId = Just stockQuit- , actionEntryAccelerator = Just "<Control>q"- , actionEntryTooltip = Nothing- , actionEntryCallback = mainQuit- }- , ActionEntry- { actionEntryName = "close-window"- , actionEntryLabel = "_Close window"- , actionEntryStockId = Just stockClose- , actionEntryAccelerator = Just "<Control>w"- , actionEntryTooltip = Nothing- , actionEntryCallback = widgetDestroy window- }- , ActionEntry- { actionEntryName = "help"- , actionEntryLabel = "_Help"- , actionEntryStockId = Nothing- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = return ()- }- , ActionEntry- { actionEntryName = "about"- , actionEntryLabel = "_About"- , actionEntryStockId = Just stockAbout- , actionEntryAccelerator = Nothing- , actionEntryTooltip = Nothing- , actionEntryCallback = showAbout window- }- ]+bindActions builder =+ mapM (uncurry $ bindAction builder)++maybeBindAction builder name func = do+ ma <- builderGetObjectRaw builder name+ case ma of+ Just a -> Just <$> on (castToAction a) actionActivated func+ Nothing -> return Nothing+
src/Utils.hs view
@@ -34,6 +34,9 @@ , hideOnDeleteEvent , eqBy , tryModifyMVar_+ , EntryIcon (..)+ , onIconPress+ , secondaryIconSensitive ) where import Prelude hiding (catch)@@ -46,7 +49,10 @@ import Data.Char hiding (Control) import Codec.Binary.UTF8.String +import Foreign.C.Types+ import Graphics.UI.Gtk+import System.Glib.Properties import XMMS2.Client @@ -174,3 +180,20 @@ deriving instance MonadCatchIO (ResultM c a) ++data EntryIcon+ = PrimaryIcon+ | SecondaryIcon+ deriving (Enum, Eq)++onIconPress+ :: EntryClass ec+ => ec+ -> (EntryIcon -> IO ())+ -> IO (ConnectId ec)+onIconPress entry handler =+ connectGeneric "icon-press" False entry $ \_ pos _ ->+ handler $ toEnum $ fromIntegral (pos :: CInt)++secondaryIconSensitive =+ newAttrFromBoolProperty "secondary-icon-sensitive"
src/XMMS.hs view
@@ -79,23 +79,19 @@ scheduleTryConnect = timeoutAdd tryConnect tryConnect = do- putStr "connecting... " success <- connect xmms xmmsPath if success then do- putStrLn "connected!" disconnectCallbackSet xmms disconnectCallback mainLoopGMainInit xmms modifyMVar_ state $ \s -> return s { sConnected = True } onServerConnection $ invoke True return False else do- putStrLn "failed." scheduleTryConnect 1000 return False disconnectCallback = do- putStrLn "disconnected." modifyMVar_ state $ \s -> return s { sConnected = False } onServerConnection $ invoke False scheduleTryConnect 1000
+ ui/collection-browser.glade view
@@ -0,0 +1,352 @@+<?xml version="1.0" encoding="UTF-8"?>+<interface>+ <requires lib="gtk+" version="2.20"/>+ <!-- interface-naming-policy toplevel-contextual -->+ <object class="GtkUIManager" id="ui-manager">+ <child>+ <object class="GtkActionGroup" id="ui-actions">+ <child>+ <object class="GtkAction" id="collection">+ <property name="label">_Collection</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="new-window">+ <property name="label">_New window</property>+ <property name="stock_id">gtk-new</property>+ </object>+ <accelerator key="n" modifiers="GDK_CONTROL_MASK"/>+ </child>+ <child>+ <object class="GtkAction" id="edit-filter">+ <property name="label">_Edit filter</property>+ <property name="stock_id">gtk-edit</property>+ </object>+ <accelerator key="l" modifiers="GDK_CONTROL_MASK"/>+ </child>+ <child>+ <object class="GtkAction" id="all-media">+ <property name="label">A_ll media</property>+ <property name="stock_id">gtk-new</property>+ </object>+ <accelerator key="u" modifiers="GDK_CONTROL_MASK"/>+ </child>+ <child>+ <object class="GtkAction" id="close">+ <property name="label">_Close window</property>+ <property name="stock_id">gtk-close</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="quit">+ <property name="label">_Quit</property>+ <property name="stock_id">gtk-quit</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="edit">+ <property name="label">_Edit</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="view">+ <property name="label">_View</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="configure-columns">+ <property name="label">Configure _columns</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="configure-ordering">+ <property name="label">Configure _ordering</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="properties">+ <property name="label">P_roperties</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="manage-properties">+ <property name="label">_Manage properties…</property>+ <property name="stock_id">gtk-preferences</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="help">+ <property name="label">_Help</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="about">+ <property name="label">_About</property>+ <property name="stock_id">gtk-about</property>+ </object>+ </child>+ </object>+ </child>+ <child>+ <object class="GtkActionGroup" id="server-actions">+ <child>+ <object class="GtkAction" id="browse-in-new-window">+ <property name="label">_Browse in new window</property>+ <property name="stock_id">gtk-open</property>+ </object>+ <accelerator key="Return" modifiers="GDK_CONTROL_MASK"/>+ </child>+ <child>+ <object class="GtkAction" id="save-collection">+ <property name="label">_Save collection…</property>+ <property name="stock_id">gtk-save</property>+ </object>+ <accelerator key="s" modifiers="GDK_CONTROL_MASK"/>+ </child>+ <child>+ <object class="GtkAction" id="rename-collection">+ <property name="label">Rena_me collection…</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="delete-collection">+ <property name="label">_Delete collection</property>+ <property name="stock_id">gtk-delete</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="add-to-playlist">+ <property name="label">_Add to playlist</property>+ <property name="stock_id">gtk-add</property>+ </object>+ <accelerator key="p" modifiers="GDK_CONTROL_MASK"/>+ </child>+ <child>+ <object class="GtkAction" id="replace-playlist">+ <property name="label">_Replace playlist</property>+ </object>+ <accelerator key="p" modifiers="GDK_CONTROL_MASK | GDK_SHIFT_MASK"/>+ </child>+ <child>+ <object class="GtkAction" id="coll-add-to-playlist">+ <property name="label">_Add to playlist</property>+ <property name="stock_id">gtk-add</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="coll-replace-playlist">+ <property name="label">_Replace playlist</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="list-add-to-playlist">+ <property name="label">_Add to playlist</property>+ <property name="stock_id">gtk-add</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="list-replace-playlist">+ <property name="label">_Replace playlist</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="copy">+ <property name="label">_Copy</property>+ <property name="stock_id">gtk-copy</property>+ </object>+ <accelerator key="c" modifiers="GDK_CONTROL_MASK"/>+ </child>+ <child>+ <object class="GtkAction" id="select-all">+ <property name="label">_Select all</property>+ <property name="stock_id">gtk-select-all</property>+ </object>+ <accelerator key="a" modifiers="GDK_CONTROL_MASK"/>+ </child>+ <child>+ <object class="GtkAction" id="invert-selection">+ <property name="label">_Invert selection</property>+ <property name="stock_id">gtk-select-all</property>+ </object>+ <accelerator key="a" modifiers="GDK_CONTROL_MASK | GDK_SHIFT_MASK"/>+ </child>+ <child>+ <object class="GtkAction" id="edit-properties">+ <property name="label">_Edit properties</property>+ <property name="stock_id">gtk-edit</property>+ </object>+ <accelerator key="Return" modifiers="GDK_MOD1_MASK"/>+ </child>+ <child>+ <object class="GtkAction" id="export-properties">+ <property name="label">E_xport properties…</property>+ <property name="stock_id">gtk-save</property>+ </object>+ <accelerator/>+ </child>+ <child>+ <object class="GtkAction" id="import-properties">+ <property name="label">_Import properties…</property>+ <property name="stock_id">gtk-open</property>+ </object>+ <accelerator/>+ </child>+ </object>+ </child>+ <ui>+ <menubar name="menubar">+ <placeholder name="entries">+ <menu action="collection">+ <menuitem action="new-window"/>+ <menuitem action="edit-filter"/>+ <menuitem action="browse-in-new-window"/>+ <menuitem action="all-media"/>+ <separator/>+ <menuitem action="save-collection"/>+ <menuitem action="rename-collection"/>+ <menuitem action="delete-collection"/>+ <separator/>+ <menuitem action="add-to-playlist"/>+ <menuitem action="replace-playlist"/>+ <separator/>+ <menuitem action="close"/>+ <menuitem action="quit"/>+ </menu>+ <menu action="edit">+ <menuitem action="copy"/>+ <separator/>+ <menuitem action="select-all"/>+ <menuitem action="invert-selection"/>+ </menu>+ <menu action="view">+ <menuitem action="configure-columns"/>+ <menuitem action="configure-ordering"/>+ </menu>+ <menu action="properties">+ <menuitem action="edit-properties"/>+ <menuitem action="export-properties"/>+ <menuitem action="import-properties"/>+ <separator/>+ <menuitem action="manage-properties"/>+ </menu>+ <menu action="help">+ <menuitem action="about"/>+ </menu>+ </placeholder>+ </menubar>+ <popup action="collection-popup">+ <menuitem action="coll-add-to-playlist"/>+ <menuitem action="coll-replace-playlist"/>+ <separator/>+ <menuitem action="copy"/>+ <separator/>+ <menuitem action="select-all"/>+ <menuitem action="invert-selection"/>+ <separator/>+ <menuitem action="edit-properties"/>+ </popup>+ <popup action="list-popup">+ <menuitem action="list-add-to-playlist"/>+ <menuitem action="list-replace-playlist"/>+ <separator/>+ <menuitem action="rename-collection"/>+ <menuitem action="delete-collection"/>+ <separator/>+ <menuitem action="browse-in-new-window"/>+ </popup>+ </ui>+ </object>+ <object class="GtkWindow" id="main-window">+ <child>+ <object class="GtkVBox" id="contents">+ <property name="visible">True</property>+ <child>+ <object class="GtkMenuBar" constructor="ui-manager" id="menubar">+ <property name="visible">True</property>+ </object>+ <packing>+ <property name="expand">False</property>+ <property name="position">0</property>+ </packing>+ </child>+ <child>+ <object class="GtkHPaned" id="paned">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <child>+ <object class="GtkScrolledWindow" id="list-scroll">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="hscrollbar_policy">automatic</property>+ <property name="vscrollbar_policy">automatic</property>+ <property name="shadow_type">in</property>+ <child>+ <object class="GtkTreeView" id="list-view">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="headers_visible">False</property>+ <property name="headers_clickable">False</property>+ </object>+ </child>+ </object>+ <packing>+ <property name="resize">False</property>+ <property name="shrink">True</property>+ </packing>+ </child>+ <child>+ <object class="GtkVBox" id="collection-box">+ <property name="visible">True</property>+ <property name="spacing">5</property>+ <child>+ <object class="GtkEntry" id="filter-entry">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="invisible_char">●</property>+ <property name="primary_icon_stock">gtk-clear</property>+ <property name="primary_icon_activatable">True</property>+ <property name="primary_icon_tooltip_text">Clear filter</property>+ <property name="secondary_icon_stock">gtk-jump-to</property>+ <property name="secondary_icon_activatable">True</property>+ <property name="secondary_icon_tooltip_text">Apply filter to selected collection</property>+ </object>+ <packing>+ <property name="expand">False</property>+ <property name="position">0</property>+ </packing>+ </child>+ <child>+ <object class="GtkScrolledWindow" id="collection-scroll">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="hscrollbar_policy">automatic</property>+ <property name="vscrollbar_policy">automatic</property>+ <property name="shadow_type">in</property>+ <child>+ <object class="GtkTreeView" id="collection-view">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="headers_clickable">False</property>+ <property name="rules_hint">True</property>+ </object>+ </child>+ </object>+ <packing>+ <property name="position">1</property>+ </packing>+ </child>+ </object>+ <packing>+ <property name="resize">True</property>+ <property name="shrink">False</property>+ </packing>+ </child>+ </object>+ <packing>+ <property name="position">1</property>+ </packing>+ </child>+ </object>+ </child>+ </object>+</interface>
− ui/collection-browser.xml
@@ -1,59 +0,0 @@-<ui>- <menubar action="menubar">- <placeholder name="entries">- <menu action="collection">- <menuitem action="new-window"/>- <menuitem action="edit-filter"/>- <menuitem action="browse-in-new-window"/>- <menuitem action="all-media"/>- <separator/>- <menuitem action="save-collection"/>- <menuitem action="rename-collection"/>- <menuitem action="remove-collection"/>- <separator/>- <menuitem action="add-to-playlist"/>- <menuitem action="replace-playlist"/>- <separator/>- <menuitem action="close-window"/>- <menuitem action="quit"/>- </menu>- <menu action="edit">- <menuitem action="copy"/>- <separator/>- <menuitem action="select-all"/>- <menuitem action="invert-selection"/>- </menu>- <menu action="view">- <menuitem action="configure-columns"/>- <menuitem action="configure-ordering"/>- </menu>- <menu action="properties">- <menuitem action="edit-properties"/>- <menuitem action="export-properties"/>- <menuitem action="import-properties"/>- <separator/>- <menuitem action="manage-properties"/>- </menu>- </placeholder>- </menubar>- <popup action="collection-popup">- <menuitem action="coll-add-to-playlist"/>- <menuitem action="coll-replace-playlist"/>- <separator/>- <menuitem action="copy"/>- <separator/>- <menuitem action="select-all"/>- <menuitem action="invert-selection"/>- <separator/>- <menuitem action="edit-properties"/>- </popup>- <popup action="list-popup">- <menuitem action="list-add-to-playlist"/>- <menuitem action="list-replace-playlist"/>- <separator/>- <menuitem action="rename-collection"/>- <menuitem action="remove-collection"/>- <separator/>- <menuitem action="browse-in-new-window"/>- </popup>-</ui>
+ ui/location-browser.glade view
@@ -0,0 +1,210 @@+<?xml version="1.0" encoding="UTF-8"?>+<interface>+ <requires lib="gtk+" version="2.20"/>+ <!-- interface-naming-policy toplevel-contextual -->+ <object class="GtkUIManager" id="ui-manager">+ <child>+ <object class="GtkActionGroup" id="ui-actions">+ <child>+ <object class="GtkAction" id="location">+ <property name="label">_Location</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="new-window">+ <property name="label">_New window</property>+ <property name="stock_id">gtk-new</property>+ </object>+ <accelerator key="n" modifiers="GDK_CONTROL_MASK"/>+ </child>+ <child>+ <object class="GtkAction" id="open-location">+ <property name="label">_Open location</property>+ </object>+ <accelerator key="l" modifiers="GDK_CONTROL_MASK"/>+ </child>+ <child>+ <object class="GtkAction" id="close">+ <property name="label">_Close window</property>+ <property name="stock_id">gtk-close</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="quit">+ <property name="label">_Quit</property>+ <property name="stock_id">gtk-quit</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="go">+ <property name="label">_Go</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="help">+ <property name="label">_Help</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="about">+ <property name="label">_About</property>+ <property name="stock_id">gtk-about</property>+ </object>+ </child>+ </object>+ </child>+ <child>+ <object class="GtkActionGroup" id="server-actions">+ <child>+ <object class="GtkAction" id="load"/>+ </child>+ <child>+ <object class="GtkAction" id="down"/>+ </child>+ <child>+ <object class="GtkAction" id="browse-in-new-window">+ <property name="label">_Browse in new window</property>+ <property name="stock_id">gtk-open</property>+ </object>+ <accelerator key="Return" modifiers="GDK_CONTROL_MASK"/>+ </child>+ <child>+ <object class="GtkAction" id="add-to-playlist">+ <property name="label">_Add to playlist</property>+ <property name="stock_id">gtk-add</property>+ </object>+ <accelerator key="p" modifiers="GDK_CONTROL_MASK"/>+ </child>+ <child>+ <object class="GtkAction" id="replace-playlist">+ <property name="label">_Replace playlist</property>+ </object>+ <accelerator key="p" modifiers="GDK_CONTROL_MASK | GDK_SHIFT_MASK"/>+ </child>+ <child>+ <object class="GtkAction" id="back">+ <property name="label">Go _back</property>+ <property name="stock_id">gtk-go-back</property>+ </object>+ <accelerator key="Left" modifiers="GDK_MOD1_MASK"/>+ </child>+ <child>+ <object class="GtkAction" id="forward">+ <property name="label">Go _forward</property>+ <property name="stock_id">gtk-go-forward</property>+ </object>+ <accelerator key="Right" modifiers="GDK_MOD1_MASK"/>+ </child>+ <child>+ <object class="GtkAction" id="up">+ <property name="label">Go _up</property>+ <property name="stock_id">gtk-go-up</property>+ </object>+ <accelerator key="Up" modifiers="GDK_MOD1_MASK"/>+ </child>+ <child>+ <object class="GtkAction" id="refresh">+ <property name="label">_Refresh</property>+ <property name="stock_id">gtk-refresh</property>+ </object>+ <accelerator key="F5"/>+ </child>+ </object>+ </child>+ <ui>+ <menubar action="menubar">+ <placeholder name="entries">+ <menu action="location">+ <menuitem action="new-window"/>+ <menuitem action="open-location"/>+ <menuitem action="browse-in-new-window"/>+ <separator/>+ <menuitem action="add-to-playlist"/>+ <menuitem action="replace-playlist"/>+ <separator/>+ <menuitem action="close"/>+ <menuitem action="quit"/>+ </menu>+ <menu action="go">+ <menuitem action="back"/>+ <menuitem action="forward"/>+ <menuitem action="up"/>+ <separator/>+ <menuitem action="refresh"/>+ </menu>+ <menu action="help">+ <menuitem action="about"/>+ </menu>+ </placeholder>+ </menubar>+ <toolbar action="toolbar">+ <toolitem action="back"/>+ <toolitem action="forward"/>+ <toolitem action="up"/>+ <toolitem action="refresh"/>+ </toolbar>+ <popup action="location-popup">+ <menuitem action="add-to-playlist"/>+ <menuitem action="replace-playlist"/>+ <separator/>+ <menuitem action="browse-in-new-window"/>+ </popup>+ </ui>+ </object>+ <object class="GtkWindow" id="main-window">+ <child>+ <object class="GtkVBox" id="contents">+ <property name="visible">True</property>+ <child>+ <object class="GtkMenuBar" id="menubar" constructor="ui-manager">+ <property name="visible">True</property>+ </object>+ <packing>+ <property name="expand">False</property>+ <property name="position">0</property>+ </packing>+ </child>+ <child>+ <object class="GtkToolbar" id="toolbar" constructor="ui-manager">+ <property name="visible">True</property>+ <property name="toolbar_style">icons</property>+ </object>+ <packing>+ <property name="expand">False</property>+ <property name="position">1</property>+ </packing>+ </child>+ <child>+ <object class="GtkScrolledWindow" id="location-scroll">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="hscrollbar_policy">automatic</property>+ <property name="vscrollbar_policy">automatic</property>+ <property name="shadow_type">in</property>+ <child>+ <object class="GtkTreeView" id="location-view">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="rules_hint">True</property>+ </object>+ </child>+ </object>+ <packing>+ <property name="position">2</property>+ </packing>+ </child>+ </object>+ </child>+ </object>+ <object class="GtkEntry" id="location-entry">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="invisible_char">●</property>+ <property name="primary_icon_stock">gtk-clear</property>+ <property name="primary_icon_activatable">True</property>+ <property name="primary_icon_tooltip_text">Clear location</property>+ <property name="secondary_icon_stock">gtk-jump-to</property>+ <property name="secondary_icon_activatable">True</property>+ <property name="secondary_icon_tooltip_text">Open location</property>+ </object>+</interface>
− ui/location-browser.xml
@@ -1,39 +0,0 @@-<ui>- <menubar action="menubar">- <placeholder name="entries">- <menu action="location">- <menuitem action="new-window"/>- <menuitem action="open-location"/>- <menuitem action="browse-in-new-window"/>- <separator/>- <menuitem action="add-to-playlist"/>- <menuitem action="replace-playlist"/>- <separator/>- <menuitem action="close-window"/>- <menuitem action="quit"/>- </menu>- <menu action="go">- <menuitem action="back"/>- <menuitem action="forward"/>- <menuitem action="up"/>- <separator/>- <menuitem action="refresh"/>- </menu>- </placeholder>- </menubar>- <toolbar action="toolbar">- <toolitem action="back"/>- <toolitem action="forward"/>- <toolitem action="up"/>- <toolitem action="refresh"/>- <separator/>- <toolitem action="clear"/>- <toolitem action="load"/>- </toolbar>- <popup action="location-popup">- <menuitem action="add-to-playlist"/>- <menuitem action="replace-playlist"/>- <separator/>- <menuitem action="browse-in-new-window"/>- </popup>-</ui>
+ ui/playlist.glade view
@@ -0,0 +1,314 @@+<?xml version="1.0"?>+<interface>+ <requires lib="gtk+" version="2.16"/>+ <!-- interface-naming-policy toplevel-contextual -->+ <object class="GtkUIManager" id="ui-manager">+ <child>+ <object class="GtkActionGroup" id="ui-actions">+ <child>+ <object class="GtkAction" id="music">+ <property name="label">_Music</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="quit">+ <property name="label">_Quit</property>+ <property name="stock_id">gtk-quit</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="edit">+ <property name="label">_Edit</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="browse">+ <property name="label">_Browse</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="browse-location">+ <property name="label">Browse _location</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="browse-collection">+ <property name="label">Browse _collection</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="playlist">+ <property name="label">_Playlist</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="configure-playlist">+ <property name="label">C_onfigure playlist…</property>+ <property name="stock_id">gtk-preferences</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="properties">+ <property name="label">P_roperties</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="manage-properties">+ <property name="label">_Manage properties…</property>+ <property name="stock_id">gtk-preferences</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="help">+ <property name="label">_Help</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="about">+ <property name="label">_About</property>+ <property name="stock_id">gtk-about</property>+ </object>+ </child>+ </object>+ </child>+ <child>+ <object class="GtkActionGroup" id="server-actions">+ <child>+ <object class="GtkAction" id="play">+ <property name="label">_Play</property>+ <property name="stock_id">gtk-media-play</property>+ </object>+ <accelerator key="Return" modifiers="GDK_CONTROL_MASK"/>+ </child>+ <child>+ <object class="GtkAction" id="pause">+ <property name="label">_Pause</property>+ <property name="stock_id">gtk-media-pause</property>+ </object>+ <accelerator key="Return" modifiers="GDK_CONTROL_MASK"/>+ </child>+ <child>+ <object class="GtkAction" id="stop">+ <property name="label">_Stop</property>+ <property name="stock_id">gtk-media-stop</property>+ </object>+ <accelerator key="s" modifiers="GDK_CONTROL_MASK"/>+ </child>+ <child>+ <object class="GtkAction" id="prev">+ <property name="label">P_revious track</property>+ <property name="stock_id">gtk-media-previous</property>+ </object>+ <accelerator key="p" modifiers="GDK_CONTROL_MASK"/>+ </child>+ <child>+ <object class="GtkAction" id="next">+ <property name="label">_Next track</property>+ <property name="stock_id">gtk-media-next</property>+ </object>+ <accelerator key="n" modifiers="GDK_CONTROL_MASK"/>+ </child>+ <child>+ <object class="GtkAction" id="cut">+ <property name="label">Cu_t</property>+ <property name="stock_id">gtk-cut</property>+ </object>+ <accelerator key="x" modifiers="GDK_CONTROL_MASK"/>+ </child>+ <child>+ <object class="GtkAction" id="copy">+ <property name="label">_Copy</property>+ <property name="stock_id">gtk-copy</property>+ </object>+ <accelerator key="c" modifiers="GDK_CONTROL_MASK"/>+ </child>+ <child>+ <object class="GtkAction" id="paste">+ <property name="label">_Paste</property>+ <property name="stock_id">gtk-paste</property>+ </object>+ <accelerator key="v" modifiers="GDK_CONTROL_MASK"/>+ </child>+ <child>+ <object class="GtkAction" id="append">+ <property name="label">_Append</property>+ <property name="stock_id">gtk-paste</property>+ </object>+ <accelerator key="v" modifiers="GDK_CONTROL_MASK | GDK_SHIFT_MASK"/>+ </child>+ <child>+ <object class="GtkAction" id="delete">+ <property name="label">_Delete</property>+ <property name="stock_id">gtk-delete</property>+ </object>+ <accelerator key="Delete"/>+ </child>+ <child>+ <object class="GtkAction" id="select-all">+ <property name="label">_Select all</property>+ <property name="stock_id">gtk-select-all</property>+ </object>+ <accelerator key="a" modifiers="GDK_CONTROL_MASK"/>+ </child>+ <child>+ <object class="GtkAction" id="invert-selection">+ <property name="label">_Invert selection</property>+ <property name="stock_id">gtk-select-all</property>+ </object>+ <accelerator key="a" modifiers="GDK_CONTROL_MASK | GDK_SHIFT_MASK"/>+ </child>+ <child>+ <object class="GtkAction" id="add-media">+ <property name="label">_Add media…</property>+ <property name="stock_id">gtk-add</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="clear-playlist">+ <property name="label">_Clear playlist</property>+ <property name="stock_id">gtk-clear</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="sort-by">+ <property name="label">_Sort by…</property>+ </object>+ </child>+ <child>+ <object class="GtkAction" id="edit-properties">+ <property name="label">_Edit properties</property>+ <property name="stock_id">gtk-edit</property>+ </object>+ <accelerator key="Return" modifiers="GDK_MOD1_MASK"/>+ </child>+ <child>+ <object class="GtkAction" id="export-properties">+ <property name="label">E_xport properties…</property>+ <property name="stock_id">gtk-save</property>+ </object>+ <accelerator/>+ </child>+ <child>+ <object class="GtkAction" id="import-properties">+ <property name="label">_Import properties…</property>+ <property name="stock_id">gtk-open</property>+ </object>+ <accelerator/>+ </child>+ </object>+ </child>+ <ui>+ <menubar name="menubar">+ <placeholder name="entries">+ <menu action="music">+ <menuitem action="prev"/>+ <menuitem action="play"/>+ <menuitem action="pause"/>+ <menuitem action="stop"/>+ <menuitem action="next"/>+ <separator/>+ <menuitem action="quit"/>+ </menu>+ <menu action="edit">+ <menuitem action="cut"/>+ <menuitem action="copy"/>+ <menuitem action="paste"/>+ <menuitem action="append"/>+ <menuitem action="delete"/>+ <separator/>+ <menuitem action="select-all"/>+ <menuitem action="invert-selection"/>+ </menu>+ <menu action="browse">+ <menuitem action="browse-location"/>+ <menuitem action="browse-collection"/>+ </menu>+ <menu action="playlist">+ <menuitem action="add-media"/>+ <menuitem action="clear-playlist"/>+ <menuitem action="sort-by"/>+ <separator/>+ <menuitem action="configure-playlist"/>+ </menu>+ <menu action="properties">+ <menuitem action="edit-properties"/>+ <menuitem action="export-properties"/>+ <menuitem action="import-properties"/>+ <separator/>+ <menuitem action="manage-properties"/>+ </menu>+ <menu action="help">+ <menuitem action="about"/>+ </menu>+ </placeholder>+ </menubar>+ <toolbar name="playbar">+ <toolitem action="prev"/>+ <toolitem action="play"/>+ <toolitem action="pause"/>+ <toolitem action="stop"/>+ <toolitem action="next"/>+ </toolbar>+ <popup action="playlist-popup">+ <menuitem action="cut"/>+ <menuitem action="copy"/>+ <menuitem action="paste"/>+ <menuitem action="append"/>+ <menuitem action="delete"/>+ <separator/>+ <menuitem action="select-all"/>+ <menuitem action="invert-selection"/>+ <separator/>+ <menuitem action="edit-properties"/>+ </popup>+ </ui>+ </object>+ <object class="GtkWindow" id="main-window">+ <child>+ <object class="GtkVBox" id="contents">+ <property name="visible">True</property>+ <property name="orientation">vertical</property>+ <child>+ <object class="GtkMenuBar" constructor="ui-manager" id="menubar">+ <property name="visible">True</property>+ </object>+ <packing>+ <property name="expand">False</property>+ <property name="position">0</property>+ </packing>+ </child>+ <child>+ <object class="GtkScrolledWindow" id="playlist-scroll">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="hscrollbar_policy">automatic</property>+ <property name="vscrollbar_policy">automatic</property>+ <property name="shadow_type">in</property>+ <child>+ <object class="GtkTreeView" id="playlist-view">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="headers_visible">False</property>+ <property name="reorderable">True</property>+ <property name="rules_hint">True</property>+ </object>+ </child>+ </object>+ <packing>+ <property name="position">1</property>+ </packing>+ </child>+ <child>+ <object class="GtkToolbar" constructor="ui-manager" id="playbar">+ <property name="visible">True</property>+ <property name="toolbar_style">icons</property>+ </object>+ <packing>+ <property name="expand">False</property>+ <property name="position">2</property>+ </packing>+ </child>+ </object>+ </child>+ </object>+</interface>
− ui/playlist.xml
@@ -1,62 +0,0 @@-<ui>- <menubar name="menubar">- <placeholder name="entries">- <menu action="music">- <menuitem action="prev"/>- <menuitem action="play"/>- <menuitem action="pause"/>- <menuitem action="stop"/>- <menuitem action="next"/>- <separator/>- <menuitem action="quit"/>- </menu>- <menu action="edit">- <menuitem action="cut"/>- <menuitem action="copy"/>- <menuitem action="paste"/>- <menuitem action="append"/>- <menuitem action="delete"/>- <separator/>- <menuitem action="select-all"/>- <menuitem action="invert-selection"/>- </menu>- <menu action="browse">- <menuitem action="browse-location"/>- <menuitem action="browse-collection"/>- </menu>- <menu action="playlist">- <menuitem action="add-media"/>- <menuitem action="clear-playlist"/>- <menuitem action="sort-by"/>- <separator/>- <menuitem action="configure-playlist"/>- </menu>- <menu action="properties">- <menuitem action="edit-properties"/>- <menuitem action="export-properties"/>- <menuitem action="import-properties"/>- <separator/>- <menuitem action="manage-properties"/>- </menu>- </placeholder>- </menubar>- <toolbar name="playbar">- <toolitem action="prev"/>- <toolitem action="play"/>- <toolitem action="pause"/>- <toolitem action="stop"/>- <toolitem action="next"/>- </toolbar>- <popup action="playlist-popup">- <menuitem action="cut"/>- <menuitem action="copy"/>- <menuitem action="paste"/>- <menuitem action="append"/>- <menuitem action="delete"/>- <separator/>- <menuitem action="select-all"/>- <menuitem action="invert-selection"/>- <separator/>- <menuitem action="edit-properties"/>- </popup>-</ui>
vision.cabal view
@@ -1,5 +1,5 @@ name: vision-version: 0.0.3.0+version: 0.0.4.0 author: Oleg Belozeorov maintainer: Oleg Belozeorov <upwawet@gmail.com>@@ -30,7 +30,8 @@ src/Collection/List/Makefile.in, Makefile.in, ui/Makefile.in-data-files: ui/*.xml+data-files: ui/*.xml,+ ui/*.glade executable vision main-is: Vision.hs@@ -117,4 +118,4 @@ source-repository this type: git location: git://github.com/upwawet/vision.git- tag: v0.0.3.0+ tag: v0.0.4.0