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

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

    From 43b284b0fcadb798469ea008fd540fbe9df3d6a3 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               |  38 +++++--
     src/apps/mediaplayer/playlist/PlaylistItem.cpp | 138 +++++++++++++++++++++++++
     src/apps/mediaplayer/playlist/PlaylistItem.h   |  10 +-
     3 files changed, 178 insertions(+), 8 deletions(-)
    
    diff --git a/src/apps/mediaplayer/MainWin.cpp b/src/apps/mediaplayer/MainWin.cpp
    index b338404..609ceed 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::MessageReceived(BMessage* msg)  
    622627
    623628                case 14:
    624629                {
    625                     int32 i = specifier.GetInt32("index", 0);
    626                     if (i >= fPlaylist->CountItems()) {
     630                    int32 index = specifier.GetInt32("index", 0);
     631                    if (index >= fPlaylist->CountItems()) {
    627632                        result = B_NO_INIT;
    628633                        break;
    629634                    }
    630635
    631636                    BAutolock _(fPlaylist);
    632                     const PlaylistItem* item = fPlaylist->ItemAt(i);
     637                    const PlaylistItem* item = fPlaylist->ItemAt(index);
    633638                    result = item == NULL ? B_NO_INIT
    634639                        : reply.AddString("result", item->Title());
    635640                    break;
    MainWin::MessageReceived(BMessage* msg)  
    774779                itemRef.SetTo(fPlaylist->ItemAt(
    775780                    fPlaylist->CurrentItemIndex()));
    776781            }
     782//          AddHandler(item);
    777783            _PlaylistItemOpened(itemRef, result);
    778784            break;
    779785        }
    MainWin::GetQuitMessage(BMessage* message)  
    13251331
    13261332
    13271333BHandler*
    1328 MainWin::ResolveSpecifier(BMessage* message, int32 index, BMessage* specifier,
     1334MainWin::ResolveSpecifier(BMessage* msg, int32 index, BMessage* specifier,
    13291335    int32 what, const char* property)
    13301336{
    13311337    BPropertyInfo propertyInfo(sPropertyInfo);
    1332     if (propertyInfo.FindMatch(message, index, specifier, what, property)
    1333         < propertyInfo.CountProperties())
     1338
     1339    if (propertyInfo.FindMatch(msg, index, specifier, what, property) >= 0) {
     1340        if (strcmp(property, "CurrentTrack") == 0) {
     1341            BAutolock _(fPlaylist);
     1342            const PlaylistItem* item = fController->Item();
     1343
     1344            if (item != NULL) {
     1345                AddHandler((BHandler*) item);
     1346                msg->PopSpecifier();
     1347                return (BHandler*) item;
     1348            }
     1349
     1350            BMessage replyMsg(B_MESSAGE_NOT_UNDERSTOOD);
     1351            replyMsg.AddInt32("error", B_NAME_NOT_FOUND);
     1352            replyMsg.AddString("message", "There is no current track.");
     1353            msg->SendReply(&replyMsg);
     1354            return NULL;
     1355        }
     1356
    13341357        return this;
     1358    }
    13351359
    1336     return BWindow::ResolveSpecifier(message, index, specifier, what, property);
     1360    return BWindow::ResolveSpecifier(msg, index, specifier, what, property);
    13371361}
    13381362
    13391363
  • 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',