more work on project management
This commit is contained in:
+37
-4
@@ -26,6 +26,7 @@
|
|||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
|
||||||
#include "panel/panelfocusmanager.h"
|
#include "panel/panelfocusmanager.h"
|
||||||
#include "panel/project/project.h"
|
#include "panel/project/project.h"
|
||||||
@@ -34,7 +35,9 @@
|
|||||||
#include "task/taskmanager.h"
|
#include "task/taskmanager.h"
|
||||||
#include "ui/icons/icons.h"
|
#include "ui/icons/icons.h"
|
||||||
#include "ui/style/style.h"
|
#include "ui/style/style.h"
|
||||||
|
#include "undo/undostack.h"
|
||||||
#include "widget/menu/menushared.h"
|
#include "widget/menu/menushared.h"
|
||||||
|
#include "widget/taskview/taskviewitem.h"
|
||||||
|
|
||||||
Core olive::core;
|
Core olive::core;
|
||||||
|
|
||||||
@@ -100,14 +103,14 @@ olive::MainWindow *Core::main_window()
|
|||||||
return main_window_;
|
return main_window_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::ImportFiles(const QStringList &urls, Folder* parent)
|
void Core::ImportFiles(const QStringList &urls, ProjectViewModel* model, Folder* parent)
|
||||||
{
|
{
|
||||||
if (urls.isEmpty()) {
|
if (urls.isEmpty()) {
|
||||||
QMessageBox::critical(main_window_, tr("Import error"), tr("Nothing to import"));
|
QMessageBox::critical(main_window_, tr("Import error"), tr("Nothing to import"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
olive::task_manager.AddTask(new ImportTask(parent, urls));
|
olive::task_manager.AddTask(new ImportTask(model, parent, urls));
|
||||||
}
|
}
|
||||||
|
|
||||||
const olive::tool::Tool &Core::tool()
|
const olive::tool::Tool &Core::tool()
|
||||||
@@ -115,6 +118,26 @@ const olive::tool::Tool &Core::tool()
|
|||||||
return tool_;
|
return tool_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Core::StartModalTask(Task *t)
|
||||||
|
{
|
||||||
|
QDialog dialog(main_window_);
|
||||||
|
|
||||||
|
QHBoxLayout* layout = new QHBoxLayout(&dialog);
|
||||||
|
layout->setMargin(0);
|
||||||
|
|
||||||
|
TaskViewItem* task_view = new TaskViewItem(&dialog);
|
||||||
|
task_view->SetTask(t);
|
||||||
|
layout->addWidget(task_view);
|
||||||
|
|
||||||
|
connect(t, SIGNAL(Finished()), &dialog, SLOT(accept()));
|
||||||
|
|
||||||
|
// FIXME: Risk of task finishing before dialog execs?
|
||||||
|
|
||||||
|
if (t->Start()) {
|
||||||
|
dialog.exec();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Core::SetTool(const olive::tool::Tool &tool)
|
void Core::SetTool(const olive::tool::Tool &tool)
|
||||||
{
|
{
|
||||||
tool_ = tool;
|
tool_ = tool;
|
||||||
@@ -144,7 +167,7 @@ void Core::StartImportFootage()
|
|||||||
// Get the selected folder in this panel
|
// Get the selected folder in this panel
|
||||||
Folder* folder = active_project_panel->GetSelectedFolder();
|
Folder* folder = active_project_panel->GetSelectedFolder();
|
||||||
|
|
||||||
ImportFiles(files, folder);
|
ImportFiles(files, active_project_panel->model(), folder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,11 +186,21 @@ void Core::CreateNewFolder()
|
|||||||
// Get the selected folder in this panel
|
// Get the selected folder in this panel
|
||||||
Folder* folder = active_project_panel->GetSelectedFolder();
|
Folder* folder = active_project_panel->GetSelectedFolder();
|
||||||
|
|
||||||
|
// Create new folder
|
||||||
Folder* new_folder = new Folder();
|
Folder* new_folder = new Folder();
|
||||||
|
|
||||||
|
// Set a default name
|
||||||
new_folder->set_name(tr("New Folder"));
|
new_folder->set_name(tr("New Folder"));
|
||||||
|
|
||||||
active_project_panel->model()->AddChild(folder, new_folder);
|
// Create an undoable command
|
||||||
|
ProjectViewModel::AddItemCommand* aic = new ProjectViewModel::AddItemCommand(active_project_panel->model(),
|
||||||
|
folder,
|
||||||
|
new_folder);
|
||||||
|
|
||||||
|
olive::undo_stack.push(aic);
|
||||||
|
|
||||||
|
// Trigger an automatic rename so users can enter the folder name
|
||||||
|
active_project_panel->Edit(new_folder);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::AddOpenProject(ProjectPtr p)
|
void Core::AddOpenProject(ProjectPtr p)
|
||||||
|
|||||||
+15
-1
@@ -24,7 +24,9 @@
|
|||||||
#include <QList>
|
#include <QList>
|
||||||
|
|
||||||
#include "project/project.h"
|
#include "project/project.h"
|
||||||
|
#include "project/projectviewmodel.h"
|
||||||
#include "window/mainwindow/mainwindow.h"
|
#include "window/mainwindow/mainwindow.h"
|
||||||
|
#include "task/task.h"
|
||||||
#include "tool/tool.h"
|
#include "tool/tool.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -73,15 +75,27 @@ public:
|
|||||||
/**
|
/**
|
||||||
* @brief Import a list of files
|
* @brief Import a list of files
|
||||||
*
|
*
|
||||||
|
* FIXME: I kind of hate this, it needs a model to update correctly. Is there a way that Items can signal enough to
|
||||||
|
* make passing references to the model unnecessary?
|
||||||
|
*
|
||||||
* @param urls
|
* @param urls
|
||||||
*/
|
*/
|
||||||
void ImportFiles(const QStringList& urls, Folder *parent);
|
void ImportFiles(const QStringList& urls, ProjectViewModel *model, Folder *parent);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the currently active tool
|
* @brief Get the currently active tool
|
||||||
*/
|
*/
|
||||||
const olive::tool::Tool& tool();
|
const olive::tool::Tool& tool();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Starts a modal task
|
||||||
|
*
|
||||||
|
* This function does NOT take ownership of the Task.
|
||||||
|
*
|
||||||
|
* @param t
|
||||||
|
*/
|
||||||
|
void StartModalTask(Task* t);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
/**
|
/**
|
||||||
* @brief Set the current application-wide tool
|
* @brief Set the current application-wide tool
|
||||||
|
|||||||
@@ -186,8 +186,6 @@ bool FFmpegDecoder::Probe(Footage *f)
|
|||||||
|
|
||||||
str = video_stream;
|
str = video_stream;
|
||||||
|
|
||||||
qDebug() << "Stream V" << i << "Len" << (rational(avstream_->duration) * rational(avstream_->time_base)).ToDouble();
|
|
||||||
|
|
||||||
} else if (avstream_->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
|
} else if (avstream_->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||||
|
|
||||||
// Create an audio stream object
|
// Create an audio stream object
|
||||||
@@ -199,8 +197,6 @@ bool FFmpegDecoder::Probe(Footage *f)
|
|||||||
|
|
||||||
str = audio_stream;
|
str = audio_stream;
|
||||||
|
|
||||||
qDebug() << "Stream A" << i << "Len" << (rational(avstream_->duration) * rational(avstream_->time_base)).ToDouble();
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// This is data we can't utilize at the moment, but we make a Stream object anyway to keep parity with the file
|
// This is data we can't utilize at the moment, but we make a Stream object anyway to keep parity with the file
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ ProjectPanel::ProjectPanel(QWidget *parent) :
|
|||||||
QWidget* central_widget = new QWidget(this);
|
QWidget* central_widget = new QWidget(this);
|
||||||
QVBoxLayout* layout = new QVBoxLayout(central_widget);
|
QVBoxLayout* layout = new QVBoxLayout(central_widget);
|
||||||
layout->setMargin(0);
|
layout->setMargin(0);
|
||||||
layout->setSpacing(0);
|
//layout->setSpacing(0);
|
||||||
setWidget(central_widget);
|
setWidget(central_widget);
|
||||||
|
|
||||||
// Set up project toolbar
|
// Set up project toolbar
|
||||||
@@ -84,6 +84,11 @@ ProjectViewModel *ProjectPanel::model()
|
|||||||
return explorer_->model();
|
return explorer_->model();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProjectPanel::Edit(Item* item)
|
||||||
|
{
|
||||||
|
explorer_->Edit(item);
|
||||||
|
}
|
||||||
|
|
||||||
void ProjectPanel::changeEvent(QEvent *e)
|
void ProjectPanel::changeEvent(QEvent *e)
|
||||||
{
|
{
|
||||||
if (e->type() == QEvent::LanguageChange) {
|
if (e->type() == QEvent::LanguageChange) {
|
||||||
|
|||||||
@@ -40,6 +40,9 @@ public:
|
|||||||
|
|
||||||
ProjectViewModel* model();
|
ProjectViewModel* model();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void Edit(Item *item);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void changeEvent(QEvent* e) override;
|
virtual void changeEvent(QEvent* e) override;
|
||||||
|
|
||||||
|
|||||||
@@ -23,24 +23,6 @@
|
|||||||
Project::Project()
|
Project::Project()
|
||||||
{
|
{
|
||||||
name_ = tr("(untitled)");
|
name_ = tr("(untitled)");
|
||||||
|
|
||||||
// FIXME: Test code
|
|
||||||
Folder* f1 = new Folder();
|
|
||||||
f1->set_name("F1");
|
|
||||||
f1->set_parent(&root_);
|
|
||||||
Folder* f2 = new Folder();
|
|
||||||
f2->set_name("F2");
|
|
||||||
f2->set_parent(f1);
|
|
||||||
Folder* f3 = new Folder();
|
|
||||||
f3->set_name("F3");
|
|
||||||
f3->set_parent(&root_);
|
|
||||||
Folder* f4 = new Folder();
|
|
||||||
f4->set_name("F4");
|
|
||||||
f4->set_parent(f1);
|
|
||||||
Folder* f5 = new Folder();
|
|
||||||
f5->set_name("F5");
|
|
||||||
f5->set_parent(f3);
|
|
||||||
// End Test code
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Folder *Project::root()
|
Folder *Project::root()
|
||||||
|
|||||||
@@ -370,7 +370,7 @@ bool ProjectViewModel::dropMimeData(const QMimeData *data, Qt::DropAction action
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Trigger an import
|
// Trigger an import
|
||||||
olive::core.ImportFiles(urls, static_cast<Folder*>(drop_item));
|
olive::core.ImportFiles(urls, this, static_cast<Folder*>(drop_item));
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -391,6 +391,32 @@ void ProjectViewModel::AddChild(Item *parent, Item *child)
|
|||||||
endInsertRows();
|
endInsertRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProjectViewModel::RemoveChild(Item *parent, Item *child)
|
||||||
|
{
|
||||||
|
QModelIndex parent_index;
|
||||||
|
|
||||||
|
if (parent != project_->root()) {
|
||||||
|
parent_index = CreateIndexFromItem(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
int child_row = IndexOfChild(child);
|
||||||
|
|
||||||
|
beginRemoveRows(parent_index, child_row, child_row);
|
||||||
|
|
||||||
|
parent->remove_child(child);
|
||||||
|
|
||||||
|
endRemoveRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProjectViewModel::RenameChild(Item *item, const QString &name)
|
||||||
|
{
|
||||||
|
item->set_name(name);
|
||||||
|
|
||||||
|
QModelIndex index = CreateIndexFromItem(item, columns_.indexOf(kName));
|
||||||
|
|
||||||
|
emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole});
|
||||||
|
}
|
||||||
|
|
||||||
int ProjectViewModel::IndexOfChild(Item *item) const
|
int ProjectViewModel::IndexOfChild(Item *item) const
|
||||||
{
|
{
|
||||||
// Find parent's index within its own parent
|
// Find parent's index within its own parent
|
||||||
@@ -498,19 +524,41 @@ ProjectViewModel::RenameItemCommand::RenameItemCommand(ProjectViewModel* model,
|
|||||||
|
|
||||||
void ProjectViewModel::RenameItemCommand::redo()
|
void ProjectViewModel::RenameItemCommand::redo()
|
||||||
{
|
{
|
||||||
set_name(new_name_);
|
model_->RenameChild(item_, new_name_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectViewModel::RenameItemCommand::undo()
|
void ProjectViewModel::RenameItemCommand::undo()
|
||||||
{
|
{
|
||||||
set_name(old_name_);
|
model_->RenameChild(item_, old_name_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectViewModel::RenameItemCommand::set_name(const QString &n)
|
ProjectViewModel::AddItemCommand::AddItemCommand(ProjectViewModel* model, Item* folder, Item* child, QUndoCommand* parent) :
|
||||||
|
QUndoCommand(parent),
|
||||||
|
model_(model),
|
||||||
|
parent_(folder),
|
||||||
|
child_(child),
|
||||||
|
done_(false)
|
||||||
{
|
{
|
||||||
item_->set_name(n);
|
}
|
||||||
|
|
||||||
QModelIndex index = model_->CreateIndexFromItem(item_, model_->columns_.indexOf(kName));
|
ProjectViewModel::AddItemCommand::~AddItemCommand()
|
||||||
|
{
|
||||||
|
// FIXME Use smart pointers. I hate having to do this.
|
||||||
|
if (!done_) {
|
||||||
|
delete child_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
emit model_->dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole});
|
void ProjectViewModel::AddItemCommand::redo()
|
||||||
|
{
|
||||||
|
model_->AddChild(parent_, child_);
|
||||||
|
|
||||||
|
done_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProjectViewModel::AddItemCommand::undo()
|
||||||
|
{
|
||||||
|
model_->RemoveChild(parent_, child_);
|
||||||
|
|
||||||
|
done_ = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,6 +94,70 @@ public:
|
|||||||
|
|
||||||
/** Other model functions */
|
/** Other model functions */
|
||||||
void AddChild(Item* parent, Item* child);
|
void AddChild(Item* parent, Item* child);
|
||||||
|
void RemoveChild(Item* parent, Item* child);
|
||||||
|
void RenameChild(Item* item, const QString& name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Convenience function for creating QModelIndexes from an Item object
|
||||||
|
*/
|
||||||
|
QModelIndex CreateIndexFromItem(Item* item, int column = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A QUndoCommand for moving an item from one folder to another folder
|
||||||
|
*/
|
||||||
|
class MoveItemCommand : public QUndoCommand {
|
||||||
|
public:
|
||||||
|
MoveItemCommand(ProjectViewModel* model, Item* item, Folder* destination, QUndoCommand* parent = nullptr);
|
||||||
|
|
||||||
|
virtual void redo() override;
|
||||||
|
|
||||||
|
virtual void undo() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ProjectViewModel* model_;
|
||||||
|
Item* item_;
|
||||||
|
Folder* source_;
|
||||||
|
Folder* destination_;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A QUndoCommand for renaming an item
|
||||||
|
*/
|
||||||
|
class RenameItemCommand : public QUndoCommand {
|
||||||
|
public:
|
||||||
|
RenameItemCommand(ProjectViewModel* model, Item* item, const QString& name, QUndoCommand* parent = nullptr);
|
||||||
|
|
||||||
|
virtual void redo() override;
|
||||||
|
|
||||||
|
virtual void undo() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ProjectViewModel* model_;
|
||||||
|
Item* item_;
|
||||||
|
QString old_name_;
|
||||||
|
QString new_name_;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A QUndoCommand for adding an item
|
||||||
|
*/
|
||||||
|
class AddItemCommand : public QUndoCommand {
|
||||||
|
public:
|
||||||
|
AddItemCommand(ProjectViewModel* model, Item* folder, Item* child, QUndoCommand* parent = nullptr);
|
||||||
|
|
||||||
|
virtual ~AddItemCommand() override;
|
||||||
|
|
||||||
|
virtual void redo() override;
|
||||||
|
|
||||||
|
virtual void undo() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ProjectViewModel* model_;
|
||||||
|
Item* parent_;
|
||||||
|
Item* child_;
|
||||||
|
bool done_;
|
||||||
|
};
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* @brief Retrieve the index of `item` in its parent
|
* @brief Retrieve the index of `item` in its parent
|
||||||
@@ -144,53 +208,9 @@ private:
|
|||||||
*/
|
*/
|
||||||
void MoveItemInternal(Item* item, Item* destination);
|
void MoveItemInternal(Item* item, Item* destination);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Convenience function for creating QModelIndexes from an Item object
|
|
||||||
*/
|
|
||||||
QModelIndex CreateIndexFromItem(Item* item, int column = 0);
|
|
||||||
|
|
||||||
Project* project_;
|
Project* project_;
|
||||||
|
|
||||||
QVector<ColumnType> columns_;
|
QVector<ColumnType> columns_;
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief A QUndoCommand for moving an item from one folder to another folder
|
|
||||||
*/
|
|
||||||
class MoveItemCommand : public QUndoCommand {
|
|
||||||
public:
|
|
||||||
MoveItemCommand(ProjectViewModel* model, Item* item, Folder* destination, QUndoCommand* parent = nullptr);
|
|
||||||
|
|
||||||
virtual void redo() override;
|
|
||||||
|
|
||||||
virtual void undo() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
ProjectViewModel* model_;
|
|
||||||
Item* item_;
|
|
||||||
Folder* source_;
|
|
||||||
Folder* destination_;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief A QUndoCommand for renaming an item
|
|
||||||
*/
|
|
||||||
class RenameItemCommand : public QUndoCommand {
|
|
||||||
public:
|
|
||||||
RenameItemCommand(ProjectViewModel* model, Item* item, const QString& name, QUndoCommand* parent = nullptr);
|
|
||||||
|
|
||||||
virtual void redo() override;
|
|
||||||
|
|
||||||
virtual void undo() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void set_name(const QString& n);
|
|
||||||
|
|
||||||
ProjectViewModel* model_;
|
|
||||||
Item* item_;
|
|
||||||
QString old_name_;
|
|
||||||
QString new_name_;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // VIEWMODEL_H
|
#endif // VIEWMODEL_H
|
||||||
|
|||||||
+30
-20
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
/***
|
/***
|
||||||
|
|
||||||
Olive - Non-Linear Video Editor
|
Olive - Non-Linear Video Editor
|
||||||
@@ -33,8 +34,10 @@
|
|||||||
#include "project/item/footage/footage.h"
|
#include "project/item/footage/footage.h"
|
||||||
#include "task/probe/probe.h"
|
#include "task/probe/probe.h"
|
||||||
#include "task/taskmanager.h"
|
#include "task/taskmanager.h"
|
||||||
|
#include "undo/undostack.h"
|
||||||
|
|
||||||
ImportTask::ImportTask(Folder *parent, const QStringList &urls) :
|
ImportTask::ImportTask(ProjectViewModel *model, Folder *parent, const QStringList &urls) :
|
||||||
|
model_(model),
|
||||||
urls_(urls),
|
urls_(urls),
|
||||||
parent_(parent)
|
parent_(parent)
|
||||||
{
|
{
|
||||||
@@ -43,9 +46,20 @@ ImportTask::ImportTask(Folder *parent, const QStringList &urls) :
|
|||||||
|
|
||||||
bool ImportTask::Action()
|
bool ImportTask::Action()
|
||||||
{
|
{
|
||||||
for (int i=0;i<urls_.size();i++) {
|
QUndoCommand* command = new QUndoCommand();
|
||||||
|
|
||||||
const QString& url = urls_.at(i);
|
Import(urls_, parent_, command);
|
||||||
|
|
||||||
|
olive::undo_stack.push(command);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImportTask::Import(const QStringList &files, Folder *folder, QUndoCommand *parent_command)
|
||||||
|
{
|
||||||
|
for (int i=0;i<files.size();i++) {
|
||||||
|
|
||||||
|
const QString& url = files.at(i);
|
||||||
|
|
||||||
QFileInfo file_info(url);
|
QFileInfo file_info(url);
|
||||||
|
|
||||||
@@ -65,7 +79,11 @@ bool ImportTask::Action()
|
|||||||
|
|
||||||
f->set_name(file_info.fileName());
|
f->set_name(file_info.fileName());
|
||||||
|
|
||||||
parent_->add_child(f);
|
// Create undoable command that adds the items to the model
|
||||||
|
new ProjectViewModel::AddItemCommand(model_,
|
||||||
|
folder,
|
||||||
|
f,
|
||||||
|
parent_command);
|
||||||
|
|
||||||
// Convert QFileInfoList into QStringList
|
// Convert QFileInfoList into QStringList
|
||||||
QStringList full_urls;
|
QStringList full_urls;
|
||||||
@@ -76,12 +94,8 @@ bool ImportTask::Action()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start a new import task for this folder too
|
// Recursively follow this path
|
||||||
ImportTask* it = new ImportTask(f, full_urls);
|
Import(full_urls, f, parent_command);
|
||||||
|
|
||||||
it->moveToThread(qApp->thread());
|
|
||||||
|
|
||||||
olive::task_manager.AddTask(it);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -95,7 +109,11 @@ bool ImportTask::Action()
|
|||||||
f->set_name(file_info.fileName());
|
f->set_name(file_info.fileName());
|
||||||
f->set_timestamp(file_info.lastModified());
|
f->set_timestamp(file_info.lastModified());
|
||||||
|
|
||||||
parent_->add_child(f);
|
// Create undoable command that adds the items to the model
|
||||||
|
new ProjectViewModel::AddItemCommand(model_,
|
||||||
|
folder,
|
||||||
|
f,
|
||||||
|
parent_command);
|
||||||
|
|
||||||
// Create ProbeTask to analyze this media
|
// Create ProbeTask to analyze this media
|
||||||
ProbeTask* pt = new ProbeTask(f);
|
ProbeTask* pt = new ProbeTask(f);
|
||||||
@@ -109,15 +127,7 @@ bool ImportTask::Action()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
emit ProgressChanged(i * 100 / urls_.size());
|
emit ProgressChanged(i * 100 / files.size());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: No good very bad test code to update the ProjectExplorer model/view
|
|
||||||
// A better solution would be for the Project itself to signal that a new row was being added
|
|
||||||
ProjectPanel* p = olive::panel_focus_manager->MostRecentlyFocused<ProjectPanel>();
|
|
||||||
p->set_project(p->project());
|
|
||||||
// End test code
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#ifndef IMPORT_H
|
#ifndef IMPORT_H
|
||||||
#define IMPORT_H
|
#define IMPORT_H
|
||||||
|
|
||||||
|
#include "project/projectviewmodel.h"
|
||||||
#include "project/item/folder/folder.h"
|
#include "project/item/folder/folder.h"
|
||||||
#include "task/task.h"
|
#include "task/task.h"
|
||||||
|
|
||||||
@@ -36,11 +37,14 @@ class ImportTask : public Task
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
ImportTask(Folder *parent_, const QStringList& urls);
|
ImportTask(ProjectViewModel* model, Folder *parent, const QStringList& urls);
|
||||||
|
|
||||||
virtual bool Action() override;
|
virtual bool Action() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void Import(const QStringList& files, Folder* folder, QUndoCommand* parent_command);
|
||||||
|
|
||||||
|
ProjectViewModel* model_;
|
||||||
QStringList urls_;
|
QStringList urls_;
|
||||||
Folder* parent_;
|
Folder* parent_;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -116,4 +116,6 @@ void Task::ThreadComplete()
|
|||||||
} else {
|
} else {
|
||||||
set_status(kError);
|
set_status(kError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
emit Finished();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -176,6 +176,11 @@ signals:
|
|||||||
*/
|
*/
|
||||||
void ProgressChanged(int p);
|
void ProgressChanged(int p);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Signal emitted when the Task finishes whether it succeeded or failed
|
||||||
|
*/
|
||||||
|
void Finished();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* @brief Set the status of this Task (also emits StatusChanged())
|
* @brief Set the status of this Task (also emits StatusChanged())
|
||||||
|
|||||||
@@ -62,6 +62,10 @@ ProjectExplorer::ProjectExplorer(QWidget *parent) :
|
|||||||
|
|
||||||
// Set default icon size
|
// Set default icon size
|
||||||
SizeChangedSlot(olive::kProjectIconSizeDefault);
|
SizeChangedSlot(olive::kProjectIconSizeDefault);
|
||||||
|
|
||||||
|
// Set rename timer timeout
|
||||||
|
rename_timer_.setInterval(500);
|
||||||
|
connect(&rename_timer_, SIGNAL(timeout()), this, SLOT(RenameTimerSlot()));
|
||||||
}
|
}
|
||||||
|
|
||||||
const olive::ProjectViewType &ProjectExplorer::view_type()
|
const olive::ProjectViewType &ProjectExplorer::view_type()
|
||||||
@@ -90,15 +94,25 @@ void ProjectExplorer::set_view_type(olive::ProjectViewType type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProjectExplorer::Edit(Item *item)
|
||||||
|
{
|
||||||
|
CurrentView()->edit(model_.CreateIndexFromItem(item));
|
||||||
|
}
|
||||||
|
|
||||||
void ProjectExplorer::AddView(QAbstractItemView *view)
|
void ProjectExplorer::AddView(QAbstractItemView *view)
|
||||||
{
|
{
|
||||||
view->setModel(&model_);
|
view->setModel(&model_);
|
||||||
|
view->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||||
connect(view, SIGNAL(DoubleClickedView(const QModelIndex&)), this, SLOT(DoubleClickViewSlot(const QModelIndex&)));
|
connect(view, SIGNAL(DoubleClickedView(const QModelIndex&)), this, SLOT(DoubleClickViewSlot(const QModelIndex&)));
|
||||||
|
connect(view, SIGNAL(clicked(const QModelIndex&)), this, SLOT(ItemClickedSlot(const QModelIndex&)));
|
||||||
stacked_widget_->addWidget(view);
|
stacked_widget_->addWidget(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectExplorer::BrowseToFolder(const QModelIndex &index)
|
void ProjectExplorer::BrowseToFolder(const QModelIndex &index)
|
||||||
{
|
{
|
||||||
|
// Make sure any rename timers are stopped
|
||||||
|
rename_timer_.stop();
|
||||||
|
|
||||||
// Set appropriate views to this index
|
// Set appropriate views to this index
|
||||||
icon_view_->setRootIndex(index);
|
icon_view_->setRootIndex(index);
|
||||||
list_view_->setRootIndex(index);
|
list_view_->setRootIndex(index);
|
||||||
@@ -116,6 +130,30 @@ void ProjectExplorer::BrowseToFolder(const QModelIndex &index)
|
|||||||
nav_bar_->set_dir_up_enabled(index.isValid());
|
nav_bar_->set_dir_up_enabled(index.isValid());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QAbstractItemView *ProjectExplorer::CurrentView()
|
||||||
|
{
|
||||||
|
return static_cast<QAbstractItemView*>(stacked_widget_->currentWidget());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProjectExplorer::ItemClickedSlot(const QModelIndex &index)
|
||||||
|
{
|
||||||
|
if (index.isValid()) {
|
||||||
|
if (clicked_index_ == index) {
|
||||||
|
// The item has been clicked more than once, start a timer for renaming
|
||||||
|
rename_timer_.start();
|
||||||
|
} else {
|
||||||
|
// Cache this index for the next click
|
||||||
|
clicked_index_ = index;
|
||||||
|
|
||||||
|
// If the rename timer had started, stop it now
|
||||||
|
rename_timer_.stop();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Stop the rename timer
|
||||||
|
rename_timer_.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ProjectExplorer::DoubleClickViewSlot(const QModelIndex &index)
|
void ProjectExplorer::DoubleClickViewSlot(const QModelIndex &index)
|
||||||
{
|
{
|
||||||
if (index.isValid()) {
|
if (index.isValid()) {
|
||||||
@@ -160,6 +198,18 @@ void ProjectExplorer::DirUpSlot()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProjectExplorer::RenameTimerSlot()
|
||||||
|
{
|
||||||
|
// Start editing this index
|
||||||
|
CurrentView()->edit(clicked_index_);
|
||||||
|
|
||||||
|
// Reset clicked index state
|
||||||
|
clicked_index_ = QModelIndex();
|
||||||
|
|
||||||
|
// Stop rename timer
|
||||||
|
rename_timer_.stop();
|
||||||
|
}
|
||||||
|
|
||||||
Project *ProjectExplorer::project()
|
Project *ProjectExplorer::project()
|
||||||
{
|
{
|
||||||
return model_.project();
|
return model_.project();
|
||||||
@@ -172,20 +222,8 @@ void ProjectExplorer::set_project(Project *p)
|
|||||||
|
|
||||||
QList<Item *> ProjectExplorer::SelectedItems()
|
QList<Item *> ProjectExplorer::SelectedItems()
|
||||||
{
|
{
|
||||||
QModelIndexList index_list;
|
|
||||||
|
|
||||||
// Determine which view is active and get its selected indexes
|
// Determine which view is active and get its selected indexes
|
||||||
switch (view_type_) {
|
QModelIndexList index_list = CurrentView()->selectionModel()->selectedRows();
|
||||||
case olive::TreeView:
|
|
||||||
index_list = tree_view_->selectionModel()->selectedRows();
|
|
||||||
break;
|
|
||||||
case olive::ListView:
|
|
||||||
index_list = list_view_->selectionModel()->selectedRows();
|
|
||||||
break;
|
|
||||||
case olive::IconView:
|
|
||||||
index_list = icon_view_->selectionModel()->selectedRows();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert indexes to item objects
|
// Convert indexes to item objects
|
||||||
QList<Item*> selected_items;
|
QList<Item*> selected_items;
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#define PROJECTEXPLORER_H
|
#define PROJECTEXPLORER_H
|
||||||
|
|
||||||
#include <QStackedWidget>
|
#include <QStackedWidget>
|
||||||
|
#include <QTimer>
|
||||||
#include <QTreeView>
|
#include <QTreeView>
|
||||||
|
|
||||||
#include "project/project.h"
|
#include "project/project.h"
|
||||||
@@ -77,6 +78,8 @@ public:
|
|||||||
public slots:
|
public slots:
|
||||||
void set_view_type(olive::ProjectViewType type);
|
void set_view_type(olive::ProjectViewType type);
|
||||||
|
|
||||||
|
void Edit(Item* item);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
/**
|
/**
|
||||||
* @brief Emitted when an Item is double clicked
|
* @brief Emitted when an Item is double clicked
|
||||||
@@ -110,6 +113,11 @@ private:
|
|||||||
*/
|
*/
|
||||||
void BrowseToFolder(const QModelIndex& index);
|
void BrowseToFolder(const QModelIndex& index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the currently active QAbstractItemView
|
||||||
|
*/
|
||||||
|
QAbstractItemView* CurrentView();
|
||||||
|
|
||||||
QStackedWidget* stacked_widget_;
|
QStackedWidget* stacked_widget_;
|
||||||
|
|
||||||
ProjectExplorerNavigation* nav_bar_;
|
ProjectExplorerNavigation* nav_bar_;
|
||||||
@@ -122,12 +130,20 @@ private:
|
|||||||
|
|
||||||
ProjectViewModel model_;
|
ProjectViewModel model_;
|
||||||
|
|
||||||
|
QModelIndex clicked_index_;
|
||||||
|
|
||||||
|
QTimer rename_timer_;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
void ItemClickedSlot(const QModelIndex& index);
|
||||||
|
|
||||||
void DoubleClickViewSlot(const QModelIndex& index);
|
void DoubleClickViewSlot(const QModelIndex& index);
|
||||||
|
|
||||||
void SizeChangedSlot(int s);
|
void SizeChangedSlot(int s);
|
||||||
|
|
||||||
void DirUpSlot();
|
void DirUpSlot();
|
||||||
|
|
||||||
|
void RenameTimerSlot();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PROJECTEXPLORER_H
|
#endif // PROJECTEXPLORER_H
|
||||||
|
|||||||
Reference in New Issue
Block a user