diff --git a/Plugins/org.mitk.gui.qt.moviemaker2/src/internal/QmitkAnimationItemDelegate.cpp b/Plugins/org.mitk.gui.qt.moviemaker2/src/internal/QmitkAnimationItemDelegate.cpp index 518b69a4db..ce038cf4ec 100644 --- a/Plugins/org.mitk.gui.qt.moviemaker2/src/internal/QmitkAnimationItemDelegate.cpp +++ b/Plugins/org.mitk.gui.qt.moviemaker2/src/internal/QmitkAnimationItemDelegate.cpp @@ -1,123 +1,123 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkAnimationItem.h" #include "QmitkAnimationItemDelegate.h" #include #include #include #include QmitkAnimationItemDelegate::QmitkAnimationItemDelegate(QObject* parent) : QStyledItemDelegate(parent) { } QmitkAnimationItemDelegate::~QmitkAnimationItemDelegate() { } void QmitkAnimationItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { painter->save(); if (option.state & QStyle::State_Selected) painter->fillRect(option.rect, option.palette.highlight()); if (index.column() == 0) { QStyleOptionViewItem opt = option; this->initStyleOption(&opt, index); QRect rect = QRect(opt.rect.x() + 3, opt.rect.y(), opt.rect.width() - 6, opt.rect.height()); QString text = option.fontMetrics.elidedText(index.data().toString(), Qt::ElideRight, rect.width()); QPalette::ColorRole colorRole = (option.state & QStyle::State_Selected) ? QPalette::HighlightedText : QPalette::Text; QApplication::style()->drawItemText(painter, rect, 0, option.palette, true, text, colorRole); } else if (index.column() == 1) { const QStandardItemModel* model = dynamic_cast(index.model()); const QmitkAnimationItem* thisItem = dynamic_cast(model->item(index.row(), 1)); QList items; const int rowCount = model->rowCount(); for (int i = 0; i < rowCount; ++i) items << dynamic_cast(model->item(i, 1)); double totalDuration = 0.0; double previousStart = 0.0; double thisStart = 0.0; Q_FOREACH(const QmitkAnimationItem* item, items) { if (item->GetStartWithPrevious()) { totalDuration = std::max(totalDuration, previousStart + item->GetDelay() + item->GetDuration()); } else { previousStart = totalDuration; totalDuration += item->GetDelay() + item->GetDuration(); } if (item == thisItem) thisStart = previousStart; } QColor color = thisItem->GetStartWithPrevious() - ? QColor("Khaki") - : QColor("DarkKhaki"); + ? QColor("DarkGray") + : QColor("DimGray"); painter->setBrush(color); painter->setPen(Qt::NoPen); const QRect& rect = option.rect; const double widthPerSecond = rect.width() / totalDuration; painter->drawRect( rect.x() + static_cast(widthPerSecond * (thisStart + thisItem->GetDelay())), rect.y() + 1, static_cast(widthPerSecond * thisItem->GetDuration()), rect.height() - 2); if (thisItem->GetDelay() > std::numeric_limits::min()) { QPen pen(color); painter->setPen(pen); painter->drawLine( rect.x() + static_cast(widthPerSecond * thisStart), rect.y() + 1, rect.x() + static_cast(widthPerSecond * thisStart), rect.y() + rect.height() - 2); pen.setStyle(Qt::DashLine); painter->setPen(pen); painter->drawLine( rect.x() + static_cast(widthPerSecond * thisStart), rect.y() + rect.height() / 2, rect.x() + static_cast(widthPerSecond * (thisStart + thisItem->GetDelay())) - 1, rect.y() + rect.height() / 2); } } painter->restore(); } diff --git a/Plugins/org.mitk.gui.qt.moviemaker2/src/internal/QmitkFFmpegWriter.cpp b/Plugins/org.mitk.gui.qt.moviemaker2/src/internal/QmitkFFmpegWriter.cpp index b80b90ffc5..f985bfd402 100644 --- a/Plugins/org.mitk.gui.qt.moviemaker2/src/internal/QmitkFFmpegWriter.cpp +++ b/Plugins/org.mitk.gui.qt.moviemaker2/src/internal/QmitkFFmpegWriter.cpp @@ -1,156 +1,164 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkFFmpegWriter.h" #include #include +#include QmitkFFmpegWriter::QmitkFFmpegWriter(QObject* parent) : QObject(parent), - m_Process(new QProcess(this)) + m_Process(new QProcess(this)), + m_Framerate(0) { this->connect(m_Process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(OnProcessError(QProcess::ProcessError))); this->connect(m_Process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(OnProcessFinished(int, QProcess::ExitStatus))); } QmitkFFmpegWriter::~QmitkFFmpegWriter() { } QString QmitkFFmpegWriter::GetFFmpegPath() const { return m_FFmpegPath; } void QmitkFFmpegWriter::SetFFmpegPath(const QString& path) { m_FFmpegPath = path; } QSize QmitkFFmpegWriter::GetSize() const { return m_Size; } void QmitkFFmpegWriter::SetSize(const QSize& size) { m_Size = size; } void QmitkFFmpegWriter::SetSize(int width, int height) { m_Size = QSize(width, height); } int QmitkFFmpegWriter::GetFramerate() const { return m_Framerate; } void QmitkFFmpegWriter::SetFramerate(int framerate) { m_Framerate = framerate; } QString QmitkFFmpegWriter::GetOutputPath() const { return m_OutputPath; } void QmitkFFmpegWriter::SetOutputPath(const QString& path) { m_OutputPath = path; } void QmitkFFmpegWriter::Start() { + if (m_FFmpegPath.isEmpty()) + mitkThrow() << "FFmpeg/Libav path is empty!"; + + if (m_Size.isNull()) + mitkThrow() << "Invalid video frame size!"; + + if (m_Framerate <= 0) + mitkThrow() << "Invalid framerate!"; + + if (m_OutputPath.isEmpty()) + mitkThrow() << "Output path is empty!"; + m_Process->start(m_FFmpegPath, QStringList() << "-y" << "-f" << "rawvideo" << "-pix_fmt" << "rgb24" << "-s" << QString("%1x%2").arg(m_Size.width()).arg(m_Size.height()) << "-r" << QString("%1").arg(m_Framerate) << "-i" << "-" << "-vf" << "vflip" << "-pix_fmt" << "yuv420p" << "-crf" << "18" << m_OutputPath); m_Process->waitForStarted(); } void QmitkFFmpegWriter::WriteFrame(const unsigned char* frame) { if (frame == NULL || !m_Process->isOpen()) return; m_Process->write(reinterpret_cast(frame), m_Size.width() * m_Size.height() * 3); m_Process->waitForBytesWritten(); } void QmitkFFmpegWriter::Stop() { m_Process->closeWriteChannel(); } void QmitkFFmpegWriter::OnProcessError(QProcess::ProcessError error) { + MITK_ERROR << QString::fromLatin1(m_Process->readAllStandardError()).toStdString(); + switch (error) { - case QProcess::FailedToStart: - QMessageBox::critical(NULL, "FFmpeg Writer", "FFmpeg failed to start!"); - break; + case QProcess::FailedToStart: + mitkThrow() << "FFmpeg/Libav failed to start!"; - case QProcess::Crashed: - QMessageBox::critical(NULL, "FFmpeg Writer", "FFmpeg crashed!"); - break; + case QProcess::Crashed: + mitkThrow() << "FFmpeg/Libav crashed!"; - case QProcess::Timedout: - QMessageBox::critical(NULL, "FFmpeg Writer", "FFmpeg timed out!"); - break; + case QProcess::Timedout: + mitkThrow() << "FFmpeg/Libav timed out!"; - case QProcess::WriteError: - QMessageBox::critical(NULL, "FFmpeg Writer", "Could not write to FFmpeg!"); - break; + case QProcess::WriteError: + mitkThrow() << "Could not write to FFmpeg/Libav!"; - case QProcess::ReadError: - QMessageBox::critical(NULL, "FFmpeg Writer", "Could not read from FFmpeg!"); - break; + case QProcess::ReadError: + mitkThrow() << "Could not read from FFmpeg/Libav!"; - default: - QMessageBox::critical(NULL, "FFmpeg Writer", "An unknown error occurred!"); - break; + default: + mitkThrow() << "An unknown error occurred!"; } - - MITK_ERROR << QString::fromLatin1(m_Process->readAllStandardError()).toStdString(); } void QmitkFFmpegWriter::OnProcessFinished(int exitCode, QProcess::ExitStatus exitStatus) { if (exitStatus != QProcess::CrashExit) { if (exitCode != 0) { - QMessageBox::critical(NULL, "FFmpeg Writer", QString("FFmpeg exit code: %1").arg(exitCode)); - MITK_ERROR << QString::fromLatin1(m_Process->readAllStandardError()).toStdString(); + m_Process->close(); + mitkThrow() << QString("FFmpeg/Libav exit code: %1").arg(exitCode).toStdString().c_str(); } } m_Process->close(); } diff --git a/Plugins/org.mitk.gui.qt.moviemaker2/src/internal/QmitkMovieMaker2View.cpp b/Plugins/org.mitk.gui.qt.moviemaker2/src/internal/QmitkMovieMaker2View.cpp index b0e79016c5..84f5ac92c1 100644 --- a/Plugins/org.mitk.gui.qt.moviemaker2/src/internal/QmitkMovieMaker2View.cpp +++ b/Plugins/org.mitk.gui.qt.moviemaker2/src/internal/QmitkMovieMaker2View.cpp @@ -1,501 +1,508 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkAnimationItemDelegate.h" #include "QmitkFFmpegWriter.h" #include "QmitkMovieMaker2View.h" #include "QmitkOrbitAnimationItem.h" #include "QmitkOrbitAnimationWidget.h" #include "QmitkSliceAnimationItem.h" #include "QmitkSliceAnimationWidget.h" #include #include #include #include #include #include #include static QmitkAnimationItem* CreateDefaultAnimation(const QString& widgetKey) { if (widgetKey == "Orbit") return new QmitkOrbitAnimationItem(360.0, false); if (widgetKey == "Slice") return new QmitkSliceAnimationItem(0, 0, 999, false); return NULL; } static QString GetFFmpegPath() { berry::IPreferencesService::Pointer preferencesService = berry::Platform::GetServiceRegistry().GetServiceById(berry::IPreferencesService::ID); berry::IPreferences::Pointer preferences = preferencesService->GetSystemPreferences()->Node("/org.mitk.gui.qt.ext.externalprograms"); return QString::fromStdString(preferences->Get("ffmpeg", "")); } static unsigned char* ReadPixels(vtkRenderWindow* renderWindow, int x, int y, int width, int height) { if (renderWindow == NULL) return NULL; unsigned char* frame = new unsigned char[width * height * 3]; renderWindow->MakeCurrent(); glReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, frame); return frame; } const std::string QmitkMovieMaker2View::VIEW_ID = "org.mitk.views.moviemaker2"; QmitkMovieMaker2View::QmitkMovieMaker2View() : m_FFmpegWriter(NULL), m_Ui(new Ui::QmitkMovieMaker2View), m_AnimationModel(NULL), m_AddAnimationMenu(NULL), m_RecordMenu(NULL) { } QmitkMovieMaker2View::~QmitkMovieMaker2View() { } void QmitkMovieMaker2View::CreateQtPartControl(QWidget* parent) { m_FFmpegWriter = new QmitkFFmpegWriter(parent); m_Ui->setupUi(parent); this->InitializeAnimationWidgets(); this->InitializeAnimationTreeViewWidgets(); this->InitializePlaybackAndRecordWidgets(); m_Ui->animationWidgetGroupBox->setVisible(false); } void QmitkMovieMaker2View::InitializeAnimationWidgets() { m_AnimationWidgets["Orbit"] = new QmitkOrbitAnimationWidget; m_AnimationWidgets["Slice"] = new QmitkSliceAnimationWidget; Q_FOREACH(QWidget* widget, m_AnimationWidgets.values()) { if (widget != NULL) { widget->setVisible(false); m_Ui->animationWidgetGroupBoxLayout->addWidget(widget); } } this->ConnectAnimationWidgets(); } void QmitkMovieMaker2View::InitializeAnimationTreeViewWidgets() { this->InitializeAnimationModel(); this->InitializeAddAnimationMenu(); this->ConnectAnimationTreeViewWidgets(); } void QmitkMovieMaker2View::InitializePlaybackAndRecordWidgets() { this->InitializeRecordMenu(); this->ConnectPlaybackAndRecordWidgets(); } void QmitkMovieMaker2View::InitializeAnimationModel() { m_AnimationModel = new QStandardItemModel(m_Ui->animationTreeView); m_AnimationModel->setHorizontalHeaderLabels(QStringList() << "Animation" << "Timeline"); m_Ui->animationTreeView->setModel(m_AnimationModel); m_Ui->animationTreeView->setItemDelegate(new QmitkAnimationItemDelegate(m_Ui->animationTreeView)); } void QmitkMovieMaker2View::InitializeAddAnimationMenu() { m_AddAnimationMenu = new QMenu(m_Ui->addAnimationButton); Q_FOREACH(const QString& key, m_AnimationWidgets.keys()) { m_AddAnimationMenu->addAction(key); } } void QmitkMovieMaker2View::InitializeRecordMenu() { typedef QPair PairOfStrings; m_RecordMenu = new QMenu(m_Ui->recordButton); QVector renderWindows; renderWindows.push_back(qMakePair(QString("Axial"), QString("stdmulti.widget1"))); renderWindows.push_back(qMakePair(QString("Sagittal"), QString("stdmulti.widget2"))); renderWindows.push_back(qMakePair(QString("Coronal"), QString("stdmulti.widget3"))); renderWindows.push_back(qMakePair(QString("3D"), QString("stdmulti.widget4"))); Q_FOREACH(const PairOfStrings& renderWindow, renderWindows) { QAction* action = new QAction(m_RecordMenu); action->setText(renderWindow.first); action->setData(renderWindow.second); m_RecordMenu->addAction(action); } } void QmitkMovieMaker2View::ConnectAnimationTreeViewWidgets() { this->connect(m_AnimationModel, SIGNAL(rowsInserted(const QModelIndex&, int, int)), this, SLOT(OnAnimationTreeViewRowsInserted(const QModelIndex&, int, int))); this->connect(m_AnimationModel, SIGNAL(rowsRemoved(const QModelIndex&, int, int)), this, SLOT(OnAnimationTreeViewRowsRemoved(const QModelIndex&, int, int))); this->connect(m_Ui->animationTreeView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SLOT(OnAnimationTreeViewSelectionChanged(const QItemSelection&, const QItemSelection&))); this->connect(m_Ui->moveAnimationUpButton, SIGNAL(clicked()), this, SLOT(OnMoveAnimationUpButtonClicked())); this->connect(m_Ui->moveAnimationDownButton, SIGNAL(clicked()), this, SLOT(OnMoveAnimationDownButtonClicked())); this->connect(m_Ui->addAnimationButton, SIGNAL(clicked()), this, SLOT(OnAddAnimationButtonClicked())); this->connect(m_Ui->removeAnimationButton, SIGNAL(clicked()), this, SLOT(OnRemoveAnimationButtonClicked())); } void QmitkMovieMaker2View::ConnectAnimationWidgets() { this->connect(m_Ui->startComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(OnStartComboBoxCurrentIndexChanged(int))); this->connect(m_Ui->durationSpinBox, SIGNAL(valueChanged(double)), this, SLOT(OnDurationSpinBoxValueChanged(double))); this->connect(m_Ui->delaySpinBox, SIGNAL(valueChanged(double)), this, SLOT(OnDelaySpinBoxValueChanged(double))); } void QmitkMovieMaker2View::ConnectPlaybackAndRecordWidgets() { this->connect(m_Ui->playButton, SIGNAL(toggled(bool)), this, SLOT(OnPlayButtonToggled(bool))); this->connect(m_Ui->recordButton, SIGNAL(clicked()), this, SLOT(OnRecordButtonClicked())); } void QmitkMovieMaker2View::SetFocus() { m_Ui->addAnimationButton->setFocus(); } void QmitkMovieMaker2View::OnMoveAnimationUpButtonClicked() { const QItemSelection selection = m_Ui->animationTreeView->selectionModel()->selection(); if (!selection.isEmpty()) { const int selectedRow = selection[0].top(); if (selectedRow > 0) m_AnimationModel->insertRow(selectedRow - 1, m_AnimationModel->takeRow(selectedRow)); } } void QmitkMovieMaker2View::OnMoveAnimationDownButtonClicked() { const QItemSelection selection = m_Ui->animationTreeView->selectionModel()->selection(); if (!selection.isEmpty()) { const int rowCount = m_AnimationModel->rowCount(); const int selectedRow = selection[0].top(); if (selectedRow < rowCount - 1) m_AnimationModel->insertRow(selectedRow + 1, m_AnimationModel->takeRow(selectedRow)); } } void QmitkMovieMaker2View::OnAddAnimationButtonClicked() { QAction* action = m_AddAnimationMenu->exec(QCursor::pos()); if (action != NULL) { const QString widgetKey = action->text(); m_AnimationModel->appendRow(QList() << new QStandardItem(widgetKey) << CreateDefaultAnimation(widgetKey)); m_Ui->playbackAndRecordingGroupBox->setEnabled(true); } } void QmitkMovieMaker2View::OnPlayButtonToggled(bool /*checked*/) { vtkRenderWindow* renderWindow = mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget4"); mitk::Stepper* stepper = mitk::BaseRenderer::GetInstance(renderWindow)->GetCameraRotationController()->GetSlice(); unsigned int startPos = stepper->GetPos(); for (unsigned int i = 1; i < 30; ++i) { unsigned int newPos = startPos + 360.0 / 29.0 * i; if (newPos > 360) newPos -= 360; stepper->SetPos(newPos); mitk::RenderingManager::GetInstance()->ForceImmediateUpdate(renderWindow); } } void QmitkMovieMaker2View::OnRecordButtonClicked() // TODO: Refactor { m_FFmpegWriter->SetFFmpegPath(GetFFmpegPath()); if (m_FFmpegWriter->GetFFmpegPath().isEmpty()) { QMessageBox::critical(NULL, "Movie Maker 2", "Path to FFmpeg executable is not set in preferences!"); return; } QAction* action = m_RecordMenu->exec(QCursor::pos()); if (action == NULL) return; vtkRenderWindow* renderWindow = mitk::BaseRenderer::GetRenderWindowByName(action->data().toString().toStdString()); if (renderWindow == NULL) return; const int border = 3; const int x = border; const int y = border; int width = renderWindow->GetSize()[0] - border * 2; int height = renderWindow->GetSize()[1] - border * 2; if (width & 1) --width; if (height & 1) --height; if (width < 16 || height < 16) return; m_FFmpegWriter->SetSize(width, height); m_FFmpegWriter->SetFramerate(m_Ui->fpsSpinBox->value()); QString saveFileName = QFileDialog::getSaveFileName(NULL, "Specify a filename", "", "Movie (*.mp4)"); if (saveFileName.isEmpty()) return; if(!saveFileName.endsWith(".mp4")) saveFileName += ".mp4"; m_FFmpegWriter->SetOutputPath(saveFileName); - m_FFmpegWriter->Start(); + try + { + m_FFmpegWriter->Start(); + + // TODO: Play animation - // TODO: Play animation + for (int i = 0; i < 30; ++i) + { + renderWindow->MakeCurrent(); + unsigned char* frame = ReadPixels(renderWindow, x, y, width, height); + m_FFmpegWriter->WriteFrame(frame); + delete[] frame; + mitk::BaseRenderer::GetInstance(renderWindow)->GetCameraRotationController()->GetSlice()->Next(); + mitk::RenderingManager::GetInstance()->ForceImmediateUpdate(renderWindow); + } - for (int i = 0; i < 30; ++i) + m_FFmpegWriter->Stop(); + } + catch (const mitk::Exception& exception) { - renderWindow->MakeCurrent(); - unsigned char* frame = ReadPixels(renderWindow, x, y, width, height); - m_FFmpegWriter->WriteFrame(frame); - delete[] frame; - mitk::BaseRenderer::GetInstance(renderWindow)->GetCameraRotationController()->GetSlice()->Next(); - mitk::RenderingManager::GetInstance()->ForceImmediateUpdate(renderWindow); + QMessageBox::critical(NULL, "Movie Maker 2", exception.GetDescription()); } - - m_FFmpegWriter->Stop(); } void QmitkMovieMaker2View::OnRemoveAnimationButtonClicked() { const QItemSelection selection = m_Ui->animationTreeView->selectionModel()->selection(); if (!selection.isEmpty()) m_AnimationModel->removeRow(selection[0].top()); } void QmitkMovieMaker2View::OnAnimationTreeViewRowsInserted(const QModelIndex& parent, int start, int) { m_Ui->animationTreeView->selectionModel()->select( m_AnimationModel->index(start, 0, parent), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); } void QmitkMovieMaker2View::OnAnimationTreeViewRowsRemoved(const QModelIndex&, int, int) { this->UpdateWidgets(); } void QmitkMovieMaker2View::OnAnimationTreeViewSelectionChanged(const QItemSelection&, const QItemSelection&) { this->UpdateWidgets(); } void QmitkMovieMaker2View::OnStartComboBoxCurrentIndexChanged(int index) { QmitkAnimationItem* item = this->GetSelectedAnimationItem(); if (item != NULL) { item->SetStartWithPrevious(index); this->RedrawTimeline(); } } void QmitkMovieMaker2View::OnDurationSpinBoxValueChanged(double value) { QmitkAnimationItem* item = this->GetSelectedAnimationItem(); if (item != NULL) { item->SetDuration(value); this->RedrawTimeline(); } } void QmitkMovieMaker2View::OnDelaySpinBoxValueChanged(double value) { QmitkAnimationItem* item = this->GetSelectedAnimationItem(); if (item != NULL) { item->SetDelay(value); this->RedrawTimeline(); } } void QmitkMovieMaker2View::UpdateWidgets() { const QItemSelection selection = m_Ui->animationTreeView->selectionModel()->selection(); if (selection.isEmpty()) { m_Ui->moveAnimationUpButton->setEnabled(false); m_Ui->moveAnimationDownButton->setEnabled(false); m_Ui->removeAnimationButton->setEnabled(false); m_Ui->playbackAndRecordingGroupBox->setEnabled(false); this->HideCurrentAnimationWidget(); } else { const int rowCount = m_AnimationModel->rowCount(); const int selectedRow = selection[0].top(); m_Ui->moveAnimationUpButton->setEnabled(rowCount > 1 && selectedRow != 0); m_Ui->moveAnimationDownButton->setEnabled(rowCount > 1 && selectedRow < rowCount - 1); m_Ui->removeAnimationButton->setEnabled(true); m_Ui->playbackAndRecordingGroupBox->setEnabled(true); this->ShowAnimationWidget(dynamic_cast(m_AnimationModel->item(selectedRow, 1))); } this->UpdateAnimationWidgets(); } void QmitkMovieMaker2View::UpdateAnimationWidgets() { QmitkAnimationItem* item = this->GetSelectedAnimationItem(); if (item != NULL) { m_Ui->startComboBox->setCurrentIndex(item->GetStartWithPrevious()); m_Ui->durationSpinBox->setValue(item->GetDuration()); m_Ui->delaySpinBox->setValue(item->GetDelay()); m_Ui->animationGroupBox->setEnabled(true); } else { m_Ui->animationGroupBox->setEnabled(false); } } void QmitkMovieMaker2View::HideCurrentAnimationWidget() { if (m_Ui->animationWidgetGroupBox->isVisible()) { m_Ui->animationWidgetGroupBox->setVisible(false); int numWidgets = m_Ui->animationWidgetGroupBoxLayout->count(); for (int i = 0; i < numWidgets; ++i) m_Ui->animationWidgetGroupBoxLayout->itemAt(i)->widget()->setVisible(false); } } void QmitkMovieMaker2View::ShowAnimationWidget(QmitkAnimationItem* animationItem) { this->HideCurrentAnimationWidget(); if (animationItem == NULL) return; const QString widgetKey = animationItem->GetWidgetKey(); QmitkAnimationWidget* animationWidget = NULL; if (m_AnimationWidgets.contains(widgetKey)) { animationWidget = m_AnimationWidgets[widgetKey]; if (animationWidget != NULL) { m_Ui->animationWidgetGroupBox->setTitle(widgetKey); animationWidget->SetAnimationItem(animationItem); animationWidget->setVisible(true); } } m_Ui->animationWidgetGroupBox->setVisible(animationWidget != NULL); } void QmitkMovieMaker2View::RedrawTimeline() { if (m_AnimationModel->rowCount() > 1) { m_Ui->animationTreeView->dataChanged( m_AnimationModel->index(0, 1), m_AnimationModel->index(m_AnimationModel->rowCount() - 1, 1)); } } QmitkAnimationItem* QmitkMovieMaker2View::GetSelectedAnimationItem() const { const QItemSelection selection = m_Ui->animationTreeView->selectionModel()->selection(); return !selection.isEmpty() ? dynamic_cast(m_AnimationModel->item(selection[0].top(), 1)) : NULL; }