Ticket #13845: 0005-Expose-the-current-track-as-a-scripting-object.2.patch

File 0005-Expose-the-current-track-as-a-scripting-object.2.patch, 8.5 KB (added by owenca, 6 years ago)
  • src/apps/mediaplayer/MainWin.cpp

    From 248101f17b3d48d7c20bb9332aa9549d42b5c506 Mon Sep 17 00:00:00 2001
    From: Owen <owenca@users.noreply.github.com>
    Date: Fri, 15 Dec 2017 06:23:10 +0000
    Subject: [PATCH 5/5] Expose the current track as a scripting object.
    
    * Add the CurrentTrack property to the MainWin class.
    * Make the PlaylistItem class scriptable.
    * Add the Name, Author, Album, Title, TrackNumber, Duration, and
    	LocationURI properties to PlaylistItem.
    
    Example usage of the hey command:
    
    	hey MediaPlayer GET Name OF CurrentTrack OF Window 0
    ---
     src/apps/mediaplayer/MainWin.cpp               |  43 ++++++--
     src/apps/mediaplayer/MainWin.h                 |   2 +
     src/apps/mediaplayer/playlist/PlaylistItem.cpp | 138 +++++++++++++++++++++++++
     src/apps/mediaplayer/playlist/PlaylistItem.h   |  10 +-
     4 files changed, 185 insertions(+), 8 deletions(-)
    
    diff --git a/src/apps/mediaplayer/MainWin.cpp b/src/apps/mediaplayer/MainWin.cpp
    index b338404..0361bc7 100644
    a b static property_info sPropertyInfo[] = {  
    190190        "Gets the title of the nth track in Playlist.", 0,
    191191        { B_STRING_TYPE }
    192192    },
     193    { "CurrentTrack", { 0 },
     194        { B_DIRECT_SPECIFIER, 0 },
     195        NULL, 0,
     196        { 0 }
     197    },
    193198
    194199    { 0 }
    195200};
    MainWin::MainWin(bool isFirstWindow, BMessage* message)  
    212217    fHasFile(false),
    213218    fHasVideo(false),
    214219    fHasAudio(false),
     220    fCurrentItem(NULL),
    215221    fPlaylist(new Playlist),
    216222    fPlaylistObserver(new PlaylistObserver(this)),
    217223    fController(new Controller),
    MainWin::MessageReceived(BMessage* msg)  
    622628
    623629                case 14:
    624630                {
    625                     int32 i = specifier.GetInt32("index", 0);
    626                     if (i >= fPlaylist->CountItems()) {
     631                    int32 index = specifier.GetInt32("index", 0);
     632                    if (index >= fPlaylist->CountItems()) {
    627633                        result = B_NO_INIT;
    628634                        break;
    629635                    }
    630636
    631637                    BAutolock _(fPlaylist);
    632                     const PlaylistItem* item = fPlaylist->ItemAt(i);
     638                    const PlaylistItem* item = fPlaylist->ItemAt(index);
    633639                    result = item == NULL ? B_NO_INIT
    634640                        : reply.AddString("result", item->Title());
    635641                    break;
    MainWin::MessageReceived(BMessage* msg)  
    774780                itemRef.SetTo(fPlaylist->ItemAt(
    775781                    fPlaylist->CurrentItemIndex()));
    776782            }
     783
     784            if (fCurrentItem != NULL)
     785                RemoveHandler(fCurrentItem);
     786
     787            fCurrentItem = item;
    777788            _PlaylistItemOpened(itemRef, result);
    778789            break;
    779790        }
    MainWin::WindowActivated(bool active)  
    11201131bool
    11211132MainWin::QuitRequested()
    11221133{
     1134    if (fCurrentItem != NULL)
     1135        RemoveHandler(fCurrentItem);
     1136
    11231137    BMessage message(M_PLAYER_QUIT);
    11241138    GetQuitMessage(&message);
    11251139    be_app->PostMessage(&message);
    MainWin::GetQuitMessage(BMessage* message)  
    13251339
    13261340
    13271341BHandler*
    1328 MainWin::ResolveSpecifier(BMessage* message, int32 index, BMessage* specifier,
     1342MainWin::ResolveSpecifier(BMessage* msg, int32 index, BMessage* specifier,
    13291343    int32 what, const char* property)
    13301344{
    13311345    BPropertyInfo propertyInfo(sPropertyInfo);
    1332     if (propertyInfo.FindMatch(message, index, specifier, what, property)
    1333         < propertyInfo.CountProperties())
     1346
     1347    if (propertyInfo.FindMatch(msg, index, specifier, what, property) >= 0) {
     1348        if (strcmp(property, "CurrentTrack") == 0) {
     1349            if (fCurrentItem != NULL) {
     1350                AddHandler(fCurrentItem);
     1351                msg->PopSpecifier();
     1352                return fCurrentItem;
     1353            }
     1354
     1355            BMessage replyMsg(B_MESSAGE_NOT_UNDERSTOOD);
     1356            replyMsg.AddInt32("error", B_NAME_NOT_FOUND);
     1357            replyMsg.AddString("message", "There is no current track.");
     1358            msg->SendReply(&replyMsg);
     1359            return NULL;
     1360        }
     1361
    13341362        return this;
     1363    }
    13351364
    1336     return BWindow::ResolveSpecifier(message, index, specifier, what, property);
     1365    return BWindow::ResolveSpecifier(msg, index, specifier, what, property);
    13371366}
    13381367
    13391368
  • src/apps/mediaplayer/MainWin.h

    diff --git a/src/apps/mediaplayer/MainWin.h b/src/apps/mediaplayer/MainWin.h
    index c2b2de8..aa2c172 100644
    a b private:  
    164164            bool                fHasVideo;
    165165            bool                fHasAudio;
    166166
     167            PlaylistItem*       fCurrentItem;
     168
    167169            Playlist*           fPlaylist;
    168170            PlaylistObserver*   fPlaylistObserver;
    169171            Controller*         fController;
  • src/apps/mediaplayer/playlist/PlaylistItem.cpp

    diff --git a/src/apps/mediaplayer/playlist/PlaylistItem.cpp b/src/apps/mediaplayer/playlist/PlaylistItem.cpp
    index 1ed5fdc..d4c32b5 100644
    a b  
    99
    1010#include <Catalog.h>
    1111#include <Locale.h>
     12#include <PropertyInfo.h>
    1213
    1314#include "AudioTrackSupplier.h"
    1415#include "TrackSupplier.h"
     
    1819#define B_TRANSLATION_CONTEXT "MediaPlayer-PlaylistItem"
    1920
    2021
     22static property_info sProperties[] = {
     23    { "Name", { B_GET_PROPERTY, 0 },
     24        { B_DIRECT_SPECIFIER, 0 },
     25        "Gets the name.", 0,
     26        { B_STRING_TYPE }
     27    },
     28    { "Author", { B_GET_PROPERTY, 0 },
     29        { B_DIRECT_SPECIFIER, 0 },
     30        "Gets the author.", 0,
     31        { B_STRING_TYPE }
     32    },
     33    { "Album", { B_GET_PROPERTY, 0 },
     34        { B_DIRECT_SPECIFIER, 0 },
     35        "Gets the album.", 0,
     36        { B_STRING_TYPE }
     37    },
     38    { "Title", { B_GET_PROPERTY, 0 },
     39        { B_DIRECT_SPECIFIER, 0 },
     40        "Gets the title.", 0,
     41        { B_STRING_TYPE }
     42    },
     43    { "TrackNumber", { B_GET_PROPERTY, 0 },
     44        { B_DIRECT_SPECIFIER, 0 },
     45        "Gets the track number.", 0,
     46        { B_INT32_TYPE }
     47    },
     48    { "Duration", { B_GET_PROPERTY, 0 },
     49        { B_DIRECT_SPECIFIER, 0 },
     50        "Gets the duration.", 0,
     51        { B_INT64_TYPE }
     52    },
     53    { "LocationURI", { B_GET_PROPERTY, 0 },
     54        { B_DIRECT_SPECIFIER, 0 },
     55        "Gets the location URI.", 0,
     56        { B_STRING_TYPE }
     57    },
     58
     59    { 0 }
     60};
     61
     62
     63BHandler*
     64PlaylistItem::ResolveSpecifier(BMessage* msg, int32 index, BMessage* specifier,
     65    int32 what, const char* property)
     66{
     67    BPropertyInfo propertyInfo(sProperties);
     68    int32 i = propertyInfo.FindMatch(msg, index, specifier, what, property);
     69
     70    if (i >= 0 && i < propertyInfo.CountProperties())
     71        return this;
     72
     73    return BHandler::ResolveSpecifier(msg, index, specifier, what, property);
     74}
     75
     76
     77status_t
     78PlaylistItem::GetSupportedSuites(BMessage* msg)
     79{
     80    msg->AddString("suites", "suite/vnd.Haiku-MediaPlayer");
     81
     82    BPropertyInfo propertyInfo(sProperties);
     83    msg->AddFlat("messages", &propertyInfo);
     84
     85    return BHandler::GetSupportedSuites(msg);
     86}
     87
     88
     89void
     90PlaylistItem::MessageReceived(BMessage* msg)
     91{
     92    if (msg->what != B_GET_PROPERTY) {
     93        BHandler::MessageReceived(msg);
     94        return;
     95    }
     96
     97    int32 index;
     98    BMessage specifier;
     99    int32 what;
     100    const char* property;
     101
     102    if (msg->GetCurrentSpecifier(&index, &specifier, &what, &property)
     103        != B_OK) {
     104        BHandler::MessageReceived(msg);
     105        return;
     106    }
     107
     108    BPropertyInfo propertyInfo(sProperties);
     109    int32 propertyIndex = propertyInfo.FindMatch(msg, index, &specifier, what,
     110                            property);
     111
     112    if (propertyIndex == B_ERROR) {
     113        BHandler::MessageReceived(msg);
     114        return;
     115    }
     116
     117    status_t rc = B_BAD_SCRIPT_SYNTAX;
     118    BMessage reply(B_REPLY);
     119
     120    switch (propertyIndex) {
     121        case 0:
     122            rc = reply.AddString("result", Name());
     123            break;
     124        case 1:
     125            rc = reply.AddString("result", Author());
     126            break;
     127        case 2:
     128            rc = reply.AddString("result", Album());
     129            break;
     130        case 3:
     131            rc = reply.AddString("result", Title());
     132            break;
     133        case 4:
     134            rc = reply.AddInt32("result", TrackNumber());
     135            break;
     136        case 5:
     137            rc = reply.AddInt64("result", Duration());
     138            break;
     139        case 6:
     140            rc = reply.AddString("result", LocationURI());
     141            break;
     142        default:
     143            BHandler::MessageReceived(msg);
     144            return;
     145    }
     146
     147    if (rc != B_OK) {
     148        reply.what = B_MESSAGE_NOT_UNDERSTOOD;
     149        reply.AddString("message", rc == B_BAD_SCRIPT_SYNTAX
     150                                    ? "Didn't understand the specifier"
     151                                    : strerror(rc));
     152        reply.AddInt32("error", rc);
     153    }
     154
     155    msg->SendReply(&reply);
     156}
     157
     158
    21159PlaylistItem::Listener::Listener()
    22160{
    23161}
  • src/apps/mediaplayer/playlist/PlaylistItem.h

    diff --git a/src/apps/mediaplayer/playlist/PlaylistItem.h b/src/apps/mediaplayer/playlist/PlaylistItem.h
    index 7331c21..416afe0 100644
    a b  
    77
    88
    99#include <Archivable.h>
     10#include <Handler.h>
    1011#include <List.h>
    1112#include <NodeInfo.h>
    1213#include <Referenceable.h>
    class BMessage;  
    1819class TrackSupplier;
    1920
    2021
    21 class PlaylistItem : public BArchivable, public BReferenceable {
     22class PlaylistItem : public BHandler, public BReferenceable {
    2223public:
    2324    class Listener {
    2425    public:
    public:  
    3839    virtual status_t            Archive(BMessage* into,
    3940                                    bool deep = true) const = 0;
    4041
     42            BHandler*           ResolveSpecifier(BMessage* msg, int32 index,
     43                                    BMessage* specifier, int32 what,
     44                                    const char* property);
     45            status_t            GetSupportedSuites(BMessage* msg);
     46
     47            void                MessageReceived(BMessage* msg);
     48
    4149    // attributes
    4250    typedef enum {
    4351        ATTR_STRING_NAME            = 'name',