diff --git a/io/config.cpp b/io/config.cpp index bd0882f68..2ecb744ba 100644 --- a/io/config.cpp +++ b/io/config.cpp @@ -32,7 +32,8 @@ Config::Config() autoscroll(AUTOSCROLL_PAGE_SCROLL), audio_rate(48000), fast_seeking(false), - hover_focus(false) + hover_focus(false), + project_view_type(PROJECT_VIEW_TREE) {} void Config::load(QString path) { @@ -115,6 +116,9 @@ void Config::load(QString path) { } else if (stream.name() == "HoverFocus") { stream.readNext(); hover_focus = (stream.text() == "1"); + } else if (stream.name() == "ProjectViewType") { + stream.readNext(); + project_view_type = stream.text().toInt(); } } } @@ -163,6 +167,7 @@ void Config::save(QString path) { stream.writeTextElement("AudioRate", QString::number(audio_rate)); stream.writeTextElement("FastSeeking", QString::number(fast_seeking)); stream.writeTextElement("HoverFocus", QString::number(hover_focus)); + stream.writeTextElement("ProjectViewType", QString::number(project_view_type)); stream.writeEndElement(); // configuration stream.writeEndDocument(); // doc diff --git a/io/config.h b/io/config.h index 4092204ff..4972c9dd3 100644 --- a/io/config.h +++ b/io/config.h @@ -18,6 +18,9 @@ #define AUTOSCROLL_PAGE_SCROLL 1 #define AUTOSCROLL_SMOOTH_SCROLL 2 +#define PROJECT_VIEW_TREE 0 +#define PROJECT_VIEW_ICON 1 + struct Config { Config(); bool saved_layout; @@ -44,6 +47,7 @@ struct Config { int audio_rate; bool fast_seeking; bool hover_focus; + int project_view_type; void load(QString path); void save(QString path); diff --git a/mainwindow.cpp b/mainwindow.cpp index 404a6dc9b..ee01aa846 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -439,7 +439,7 @@ void MainWindow::new_project() { panel_project->new_project(); updateTitle(""); update_ui(false); - panel_project->source_table->update(); + panel_project->tree_view->update(); } } diff --git a/mainwindow.ui b/mainwindow.ui index 61cc110c8..6533a2453 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -33,7 +33,7 @@ 0 0 653 - 25 + 16 @@ -148,6 +148,7 @@ + diff --git a/panels/project.cpp b/panels/project.cpp index dc391ae0b..7d52ac2c0 100644 --- a/panels/project.cpp +++ b/panels/project.cpp @@ -70,26 +70,40 @@ Project::Project(QWidget *parent) : QWidget* dockWidgetContents = new QWidget(); QVBoxLayout* verticalLayout = new QVBoxLayout(dockWidgetContents); verticalLayout->setContentsMargins(0, 0, 0, 0); + verticalLayout->setSpacing(0); setWidget(dockWidgetContents); - source_table = new SourceTable(dockWidgetContents); - source_table->project_parent = this; - source_table->setAcceptDrops(true); - source_table->setEditTriggers(QAbstractItemView::NoEditTriggers); - source_table->setDragDropMode(QAbstractItemView::DragDrop); - source_table->setSelectionMode(QAbstractItemView::ExtendedSelection); - verticalLayout->addWidget(source_table); - //setWidget(source_table); - - //layout->addWidget(source_table); - sorter = new QSortFilterProxyModel(this); sorter->setSourceModel(&project_model); - source_table->setModel(sorter); + + tree_view = new SourceTable(dockWidgetContents); + tree_view->project_parent = this; + tree_view->setAcceptDrops(true); + tree_view->setEditTriggers(QAbstractItemView::NoEditTriggers); + tree_view->setDragDropMode(QAbstractItemView::DragDrop); + tree_view->setSelectionMode(QAbstractItemView::ExtendedSelection); + tree_view->setModel(sorter); + verticalLayout->addWidget(tree_view); + + icon_view = new QListView(dockWidgetContents); + icon_view->setModel(sorter); + icon_view->setIconSize(QSize(100, 100)); + icon_view->setViewMode(QListView::IconMode); + icon_view->setUniformItemSizes(true); + verticalLayout->addWidget(icon_view); + + QPushButton* tree_view_button = new QPushButton("Tree View"); + verticalLayout->addWidget(tree_view_button); + connect(tree_view_button, SIGNAL(clicked(bool)), this, SLOT(set_tree_view())); + QPushButton* icon_view_button = new QPushButton("Icon View"); + verticalLayout->addWidget(icon_view_button); + connect(icon_view_button, SIGNAL(clicked(bool)), this, SLOT(set_icon_view())); //retranslateUi(Project); setWindowTitle(QApplication::translate("Project", "Project", nullptr)); + + update_view_type(); } Project::~Project() { @@ -189,7 +203,7 @@ Sequence* create_sequence_from_media(QVector& media_list) { } void Project::duplicate_selected() { - QModelIndexList items = source_table->selectionModel()->selectedRows(); + QModelIndexList items = tree_view->selectionModel()->selectedRows(); bool duped = false; ComboAction* ca = new ComboAction(); for (int j=0;jselectionModel()->selectedRows(); + QModelIndexList selected_items = tree_view->selectionModel()->selectedRows(); if (selected_items.size() == 1) { Media* item = item_to_media(selected_items.at(0)); if (item->get_type() == MEDIA_TYPE_FOOTAGE) { @@ -230,13 +244,13 @@ void Project::replace_clip_media() { if (sequence == NULL) { QMessageBox::critical(this, "No active sequence", "No sequence is active, please open the sequence you want to replace clips from.", QMessageBox::Ok); } else { - QModelIndexList selected_items = source_table->selectionModel()->selectedRows(); + QModelIndexList selected_items = tree_view->selectionModel()->selectedRows(); if (selected_items.size() == 1) { Media* item = item_to_media(selected_items.at(0)); if (item->get_type() == MEDIA_TYPE_SEQUENCE && sequence == item->to_sequence()) { QMessageBox::critical(this, "Active sequence selected", "You cannot insert a sequence into itself, so no clips of this media would be in this sequence.", QMessageBox::Ok); } else { - ReplaceClipMediaDialog dialog(this, source_table, item); + ReplaceClipMediaDialog dialog(this, tree_view, item); dialog.exec(); } } @@ -244,7 +258,7 @@ void Project::replace_clip_media() { } void Project::open_properties() { - QModelIndexList selected_items = source_table->selectionModel()->selectedRows(); + QModelIndexList selected_items = tree_view->selectionModel()->selectedRows(); if (selected_items.size() == 1) { Media* item = item_to_media(selected_items.at(0)); switch (item->get_type()) { @@ -302,7 +316,7 @@ QString Project::get_file_name_from_path(const QString& path) { }*/ bool Project::is_focused() { - return source_table->hasFocus(); + return tree_view->hasFocus(); } Media* Project::new_folder(QString name) { @@ -347,7 +361,7 @@ bool delete_clips_in_clipboard_with_media(ComboAction* ca, Media* m) { void Project::delete_selected_media() { ComboAction* ca = new ComboAction(); - QModelIndexList selected_items = source_table->selectionModel()->selectedRows(); + QModelIndexList selected_items = tree_view->selectionModel()->selectedRows(); QList items; for (int i=0;isetSortingEnabled(false); - source_table->setSortingEnabled(true); + tree_view->setSortingEnabled(false); + tree_view->setSortingEnabled(true); // check if media is in use QVector parents; @@ -666,7 +680,7 @@ void Project::process_file_list(QStringList& files, bool recursive, Media* repla Media* Project::get_selected_folder() { // if one item is selected and it's a folder, return it - QModelIndexList selected_items = source_table->selectionModel()->selectedRows(); + QModelIndexList selected_items = tree_view->selectionModel()->selectedRows(); if (selected_items.size() == 1) { Media* m = item_to_media(selected_items.at(0)); if (m->get_type() == MEDIA_TYPE_FOLDER) return m; @@ -685,12 +699,12 @@ bool Project::reveal_media(void *media, QModelIndex parent) { // expand all folders leading to this media QModelIndex hierarchy = item.parent(); while (hierarchy.isValid()) { - source_table->setExpanded(hierarchy, true); + tree_view->setExpanded(hierarchy, true); hierarchy = hierarchy.parent(); } // select item - source_table->selectionModel()->select(item, QItemSelectionModel::Select); + tree_view->selectionModel()->select(item, QItemSelectionModel::Select); return true; } @@ -715,7 +729,7 @@ void Project::delete_clips_using_selected_media() { } else { ComboAction* ca = new ComboAction(); bool deleted = false; - QModelIndexList items = source_table->selectionModel()->selectedRows(); + QModelIndexList items = tree_view->selectionModel()->selectedRows(); for (int i=0;iclips.size();i++) { Clip* c = sequence->clips.at(i); if (c != NULL) { @@ -984,6 +998,21 @@ void Project::save_project(bool autorecovery) { } } +void Project::update_view_type() { + tree_view->setVisible(config.project_view_type == PROJECT_VIEW_TREE); + icon_view->setVisible(config.project_view_type == PROJECT_VIEW_ICON); +} + +void Project::set_icon_view() { + config.project_view_type = PROJECT_VIEW_ICON; + update_view_type(); +} + +void Project::set_tree_view() { + config.project_view_type = PROJECT_VIEW_TREE; + update_view_type(); +} + void Project::save_recent_projects() { // save to file QFile f(recent_proj_file); @@ -1094,7 +1123,7 @@ void MediaThrobber::stop(int icon_type, bool replace) { // redraw clips update_ui(replace); - panel_project->source_table->viewport()->update(); + panel_project->tree_view->viewport()->update(); item->throbber = NULL; deleteLater(); } diff --git a/panels/project.h b/panels/project.h index 563ae5ac0..f027c4298 100644 --- a/panels/project.h +++ b/panels/project.h @@ -20,6 +20,7 @@ class QXmlStreamReader; class QFile; class QSortFilterProxyModel; class ComboAction; +class QListView; #define LOAD_TYPE_VERSION 69 #define LOAD_TYPE_URL 70 @@ -40,10 +41,8 @@ Sequence* create_sequence_from_media(QVector &media_list); QString get_channel_layout_name(int channels, uint64_t layout); QString get_interlacing_name(int interlacing); -class Project : public QDockWidget -{ +class Project : public QDockWidget { Q_OBJECT - public: explicit Project(QWidget *parent = 0); ~Project(); @@ -68,7 +67,9 @@ public: QVector list_all_project_sequences(); - SourceTable* source_table; + SourceTable* tree_view; + QListView* icon_view; + QSortFilterProxyModel* sorter; QVector last_imported_media; @@ -94,6 +95,9 @@ private: QString get_file_name_from_path(const QString &path); QDir proj_dir; private slots: + void update_view_type(); + void set_icon_view(); + void set_tree_view(); void clear_recent_projects(); }; diff --git a/project/media.cpp b/project/media.cpp index bb01dc72e..4be8add33 100644 --- a/project/media.cpp +++ b/project/media.cpp @@ -253,6 +253,15 @@ QVariant Media::data(int column, int role) { switch (role) { case Qt::DecorationRole: if (column == 0) { + if (config.project_view_type == PROJECT_VIEW_ICON + && get_type() == MEDIA_TYPE_FOOTAGE) { + Footage* f = to_footage(); + if (f->video_tracks.size() > 0 + && f->video_tracks.at(0)->preview_done) { + return QIcon(QPixmap::fromImage(f->video_tracks.at(0)->video_preview)); + } + } + return icon; } break; diff --git a/ui/sourcetable.h b/ui/sourcetable.h index c2a2637a7..0e3428152 100644 --- a/ui/sourcetable.h +++ b/ui/sourcetable.h @@ -12,7 +12,7 @@ class SourceTable : public QTreeView { Q_OBJECT public: - SourceTable(QWidget* parent = 0); + SourceTable(QWidget* parent = 0); Project* project_parent; protected: void mousePressEvent(QMouseEvent*); diff --git a/ui/timelinewidget.cpp b/ui/timelinewidget.cpp index ba4d42fcb..c05782bf8 100644 --- a/ui/timelinewidget.cpp +++ b/ui/timelinewidget.cpp @@ -265,8 +265,8 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) { QVector media_list; panel_timeline->importing_files = false; - if (event->source() == panel_project->source_table) { - QModelIndexList items = panel_project->source_table->selectionModel()->selectedRows(); + if (event->source() == panel_project->tree_view) { + QModelIndexList items = panel_project->tree_view->selectionModel()->selectedRows(); media_list.resize(items.size()); for (int i=0;iitem_to_media(items.at(i));