예제 #1
0
void TimelineDock::emitSelectedFromSelection()
{
    if (!m_model.trackList().count()) {
        if (m_model.tractor())
            selectMultitrack();
        else
            emit selected(0);
        return;
    }

    int trackIndex = currentTrack();
    int clipIndex = selection().isEmpty()? 0 : selection().first();
    QScopedPointer<Mlt::ClipInfo> info(getClipInfo(trackIndex, clipIndex));
    if (info && info->producer && info->producer->is_valid()) {
        m_updateCommand.reset(new Timeline::UpdateCommand(*this, trackIndex, clipIndex, info->start));
        // We need to set these special properties so time-based filters
        // can get information about the cut while still applying filters
        // to the cut parent.
        info->producer->set(kFilterInProperty, info->frame_in);
        info->producer->set(kFilterOutProperty, info->frame_out);
        info->producer->set(kPlaylistStartProperty, info->start);
        info->producer->set(kMultitrackItemProperty, QString("%1:%2").arg(clipIndex).arg(trackIndex).toLatin1().constData());
        m_ignoreNextPositionChange = true;
        emit selected(info->producer);
    }
    m_model.tractor()->set(kFilterInProperty, 0);
    m_model.tractor()->set(kFilterOutProperty, m_model.tractor()->get_length() - 1);
}
예제 #2
0
void TimelineDock::trimClipAtPlayhead(TrimLocation location, bool ripple)
{
    int trackIndex = currentTrack(), clipIndex = -1;
    chooseClipAtPosition(m_position, trackIndex, clipIndex);
    if (trackIndex < 0 || clipIndex < 0)
        return;
    setCurrentTrack(trackIndex);

    int i = m_model.trackList().at(trackIndex).mlt_index;
    QScopedPointer<Mlt::Producer> track(m_model.tractor()->track(i));
    if (!track)
        return;

    QScopedPointer<Mlt::ClipInfo> info(getClipInfo(trackIndex, clipIndex));
    if (!info)
        return;

    if (location == TrimInPoint) {
        MAIN.undoStack()->push(
            new Timeline::TrimClipInCommand(m_model, trackIndex, clipIndex, m_position - info->start, ripple));
        if (ripple)
            setPosition(info->start);
        if (m_updateCommand && m_updateCommand->trackIndex() == trackIndex && m_updateCommand->clipIndex() == clipIndex)
            m_updateCommand->setPosition(trackIndex, clipIndex, m_updateCommand->position() + m_position - info->start);
    } else {
        MAIN.undoStack()->push(
            new Timeline::TrimClipOutCommand(m_model, trackIndex, clipIndex, info->start + info->frame_count - m_position, ripple));
        if (m_updateCommand && m_updateCommand->trackIndex() == trackIndex && m_updateCommand->clipIndex() == clipIndex)
            m_updateCommand->setPosition(trackIndex, clipIndex,-1);
    }
}
예제 #3
0
void TimelineDock::removeSelection(bool withCopy)
{
    if (isTrackLocked(currentTrack())) {
        pulseLockButtonOnTrack(currentTrack());
        return;
    }
    if (selection().isEmpty())
        selectClipUnderPlayhead();
    if (selection().isEmpty() || currentTrack() < 0)
        return;

    if (withCopy)
        copyClip(currentTrack(), selection().first());
    foreach (int index, selection())
        remove(currentTrack(), index);
}
void MediaPlayerPrivateAVFoundation::seekCompleted(bool finished)
{
    LOG(Media, "MediaPlayerPrivateAVFoundation::seekCompleted(%p) - finished = %d", this, finished);
    UNUSED_PARAM(finished);

    ASSERT(m_seekCount);
    if (--m_seekCount)
        return;

    if (currentTrack())
        currentTrack()->endSeeking();

    m_seekTo = MediaPlayer::invalidTime();
    updateStates();
    m_player->timeChanged();
}
예제 #5
0
void TimelineDock::selectTrack(int by)
{
    int newTrack = currentTrack();
    if (by < 0)
        newTrack = qMax(0, newTrack + by);
    else
        newTrack = qMin(m_model.trackList().size() - 1, newTrack + by);
    setCurrentTrack(newTrack);
}
예제 #6
0
UniversalPana::UniversalPana(KInstance *inst,QObject *parent,QWidget *widgetParent, QString &desktopName, const char* name):
                   KonqSidebarPlugin(inst,parent,widgetParent,desktopName,name)
{
    KGlobal::iconLoader()->addAppDir( "pana" );
    widget = new panaWidget( widgetParent );
//    widgetParent->resize(580,300);
    KToolBar *topBar = new KToolBar( widget, "Topbar" );
    topBar->setIconSize(16);
    topBar->insertButton( "today",    0, SIGNAL( clicked() ), this, SLOT( currentTrack() ) );
    topBar->insertButton( "document", 0, SIGNAL( clicked() ), this, SLOT( lyrics() ) );
    topBar->insertButton( "personal", 0, SIGNAL( clicked() ), this, SLOT( wiki() ) );

    browser = new KHTMLPart(widget, "widget-browser");
//browser=new KHTMLPart(widget);
    kdDebug() << "parentPart() << " << browser->parentPart() << endl;
    browser->setDNDEnabled( true );
    browser->setEncoding( "utf8", true );
    updateBrowser( HTML_FILE );
    browser->view()->installEventFilter( widget );
    panaDCOP = new DCOPClient();
    panaDCOP->attach();

    playerStub   = new PanaPlayerInterface_stub( panaDCOP, "pana", "player");
    playlistStub = new PanaPlaylistInterface_stub( panaDCOP, "pana", "playlist");
    contextStub = new PanaContextBrowserInterface_stub (panaDCOP, "pana", "contextbrowser");

    KToolBar* toolBar=new KToolBar(widget, "PlayerControls");

    toolBar->setIconSize(16);
    toolBar->insertButton( "player_start",0, SIGNAL( clicked() ), this, SLOT( sendPrev() ) );
    toolBar->insertButton( "player_play", 0, SIGNAL( clicked() ), this, SLOT( sendPlay() ) );
    toolBar->insertButton( "player_pause",0, SIGNAL( clicked() ), this, SLOT( sendPause() ) );
    toolBar->insertButton( "player_stop", 0, SIGNAL( clicked() ), this, SLOT( sendStop() ) );
    toolBar->insertButton( "player_end",  0, SIGNAL( clicked() ), this, SLOT( sendNext() ) );

    toolBar->insertSeparator();
    toolBar->insertButton( "arts",        0, SIGNAL( clicked() ), this, SLOT( sendMute() ) );

    vol_slider = new QSlider(0,100,1,0,Qt::Horizontal, toolBar,"volume");
    vol_slider->setLineStep(2);

    connect(vol_slider, SIGNAL( valueChanged(int) ), this, SLOT(volChanged(int ) ) );
    toolBar->insertWidget(1,2, vol_slider);

    fileInfo  = new QFileInfo(HTML_FILE);
    QTimer *t = new QTimer( this );

    connect( t, SIGNAL(timeout()), SLOT(updateStatus() ) );
    t->start( 2000, false );
    kdDebug() << "Connecting widget signal" << endl;

    connect( widget,                      SIGNAL( emitURL( const KURL &)),
             this,                        SLOT( openURLRequest( const KURL &) ) );
    connect( browser->browserExtension(), SIGNAL( openURLRequest( const KURL &, const KParts::URLArgs & ) ),
             this,                        SLOT( openURLRequest( const KURL & ) ) );
    widget->show();
}
예제 #7
0
void TimelineDock::appendFromPlaylist(Mlt::Playlist *playlist)
{
    int trackIndex = currentTrack();
    if (isTrackLocked(trackIndex)) {
        pulseLockButtonOnTrack(trackIndex);
        return;
    }
    m_model.appendFromPlaylist(playlist, trackIndex);
}
예제 #8
0
void TimelineDock::emitClipSelectedFromSelection()
{
    if (selection().isEmpty() || currentTrack() == -1) {
        emit clipSelected(0);
        return;
    }

    Mlt::ClipInfo* info = getClipInfo(currentTrack(), selection().first());
    if (info && info->producer && info->producer->is_valid()) {
        // We need to set these special properties so time-based filters
        // can get information about the cut while still applying filters
        // to the cut parent.
        info->producer->set(kFilterInProperty, info->frame_in);
        info->producer->set(kFilterOutProperty, info->frame_out);
        emit clipSelected(info->producer);
        MAIN.loadProducerWidget(info->producer);
        delete info;
    }
}
예제 #9
0
void TimelineDock::removeTrack()
{
    if (m_model.trackList().size() > 0) {
        int trackIndex = currentTrack();
        MAIN.undoStack()->push(
                new Timeline::RemoveTrackCommand(m_model, trackIndex));
        if (trackIndex >= m_model.trackList().count())
            setCurrentTrack(m_model.trackList().count() - 1);
    }
}
예제 #10
0
int PlaylistModel::randomTrack() const
{
    if (trackCount() < 2)
    {
        return 0;
    }

    qsrand(QDateTime::currentDateTime().toTime_t());

    KRandomSequence sequence(qrand() % 1000);
    int randomTrack = currentTrack();

    while (randomTrack == currentTrack())
    {
        randomTrack = sequence.getLong(trackCount() - 1);
    }

    return randomTrack;
}
예제 #11
0
void TimelineDock::selectClipUnderPlayhead()
{
    int track = -1, clip = -1;
    chooseClipAtPosition(m_position, &track, &clip);
    if (clip == -1) {
        if (isTrackLocked(currentTrack())) {
            pulseLockButtonOnTrack(currentTrack());
            return;
        }
        int idx = clipIndexAtPlayhead(-1);
        if (idx == -1)
            setSelection(QList<int>());
        else
            setSelection(QList<int>() << idx);
        return;
    }

    setCurrentTrack(track);
    setSelection(QList<int>() << clip);
}
void MediaPlayerPrivateAVFoundation::seekWithTolerance(double time, double negativeTolerance, double positiveTolerance)
{
    if (!metaDataAvailable())
        return;

    if (time > duration())
        time = duration();

    if (currentTime() == time)
        return;

    if (currentTrack())
        currentTrack()->beginSeeking();
    
    LOG(Media, "MediaPlayerPrivateAVFoundation::seek(%p) - seeking to %f", this, time);
    m_seekTo = time;

    ++m_seekCount;
    seekToTime(time, negativeTolerance, positiveTolerance);
}
예제 #13
0
void TimelineDock::dropEvent(QDropEvent *event)
{
    if (event->mimeData()->hasFormat(Mlt::XmlMimeType)) {
        int trackIndex = currentTrack();
        if (trackIndex >= 0) {
            emit dropAccepted(QString::fromUtf8(event->mimeData()->data(Mlt::XmlMimeType)));
            event->acceptProposedAction();
        }
    }
    emit dropped();
}
void MediaPlayerPrivateAVFoundation::seekCompleted(bool finished)
{
    LOG(Media, "MediaPlayerPrivateAVFoundation::seekCompleted(%p) - finished = %d", this, finished);
    UNUSED_PARAM(finished);

    m_seeking = false;

    std::function<void()> pendingSeek;
    std::swap(pendingSeek, m_pendingSeek);

    if (pendingSeek) {
        LOG(Media, "MediaPlayerPrivateAVFoundation::seekCompleted(%p) - issuing pending seek", this);
        pendingSeek();
        return;
    }

    if (currentTrack())
        currentTrack()->endSeeking();

    updateStates();
    m_player->timeChanged();
}
예제 #15
0
void TimelineDock::clearSelectionIfInvalid()
{
    int count = clipCount(currentTrack());

    QList<int> newSelection;
    foreach (int index, selection()) {
        if (index >= count)
            continue;

        newSelection << index;
    }
    setSelection(newSelection);
}
QVariantMap MPRISMediaPlayerPlayer::Metadata()
{
    auto inst = QSpotifySession::instance();
    QVariantMap metadata;
    if (auto track = inst->currentTrack()) {
        metadata.insert("mpris:trackid", QString("/org/mpris/MediaPlayer2/Track/%1").arg(1));//TODO use correct value?
        metadata.insert("mpris:length", track->durationString());
        metadata.insert("xesam:albumArtist", track->albumObject()->artist());
        metadata.insert("xesam:artist", track->artistObject()->name());
        metadata.insert("xesam:title", track->name());
    }
    return metadata;
}
예제 #17
0
int TimelineDock::clipCount(int trackIndex) const
{
    if (trackIndex < 0)
        trackIndex = currentTrack();
    if (trackIndex >= 0 && trackIndex < m_model.trackList().size()) {
        int i = m_model.trackList().at(trackIndex).mlt_index;
        QScopedPointer<Mlt::Producer> track(m_model.tractor()->track(i));
        if (track) {
            Mlt::Playlist playlist(*track);
            return playlist.count();
        }
    }
    return 0;
}
예제 #18
0
void TimelineDock::append(int trackIndex)
{
    if (trackIndex < 0)
        trackIndex = currentTrack();
    if (isTrackLocked(trackIndex)) {
        pulseLockButtonOnTrack(trackIndex);
        return;
    }
    if (MLT.isSeekableClip() || MLT.savedProducer()) {
        MAIN.undoStack()->push(
            new Timeline::AppendCommand(m_model, trackIndex,
                MLT.XML(MLT.isClip()? 0 : MLT.savedProducer())));
    }
}
예제 #19
0
int TimelineDock::clipIndexAtPosition(int trackIndex, int position)
{
    int result = -1;
    if (trackIndex < 0)
        trackIndex = currentTrack();
    if (trackIndex >= 0 && trackIndex < m_model.trackList().size()) {
        int i = m_model.trackList().at(trackIndex).mlt_index;
        QScopedPointer<Mlt::Producer> track(m_model.tractor()->track(i));
        if (track) {
            Mlt::Playlist playlist(*track);
            result = playlist.get_clip_index_at(position);
        }
    }
    return result;
}
예제 #20
0
void MediaPlayerPrivateAVFoundation::seek(float time)
{
    if (!metaDataAvailable())
        return;

    if (time > duration())
        time = duration();

    if (currentTime() == time)
        return;

#if HAVE(AVFOUNDATION_TEXT_TRACK_SUPPORT)
    // Forget any partially accumulated cue data as the seek could be to a time outside of the cue's
    // range, which will mean that the next cue delivered will result in the current cue getting the
    // incorrect duration.
    if (currentTrack())
        currentTrack()->resetCueValues();
#endif
    
    LOG(Media, "MediaPlayerPrivateAVFoundation::seek(%p) - seeking to %f", this, time);
    m_seekTo = time;

    seekToTime(time);
}
예제 #21
0
void TimelineDock::onProducerChanged(Mlt::Producer* after)
{
    int trackIndex = currentTrack();
    if (trackIndex < 0 || selection().isEmpty() || !m_updateCommand || !after || !after->is_valid())
        return;
    if (isTrackLocked(trackIndex)) {
        pulseLockButtonOnTrack(trackIndex);
        return;
    }
    int i = m_model.trackList().at(trackIndex).mlt_index;
    QScopedPointer<Mlt::Producer> track(m_model.tractor()->track(i));
    if (track) {
        // Ensure the new XML has same in/out point as selected clip by making
        // a copy of the changed producer and copying the in/out from timeline.
        Mlt::Playlist playlist(*track);
        int clipIndex = selection().first();
        QScopedPointer<Mlt::ClipInfo> info(playlist.clip_info(clipIndex));
        if (info) {
            double oldSpeed = qstrcmp("timewarp", info->producer->get("mlt_service")) ? 1.0 : info->producer->get_double("warp_speed");
            double newSpeed = qstrcmp("timewarp", after->get("mlt_service")) ? 1.0 : after->get_double("warp_speed");
            double speedRatio = oldSpeed / newSpeed;

            int length = qRound(info->length * speedRatio);
            int in = qMin(qRound(info->frame_in * speedRatio), length - 1);
            int out = qMin(qRound(info->frame_out * speedRatio), length - 1);
            after->set("length", length);
            after->set_in_and_out(in, out);

            // Adjust filters.
            int n = after->filter_count();
            for (int j = 0; j < n; j++) {
                QScopedPointer<Mlt::Filter> filter(after->filter(j));
                if (filter && filter->is_valid() && !filter->get_int("_loader")) {
                    in = qMin(qRound(filter->get_in() * speedRatio), length - 1);
                    out = qMin(qRound(filter->get_out() * speedRatio), length - 1);
                    filter->set_in_and_out(in, out);
                    //TODO: keyframes
                }
            }
        }
    }
    QString xmlAfter = MLT.XML(after);
    m_updateCommand->setXmlAfter(xmlAfter);
    setSelection(); // clearing selection prevents a crash
    MAIN.undoStack()->push(m_updateCommand.take());
}
예제 #22
0
void TimelineDock::overwrite(int trackIndex, int position, const QString &xml)
{
    if (trackIndex < 0)
        trackIndex = currentTrack();
    if (isTrackLocked(trackIndex)) {
        pulseLockButtonOnTrack(trackIndex);
        return;
    }
    if (MLT.isSeekableClip() || MLT.savedProducer() || !xml.isEmpty()) {
        QString xmlToUse = !xml.isEmpty()? xml
            : MLT.XML(MLT.isClip()? 0 : MLT.savedProducer());
        if (position < 0)
            position = m_position;
        MAIN.undoStack()->push(
            new Timeline::OverwriteCommand(m_model, trackIndex, position, xmlToUse));
    }
}
예제 #23
0
void TimelineDock::append(int trackIndex)
{
    if (trackIndex < 0)
        trackIndex = currentTrack();
    if (isTrackLocked(trackIndex)) {
        pulseLockButtonOnTrack(trackIndex);
        return;
    }
    if (MAIN.isSourceClipMyProject()) return;
    if (MLT.isSeekableClip() || MLT.savedProducer()) {
        MAIN.undoStack()->push(
            new Timeline::AppendCommand(m_model, trackIndex,
                MLT.XML(MLT.isClip()? 0 : MLT.savedProducer())));
        selectClipUnderPlayhead();
    } else if (!MLT.isSeekableClip()) {
        emit showStatusMessage(kNonSeekableWarning);
    }
}
예제 #24
0
void TimelineDock::removeTrack()
{
    if (m_model.trackList().size() > 0)
        MAIN.undoStack()->push(
                new Timeline::RemoveTrackCommand(m_model, currentTrack()));
}
예제 #25
0
void TimelineDock::insertTrack()
{
    MAIN.undoStack()->push(
                new Timeline::InsertTrackCommand(m_model, currentTrack()));
}