return (current_fps != m_fps);
}
-double KdenliveDoc::dar()
+double KdenliveDoc::dar() const
{
return (double) m_profile.display_aspect_num / m_profile.display_aspect_den;
}
void syncGuides(QList <Guide *> guides);
void setZoom(int horizontal, int vertical);
QPoint zoom() const;
- double dar();
+ double dar() const;
double projectDuration() const;
bool saveSceneList(const QString &path, const QString &scene);
int tracksCount() const;
Monitor::Monitor(QString name, MonitorManager *manager, QString profile, QWidget *parent) :
- QWidget(parent),
- render(NULL),
- m_name(name),
- m_monitorManager(manager),
- m_currentClip(NULL),
- m_ruler(new SmallRuler(m_monitorManager)),
- m_overlay(NULL),
- m_isActive(false),
- m_scale(1),
- m_length(0),
- m_dragStarted(false),
- m_effectScene(NULL),
- m_effectView(NULL)
+ QWidget(parent),
+ render(NULL),
+ m_name(name),
+ m_monitorManager(manager),
+ m_currentClip(NULL),
+ m_ruler(new SmallRuler(m_monitorManager)),
+ m_overlay(NULL),
+ m_isActive(false),
+ m_scale(1),
+ m_length(0),
+ m_dragStarted(false),
+ m_effectScene(NULL),
+ m_effectView(NULL)
{
m_ui.setupUi(this);
QVBoxLayout *layout = new QVBoxLayout;
render->setProducer(NULL, -1);
return;
}
- if (m_currentClip != NULL) activateMonitor();
+ if (m_currentClip != NULL || clip != NULL) activateMonitor();
if (clip != m_currentClip) {
m_currentClip = clip;
updateMarkers(clip);
}
MonitorRefresh::MonitorRefresh(QWidget* parent) :
- QWidget(parent),
- m_renderer(NULL)
+ QWidget(parent),
+ m_renderer(NULL)
{
setAttribute(Qt::WA_PaintOnScreen);
setAttribute(Qt::WA_OpaquePaintEvent);
}
Overlay::Overlay(QWidget* parent) :
- QLabel(parent)
+ QLabel(parent)
{
setAttribute(Qt::WA_TransparentForMouseEvents);
//setAttribute(Qt::WA_OpaquePaintEvent);
}
// static
-QString ProfilesDialog::getPathFromProperties(int width, int height, double fps, bool useDisplayWidth)
+bool ProfilesDialog::matchProfile(int width, int height, double fps, double par, bool isImage, MltVideoProfile profile)
+{
+ int profileWidth;
+ if (isImage) {
+ // when using image, compare with display width
+ profileWidth = profile.height * profile.display_aspect_num / profile.display_aspect_den + 0.5;
+ } else profileWidth = profile.width;
+ if (width != profileWidth || height != profile.height || (fps > 0 && qAbs(profile.frame_rate_num / profile.frame_rate_den - fps) > 0.4) || (par > 0 && qAbs(profile.sample_aspect_num / profile.sample_aspect_den - par) > 0.1)) return false;
+ return true;
+}
+
+// static
+QMap <QString, QString> ProfilesDialog::getProfilesFromProperties(int width, int height, double fps, double par, bool useDisplayWidth)
{
QStringList profilesNames;
QStringList profilesFiles;
QStringList profilesFilter;
+ QMap <QString, QString> result;
profilesFilter << "*";
// List the Mlt profiles
profilesFiles = QDir(KdenliveSettings::mltpath()).entryList(profilesFilter, QDir::Files);
else profileWidth = values.value("width").toInt();
if (profileWidth == width && values.value("height").toInt() == height) {
double profile_fps = values.value("frame_rate_num").toDouble() / values.value("frame_rate_den").toDouble();
- if (fps <= 0 || qAbs(profile_fps - fps) < 0.5)
- return profilesFiles.at(i);
+ double profile_par = values.value("sample_aspect_num").toDouble() / values.value("sample_aspect_den").toDouble();
+ if ((fps <= 0 || qAbs(profile_fps - fps) < 0.5) && (par <= 0 || qAbs(profile_par - par) < 0.1))
+ result.insert(profilesFiles.at(i), values.value("description"));
}
}
else profileWidth = values.value("width").toInt();
if (profileWidth == width && values.value("height").toInt() == height) {
double profile_fps = values.value("frame_rate_num").toDouble() / values.value("frame_rate_den").toDouble();
- if (fps <= 0 || qAbs(profile_fps - fps) < 0.5)
- return customProfiles.at(i) + profiles.at(j);
+ double profile_par = values.value("sample_aspect_num").toDouble() / values.value("sample_aspect_den").toDouble();
+ if ((fps <= 0 || qAbs(profile_fps - fps) < 0.5) && (par <= 0 || qAbs(profile_par - par) < 0.1))
+ result.insert(profiles.at(j), values.value("description"));
}
}
}
- return QString();
+ return result;
}
// static
static QString existingProfile(MltVideoProfile profile);
static bool existingProfileDescription(const QString &desc);
+ /** @brief Check if a given profile matches passed properties:
+ * @param width The profile frame width
+ * @param height The profile frame height
+ * @param fps The profile fps
+ * @param par The sample aspect ratio
+ * @param isImage If true, compare width with profile's display width ( = dar * height)
+ * @param profile The profile to match
+ * @return true if properties match profile */
+ static bool matchProfile(int width, int height, double fps, double par, bool isImage, MltVideoProfile profile);
+
/** @brief Find a profile to match parameter properties:
* @param width The profile frame width
* @param height The profile frame height
* @param fps The profile fps
- * @param useDisplayWidth If true, compare width with profile's display width ( = dar * height) */
- static QString getPathFromProperties(int width, int height, double fps, bool useDisplayWidth = false);
+ * @param par The sample aspect ratio
+ * @param useDisplayWidth If true, compare width with profile's display width ( = dar * height)
+ * @return A string list of the matching profiles description */
+ static QMap <QString, QString> getProfilesFromProperties(int width, int height, double fps, double par, bool useDisplayWidth = false);
+
+ /** @brief Returns an value from a string by replacing "%width" and "%height" with given profile values:
+ * @param profile The profile that gives width & height
+ * @param eval The string to be evaluated, for example: "%width / 2"
+ * @return the evaluated value */
static double getStringEval(const MltVideoProfile &profile, QString eval);
protected:
int max = m_doc->clipManager()->clipsCount();
if (item && m_infoQueue.isEmpty() && m_thumbnailQueue.isEmpty()) {
m_listView->setCurrentItem(item);
+ bool displayClipInMonitor = true;
if (item->parent()) {
if (item->parent()->type() == PROJECTFOLDERTYPE)
static_cast <FolderProjectItem *>(item->parent())->switchIcon();
int width = properties.value("frame_size").section('x', 0, 0).toInt();
int height = properties.value("frame_size").section('x', -1).toInt();
double fps = properties.value("fps").toDouble();
- int renderWidth = -1;
- int renderHeight = -1;
- double renderFps = -1;
- if (item->clipType() == IMAGE) {
- renderWidth = m_doc->renderer()->renderWidth();
- renderHeight = m_doc->height();
- } else if (item->clipType() == AV || item->clipType() == VIDEO) {
- renderWidth = m_doc->width();
- renderHeight = m_doc->height();
- renderFps = m_doc->fps();
- }
- if ((renderWidth > 0 && width != renderWidth) || (renderHeight > 0 && height != renderHeight) || (renderFps > 0 && qAbs(fps - renderFps) > 0.5)) {
- QString suggestedProfile = ProfilesDialog::getPathFromProperties(width, height, fps, item->clipType() == IMAGE);
- if (!suggestedProfile.isEmpty()) {
- QString description = ProfilesDialog::getSettingsFromFile(suggestedProfile).value("description");
- if (KMessageBox::questionYesNo(this, i18n("Your clip does not match current project's profile.\nDo you want to adjust the profile (clip size: %1, fps: %2)?\nSuggested profile is %3", properties.value("frame_size"), fps, description)) == KMessageBox::Yes) {
- //Change project profile
- emit updateProfile(suggestedProfile);
- }
- } else KMessageBox::information(this, i18n("Your clip does not match current project's profile.\nNo existing profile found to match the clip's properties.\nClip size: %1\nFps: %2\n", properties.value("frame_size"), fps));
+ double par = properties.value("aspect_ratio").toDouble();
+ if (item->clipType() == IMAGE || item->clipType() == AV || item->clipType() == VIDEO) {
+ if (ProfilesDialog::matchProfile(width, height, fps, par, item->clipType() == IMAGE, m_doc->mltProfile()) == false) {
+ // get a list of compatible profiles
+ QMap <QString, QString> suggestedProfiles = ProfilesDialog::getProfilesFromProperties(width, height, fps, par, item->clipType() == IMAGE);
+ if (!suggestedProfiles.isEmpty()) {
+ KDialog *dialog = new KDialog(this);
+ dialog->setCaption(i18n("Change project profile"));
+ dialog->setButtons(KDialog::Ok | KDialog::Cancel);
+
+ QWidget container;
+ QVBoxLayout *l = new QVBoxLayout;
+ QLabel *label = new QLabel(i18n("Your clip does not match current project's profile.\nDo you want to change the project profile?\n\nThe following profiles match the clip (size: %1, fps: %2)", properties.value("frame_size"), fps));
+ l->addWidget(label);
+ QListWidget *list = new QListWidget;
+ list->setAlternatingRowColors(true);
+ QMapIterator<QString, QString> i(suggestedProfiles);
+ while (i.hasNext()) {
+ i.next();
+ QListWidgetItem *item = new QListWidgetItem(i.value(), list);
+ item->setData(Qt::UserRole, i.key());
+ item->setToolTip(i.key());
+ }
+ list->setCurrentRow(0);
+ l->addWidget(list);
+ container.setLayout(l);
+ dialog->setButtonText(KDialog::Ok, i18n("Update profile"));
+ dialog->setMainWidget(&container);
+ if (dialog->exec() == QDialog::Accepted) {
+ //Change project profile
+ displayClipInMonitor = false;
+ if (list->currentItem())
+ emit updateProfile(list->currentItem()->data(Qt::UserRole).toString());
+ }
+ delete list;
+ delete label;
+ } else KMessageBox::information(this, i18n("Your clip does not match current project's profile.\nNo existing profile found to match the clip's properties.\nClip size: %1\nFps: %2\n", properties.value("frame_size"), fps));
+ }
}
}
- emit clipSelected(item->referencedClip());
+ if (displayClipInMonitor) emit clipSelected(item->referencedClip());
} else {
emit displayMessage(i18n("Loading clips"), (int)(100 *(max - m_infoQueue.count()) / max));
}