more project management updates
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "core.h"
|
||||
#include "widget/projecttoolbar/projecttoolbar.h"
|
||||
|
||||
ProjectPanel::ProjectPanel(QWidget *parent) :
|
||||
@@ -41,6 +42,7 @@ ProjectPanel::ProjectPanel(QWidget *parent) :
|
||||
// Set up main explorer object
|
||||
explorer_ = new ProjectExplorer(this);
|
||||
layout->addWidget(explorer_);
|
||||
connect(explorer_, SIGNAL(DoubleClickedItem(Item*)), this, SLOT(ItemDoubleClickSlot(Item*)));
|
||||
|
||||
// Set toolbar's view to the explorer's view
|
||||
toolbar->SetView(explorer_->view_type());
|
||||
@@ -85,3 +87,10 @@ void ProjectPanel::Retranslate()
|
||||
SetSubtitle(project()->name());
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectPanel::ItemDoubleClickSlot(Item *item)
|
||||
{
|
||||
if (item == nullptr) {
|
||||
olive::core.StartImportFootage();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,9 @@ private:
|
||||
void Retranslate();
|
||||
|
||||
ProjectExplorer* explorer_;
|
||||
|
||||
private slots:
|
||||
void ItemDoubleClickSlot(Item* item);
|
||||
};
|
||||
|
||||
#endif // PROJECT_PANEL_H
|
||||
|
||||
@@ -20,11 +20,13 @@
|
||||
|
||||
#include "footage.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
|
||||
#include "ui/icons/icons.h"
|
||||
|
||||
Footage::Footage() :
|
||||
status_(kUnprobed)
|
||||
Footage::Footage()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
Footage::~Footage()
|
||||
@@ -41,19 +43,9 @@ void Footage::set_status(const Footage::Status &status)
|
||||
{
|
||||
status_ = status;
|
||||
|
||||
switch (status_) {
|
||||
case kUnprobed:
|
||||
// FIXME Set a waiting icon
|
||||
set_icon(QIcon());
|
||||
break;
|
||||
case kReady:
|
||||
// FIXME Set a ready icon
|
||||
set_icon(QIcon());
|
||||
break;
|
||||
case kInvalid:
|
||||
set_icon(olive::icon::Error);
|
||||
break;
|
||||
}
|
||||
UpdateIcon();
|
||||
|
||||
UpdateTooltip();
|
||||
}
|
||||
|
||||
void Footage::Clear()
|
||||
@@ -123,3 +115,97 @@ void Footage::ClearStreams()
|
||||
// Empty array
|
||||
streams_.clear();
|
||||
}
|
||||
|
||||
bool Footage::HasStreamsOfType(const Stream::Type type)
|
||||
{
|
||||
// Return true if any streams are video streams
|
||||
for (int i=0;i<streams_.size();i++) {
|
||||
if (streams_.at(i)->type() == type) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Footage::UpdateIcon()
|
||||
{
|
||||
switch (status_) {
|
||||
case kUnprobed:
|
||||
// FIXME Set a waiting icon
|
||||
set_icon(QIcon());
|
||||
break;
|
||||
case kReady:
|
||||
if (HasStreamsOfType(Stream::kVideo)) {
|
||||
|
||||
// Prioritize the video icon
|
||||
set_icon(olive::icon::Video);
|
||||
|
||||
// FIXME: When image sources can be reliably picked up, use image icon instead
|
||||
// Perhaps all image sources can be left to OpenImageIO meaning only video sources need to be here
|
||||
|
||||
} else if (HasStreamsOfType(Stream::kAudio)) {
|
||||
|
||||
// Otherwise assume it's audio only
|
||||
set_icon(olive::icon::Audio);
|
||||
|
||||
} else {
|
||||
|
||||
// FIXME Icon/indicator for a media file with no video or audio streams?
|
||||
// The footage should probably be deemed kInvalid in this state
|
||||
|
||||
}
|
||||
break;
|
||||
case kInvalid:
|
||||
set_icon(olive::icon::Error);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Footage::UpdateTooltip()
|
||||
{
|
||||
switch (status_) {
|
||||
case kUnprobed:
|
||||
set_tooltip(QCoreApplication::translate("Footage", "Waiting for probe"));
|
||||
break;
|
||||
case kReady:
|
||||
{
|
||||
QString tip = QCoreApplication::translate("Footage", "Filename: %1");
|
||||
|
||||
if (!streams_.isEmpty()) {
|
||||
tip.append("\n");
|
||||
|
||||
for (int i=0;i<streams_.size();i++) {
|
||||
|
||||
Stream* s = streams_.at(i);
|
||||
|
||||
if (s->type() == Stream::kVideo) {
|
||||
VideoStream* vs = static_cast<VideoStream*>(s);
|
||||
|
||||
tip.append(
|
||||
QCoreApplication::translate("Footage",
|
||||
"\nVideo %1: %2x%3").arg(QString::number(i),
|
||||
QString::number(vs->width()),
|
||||
QString::number(vs->height()))
|
||||
);
|
||||
} else if (streams_.at(i)->type() == Stream::kAudio) {
|
||||
AudioStream* as = static_cast<AudioStream*>(s);
|
||||
|
||||
tip.append(
|
||||
QCoreApplication::translate("Footage",
|
||||
"\nAudio %1: %2 channels %3 Hz").arg(QString::number(i),
|
||||
QString::number(as->channels()),
|
||||
QString::number(as->sample_rate()))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set_tooltip(tip);
|
||||
}
|
||||
break;
|
||||
case kInvalid:
|
||||
set_tooltip(QCoreApplication::translate("Footage", "An error occurred probing this footage"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,11 @@ public:
|
||||
/**
|
||||
* @brief Set ready state
|
||||
*
|
||||
* This should only be set by olive::ProbeMedia. Sets the ready state (see ready()).
|
||||
* This should only be set by olive::ProbeMedia. Sets the Footage's current status to a member of enum
|
||||
* Footage::Status.
|
||||
*
|
||||
* This function also runs UpdateIcon() and UpdateTooltip(). If you need to override the tooltip (e.g. for an error
|
||||
* message), you must run set_tooltip() *after* running set_status();
|
||||
*/
|
||||
void set_status(const Status& status);
|
||||
|
||||
@@ -178,6 +182,31 @@ private:
|
||||
*/
|
||||
void ClearStreams();
|
||||
|
||||
/**
|
||||
* @brief Check if this footage has streams of a certain type
|
||||
*
|
||||
* @param type
|
||||
*
|
||||
* The stream type to check for
|
||||
*/
|
||||
bool HasStreamsOfType(const Stream::Type type);
|
||||
|
||||
/**
|
||||
* @brief Update the icon based on the Footage status
|
||||
*
|
||||
* For kUnprobed and kError an appropriate icon will be shown. For kReady, this function will determine what the
|
||||
* dominant type of media in this Footage is (video/audio/image) and set the icon accordingly based on that.
|
||||
*/
|
||||
void UpdateIcon();
|
||||
|
||||
/**
|
||||
* @brief Update the tooltip based on the Footage status
|
||||
*
|
||||
* For kUnprobed and kError, this sets an appropriate generic message. For kReady, this function will set
|
||||
* basic information about the Footage in the tooltip (based on the results of a previous probe).
|
||||
*/
|
||||
void UpdateTooltip();
|
||||
|
||||
/**
|
||||
* @brief Internal filename string
|
||||
*/
|
||||
|
||||
@@ -73,6 +73,16 @@ void Item::set_name(const QString &n)
|
||||
name_ = n;
|
||||
}
|
||||
|
||||
const QString &Item::tooltip() const
|
||||
{
|
||||
return tooltip_;
|
||||
}
|
||||
|
||||
void Item::set_tooltip(const QString &t)
|
||||
{
|
||||
tooltip_ = t;
|
||||
}
|
||||
|
||||
const QIcon &Item::icon()
|
||||
{
|
||||
return icon_;
|
||||
|
||||
@@ -74,6 +74,9 @@ public:
|
||||
const QString& name() const;
|
||||
void set_name(const QString& n);
|
||||
|
||||
const QString& tooltip() const;
|
||||
void set_tooltip(const QString& t);
|
||||
|
||||
const QIcon& icon();
|
||||
void set_icon(const QIcon& icon);
|
||||
|
||||
@@ -89,6 +92,8 @@ private:
|
||||
|
||||
QIcon icon_;
|
||||
|
||||
QString tooltip_;
|
||||
|
||||
};
|
||||
|
||||
#endif // ITEM_H
|
||||
|
||||
@@ -148,6 +148,8 @@ QVariant ProjectViewModel::data(const QModelIndex &index, int role) const
|
||||
return internal_item->icon();
|
||||
}
|
||||
break;
|
||||
case Qt::ToolTipRole:
|
||||
return internal_item->tooltip();
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
|
||||
@@ -52,13 +52,16 @@ QIcon olive::icon::ToolSlip;
|
||||
QIcon olive::icon::ToolSlide;
|
||||
QIcon olive::icon::ToolHand;
|
||||
QIcon olive::icon::ToolTransition;
|
||||
QIcon olive::icon::Folder;
|
||||
QIcon olive::icon::Video;
|
||||
QIcon olive::icon::Audio;
|
||||
QIcon olive::icon::Image;
|
||||
QIcon olive::icon::Snapping;
|
||||
QIcon olive::icon::ZoomIn;
|
||||
QIcon olive::icon::ZoomOut;
|
||||
QIcon olive::icon::Record;
|
||||
QIcon olive::icon::Add;
|
||||
QIcon olive::icon::Error;
|
||||
QIcon olive::icon::Folder;
|
||||
|
||||
void olive::icon::LoadAll()
|
||||
{
|
||||
@@ -87,13 +90,17 @@ void olive::icon::LoadAll()
|
||||
ToolHand = Create("hand");
|
||||
ToolTransition = Create("transition-tool");
|
||||
|
||||
Folder = Create("folder");
|
||||
Video = Create("videosource");
|
||||
Audio = Create("audiosource");
|
||||
Image = Create("imagesource");
|
||||
|
||||
Snapping = Create("magnet");
|
||||
ZoomIn = Create("zoomin");
|
||||
ZoomOut = Create("zoomout");
|
||||
Record = Create("record");
|
||||
Add = Create("add-button");
|
||||
Error = Create("error");
|
||||
Folder = Create("folder");
|
||||
}
|
||||
|
||||
QIcon olive::icon::Create(const QString &name)
|
||||
|
||||
@@ -54,6 +54,12 @@ extern QIcon ToolSlide;
|
||||
extern QIcon ToolHand;
|
||||
extern QIcon ToolTransition;
|
||||
|
||||
// Project Icons
|
||||
extern QIcon Folder;
|
||||
extern QIcon Video;
|
||||
extern QIcon Audio;
|
||||
extern QIcon Image;
|
||||
|
||||
// Miscellaneous Icons
|
||||
extern QIcon Snapping;
|
||||
extern QIcon ZoomIn;
|
||||
@@ -61,7 +67,6 @@ extern QIcon ZoomOut;
|
||||
extern QIcon Record;
|
||||
extern QIcon Add;
|
||||
extern QIcon Error;
|
||||
extern QIcon Folder;
|
||||
|
||||
/**
|
||||
* @brief Create an icon object loaded from file
|
||||
|
||||
@@ -85,3 +85,9 @@ QPushButton::checked {
|
||||
QMenu::separator {
|
||||
background: #353535;
|
||||
}
|
||||
|
||||
/* ToolTips use dark */
|
||||
QToolTip {
|
||||
background: #191919;;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
@@ -85,3 +85,9 @@ QPushButton::checked {
|
||||
QMenu::separator {
|
||||
background: #d0d0d0;
|
||||
}
|
||||
|
||||
/* ToolTips use dark */
|
||||
QToolTip {
|
||||
background: #f0f0f0;;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
@@ -85,3 +85,9 @@ QPushButton::checked {
|
||||
QMenu::separator {
|
||||
background: #808080;
|
||||
}
|
||||
|
||||
/* ToolTips use dark */
|
||||
QToolTip {
|
||||
background: #c0c0c0;;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
@@ -18,5 +18,7 @@ set(OLIVE_SOURCES
|
||||
${OLIVE_SOURCES}
|
||||
widget/projectexplorer/projectexplorer.h
|
||||
widget/projectexplorer/projectexplorer.cpp
|
||||
widget/projectexplorer/projectexplorertreeview.h
|
||||
widget/projectexplorer/projectexplorertreeview.cpp
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
||||
@@ -20,13 +20,16 @@
|
||||
|
||||
#include "projectexplorer.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
ProjectExplorer::ProjectExplorer(QWidget *parent) :
|
||||
QStackedWidget(parent),
|
||||
view_type_(olive::TreeView),
|
||||
model_(this)
|
||||
{
|
||||
tree_view_ = new QTreeView(this);
|
||||
tree_view_ = new ProjectExplorerTreeView(this);
|
||||
tree_view_->setModel(&model_);
|
||||
connect(tree_view_, SIGNAL(DoubleClickedView(const QModelIndex&)), this, SLOT(DoubleClickViewSlot(const QModelIndex&)));
|
||||
addWidget(tree_view_);
|
||||
}
|
||||
|
||||
@@ -40,6 +43,24 @@ void ProjectExplorer::set_view_type(olive::ProjectViewType type)
|
||||
view_type_ = type;
|
||||
}
|
||||
|
||||
void ProjectExplorer::DoubleClickViewSlot(const QModelIndex &index)
|
||||
{
|
||||
if (index.isValid()) {
|
||||
|
||||
// Retrieve source item from index
|
||||
Item* i = static_cast<Item*>(index.internalPointer());
|
||||
|
||||
// Emit a signal
|
||||
emit DoubleClickedItem(i);
|
||||
|
||||
} else {
|
||||
|
||||
// Emit nullptr since no item was actually clicked on
|
||||
emit DoubleClickedItem(nullptr);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Project *ProjectExplorer::project()
|
||||
{
|
||||
return model_.project();
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "project/project.h"
|
||||
#include "project/projectviewmodel.h"
|
||||
#include "project/projectviewtype.h"
|
||||
#include "widget/projectexplorer/projectexplorertreeview.h"
|
||||
|
||||
/**
|
||||
* @brief The ProjectExplorer class
|
||||
@@ -52,12 +53,25 @@ public:
|
||||
public slots:
|
||||
void set_view_type(olive::ProjectViewType type);
|
||||
|
||||
signals:
|
||||
/**
|
||||
* @brief Emitted when an Item is double clicked
|
||||
*
|
||||
* @param item
|
||||
*
|
||||
* The Item that was double clicked, or nullptr if empty area was double clicked
|
||||
*/
|
||||
void DoubleClickedItem(Item* item);
|
||||
|
||||
private:
|
||||
QTreeView* tree_view_;
|
||||
ProjectExplorerTreeView* tree_view_;
|
||||
|
||||
olive::ProjectViewType view_type_;
|
||||
|
||||
ProjectViewModel model_;
|
||||
|
||||
private slots:
|
||||
void DoubleClickViewSlot(const QModelIndex& index);
|
||||
};
|
||||
|
||||
#endif // PROJECTEXPLORER_H
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
#include "projectexplorertreeview.h"
|
||||
|
||||
#include <QMouseEvent>
|
||||
|
||||
ProjectExplorerTreeView::ProjectExplorerTreeView(QWidget *parent) :
|
||||
QTreeView(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void ProjectExplorerTreeView::mouseDoubleClickEvent(QMouseEvent *event)
|
||||
{
|
||||
// Perform default double click functions
|
||||
QTreeView::mouseDoubleClickEvent(event);
|
||||
|
||||
// Get the index at whatever position was double clicked
|
||||
QModelIndex index = indexAt(event->pos());
|
||||
|
||||
// Emit the signal with this index
|
||||
emit DoubleClickedView(index);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef PROJECTEXPLORERTREEVIEW_H
|
||||
#define PROJECTEXPLORERTREEVIEW_H
|
||||
|
||||
#include <QTreeView>
|
||||
|
||||
/**
|
||||
* @brief The ProjectExplorerTreeView class
|
||||
*
|
||||
* A fairly simple subclass of QTreeView that provides a double clicked signal whether the index is valid or not
|
||||
* (QAbstractItemView has a doubleClicked() signal but it's only emitted with a valid index).
|
||||
*/
|
||||
class ProjectExplorerTreeView : public QTreeView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ProjectExplorerTreeView(QWidget* parent);
|
||||
|
||||
protected:
|
||||
virtual void mouseDoubleClickEvent(QMouseEvent *event) override;
|
||||
|
||||
signals:
|
||||
void DoubleClickedView(const QModelIndex& index);
|
||||
};
|
||||
|
||||
#endif // PROJECTEXPLORERTREEVIEW_H
|
||||
Reference in New Issue
Block a user