aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Baptiste Mardelle <[email protected]>2016-05-30 22:51:59 +0200
committerJean-Baptiste Mardelle <[email protected]>2016-05-30 22:51:59 +0200
commit45838cf14f135a082e0a9f9e5d1fc3f3bf883bff (patch)
tree1cfe857b8d99968138c2153f776d93a175abb2da
parent9dbbcd7f5a001616b239f105354cf4dd32bc81b5 (diff)
Cleanup statusbar messaging system.
Add warning about using a development version Nicer progress bar for audio thumbs
-rw-r--r--src/bin/bin.cpp38
-rw-r--r--src/bin/bin.h35
-rw-r--r--src/bin/projectclip.cpp25
-rw-r--r--src/bin/projectclip.h1
-rw-r--r--src/doc/kdenlivedoc.h1
-rw-r--r--src/mainwindow.cpp95
-rw-r--r--src/mainwindow.h7
-rw-r--r--src/project/projectmanager.cpp5
-rw-r--r--src/statusbarmessagelabel.cpp232
-rw-r--r--src/statusbarmessagelabel.h55
10 files changed, 213 insertions, 281 deletions
diff --git a/src/bin/bin.cpp b/src/bin/bin.cpp
index dd9d04a..d9b4b92 100644
--- a/src/bin/bin.cpp
+++ b/src/bin/bin.cpp
@@ -323,6 +323,8 @@ Bin::Bin(QWidget* parent) :
, m_blankThumb()
, m_invalidClipDialog(NULL)
, m_gainedFocus(false)
+ , m_audioDuration(0)
+ , m_processedAudio(0)
{
m_layout = new QVBoxLayout(this);
@@ -505,23 +507,31 @@ QDockWidget *Bin::clipPropertiesDock()
return m_propertiesDock;
}
-void Bin::slotAbortAudioThumb(const QString &id)
+void Bin::slotAbortAudioThumb(const QString &id, long duration)
{
if (!m_audioThumbsThread.isRunning()) return;
QMutexLocker aMutex(&m_audioThumbMutex);
- m_audioThumbsList.removeAll(id);
+ if (m_audioThumbsList.removeAll(id) > 0)
+ m_audioDuration -= duration;
}
-void Bin::requestAudioThumbs(const QString &id)
+void Bin::requestAudioThumbs(const QString &id, long duration)
{
if (!m_audioThumbsList.contains(id) && m_processingAudioThumb != id) {
m_audioThumbMutex.lock();
m_audioThumbsList.append(id);
+ m_audioDuration += duration;
m_audioThumbMutex.unlock();
processAudioThumbs();
}
}
+void Bin::doUpdateThumbsProgress(long ms)
+{
+ int progress = (m_processedAudio + ms) * 100 / m_audioDuration;
+ emitMessage(i18n("Creating audio thumbnails"), progress, ProcessingJobMessage);
+}
+
void Bin::processAudioThumbs()
{
if (m_audioThumbsThread.isRunning()) return;
@@ -536,6 +546,10 @@ void Bin::abortAudioThumbs()
if (clip) clip->abortAudioThumbs();
}
m_audioThumbMutex.lock();
+ foreach(const QString &id, m_audioThumbsList) {
+ ProjectClip *clip = m_rootFolder->clip(id);
+ if (clip) clip->setJobStatus(AbstractClipJob::THUMBJOB, JobDone, 0);
+ }
m_audioThumbsList.clear();
m_audioThumbMutex.unlock();
m_audioThumbsThread.waitForFinished();
@@ -545,20 +559,26 @@ void Bin::slotCreateAudioThumbs()
{
int max = m_audioThumbsList.count();
int count = 0;
+ m_processedAudio = 0;
while (!m_audioThumbsList.isEmpty()) {
m_audioThumbMutex.lock();
max = qMax(max, m_audioThumbsList.count());
m_processingAudioThumb = m_audioThumbsList.takeFirst();
count++;
m_audioThumbMutex.unlock();
- emitMessage(i18n("Creating audio thumbnails") + QString(" (%1/%2)").arg(count).arg(max), ProcessingJobMessage);
+ //emitMessage(i18n("Creating audio thumbnails"), (count - 1) * 100 / max, ProcessingJobMessage);
ProjectClip *clip = m_rootFolder->clip(m_processingAudioThumb);
- if (clip) clip->slotCreateAudioThumbs();
+ if (clip) {
+ clip->slotCreateAudioThumbs();
+ m_processedAudio += clip->duration().ms();
+ }
}
m_audioThumbMutex.lock();
m_processingAudioThumb.clear();
+ m_processedAudio = 0;
+ m_audioDuration = 0;
m_audioThumbMutex.unlock();
- emitMessage(i18n("Audio thumbnails done"), OperationCompletedMessage);
+ emitMessage(i18n("Audio thumbnails done"), 100, OperationCompletedMessage);
}
bool Bin::eventFilter(QObject *obj, QEvent *event)
@@ -847,7 +867,7 @@ void Bin::slotLocateClip()
qDebug()<<" / / "+url.toString();
} else {
if(!exists){
- emitMessage(i18n("Couldn't locate ") + QString(" ("+url.toString()+")"), ErrorMessage);
+ emitMessage(i18n("Couldn't locate ") + QString(" ("+url.toString()+")"), 100, ErrorMessage);
}
return;
}
@@ -3018,9 +3038,9 @@ void Bin::slotResetInfoMessage()
}
}
-void Bin::emitMessage(const QString &text, MessageType type)
+void Bin::emitMessage(const QString &text, int progress, MessageType type)
{
- emit displayMessage(text, type);
+ emit displayMessage(text, progress, type);
}
void Bin::slotCreateAudioThumb(const QString &id)
diff --git a/src/bin/bin.h b/src/bin/bin.h
index 755e936..7742503 100644
--- a/src/bin/bin.h
+++ b/src/bin/bin.h
@@ -282,23 +282,21 @@ public:
int jobProgress = index.data(AbstractProjectItem::JobProgress).toInt();
if (jobProgress > 0 || jobProgress == JobWaiting) {
// Draw job progress bar
- QColor color = option.palette.alternateBase().color();
+ int progressWidth = option.fontMetrics.averageCharWidth() * 8;
+ int progressHeight = option.fontMetrics.ascent() / 4;
+ QRect progress(r1.x() + 1, opt.rect.bottom() - progressHeight - 2, progressWidth , progressHeight);
painter->setPen(Qt::NoPen);
- color.setAlpha(180);
- painter->setBrush(QBrush(color));
- QRect progress(r1.x() + 1, opt.rect.bottom() - 12, r1.width() / 2, 8);
- painter->drawRect(progress);
- painter->setBrush(option.palette.text());
+ painter->setBrush(Qt::darkGray);
if (jobProgress > 0) {
- progress.adjust(1, 1, 0, -1);
- progress.setWidth((progress.width() - 4) * jobProgress / 100);
- painter->drawRect(progress);
+ painter->drawRoundedRect(progress, 2, 2);
+ painter->setBrush(option.state & QStyle::State_Selected ? option.palette.text() : option.palette.highlight());
+ progress.setWidth((progressWidth - 2) * jobProgress / 100);
+ painter->drawRoundedRect(progress, 2, 2);
} else if (jobProgress == JobWaiting) {
// Draw kind of a pause icon
- progress.adjust(1, 1, 0, -1);
- progress.setWidth(2);
+ progress.setWidth(3);
painter->drawRect(progress);
- progress.moveLeft(progress.right() + 2);
+ progress.moveLeft(progress.right() + 3);
painter->drawRect(progress);
}
} else if (jobProgress == JobCrashed) {
@@ -496,13 +494,13 @@ public:
/** @brief Returns current project's folder for storing items. */
QUrl projectFolder() const;
/** @brief Display a message about an operation in status bar. */
- void emitMessage(const QString &, MessageType);
+ void emitMessage(const QString &, int, MessageType);
void rebuildMenu();
void refreshIcons();
/** @brief Update status of disable effects action (when loading a document). */
void setBinEffectsDisabledStatus(bool disabled);
- void requestAudioThumbs(const QString &id);
+ void requestAudioThumbs(const QString &id, long duration);
/** @brief Proxy status for the project changed, update. */
void refreshProxySettings();
/** @brief A clip is ready, update its info panel if displayed. */
@@ -617,7 +615,7 @@ public slots:
/** @brief Request audio thumbnail for clip with id */
void slotCreateAudioThumb(const QString &id);
/** @brief Abort audio thumbnail for clip with id */
- void slotAbortAudioThumb(const QString &id);
+ void slotAbortAudioThumb(const QString &id, long duration);
/** @brief Add extra data to a clip. */
void slotAddClipExtraData(const QString &id, const QString &key, const QString &data = QString(), QUndoCommand *groupCommand = 0);
void slotUpdateClipProperties(const QString &id, QMap <QString, QString> properties, bool refreshPropertiesPanel);
@@ -635,6 +633,7 @@ public slots:
/** @brief Select a clip in the Bin from its id. */
void selectClipById(const QString &id, int frame = -1, const QPoint &zone = QPoint());
void slotAddClipToProject(QUrl url);
+ void doUpdateThumbsProgress(long ms);
protected:
void contextMenuEvent(QContextMenuEvent *event);
@@ -699,6 +698,10 @@ private:
QStringList m_audioThumbsList;
QString m_processingAudioThumb;
QMutex m_audioThumbMutex;
+ /** @brief Total number of milliseconds to process for audio thumbnails */
+ long m_audioDuration;
+ /** @brief Total number of milliseconds already processed for audio thumbnails */
+ long m_processedAudio;
/** @brief Indicates whether audio thumbnail creation is running. */
QFuture<void> m_audioThumbsThread;
void showClipProperties(ProjectClip *clip, bool forceRefresh = false);
@@ -727,7 +730,7 @@ signals:
/** @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 displayMessage(const QString &, int, MessageType);
void requesteInvalidRemoval(const QString &, QUrl, const QString &);
/** @brief Markers changed, refresh panel. */
void refreshPanelMarkers();
diff --git a/src/bin/projectclip.cpp b/src/bin/projectclip.cpp
index 96ff91f..c4a8a9b 100644
--- a/src/bin/projectclip.cpp
+++ b/src/bin/projectclip.cpp
@@ -65,6 +65,7 @@ ProjectClip::ProjectClip(const QString &id, QIcon thumb, ClipController *control
setParent(parent);
connect(this, &ProjectClip::updateJobStatus, this, &ProjectClip::setJobStatus);
bin()->loadSubClips(id, m_controller->getPropertiesFromPrefix(QStringLiteral("kdenlive:clipzone.")));
+ connect(this, &ProjectClip::updateThumbProgress, bin(), &Bin::doUpdateThumbsProgress);
createAudioThumbs();
}
@@ -95,6 +96,7 @@ ProjectClip::ProjectClip(const QDomElement& description, QIcon thumb, ProjectFol
else m_name = i18n("Untitled");
connect(this, &ProjectClip::updateJobStatus, this, &ProjectClip::setJobStatus);
setParent(parent);
+ connect(this, &ProjectClip::updateThumbProgress, bin(), &Bin::doUpdateThumbsProgress);
}
@@ -102,7 +104,7 @@ ProjectClip::~ProjectClip()
{
// controller is deleted in bincontroller
abortAudioThumbs();
- bin()->slotAbortAudioThumb(m_id);
+ bin()->slotAbortAudioThumb(m_id, duration().ms());
QMutexLocker audioLock(&m_audioMutex);
m_thumbMutex.lock();
m_requestedThumbs.clear();
@@ -365,7 +367,8 @@ bool ProjectClip::setProducer(ClipController *controller, bool replaceProducer)
void ProjectClip::createAudioThumbs()
{
if (KdenliveSettings::audiothumbnails() && (m_type == AV || m_type == Audio || m_type == Playlist)) {
- bin()->requestAudioThumbs(m_id);
+ bin()->requestAudioThumbs(m_id, duration().ms());
+ emit updateJobStatus(AbstractClipJob::THUMBJOB, JobWaiting, 0);
}
}
@@ -670,7 +673,7 @@ void ProjectClip::setJobStatus(int jobType, int status, int progress, const QStr
m_jobProgress = status;
if ((status == JobAborted || status == JobCrashed || status == JobDone) && !statusMessage.isEmpty()) {
m_jobMessage = statusMessage;
- bin()->emitMessage(statusMessage, OperationCompletedMessage);
+ bin()->emitMessage(statusMessage, 100, OperationCompletedMessage);
}
}
bin()->emitItemUpdated(this);
@@ -1002,6 +1005,7 @@ void ProjectClip::slotCreateAudioThumbs()
}
}
if (audioLevels.size() > 0) {
+ emit updateJobStatus(AbstractClipJob::THUMBJOB, JobDone, 0);
updateAudioThumbnail(audioLevels);
return;
}
@@ -1012,7 +1016,7 @@ void ProjectClip::slotCreateAudioThumbs()
for (int i = 0; i < channels; i++) {
QTemporaryFile *channelTmpfile = new QTemporaryFile;
if (!channelTmpfile->open()) {
- bin()->emitMessage(i18n("Cannot create temporary file, check disk space and permissions"), ErrorMessage);
+ bin()->emitMessage(i18n("Cannot create temporary file, check disk space and permissions"), 100, ErrorMessage);
return;
}
channelTmpfile->close();
@@ -1053,7 +1057,6 @@ void ProjectClip::slotCreateAudioThumbs()
args << QStringLiteral("-map") << QStringLiteral("[0:%1]").arg(i) << QStringLiteral("-c:a") << QStringLiteral("pcm_s16le") << QStringLiteral("-y") << QStringLiteral("-f") << QStringLiteral("data")<< channelFiles[i]->fileName();
}
}
- emit updateJobStatus(AbstractClipJob::THUMBJOB, JobWaiting, 0);
QProcess audioThumbsProcess;
connect(this, SIGNAL(doAbortAudioThumbs()), &audioThumbsProcess, SLOT(kill()), Qt::DirectConnection);
connect(&audioThumbsProcess, &QProcess::readyReadStandardOutput, this, &ProjectClip::updateFfmpegProgress);
@@ -1084,7 +1087,7 @@ void ProjectClip::slotCreateAudioThumbs()
if (res.isEmpty() || res.size() != dataSize) {
// Something went wrong, abort
emit updateJobStatus(AbstractClipJob::THUMBJOB, JobDone, 0);
- bin()->emitMessage(i18n("Error reading audio thumbnail"), ErrorMessage);
+ bin()->emitMessage(i18n("Error reading audio thumbnail"), 100, ErrorMessage);
return;
}
rawChannels << (const qint16*) res.constData();
@@ -1118,7 +1121,7 @@ void ProjectClip::slotCreateAudioThumbs()
if (steps) channelsData[k] /= steps;
audioLevels << channelsData[k] * factor;
}
- int p = 50 + (i * 50 / lengthInFrames);
+ int p = 80 + (i * 20 / lengthInFrames);
if (p != progress) {
emit updateJobStatus(AbstractClipJob::THUMBJOB, JobWorking, p);
progress = p;
@@ -1127,7 +1130,7 @@ void ProjectClip::slotCreateAudioThumbs()
}
jobFinished = true;
} else {
- bin()->emitMessage(i18n("Failed to create FFmpeg audio thumbnails, using MLT"), ErrorMessage);
+ bin()->emitMessage(i18n("Failed to create FFmpeg audio thumbnails, using MLT"), 100, ErrorMessage);
}
}
if (!jobFinished && !m_abortAudioThumb) {
@@ -1219,7 +1222,11 @@ void ProjectClip::updateFfmpegProgress()
foreach(const QString & data, lines) {
if (data.startsWith(QStringLiteral("out_time_ms"))) {
long ms = data.section(QLatin1Char('='), 1).toLong();
- emit updateJobStatus(AbstractClipJob::THUMBJOB, JobWorking, (int) (ms / duration().ms() / 20));
+ // Update clip progressbar
+ emit updateJobStatus(AbstractClipJob::THUMBJOB, JobWorking, ms / duration().ms() * 0.08);
+ // Update general statusbar progressbar
+ emit updateThumbProgress(ms/1000);
+ break;
}
}
}
diff --git a/src/bin/projectclip.h b/src/bin/projectclip.h
index 2748db6..35f5f79 100644
--- a/src/bin/projectclip.h
+++ b/src/bin/projectclip.h
@@ -268,6 +268,7 @@ signals:
void loadPropertiesPanel();
/** @brief Terminate running audio proxy job. */
void doAbortAudioThumbs();
+ void updateThumbProgress(long);
};
#endif
diff --git a/src/doc/kdenlivedoc.h b/src/doc/kdenlivedoc.h
index 1ccdccc..96c5740 100644
--- a/src/doc/kdenlivedoc.h
+++ b/src/doc/kdenlivedoc.h
@@ -247,7 +247,6 @@ private slots:
signals:
void resetProjectList();
- void progressInfo(const QString &, int);
/** @brief Informs that the document status has been changed.
*
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index ee7e535..c239488 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -239,6 +239,7 @@ MainWindow::MainWindow(const QString &MltPath, const QUrl &Url, const QString &
m_projectMonitor(NULL),
m_recMonitor(NULL),
m_renderWidget(NULL),
+ m_messageLabel(NULL),
m_themeInitialized(false),
m_isDarkTheme(false)
{
@@ -367,7 +368,6 @@ MainWindow::MainWindow(const QString &MltPath, const QUrl &Url, const QString &
//TODO deprecated, replace with Bin methods if necessary
/*connect(m_projectList, SIGNAL(loadingIsOver()), this, SLOT(slotElapsedTime()));
- connect(m_projectList, SIGNAL(displayMessage(QString,int,MessageType)), this, SLOT(slotGotProgressInfo(QString,int,MessageType)));
connect(m_projectList, SIGNAL(updateRenderStatus()), this, SLOT(slotCheckRenderStatus()));
connect(m_projectList, SIGNAL(updateProfile(QString)), this, SLOT(slotUpdateProjectProfile(QString)));
connect(m_projectList, SIGNAL(refreshClip(QString,bool)), pCore->monitorManager(), SLOT(slotRefreshCurrentMonitor(QString)));
@@ -410,7 +410,7 @@ MainWindow::MainWindow(const QString &MltPath, const QUrl &Url, const QString &
connect(m_effectStack, SIGNAL(removeMasterEffect(QString,QDomElement)), pCore->bin(), SLOT(slotDeleteEffect(QString,QDomElement)));
connect(m_effectStack, SIGNAL(changeEffectPosition(QString,const QList <int>,int)), pCore->bin(), SLOT(slotMoveEffect(QString,const QList <int>,int)));
connect(m_effectStack, SIGNAL(reloadEffects()), this, SLOT(slotReloadEffects()));
- connect(m_effectStack, SIGNAL(displayMessage(QString,int)), this, SLOT(slotGotProgressInfo(QString,int)));
+ connect(m_effectStack, SIGNAL(displayMessage(QString,int)), m_messageLabel, SLOT(setMessage(QString,int)));
m_effectStackDock = addDock(i18n("Properties"), QStringLiteral("effect_stack"), m_effectStack);
m_effectList = new EffectsListView();
@@ -701,7 +701,8 @@ MainWindow::MainWindow(const QString &MltPath, const QUrl &Url, const QString &
new JogManager(this);
#endif
scmanager->slotCheckActiveScopes();
- //KMessageBox::information(this, "Warning, development version for testing only. we are currently working on core functionnalities,\ndo not save any project or your project files might be corrupted.");
+ //TODO: remove for release
+ m_messageLabel->setMessage("This is an untested development version. Always backup your data", 100, MltError);
}
void MainWindow::slotThemeChanged(const QString &theme)
@@ -721,25 +722,14 @@ void MainWindow::slotThemeChanged(const QString &theme)
if (m_transitionList) m_transitionList->updatePalette();
if (m_clipMonitor) m_clipMonitor->setPalette(plt);
if (m_projectMonitor) m_projectMonitor->setPalette(plt);
- setStatusBarStyleSheet(plt);
+ if (m_messageLabel)
+ m_messageLabel->updatePalette();
if (pCore->projectManager() && pCore->projectManager()->currentTimeline()) {
pCore->projectManager()->currentTimeline()->updatePalette();
}
if (m_timelineArea) {
m_timelineArea->setPalette(plt);
}
- /*if (statusBar()) {
- const QObjectList children = statusBar()->children();
- foreach(QObject * child, children) {
- if (child->isWidgetType())
- ((QWidget*)child)->setPalette(plt);
- const QObjectList subchildren = child->children();
- foreach(QObject * subchild, subchildren) {
- if (subchild->isWidgetType())
- ((QWidget*)subchild)->setPalette(plt);
- }
- }
- }*/
#if KXMLGUI_VERSION_MINOR < 23 && KXMLGUI_VERSION_MAJOR == 5
// Not required anymore with auto colored icons since KF5 5.23
@@ -981,12 +971,6 @@ QAction *MainWindow::addAction(const QString &name, const QString &text, const Q
void MainWindow::setupActions()
{
- m_statusProgressBar = new QProgressBar(this);
- m_statusProgressBar->setMinimum(0);
- m_statusProgressBar->setMaximum(100);
- m_statusProgressBar->setMaximumWidth(150);
- m_statusProgressBar->setVisible(false);
-
//create edit mode buttons
m_normalEditTool = new QAction(KoIconUtils::themedIcon(QStringLiteral("kdenlive-normal-edit")), i18n("Normal mode"), this);
m_normalEditTool->setShortcut(i18nc("Normal editing", "n"));
@@ -1146,7 +1130,6 @@ void MainWindow::setupActions()
toolbar->setMovable(false);
toolbar->setToolButtonStyle(Qt::ToolButtonIconOnly);
- setStatusBarStyleSheet(palette());
/*QString styleBorderless = QStringLiteral("QToolButton { border-width: 0px;margin: 1px 3px 0px;padding: 0px;}");*/
toolbar->addAction(m_buttonAutomaticSplitAudio);
toolbar->addAction(m_buttonVideoThumbs);
@@ -1179,14 +1162,16 @@ void MainWindow::setupActions()
actionWidget->setMaximumWidth(max);
actionWidget->setMaximumHeight(max - 4);*/
+ int small = style()->pixelMetric(QStyle::PM_SmallIconSize);
+ statusBar()->setMaximumHeight(2 * small);
m_messageLabel = new StatusBarMessageLabel(this);
m_messageLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::MinimumExpanding);
- statusBar()->addWidget(m_messageLabel, 10);
- statusBar()->addWidget(m_statusProgressBar, 0);
+ statusBar()->addWidget(m_messageLabel, 0);
+ QWidget *spacer = new QWidget(this);
+ spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
+ statusBar()->addWidget(spacer, 1);
statusBar()->addPermanentWidget(toolbar);
- int small = style()->pixelMetric(QStyle::PM_SmallIconSize);
- statusBar()->setMaximumHeight(2 * small);
toolbar->setIconSize(QSize(small , small));
toolbar->layout()->setContentsMargins(0, 0, 0, 0);
statusBar()->setContentsMargins(0, 0, 0, 0);
@@ -1532,18 +1517,6 @@ void MainWindow::setupActions()
}
}
-void MainWindow::setStatusBarStyleSheet(const QPalette &p)
-{
- return;
- KColorScheme scheme(p.currentColorGroup(), KColorScheme::Window, KSharedConfig::openConfig(KdenliveSettings::colortheme()));
- QColor buttonBg = scheme.background(KColorScheme::LinkBackground).color();
- QColor buttonBord = scheme.foreground(KColorScheme::LinkText).color();
- QColor buttonBord2 = scheme.shade(KColorScheme::LightShade);
- statusBar()->setStyleSheet(QStringLiteral("QStatusBar QLabel {font-size:%1pt;} QStatusBar::item { border: 0px; font-size:%1pt;padding:0px; }").arg(statusBar()->font().pointSize()));
- QString style1 = QStringLiteral("QToolBar { border: 0px } QToolButton { border-style: inset; border:1px solid transparent;border-radius: 3px;margin: 0px 3px;padding: 0px;} QToolButton#timecode {padding-right:10px;} QToolButton:hover { background: %3;border-style: inset; border:1px solid %3;border-radius: 3px;} QToolButton:checked { background-color: %1; border-style: inset; border:1px solid %2;border-radius: 3px;}").arg(buttonBg.name(), buttonBord.name(), buttonBord2.name());
- statusBar()->setStyleSheet(style1);
-}
-
void MainWindow::saveOptions()
{
KdenliveSettings::self()->save();
@@ -1807,8 +1780,8 @@ void MainWindow::connectDocument()
connect(trackView->projectView(), SIGNAL(zoomOut()), this, SLOT(slotZoomOut()));
connect(trackView, SIGNAL(setZoom(int)), this, SLOT(slotSetZoom(int)));
connect(trackView->projectView(), SIGNAL(displayMessage(QString,MessageType)), m_messageLabel, SLOT(setMessage(QString,MessageType)));
- connect(pCore->bin(), SIGNAL(clipNameChanged(QString)), trackView->projectView(), SLOT(clipNameChanged(QString)));
- connect(pCore->bin(), SIGNAL(displayMessage(QString,MessageType)), m_messageLabel, SLOT(setMessage(QString,MessageType)));
+ connect(pCore->bin(), SIGNAL(clipNameChanged(QString)), trackView->projectView(), SLOT(clipNameChanged(QString)));
+ connect(pCore->bin(), SIGNAL(displayMessage(QString,int,MessageType)), m_messageLabel, SLOT(setMessage(QString,int,MessageType)));
connect(trackView->projectView(), SIGNAL(showClipFrame(const QString&,int)), pCore->bin(), SLOT(selectClipById(const QString&,int)));
connect(trackView->projectView(), SIGNAL(playMonitor()), m_projectMonitor, SLOT(slotPlay()));
@@ -2093,7 +2066,7 @@ void MainWindow::slotAddClipMarker()
pos = m_clipMonitor->position();
}
if (!clip) {
- m_messageLabel->setMessage(i18n("Cannot find clip to add marker"), ErrorMessage);
+ m_messageLabel->setMessage(i18n("Cannot find clip to add marker"), 100, ErrorMessage);
return;
}
QString id = clip->clipId();
@@ -2125,7 +2098,7 @@ void MainWindow::slotDeleteClipMarker(bool allowGuideDeletion)
pos = m_clipMonitor->position();
}
if (!clip) {
- m_messageLabel->setMessage(i18n("Cannot find clip to remove marker"), ErrorMessage);
+ m_messageLabel->setMessage(i18n("Cannot find clip to remove marker"), 100, ErrorMessage);
return;
}
@@ -2135,7 +2108,7 @@ void MainWindow::slotDeleteClipMarker(bool allowGuideDeletion)
if (allowGuideDeletion && m_projectMonitor->isActive()) {
slotDeleteGuide();
}
- else m_messageLabel->setMessage(i18n("No marker found at cursor time"), ErrorMessage);
+ else m_messageLabel->setMessage(i18n("No marker found at cursor time"), 100, ErrorMessage);
return;
}
pCore->bin()->deleteClipMarker(comment, id, pos);
@@ -2155,7 +2128,7 @@ void MainWindow::slotDeleteAllClipMarkers()
clip = m_clipMonitor->currentController();
}
if (!clip) {
- m_messageLabel->setMessage(i18n("Cannot find clip to remove marker"), ErrorMessage);
+ m_messageLabel->setMessage(i18n("Cannot find clip to remove marker"), 100, ErrorMessage);
return;
}
pCore->bin()->deleteAllClipMarkers(clip->clipId());
@@ -2178,14 +2151,14 @@ void MainWindow::slotEditClipMarker()
pos = m_clipMonitor->position();
}
if (!clip) {
- m_messageLabel->setMessage(i18n("Cannot find clip to remove marker"), ErrorMessage);
+ m_messageLabel->setMessage(i18n("Cannot find clip to remove marker"), 100, ErrorMessage);
return;
}
QString id = clip->clipId();
CommentedTime oldMarker = clip->markerAt(pos);
if (oldMarker == CommentedTime()) {
- m_messageLabel->setMessage(i18n("No marker found at cursor time"), ErrorMessage);
+ m_messageLabel->setMessage(i18n("No marker found at cursor time"), 100, ErrorMessage);
return;
}
@@ -2214,7 +2187,7 @@ void MainWindow::slotAddMarkerGuideQuickly()
GenTime pos = m_clipMonitor->position();
if (!clip) {
- m_messageLabel->setMessage(i18n("Cannot find clip to add marker"), ErrorMessage);
+ m_messageLabel->setMessage(i18n("Cannot find clip to add marker"), 100, ErrorMessage);
return;
}
//TODO: allow user to set default marker category
@@ -2474,7 +2447,7 @@ void MainWindow::slotAddVideoEffect(QAction *result)
if (!effect.isNull()) {
slotAddEffect(effect);
} else {
- m_messageLabel->setMessage(i18n("Cannot find effect %1 / %2", info.at(0), info.at(1)), ErrorMessage);
+ m_messageLabel->setMessage(i18n("Cannot find effect %1 / %2", info.at(0), info.at(1)), 100, ErrorMessage);
}
}
@@ -2537,23 +2510,13 @@ void MainWindow::slotUpdateZoomSliderToolTip(int zoomlevel)
void MainWindow::slotGotProgressInfo(const QString &message, int progress, MessageType type)
{
- if (type == DefaultMessage) {
- m_statusProgressBar->setValue(progress);
- }
- m_messageLabel->setMessage(progress < 100 ? message : QString(), type);
- if (progress >= 0) {
- if (type == DefaultMessage) {
- m_statusProgressBar->setVisible(progress < 100);
- }
- } else {
- m_statusProgressBar->setVisible(false);
- }
+ m_messageLabel->setMessage(message, progress, type);
}
void MainWindow::customEvent(QEvent* e)
{
if (e->type() == QEvent::User)
- m_messageLabel->setMessage(static_cast <MltErrorEvent *>(e)->message(), MltError);
+ m_messageLabel->setMessage(static_cast <MltErrorEvent *>(e)->message(), 100, MltError);
}
void MainWindow::slotTimelineClipSelected(ClipItem* item, bool reloadStack, bool raise)
@@ -2658,7 +2621,7 @@ void MainWindow::slotSetTool(ProjectTool tool)
message = i18n("Shift + click to create a selection rectangle, Ctrl + click to add an item to selection");
break;
}
- m_messageLabel->setMessage(message, InformationMessage);
+ m_messageLabel->setMessage(message, 100, InformationMessage);
pCore->projectManager()->currentTimeline()->projectView()->setTool(tool);
}
}
@@ -3088,7 +3051,7 @@ void MainWindow::slotTranscode(const QStringList &urls)
return;
}
if (urls.isEmpty()) {
- m_messageLabel->setMessage(i18n("No clip to transcode"), ErrorMessage);
+ m_messageLabel->setMessage(i18n("No clip to transcode"), 100, ErrorMessage);
return;
}
ClipTranscode *d = new ClipTranscode(urls, params, QStringList(), desc);
@@ -3345,12 +3308,12 @@ void MainWindow::slotPrepareRendering(bool scriptExport, bool zoneOnly, const QS
// Do save scenelist
QFile file(plPath);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
- m_messageLabel->setMessage(i18n("Cannot write to file %1", plPath), ErrorMessage);
+ m_messageLabel->setMessage(i18n("Cannot write to file %1", plPath), 100, ErrorMessage);
return;
}
file.write(docList.at(i).toString().toUtf8());
if (file.error() != QFile::NoError) {
- m_messageLabel->setMessage(i18n("Cannot write to file %1", plPath), ErrorMessage);
+ m_messageLabel->setMessage(i18n("Cannot write to file %1", plPath), 100, ErrorMessage);
file.close();
return;
}
@@ -3499,7 +3462,7 @@ void MainWindow::slotArchiveProject()
QDomDocument doc = pCore->projectManager()->current()->xmlSceneList(m_projectMonitor->sceneList());
QPointer<ArchiveWidget> d = new ArchiveWidget(pCore->projectManager()->current()->url().fileName(), doc, list, pCore->projectManager()->currentTimeline()->projectView()->extractTransitionsLumas(), this);
if (d->exec()) {
- m_messageLabel->setMessage(i18n("Archiving project"), OperationCompletedMessage);
+ m_messageLabel->setMessage(i18n("Archiving project"), 100, OperationCompletedMessage);
}
delete d;
}
diff --git a/src/mainwindow.h b/src/mainwindow.h
index 3506be1..ccb56a8 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -23,7 +23,6 @@
#include <QDockWidget>
#include <QUndoView>
-#include <QProgressBar>
#include <QEvent>
#include <QShortcut>
#include <QMap>
@@ -133,7 +132,6 @@ public:
QUndoGroup *m_commandStack;
EffectStackView2 *m_effectStack;
QUndoView *m_undoView;
- StatusBarMessageLabel *m_messageLabel;
/** @brief holds info about whether movit is available on this system */
bool m_gpuAllowed;
int m_exitCode;
@@ -164,7 +162,6 @@ protected:
virtual void saveNewToolbarConfig();
private:
- QProgressBar *m_statusProgressBar;
/** @brief Sets up all the actions and attaches them to the collection. */
void setupActions();
@@ -219,7 +216,7 @@ private:
QShortcut* m_shortcutRemoveFocus;
RenderWidget *m_renderWidget;
-
+ StatusBarMessageLabel *m_messageLabel;
QList <QAction *>m_transitions;
QAction *m_buttonAudioThumbs;
QAction *m_buttonVideoThumbs;
@@ -266,8 +263,6 @@ private:
bool m_themeInitialized;
bool m_isDarkTheme;
QListWidget *m_effectBasket;
- /** @brief Update statusbar stylesheet (in case of color theme change). */
- void setStatusBarStyleSheet(const QPalette &p);
/** @brief Update widget style. */
void doChangeStyle();
diff --git a/src/project/projectmanager.cpp b/src/project/projectmanager.cpp
index 6ac29a6..8140692 100644
--- a/src/project/projectmanager.cpp
+++ b/src/project/projectmanager.cpp
@@ -190,7 +190,6 @@ void ProjectManager::newFile(bool showProjectSettings, bool force)
pCore->window()->slotPreferences(6);
return;
}
- connect(m_project, SIGNAL(progressInfo(QString,int)), pCore->window(), SLOT(slotGotProgressInfo(QString,int)));
pCore->window()->connectDocument();
bool disabled = m_project->getDocumentProperty(QStringLiteral("disabletimelineeffects")) == QLatin1String("1");
QAction *disableEffects = pCore->window()->actionCollection()->action(QStringLiteral("disable_timeline_effects"));
@@ -462,8 +461,7 @@ void ProjectManager::openFile(const QUrl &url)
if (checkForBackupFile(url)) {
return;
}
- pCore->window()->m_messageLabel->setMessage(i18n("Opening file %1", url.path()), InformationMessage);
- pCore->window()->m_messageLabel->repaint();
+ pCore->window()->slotGotProgressInfo(i18n("Opening file %1", url.path()), 100, InformationMessage);
doOpenFile(url, NULL);
}
@@ -506,7 +504,6 @@ void ProjectManager::doOpenFile(const QUrl &url, KAutoSaveFile *stale)
stale->setParent(doc);
}
m_progressDialog->setLabelText(i18n("Loading clips"));
- connect(doc, SIGNAL(progressInfo(QString,int)), pCore->window(), SLOT(slotGotProgressInfo(QString,int)));
pCore->bin()->setDocument(doc);
QList <QAction*> rulerActions;
diff --git a/src/statusbarmessagelabel.cpp b/src/statusbarmessagelabel.cpp
index abeaeb4..284fd12 100644
--- a/src/statusbarmessagelabel.cpp
+++ b/src/statusbarmessagelabel.cpp
@@ -33,38 +33,87 @@
#include <QPainter>
#include <QPushButton>
#include <QPixmap>
+#include <QLabel>
+#include <QProgressBar>
+#include <QMouseEvent>
+#include <QHBoxLayout>
+
+FlashLabel::FlashLabel(QWidget *parent) : QWidget(parent)
+{
+ setAutoFillBackground(true);
+}
+
+FlashLabel::~FlashLabel()
+{
+}
+
+void FlashLabel::setColor(const QColor &col)
+{
+ QPalette pal = palette();
+ pal.setColor(QPalette::Window, col);
+ setPalette(pal);
+ update();
+}
+
+QColor FlashLabel::color() const
+{
+ return palette().window().color();
+}
+
StatusBarMessageLabel::StatusBarMessageLabel(QWidget* parent) :
- QWidget(parent),
- m_state(Default),
- m_illumination(-64),
+ FlashLabel(parent),
m_minTextHeight(-1),
- m_queueSemaphore(1),
- m_closeButton(0)
+ m_queueSemaphore(1)
{
setMinimumHeight(KIconLoader::SizeSmall);
- /*QPalette palette);
- palette.setColor(QPalette::Background, Qt::transparent);
- setPalette(palette);*/
-
- m_closeButton = new QPushButton(i18nc("@action:button", "Confirm"), this);
- m_closeButton->hide();
-
+ QHBoxLayout *lay = new QHBoxLayout(this);
+ m_pixmap = new QLabel(this);
+ m_pixmap->setAlignment(Qt::AlignCenter);
+ m_label = new QLabel(this);
+ m_label->setAlignment(Qt::AlignLeft);
+ m_progress = new QProgressBar(this);
+ lay->addWidget(m_pixmap);
+ lay->addWidget(m_label);
+ lay->addWidget(m_progress);
+ setLayout(lay);
+ m_progress->setVisible(false);
+ lay->setContentsMargins(BorderGap, 0, BorderGap, 0);
+ m_animation.setTargetObject(this);
+ m_animation.setPropertyName("color");
m_queueTimer.setSingleShot(true);
-
connect(&m_queueTimer, SIGNAL(timeout()), this, SLOT(slotMessageTimeout()));
- connect(m_closeButton, SIGNAL(clicked()), this, SLOT(confirmErrorMessage()));
- connect(&m_timer, SIGNAL(timeout()), this, SLOT(timerDone()));
}
StatusBarMessageLabel::~StatusBarMessageLabel()
{
}
-void StatusBarMessageLabel::setMessage(const QString& text,
- MessageType type, int timeoutMS)
+void StatusBarMessageLabel::updatePalette()
{
+ m_animation.setKeyValueAt(1, parentWidget()->palette().window().color());
+ setColor(parentWidget()->palette().window().color());
+}
+
+void StatusBarMessageLabel::mousePressEvent(QMouseEvent *event)
+{
+ QWidget::mousePressEvent(event);
+ if (m_currentMessage.type == MltError)
+ confirmErrorMessage();
+}
+
+void StatusBarMessageLabel::setMessage(const QString& text, int progress, MessageType type, int timeoutMS)
+{
+ if (type == ProcessingJobMessage) {
+ m_progress->setValue(progress);
+ m_progress->setVisible(progress < 100);
+ }
+ else if (m_currentMessage.type != ProcessingJobMessage || type == OperationCompletedMessage) {
+ m_progress->setVisible(progress < 100);
+ }
+ if (text == m_currentMessage.text)
+ return;
StatusBarMessageItem item(text, type, timeoutMS);
if (item.type == ErrorMessage || item.type == MltError) {
@@ -77,10 +126,9 @@ void StatusBarMessageLabel::setMessage(const QString& text,
qDebug() << item.text;
// Put the new error message at first place and immediately show it
- if (item.timeoutMillis < 2000) {
- item.timeoutMillis = 2000;
+ if (item.timeoutMillis < 3000) {
+ item.timeoutMillis = 3000;
}
-
if (item.type == ProcessingJobMessage) {
// This is a job progress info, discard previous ones
QList <StatusBarMessageItem> cleanList;
@@ -97,8 +145,6 @@ void StatusBarMessageLabel::setMessage(const QString& text,
// In case we are already displaying an error message, add a little delay
int delay = 800 * (m_currentMessage.type == ErrorMessage || m_currentMessage.type == MltError);
m_queueTimer.start(delay);
-
-
} else {
// Message with normal priority
@@ -128,14 +174,16 @@ bool StatusBarMessageLabel::slotMessageTimeout()
m_messageQueue.removeFirst();
if (item.type == OperationCompletedMessage || item.type == ErrorMessage || item.type == MltError || item.type == ProcessingJobMessage) {
m_currentMessage = item;
+ m_label->setText(m_currentMessage.text);
newMessage = true;
break;
}
}
- }
+ }
else if (!m_messageQueue.isEmpty()) {
if (!m_currentMessage.needsConfirmation()) {
m_currentMessage = m_messageQueue.at(0);
+ m_label->setText(m_currentMessage.text);
m_messageQueue.removeFirst();
newMessage = true;
@@ -158,52 +206,56 @@ bool StatusBarMessageLabel::slotMessageTimeout()
}
}
- m_illumination = -64;
- m_state = Default;
- m_timer.stop();
-
+ QColor bgColor = KStatefulBrush(KColorScheme::Window, KColorScheme::NegativeBackground, KSharedConfig::openConfig(KdenliveSettings::colortheme())).brush(this).color();
const char* iconName = 0;
+ if (m_animation.state() == QAbstractAnimation::Running) {
+ m_animation.stop();
+ }
+ setColor(parentWidget()->palette().window().color());
switch (m_currentMessage.type) {
case ProcessingJobMessage:
iconName = "chronometer";
- m_closeButton->hide();
break;
case OperationCompletedMessage:
iconName = "dialog-ok";
- m_closeButton->hide();
break;
case InformationMessage:
iconName = "dialog-information";
- m_closeButton->hide();
break;
case ErrorMessage:
iconName = "dialog-warning";
- m_timer.start(100);
- m_state = Illuminate;
- m_closeButton->hide();
+ m_animation.setKeyValueAt(0, bgColor);
+ m_animation.setKeyValueAt(0.8, bgColor);
+ m_animation.setKeyValueAt(1, parentWidget()->palette().window().color());
+ m_animation.setEasingCurve(QEasingCurve::OutCubic);
+ m_animation.setDuration(4000);
+ m_animation.start();
break;
case MltError:
iconName = "dialog-close";
- m_timer.start(100);
- m_state = Illuminate;
- updateCloseButtonPosition();
- m_closeButton->show();
+ m_animation.setKeyValueAt(0, bgColor);
+ m_animation.setKeyValueAt(1, bgColor);
+ m_animation.setDuration(1000);
+ m_animation.start();
break;
case DefaultMessage:
default:
- m_closeButton->hide();
break;
}
- m_pixmap = (iconName == 0) ? QPixmap() : SmallIcon(iconName);
-
+ if (iconName == 0) {
+ m_pixmap->setVisible(false);
+ } else {
+ m_pixmap->setPixmap(SmallIcon(iconName));
+ m_pixmap->setVisible(true);
+ }
+ setCursor(m_currentMessage.type == MltError ? Qt::PointingHandCursor : Qt::ArrowCursor);
m_queueSemaphore.release();
- update();
return newMessage;
}
@@ -213,106 +265,8 @@ void StatusBarMessageLabel::confirmErrorMessage()
m_queueTimer.start(0);
}
-void StatusBarMessageLabel::paintEvent(QPaintEvent*)
-{
- QPainter painter(this);
-
- // draw background
- QColor backgroundColor;
- if (m_state == Default || m_illumination < 0) backgroundColor = palette().window().color();
- else {
- backgroundColor = KStatefulBrush(KColorScheme::Window, KColorScheme::NegativeBackground, KSharedConfig::openConfig(KdenliveSettings::colortheme())).brush(this).color();
- }
- if (m_state == Desaturate && m_illumination > 0) {
- backgroundColor.setAlpha(qMin(m_illumination * 2, 255));
- }
- painter.fillRect(0, 0, width(), height(), backgroundColor);
-
- // draw pixmap
- int x = BorderGap;
- int y = (height() - m_pixmap.height()) / 2;
-
- if (!m_pixmap.isNull()) {
- painter.drawPixmap(x, y, m_pixmap);
- x += m_pixmap.width() + BorderGap * 2;
- }
-
- // draw text
- painter.setPen(palette().text().color());
- int flags = Qt::AlignVCenter;
- if (height() > m_minTextHeight) {
- flags = flags | Qt::TextWordWrap;
- }
- painter.drawText(QRect(x, 0, availableTextWidth(), height()), flags, m_currentMessage.text);
- painter.end();
-}
-
void StatusBarMessageLabel::resizeEvent(QResizeEvent* event)
{
QWidget::resizeEvent(event);
- updateCloseButtonPosition();
-}
-
-void StatusBarMessageLabel::timerDone()
-{
- switch (m_state) {
- case Illuminate: {
- // increase the illumination
- const int illumination_max = 128;
- if (m_illumination < illumination_max) {
- m_illumination += 32;
- if (m_illumination > illumination_max) {
- m_illumination = illumination_max;
- }
- update();
- } else {
- m_state = Illuminated;
- m_timer.start(1500);
- }
- break;
- }
-
- case Illuminated: {
- // start desaturation
- if (m_currentMessage.type != MltError) {
- m_state = Desaturate;
- m_timer.start(80);
- }
- break;
- }
-
- case Desaturate: {
- // desaturate
- if (m_illumination < -128) {
- m_illumination = 0;
- m_state = Default;
- m_timer.stop();
- setMessage(QString(), DefaultMessage);
- } else {
- m_illumination -= 5;
- update();
- }
- break;
- }
-
- default:
- break;
- }
}
-int StatusBarMessageLabel::availableTextWidth() const
-{
- const int buttonWidth = 0; /*(m_type == ErrorMessage) ?
- m_closeButton->width() + BorderGap : 0;*/
- return width() - m_pixmap.width() - (BorderGap * 4) - buttonWidth;
-}
-
-void StatusBarMessageLabel::updateCloseButtonPosition()
-{
- const int x = width() - m_closeButton->width() - BorderGap;
- const int y = (height() - m_closeButton->height()) / 2;
- m_closeButton->move(x, y);
-}
-
-
-
diff --git a/src/statusbarmessagelabel.h b/src/statusbarmessagelabel.h
index ed7de8b..7c56cc5 100644
--- a/src/statusbarmessagelabel.h
+++ b/src/statusbarmessagelabel.h
@@ -30,6 +30,9 @@
#include <QWidget>
#include <QTimer>
#include <QSemaphore>
+#include <QLabel>
+#include <QColor>
+#include <QPropertyAnimation>
#include <definitions.h>
@@ -37,9 +40,20 @@
class QPaintEvent;
class QResizeEvent;
-class QPushButton;
+class QProgressBar;
+class FlashLabel: public QWidget
+{
+ Q_PROPERTY(QColor color READ color WRITE setColor)
+ Q_OBJECT
+public:
+ explicit FlashLabel(QWidget *parent = 0);
+ ~FlashLabel();
+ QColor color() const;
+ void setColor(const QColor &);
+};
+
/**
Queue-able message item holding all important information
*/
@@ -73,37 +87,26 @@ struct StatusBarMessageItem {
* DolphinStatusBar::Error a dynamic color blending is done to get the
* attention from the user.
*/
-class StatusBarMessageLabel : public QWidget
+class StatusBarMessageLabel : public FlashLabel
{
Q_OBJECT
public:
explicit StatusBarMessageLabel(QWidget* parent);
virtual ~StatusBarMessageLabel();
+ void updatePalette();
protected:
- /** @see QWidget::paintEvent() */
- void paintEvent(QPaintEvent* event);
+ //void paintEvent(QPaintEvent* event);
+ void mousePressEvent(QMouseEvent * );
/** @see QWidget::resizeEvent() */
void resizeEvent(QResizeEvent* event);
public slots:
- void setMessage(const QString& text, MessageType type, int timeoutMS = 0);
+ void setMessage(const QString& text, int progress = 100, MessageType type = DefaultMessage, int timeoutMS = 0);
private slots:
- void timerDone();
-
- /**
- * Returns the available width in pixels for the text.
- */
- int availableTextWidth() const;
-
- /**
- * Moves the close button to the upper right corner
- * of the message label.
- */
- void updateCloseButtonPosition();
/**
* Closes the currently shown error message and replaces it
@@ -118,28 +121,18 @@ private slots:
bool slotMessageTimeout();
private:
- enum State {
- Default,
- Illuminate,
- Illuminated,
- Desaturate
- };
-
enum { GeometryTimeout = 100 };
enum { BorderGap = 2 };
- State m_state;
- int m_illumination;
int m_minTextHeight;
- QTimer m_timer;
-
+ QLabel *m_pixmap;
+ QLabel *m_label;
+ QProgressBar *m_progress;
QTimerWithTime m_queueTimer;
QSemaphore m_queueSemaphore;
+ QPropertyAnimation m_animation;
QList<StatusBarMessageItem> m_messageQueue;
StatusBarMessageItem m_currentMessage;
-
- QPixmap m_pixmap;
- QPushButton* m_closeButton;
};
#endif