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); }
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); } }
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(); }
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); }
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(); }
void TimelineDock::appendFromPlaylist(Mlt::Playlist *playlist) { int trackIndex = currentTrack(); if (isTrackLocked(trackIndex)) { pulseLockButtonOnTrack(trackIndex); return; } m_model.appendFromPlaylist(playlist, trackIndex); }
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; } }
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); } }
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; }
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); }
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(); }
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; }
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; }
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()))); } }
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; }
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); }
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()); }
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)); } }
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); } }
void TimelineDock::removeTrack() { if (m_model.trackList().size() > 0) MAIN.undoStack()->push( new Timeline::RemoveTrackCommand(m_model, currentTrack())); }
void TimelineDock::insertTrack() { MAIN.undoStack()->push( new Timeline::InsertTrackCommand(m_model, currentTrack())); }