summaryrefslogtreecommitdiffstats
path: root/amarok/src/enginecontroller.h
blob: cd41112e4d3d3463af23b8a0123692aeba9ffd21 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/***************************************************************************
 *   Copyright (C) 2004 Frederik Holljen <fh@ez.no>                        *
 *             (C) 2004,5 Max Howell <max.howell@methylblue.com>           *
 *             (C) 2004,5 Mark Kretschmann                                 *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef AMAROK_ENGINECONTROLLER_H
#define AMAROK_ENGINECONTROLLER_H

#include "enginebase.h"
#include "engineobserver.h"
#include "metabundle.h"

#include <tqmap.h>
#include <tqobject.h>
#include <tqvaluelist.h>

class TQTimer;

namespace TDEIO { class Job; }


/**
 * This class captures Amarok specific behaviour for some common features.
 * Accessing the engine directly is perfectly legal but on your own risk.
 * TODO: Hide proxy stuff!
 */

class EngineController : public TQObject, public EngineSubject
{
    Q_OBJECT
  

public:
    typedef TQMap<TQString, bool>  ExtensionCache;

    // plugins have their own static space, so calling instance
    // from a plugin won't do any good. you'll only get a new
    // instance with a voidEngine
    static EngineController* instance();
    static EngineBase*       engine() { return instance()->m_engine; }
    static bool              canDecode( const KURL& );
    static ExtensionCache&   extensionCache() { return s_extensionCache; }
    static TQString           engineProperty( const TQString& key ) { return engine()->pluginProperty( key ); }
    static bool              hasEngineProperty( const TQString& key ) { return engine()->hasPluginProperty( key ); }

    uint                     trackPosition() const;

    EngineBase* loadEngine();
    void unplayableNotification();

    uint trackLength() const { return m_bundle.length() * 1000; }
    const MetaBundle &bundle() const;
    KURL previousURL() const { return m_previousUrl; }
    KURL playingURL() const { return bundle().url(); }

    void restoreSession();
    void endSession();

    void updateBundleRating( const int rating ) { m_bundle.setRating(rating); } //Can't update metabundle rating from bundle(), d'oh

    //xx000, xx100, xx200, so at most will be 200ms delay before time displays are updated
    static const int MAIN_TIMER = 300;

    /*enum Filetype { MP3 };*/ //assuming MP3 for time being
    LIBAMAROK_EXPORT static bool installDistroCodec(const TQString& engine /*Filetype type*/);

public slots:
    void previous();
    // forceNext make we go to next track even if Repeat Track is on
    //NOTE If the track ended normally, call next(false) !
    void next( const bool forceNext = true );
    void trackFinished() { next(false); };
    void play();
    void play( const MetaBundle&, uint offset = 0 );
    void pause();
    void stop();
    void playPause(); //pauses if playing, plays if paused or stopped

    void seek( int ms );
    void seekRelative( int ms );
    void seekForward( int ms = 10000 );
    void seekBackward( int ms = 10000 );

    int increaseVolume( int ticks = 100/25 );
    int decreaseVolume( int ticks = 100/25 );
    int setVolume( int percent );

    void mute();

    void playlistChanged() { m_engine->playlistChanged(); }

    void slotStreamMetaData( const MetaBundle &bundle );
    void currentTrackMetaDataChanged( const MetaBundle& bundle );

signals:
    void orderPrevious();
    void orderCurrent();
    void orderNext( const bool );
    void statusText( const TQString& );

private slots:
    void slotEngineMetaData( const Engine::SimpleMetaBundle& );
    void slotMainTimer();
    void slotTrackEnded();
    void slotStateChanged( Engine::State );

protected:
    EngineController();
   ~EngineController();

    // undefined
    EngineController( const EngineController& );
    EngineController &operator=( const EngineController& );

private:
    static ExtensionCache s_extensionCache;

    EngineBase* loadEngine( const TQString &engineName );

    EngineBase*     m_engine;
    EngineBase*     m_voidEngine;
    MetaBundle      m_bundle;
    KURL            m_previousUrl;
    BundleList      m_lastMetadata;
    long            m_delayTime;
    int             m_muteVolume;
    bool            m_xFadeThisTrack;
    bool            m_isTiming;
    TQTimer*         m_timer;
    uint            m_playFailureCount;
    // try to correct start time for tracks from last.fm streams
    bool            m_lastFm;
    uint            m_positionOffset, m_lastPositionOffset;
};


#endif