mirror of
https://invent.kde.org/multimedia/kdenlive
synced 2025-12-06 16:29:58 +01:00
Compare commits
14 Commits
work/embed
...
v20.04.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
78af26f3bf | ||
|
|
115ae088e0 | ||
|
|
211212f70f | ||
|
|
e431ccc258 | ||
|
|
970e4c0c96 | ||
|
|
b4415e26ce | ||
|
|
198037ea44 | ||
|
|
703c0878ec | ||
|
|
7ee8a90754 | ||
|
|
3051f9f235 | ||
|
|
7dd81585a0 | ||
|
|
ba1f644031 | ||
|
|
fddf890fda | ||
|
|
2618f0143e |
@@ -6,7 +6,7 @@ project(Kdenlive)
|
||||
# KDE Application Version, managed by release script
|
||||
set(KDE_APPLICATIONS_VERSION_MAJOR "20")
|
||||
set(KDE_APPLICATIONS_VERSION_MINOR "04")
|
||||
set(KDE_APPLICATIONS_VERSION_MICRO "1")
|
||||
set(KDE_APPLICATIONS_VERSION_MICRO "3")
|
||||
|
||||
set(KDENLIVE_VERSION ${KDE_APPLICATIONS_VERSION_MAJOR}.${KDE_APPLICATIONS_VERSION_MINOR}.${KDE_APPLICATIONS_VERSION_MICRO})
|
||||
|
||||
|
||||
@@ -307,6 +307,7 @@
|
||||
<caption>Kdenlive Audio Adjustments</caption>
|
||||
<caption xml:lang="ca">Ajustaments de l'àudio del Kdenlive</caption>
|
||||
<caption xml:lang="ca-valencia">Ajustaments de l'àudio del Kdenlive</caption>
|
||||
<caption xml:lang="cs">Úpravy audia v Kdenlive</caption>
|
||||
<caption xml:lang="da">Kdenlive lydjusteringer</caption>
|
||||
<caption xml:lang="el">Kdenlive προσαρμογές ήχου</caption>
|
||||
<caption xml:lang="en-GB">Kdenlive Audio Adjustments</caption>
|
||||
|
||||
@@ -261,7 +261,7 @@ void AbstractProjectItem::setClipStatus(CLIPSTATUS status)
|
||||
|
||||
bool AbstractProjectItem::statusReady() const
|
||||
{
|
||||
return m_clipStatus == StatusReady;
|
||||
return m_clipStatus == StatusReady || m_clipStatus == StatusProxyOnly;
|
||||
}
|
||||
|
||||
AbstractProjectItem::CLIPSTATUS AbstractProjectItem::clipStatus() const
|
||||
|
||||
@@ -146,7 +146,7 @@ public:
|
||||
ClipHasAudioAndVideo
|
||||
};
|
||||
|
||||
enum CLIPSTATUS { StatusReady = 0, StatusMissing, StatusWaiting, StatusDeleting };
|
||||
enum CLIPSTATUS { StatusReady = 0, StatusMissing, StatusWaiting, StatusDeleting, StatusProxyOnly };
|
||||
|
||||
virtual void setClipStatus(AbstractProjectItem::CLIPSTATUS status);
|
||||
AbstractProjectItem::CLIPSTATUS clipStatus() const;
|
||||
|
||||
@@ -228,9 +228,9 @@ public:
|
||||
}
|
||||
// Add audio/video icons for selective drag
|
||||
int cType = index.data(AbstractProjectItem::ClipType).toInt();
|
||||
if (clipStatus == AbstractProjectItem::StatusMissing) {
|
||||
if (clipStatus == AbstractProjectItem::StatusMissing || clipStatus == AbstractProjectItem::StatusProxyOnly) {
|
||||
painter->save();
|
||||
painter->setPen(QPen(Qt::red, 3));
|
||||
painter->setPen(QPen(clipStatus == AbstractProjectItem::StatusProxyOnly ? Qt::yellow : Qt::red, 3));
|
||||
painter->drawRect(m_thumbRect);
|
||||
painter->restore();
|
||||
} else if (cType == ClipType::Image || cType == ClipType::SlideShow) {
|
||||
@@ -1415,7 +1415,7 @@ void Bin::slotReloadClip()
|
||||
}
|
||||
if (currentItem) {
|
||||
emit openClip(std::shared_ptr<ProjectClip>());
|
||||
if (currentItem->clipStatus() == AbstractProjectItem::StatusMissing) {
|
||||
if (currentItem->clipStatus() == AbstractProjectItem::StatusMissing || currentItem->clipStatus() == AbstractProjectItem::StatusProxyOnly) {
|
||||
// Don't attempt to reload missing clip
|
||||
emit displayBinMessage(i18n("Missing source clip"), KMessageWidget::Warning);
|
||||
return;
|
||||
|
||||
@@ -82,8 +82,10 @@ ProjectClip::ProjectClip(const QString &id, const QIcon &thumb, const std::share
|
||||
, ClipController(id, std::move(producer))
|
||||
{
|
||||
m_markerModel = std::make_shared<MarkerListModel>(id, pCore->projectManager()->undoStack());
|
||||
if (producer->get_int("_placeholder") == 1 || producer->get_int("_missingsource") == 1) {
|
||||
if (producer->get_int("_placeholder") == 1) {
|
||||
m_clipStatus = StatusMissing;
|
||||
} else if (producer->get_int("_missingsource") == 1) {
|
||||
m_clipStatus = StatusProxyOnly;
|
||||
} else {
|
||||
m_clipStatus = StatusReady;
|
||||
}
|
||||
@@ -859,7 +861,7 @@ std::unique_ptr<Mlt::Producer> ProjectClip::getClone()
|
||||
|
||||
bool ProjectClip::isReady() const
|
||||
{
|
||||
return m_clipStatus == StatusReady;
|
||||
return m_clipStatus == StatusReady || m_clipStatus == StatusProxyOnly;
|
||||
}
|
||||
|
||||
QPoint ProjectClip::zone() const
|
||||
|
||||
@@ -729,7 +729,7 @@ bool ProjectItemModel::requestAddBinClip(QString &id, const std::shared_ptr<Mlt:
|
||||
bool res = addItem(new_clip, parentId, undo, redo);
|
||||
if (res) {
|
||||
new_clip->importEffects(producer);
|
||||
if (new_clip->sourceExists()) {
|
||||
if (new_clip->isReady() || new_clip->sourceExists()) {
|
||||
int blocking = pCore->jobManager()->getBlockingJobId(id, AbstractClipJob::LOADJOB);
|
||||
pCore->jobManager()->startJob<ThumbJob>({id}, blocking, QString(), -1, true);
|
||||
pCore->jobManager()->startJob<AudioThumbJob>({id}, blocking, QString());
|
||||
|
||||
@@ -85,7 +85,7 @@ void EffectStackModel::removeService(const std::shared_ptr<Mlt::Service> &servic
|
||||
std::vector<int> to_delete;
|
||||
for (int i = int(m_childServices.size()) - 1; i >= 0; --i) {
|
||||
auto ptr = m_childServices[uint(i)].lock();
|
||||
if (service->get_int("_childid") == ptr->get_int("_childid")) {
|
||||
if (ptr && service->get_int("_childid") == ptr->get_int("_childid")) {
|
||||
for (int j = 0; j < rootItem->childCount(); ++j) {
|
||||
std::static_pointer_cast<EffectItemModel>(rootItem->child(j))->unplantClone(ptr);
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ bool AudioThumbJob::computeWithMlt()
|
||||
bool AudioThumbJob::computeWithFFMPEG()
|
||||
{
|
||||
QString filePath = m_prod->get("kdenlive:originalurl");
|
||||
if (filePath.isEmpty()) {
|
||||
if (filePath.isEmpty() || !QFile::exists(filePath)) {
|
||||
filePath = m_prod->get("resource");
|
||||
}
|
||||
m_ffmpegProcess.reset(new QProcess);
|
||||
|
||||
@@ -902,16 +902,6 @@ void MainWindow::saveProperties(KConfigGroup &config)
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::readProperties(const KConfigGroup &config)
|
||||
{
|
||||
// read properties here
|
||||
KXmlGuiWindow::readProperties(config);
|
||||
// TODO: fix session management
|
||||
/*if (qApp->isSessionRestored()) {
|
||||
pCore->projectManager()->openFile(QUrl::fromLocalFile(config.readEntry("kdenlive_lastUrl", QString())));
|
||||
}*/
|
||||
}
|
||||
|
||||
void MainWindow::saveNewToolbarConfig()
|
||||
{
|
||||
KXmlGuiWindow::saveNewToolbarConfig();
|
||||
|
||||
@@ -146,8 +146,6 @@ protected:
|
||||
/** @brief Saves the file and the window properties when saving the session. */
|
||||
void saveProperties(KConfigGroup &config) override;
|
||||
|
||||
/** @brief Restores the window and the file when a session is loaded. */
|
||||
void readProperties(const KConfigGroup &config) override;
|
||||
void saveNewToolbarConfig() override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -887,10 +887,8 @@ void Monitor::slotStartDrag()
|
||||
}
|
||||
mimeData->setData(QStringLiteral("kdenlive/producerslist"), prodData);
|
||||
drag->setMimeData(mimeData);
|
||||
/*QPixmap pix = m_currentClip->thumbnail();
|
||||
drag->setPixmap(pix);
|
||||
drag->setHotSpot(QPoint(0, 50));*/
|
||||
drag->exec(Qt::MoveAction);
|
||||
pCore->bin()->processDragEnd();
|
||||
}
|
||||
|
||||
// virtual
|
||||
|
||||
@@ -153,6 +153,10 @@ bool MonitorManager::activateMonitor(Kdenlive::MonitorId name)
|
||||
if (!m_clipMonitor->monitorIsFullScreen()) {
|
||||
m_clipMonitor->parentWidget()->raise();
|
||||
}
|
||||
if (!m_clipMonitor->isVisible()) {
|
||||
m_activeMonitor = m_projectMonitor;
|
||||
return false;
|
||||
}
|
||||
emit updateOverlayInfos(name, KdenliveSettings::displayClipMonitorInfo());
|
||||
m_projectMonitor->displayAudioMonitor(false);
|
||||
m_clipMonitor->displayAudioMonitor(true);
|
||||
@@ -160,6 +164,10 @@ bool MonitorManager::activateMonitor(Kdenlive::MonitorId name)
|
||||
if (!m_projectMonitor->monitorIsFullScreen()) {
|
||||
m_projectMonitor->parentWidget()->raise();
|
||||
}
|
||||
if (!m_projectMonitor->isVisible()) {
|
||||
m_activeMonitor = m_clipMonitor;
|
||||
return false;
|
||||
}
|
||||
emit updateOverlayInfos(name, KdenliveSettings::displayProjectMonitorInfo());
|
||||
m_clipMonitor->displayAudioMonitor(false);
|
||||
m_projectMonitor->displayAudioMonitor(true);
|
||||
|
||||
@@ -36,17 +36,34 @@ Rectangle {
|
||||
{
|
||||
var projectFps = controller.fps()
|
||||
root.timeScale = width / root.duration
|
||||
if (root.duration < 10 * projectFps) {
|
||||
root.frameSize = projectFps * root.timeScale * 0.2
|
||||
} else if (duration < 100 * projectFps) {
|
||||
var displayedLength = root.duration / projectFps;
|
||||
if (displayedLength < 2 ) {
|
||||
// 1 frame tick
|
||||
root.frameSize = root.timeScale
|
||||
} else if (displayedLength < 30) {
|
||||
// 1 second tick
|
||||
frameSize = projectFps * root.timeScale
|
||||
} else if (duration < 400 * projectFps) {
|
||||
root.frameSize = projectFps * root.timeScale * 2
|
||||
} else if (displayedLength < 150) {
|
||||
// 5 second tick
|
||||
frameSize = 5 * projectFps * root.timeScale
|
||||
} else if (displayedLength < 300) {
|
||||
// 10 second tick
|
||||
frameSize = 10 * projectFps * root.timeScale
|
||||
} else if (displayedLength < 900) {
|
||||
// 30 second tick
|
||||
frameSize = 30 * projectFps * root.timeScale
|
||||
} else if (displayedLength < 1800) {
|
||||
// 1 min. tick
|
||||
frameSize = 60 * projectFps * root.timeScale
|
||||
} else if (displayedLength < 9000) {
|
||||
// 5 min tick
|
||||
frameSize = 300 * projectFps * root.timeScale
|
||||
} else if (displayedLength < 18000) {
|
||||
// 10 min tick
|
||||
frameSize = 600 * projectFps * root.timeScale
|
||||
} else {
|
||||
root.frameSize = projectFps * root.timeScale * 4
|
||||
while (root.frameSize < 10) {
|
||||
root.frameSize *= 4
|
||||
}
|
||||
// 30 min tick
|
||||
frameSize = 18000 * projectFps * root.timeScale
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,10 +86,9 @@ Rectangle {
|
||||
id: rulerTicks
|
||||
model: ruler.width / frameSize + 2
|
||||
Rectangle {
|
||||
property int realPos: index
|
||||
x: realPos * frameSize
|
||||
x: index * frameSize
|
||||
anchors.bottom: ruler.bottom
|
||||
height: (realPos % 4)? ((realPos % 2) ? 3 : 7) : 12
|
||||
height: (index % 5) ? ruler.height / 4 : ruler.height / 2
|
||||
width: 1
|
||||
color: activePalette.windowText
|
||||
opacity: 0.5
|
||||
|
||||
@@ -266,8 +266,9 @@ Rectangle
|
||||
if (kfrCount < 2) {
|
||||
return
|
||||
}
|
||||
context.beginPath()
|
||||
context.fillStyle = Qt.rgba(0,0,0.8, 0.5);
|
||||
var ctx = getContext("2d");
|
||||
ctx.beginPath()
|
||||
ctx.fillStyle = Qt.rgba(0,0,0.8, 0.5);
|
||||
paths = []
|
||||
var xpos
|
||||
var ypos
|
||||
@@ -291,10 +292,10 @@ Rectangle
|
||||
paths.push(compline.createObject(keyframecanvas, {"x": parent.width, "y": ypos} ))
|
||||
paths.push(compline.createObject(keyframecanvas, {"x": parent.width, "y": parent.height} ))
|
||||
myPath.pathElements = paths
|
||||
context.clearRect(0,0, width, height);
|
||||
context.path = myPath;
|
||||
context.closePath()
|
||||
context.fill()
|
||||
ctx.clearRect(0,0, width, height);
|
||||
ctx.path = myPath;
|
||||
ctx.closePath()
|
||||
ctx.fill()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user