Ask user before switching to clip profile when adding first clip to project

CCBUG: 356963
parent f72b302d
......@@ -425,7 +425,7 @@ Bin::Bin(QWidget* parent) :
// Info widget for failed jobs, other errors
m_infoMessage = new BinMessageWidget;
layout->addWidget(m_infoMessage);
m_infoMessage->setCloseButtonVisible(true);
m_infoMessage->setCloseButtonVisible(false);
connect(m_infoMessage, SIGNAL(messageClosing()), this, SLOT(slotResetInfoMessage()));
//m_infoMessage->setWordWrap(true);
m_infoMessage->hide();
......@@ -434,6 +434,7 @@ Bin::Bin(QWidget* parent) :
connect(m_logAction, SIGNAL(triggered()), this, SLOT(slotShowJobLog()));
connect(this, SIGNAL(requesteInvalidRemoval(QString,QUrl,QString)), this, SLOT(slotQueryRemoval(QString,QUrl,QString)));
connect(this, &Bin::refreshAudioThumbs, this, &Bin::doRefreshAudioThumbs);
connect(this, SIGNAL(displayBinMessage(QString,KMessageWidget::MessageType)), this, SLOT(doDisplayMessage(QString,KMessageWidget::MessageType)));
}
Bin::~Bin()
......@@ -1916,11 +1917,16 @@ void Bin::slotUpdateJobStatus(const QString&id, int jobType, int status, const Q
}
}
void Bin::displayMessage(const QString &text, KMessageWidget::MessageType type)
void Bin::doDisplayMessage(const QString &text, KMessageWidget::MessageType type, QList <QAction*> actions)
{
if (m_infoMessage->isHidden()) {
m_infoMessage->setText(text);
m_infoMessage->setWordWrap(m_infoMessage->text().length() > 35);
foreach(QAction *action, actions) {
m_infoMessage->addAction(action);
connect(action, SIGNAL(triggered(bool)), this, SLOT(slotMessageActionTriggered()));
}
m_infoMessage->setCloseButtonVisible(actions.isEmpty());
m_infoMessage->setMessageType(type);
m_infoMessage->animatedShow();
}
......@@ -2279,12 +2285,12 @@ void Bin::slotExpandUrl(ItemInfo info, QUrl url, QUndoCommand *command)
QDomNodeList producers = doc.documentElement().elementsByTagName("producer");
QDomNodeList tracks = doc.documentElement().elementsByTagName("track");
if (invalid || producers.isEmpty()) {
emit displayMessage(i18n("Playlist clip %1 is invalid.", url.fileName()), KMessageWidget::Warning);
doDisplayMessage(i18n("Playlist clip %1 is invalid.", url.fileName()), KMessageWidget::Warning);
delete command;
return;
}
if (tracks.count() > pCore->projectManager()->currentTimeline()->visibleTracksCount() + 1) {
emit displayMessage(i18n("Playlist clip %1 has too many tracks (%2) to be imported. Add new tracks to your project.", url.fileName(), tracks.count()), KMessageWidget::Warning);
doDisplayMessage(i18n("Playlist clip %1 has too many tracks (%2) to be imported. Add new tracks to your project.", url.fileName(), tracks.count()), KMessageWidget::Warning);
delete command;
return;
}
......@@ -2559,7 +2565,7 @@ void Bin::slotGotFilterJobResults(QString id, int startPos, int track, stringMap
int markersType = -1;
if (filterInfo.contains(QStringLiteral("addmarkers"))) markersType = filterInfo.value(QStringLiteral("addmarkers")).toInt();
if (results.isEmpty()) {
emit displayMessage(i18n("No data returned from clip analysis"), KMessageWidget::Warning);
emit displayBinMessage(i18n("No data returned from clip analysis"), KMessageWidget::Warning);
return;
}
bool dataProcessed = false;
......@@ -2571,9 +2577,9 @@ void Bin::slotGotFilterJobResults(QString id, int startPos, int track, stringMap
if (filterInfo.contains(QStringLiteral("resultmessage"))) {
QString mess = filterInfo.value(QStringLiteral("resultmessage"));
mess.replace(QLatin1String("%count"), QString::number(value.count()));
emit displayMessage(mess, KMessageWidget::Information);
emit displayBinMessage(mess, KMessageWidget::Information);
}
else emit displayMessage(i18n("Processing data analysis"), KMessageWidget::Information);
else emit displayBinMessage(i18n("Processing data analysis"), KMessageWidget::Information);
if (filterInfo.contains(QStringLiteral("cutscenes"))) {
// Check if we want to cut scenes from returned data
dataProcessed = true;
......@@ -2671,7 +2677,7 @@ void Bin::slotLoadClipMarkers(const QString &id)
delete cbox;
QFile file(url);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
emit displayMessage(i18n("Cannot open file %1", QUrl(url).fileName()), KMessageWidget::Warning);
emit displayBinMessage(i18n("Cannot open file %1", QUrl::fromLocalFile(url).fileName()), KMessageWidget::Warning);
return;
}
QString data = QString::fromUtf8(file.readAll());
......@@ -2768,7 +2774,7 @@ void Bin::slotSaveClipMarkers(const QString &id)
QFile file(url);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
emit displayMessage(i18n("Cannot open file %1", url), ErrorMessage);
emit displayBinMessage(i18n("Cannot open file %1", url), KMessageWidget::Error);
return;
}
file.write(data.toUtf8());
......@@ -2798,7 +2804,7 @@ void Bin::deleteAllClipMarkers(const QString &id)
QUndoCommand *command = new QUndoCommand;
command->setText(i18n("Delete clip markers"));
if (!clip->deleteClipMarkers(command)) {
emit displayMessage(i18n("Clip has no markers"), KMessageWidget::Warning);
doDisplayMessage(i18n("Clip has no markers"), KMessageWidget::Warning);
}
if (command->childCount() > 0) m_doc->commandStack()->push(command);
else delete command;
......@@ -3085,3 +3091,8 @@ void Bin::reloadAllProducers()
}
}
}
void Bin::slotMessageActionTriggered()
{
m_infoMessage->animatedHide();
}
......@@ -439,14 +439,13 @@ public:
void setupGeneratorMenu();
void startClipJob(const QStringList &params);
void droppedUrls(QList <QUrl> urls);
void displayMessage(const QString &text, KMessageWidget::MessageType type);
void addClipCut(const QString&id, int in, int out);
void removeClipCut(const QString&id, int in, int out);
/** @brief Create the subclips defined in the parent clip. */
void loadSubClips(const QString&id, const QMap <QString,QString> data);
/** @brief Select a clip in the Bin from its id. */
void selectClipById(const QString &id);
/** @brief Set focus to the Bin view. */
......@@ -549,6 +548,8 @@ private slots:
/** @brief Send audio thumb data to monitor for display. */
void slotSendAudioThumb(QString id);
void doRefreshAudioThumbs(const QString &id);
/** @brief Enable item view and hide message */
void slotMessageActionTriggered();
public slots:
void slotThumbnailReady(const QString &id, const QImage &img, bool fromFile = false);
......@@ -606,6 +607,7 @@ public slots:
void slotGetCurrentProjectImage();
void slotExpandUrl(ItemInfo info, QUrl url, QUndoCommand *command);
void abortAudioThumbs();
void doDisplayMessage(const QString &text, KMessageWidget::MessageType type, QList <QAction*> actions = QList <QAction*>());
protected:
void contextMenuEvent(QContextMenuEvent *event);
......@@ -695,6 +697,7 @@ signals:
void masterClipSelected(ClipController *, Monitor *);
/** @brief Request updating of the effect stack if currently displayed. */
void masterClipUpdated(ClipController *, Monitor *);
void displayBinMessage(const QString &, KMessageWidget::MessageType);
void displayMessage(const QString &, MessageType);
void requesteInvalidRemoval(const QString &, QUrl, const QString &);
/** @brief Markers changed, refresh panel. */
......
......@@ -63,6 +63,26 @@ MltVideoProfile::MltVideoProfile() :
{
}
MltVideoProfile::MltVideoProfile(const QVariantList &params)
{
if (params.count() != 12) {
qDebug()<<" * * Trying to build a profile with incorrect param numbers";
return;
}
frame_rate_num = params.at(0).toInt();
frame_rate_den = params.at(1).toInt();
width = params.at(2).toInt();
height = params.at(3).toInt();
progressive = params.at(4).toBool();
sample_aspect_num = params.at(5).toInt();
sample_aspect_den = params.at(6).toInt();
display_aspect_num = params.at(7).toInt();
display_aspect_den = params.at(8).toInt();
colorspace = params.at(9).toInt();
path = params.at(10).toString();
description = params.at(11).toString();
}
bool MltVideoProfile::operator==(const MltVideoProfile &point) const
{
if (!description.isEmpty() && point.description == description) {
......@@ -80,11 +100,32 @@ bool MltVideoProfile::operator==(const MltVideoProfile &point) const
point.colorspace == colorspace;
}
const QVariantList MltVideoProfile::toList()
{
QVariantList result;
result << frame_rate_num << frame_rate_den << width << height << progressive << sample_aspect_num << sample_aspect_den <<display_aspect_num << display_aspect_den << colorspace << path << description;
return result;
}
void MltVideoProfile::adjustWidth()
{
width = (width + 7) / 8 * 8;
}
const QString MltVideoProfile::descriptiveString()
{
QString data = description;
if (!data.isEmpty()) data.append(QStringLiteral(", "));
QString fps;
if (frame_rate_num % frame_rate_den == 0) {
fps = QString::number(frame_rate_num / frame_rate_den);
} else {
fps = QString::number((double)frame_rate_num / frame_rate_den, 'f', 2);
}
data.append(QString("%1x%2, %3fps").arg(width).arg(height).arg(fps));
return data;
}
bool MltVideoProfile::operator!=(const MltVideoProfile &other) const {
return !(*this == other);
}
......
......@@ -245,8 +245,11 @@ public:
// A profile's width should always be a multiple of 8
void adjustWidth();
MltVideoProfile();
MltVideoProfile(const QVariantList &params);
bool operator==(const MltVideoProfile& point) const;
bool operator!=(const MltVideoProfile &other) const;
const QVariantList toList();
const QString descriptiveString();
};
......
......@@ -38,6 +38,7 @@
#include "core.h"
#include "bin/bin.h"
#include "bin/projectclip.h"
#include "utils/KoIconUtils.h"
#include "mltcontroller/bincontroller.h"
#include "mltcontroller/effectscontroller.h"
......@@ -1566,19 +1567,48 @@ void KdenliveDoc::resetProfile()
emit docModified(true);
}
void KdenliveDoc::slotSwitchProfile()
{
QAction *action = qobject_cast<QAction *>(sender());
QVariantList data = action->data().toList();
QString id = data.takeFirst().toString();
QDomDocument doc;
doc.setContent(data.takeFirst().toString(), true);
QDomElement xml = doc.documentElement();
if (!data.isEmpty()) {
// we want a profile switch
m_profile = MltVideoProfile(data);
updateProjectProfile(true);
emit docModified(true);
}
}
void KdenliveDoc::switchProfile(MltVideoProfile profile, const QString &id, const QDomElement &xml)
{
// Request profile update
QString matchingProfile = ProfilesDialog::existingProfile(profile);
if (!matchingProfile.isEmpty()) {
// We found a known matching profile, switch and inform user
m_profile = profile;
QMap< QString, QString > profileProperties = ProfilesDialog::getSettingsFromFile(matchingProfile);
m_profile.path = matchingProfile;
m_profile.description = profileProperties.value("description");
updateProjectProfile(true);
pCore->bin()->displayMessage(i18n("Switched to clip profile: %1", m_profile.description), KMessageWidget::Information);
emit docModified(true);
profile.path = matchingProfile;
profile.description = profileProperties.value("description");
// Build actions for the info message (switch / cancel)
QList <QAction*> list;
QAction *ac = new QAction(KoIconUtils::themedIcon(QStringLiteral("dialog-ok")), i18n("Switch"), this);
QVariantList params;
connect(ac, SIGNAL(triggered(bool)), this, SLOT(slotSwitchProfile()));
QDomDocument doc;
doc.appendChild(doc.importNode(xml, true));
params << id << doc.toString() << profile.toList();
ac->setData(params);
QAction *ac2 = new QAction(KoIconUtils::themedIcon(QStringLiteral("dialog-cancel")), i18n("Cancel"), this);
QVariantList params2;
params2 << id << doc.toString();
ac2->setData(params2);
connect(ac2, SIGNAL(triggered(bool)), this, SLOT(slotSwitchProfile()));
list << ac << ac2;
pCore->bin()->doDisplayMessage(i18n("Switch to clip profile %1?", profile.descriptiveString()), KMessageWidget::Information, list);
} else {
// No known profile, ask user if he wants to use clip profile anyway
if (KMessageBox::questionYesNo(QApplication::activeWindow(), i18n("No existing profile found for your clip (%1x%2, %3fps)\nDo you want to switch to that custom profile ?", profile.width, profile.height, QString::number((double)profile.frame_rate_num / profile.frame_rate_den, 'f', 2))) == KMessageBox::Yes) {
......@@ -1586,11 +1616,11 @@ void KdenliveDoc::switchProfile(MltVideoProfile profile, const QString &id, cons
m_profile.description = QString("%1x%2 %3fps").arg(profile.width).arg(profile.height).arg(QString::number((double)profile.frame_rate_num / profile.frame_rate_den, 'f', 2));
ProfilesDialog::saveProfile(m_profile);
updateProjectProfile(true);
pCore->bin()->displayMessage(i18n("Switched to clip profile: %1", m_profile.description), KMessageWidget::Information);
pCore->bin()->doDisplayMessage(i18n("Switched to clip profile: %1", m_profile.description), KMessageWidget::Information);
emit docModified(true);
pCore->producerQueue()->getFileProperties(xml, id, 150, true);
}
}
pCore->producerQueue()->getFileProperties(xml, id, 150, true);
}
void KdenliveDoc::forceProcessing(const QString &id)
......
......@@ -223,6 +223,7 @@ private slots:
void slotModified();
void slotSetDocumentNotes(const QString &notes);
void switchProfile(MltVideoProfile profile, const QString &id, const QDomElement &xml);
void slotSwitchProfile();
signals:
void resetProjectList();
......
......@@ -289,11 +289,10 @@ void ProducerQueue::processFileProperties()
projectProfile.display_aspect_num = width;
projectProfile.display_aspect_den = height;
projectProfile.description.clear();
delete producer;
m_processingClipId.removeAll(info.clipId);
//delete producer;
//m_processingClipId.removeAll(info.clipId);
info.xml.removeAttribute(QStringLiteral("checkProfile"));
emit switchProfile(projectProfile, info.clipId, info.xml);
return;
} else {
// Very small image, we probably don't want to use this as profile
skipProducer = true;
......@@ -310,13 +309,12 @@ void ProducerQueue::processFileProperties()
MltVideoProfile projectProfile = ProfilesDialog::getVideoProfile(*m_binController->profile());
clipProfile.adjustWidth();
if (clipProfile != projectProfile) {
// Profiles do not match, adjust profile
delete producer;
// Profiles do not match, propose profile adjustment
//delete producer;
delete blankProfile;
m_processingClipId.removeAll(info.clipId);
//m_processingClipId.removeAll(info.clipId);
info.xml.removeAttribute("checkProfile");
emit switchProfile(clipProfile, info.clipId, info.xml);
return;
}
}
}
......
......@@ -231,7 +231,7 @@ void JobManager::prepareJobs(QList <ProjectClip *>clips, double fps, AbstractCli
//TODO filter clips
QList <ProjectClip *> matching = filterClips(clips, jobType, params);
if (matching.isEmpty()) {
m_bin->displayMessage(i18n("No valid clip to process"), KMessageWidget::Information);
m_bin->doDisplayMessage(i18n("No valid clip to process"), KMessageWidget::Information);
return;
}
QMap <ProjectClip *, AbstractClipJob *> jobs;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment