Merge pull request #199 from olive-editor/iconview

Icon View in Project Panel
This commit is contained in:
itsmattkc
2018-12-25 17:36:14 +11:00
committed by GitHub
28 changed files with 667 additions and 322 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

+2
View File
@@ -49,5 +49,7 @@
<file>transition-tool.png</file>
<file>transition-tool-disabled.png</file>
<file>error.png</file>
<file>dirup.png</file>
<file>dirup-disabled.png</file>
</qresource>
</RCC>
+6 -1
View File
@@ -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
+4
View File
@@ -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);
+7 -7
View File
@@ -97,8 +97,8 @@ bool ExportThread::setupVideo() {
}
// allocate context
vcodec_ctx = video_stream->codec;
// vcodec_ctx = avcodec_alloc_context3(vcodec);
// vcodec_ctx = video_stream->codec;
vcodec_ctx = avcodec_alloc_context3(vcodec);
if (!vcodec_ctx) {
dout << "[ERROR] Could not allocate video encoding context";
ed->export_error = "could not allocate video encoding context";
@@ -125,7 +125,7 @@ bool ExportThread::setupVideo() {
itoa(vcodec_ctx, buffer, 10);*/
//av_opt_set(vcodec_ctx->priv_data, "preset", "fast", AV_OPT_SEARCH_CHILDREN);
av_opt_set(vcodec_ctx->priv_data, "x264opts", "opencl", AV_OPT_SEARCH_CHILDREN);
//av_opt_set(vcodec_ctx->priv_data, "x264opts", "opencl", AV_OPT_SEARCH_CHILDREN);
switch (video_compression_type) {
case COMPRESSION_TYPE_CFR:
@@ -203,8 +203,8 @@ bool ExportThread::setupAudio() {
}
// allocate context
acodec_ctx = audio_stream->codec;
// acodec_ctx = avcodec_alloc_context3(acodec);
// acodec_ctx = audio_stream->codec;
acodec_ctx = avcodec_alloc_context3(acodec);
if (!acodec_ctx) {
dout << "[ERROR] Could not find allocate audio encoding context";
ed->export_error = "could not allocate audio encoding context";
@@ -448,14 +448,14 @@ void ExportThread::run() {
avcodec_close(vcodec_ctx);
av_packet_unref(&video_pkt);
av_frame_free(&video_frame);
// avcodec_free_context(&vcodec_ctx);
avcodec_free_context(&vcodec_ctx);
}
if (audio_enabled) {
avcodec_close(acodec_ctx);
av_packet_unref(&audio_pkt);
av_frame_free(&audio_frame);
// avcodec_free_context(&acodec_ctx);
avcodec_free_context(&acodec_ctx);
}
avformat_free_context(fmt_ctx);
+6 -4
View File
@@ -128,6 +128,7 @@ bool PreviewGenerator::retrieve_preview(const QString& hash) {
QFile f(thumb_path);
if (f.exists() && ms->video_preview.load(thumb_path)) {
//dout << "loaded thumb" << ms->file_index << "from" << thumb_path;
ms->make_square_thumb();
ms->preview_done = true;
} else {
found = false;
@@ -255,7 +256,7 @@ void PreviewGenerator::generate_waveform() {
if (!s->preview_done) {
int dstH = 120;
int dstW = dstH * ((float)temp_frame->width/(float)temp_frame->height);
uint8_t* data = new uint8_t[dstW*dstH*3];
uint8_t* data = new uint8_t[dstW*dstH*4];
sws_ctx = sws_getContext(
temp_frame->width,
@@ -263,7 +264,7 @@ void PreviewGenerator::generate_waveform() {
static_cast<AVPixelFormat>(temp_frame->format),
dstW,
dstH,
static_cast<AVPixelFormat>(AV_PIX_FMT_RGB24),
static_cast<AVPixelFormat>(AV_PIX_FMT_RGBA),
SWS_FAST_BILINEAR,
NULL,
NULL,
@@ -271,10 +272,11 @@ void PreviewGenerator::generate_waveform() {
);
int linesize[AV_NUM_DATA_POINTERS];
linesize[0] = dstW*3;
linesize[0] = dstW*4;
sws_scale(sws_ctx, temp_frame->data, temp_frame->linesize, 0, temp_frame->height, &data, linesize);
s->video_preview = QImage(data, dstW, dstH, linesize[0], QImage::Format_RGB888);
s->video_preview = QImage(data, dstW, dstH, linesize[0], QImage::Format_RGBA8888);
s->make_square_thumb();
// is video interlaced?
s->video_auto_interlacing = (temp_frame->interlaced_frame) ? ((temp_frame->top_field_first) ? VIDEO_TOP_FIELD_FIRST : VIDEO_BOTTOM_FIELD_FIRST) : VIDEO_PROGRESSIVE;
+10 -10
View File
@@ -130,15 +130,6 @@ MainWindow::MainWindow(QWidget *parent) :
layout()->invalidate();
// TODO maybe replace these with non-pointers later on?
panel_sequence_viewer = new Viewer(this);
panel_footage_viewer = new Viewer(this);
panel_project = new Project(this);
panel_effect_controls = new EffectControls(this);
panel_timeline = new Timeline(this);
setup_layout(false);
connect(ui->menuWindow, SIGNAL(aboutToShow()), this, SLOT(windowMenu_About_To_Be_Shown()));
connect(ui->menu_View, SIGNAL(aboutToShow()), this, SLOT(viewMenu_About_To_Be_Shown()));
connect(ui->menu_Tools, SIGNAL(aboutToShow()), this, SLOT(toolMenu_About_To_Be_Shown()));
@@ -215,6 +206,15 @@ MainWindow::MainWindow(QWidget *parent) :
}
}
// TODO maybe replace these with non-pointers later on?
panel_sequence_viewer = new Viewer(this);
panel_footage_viewer = new Viewer(this);
panel_project = new Project(this);
panel_effect_controls = new EffectControls(this);
panel_timeline = new Timeline(this);
setup_layout(false);
init_audio();
connect(ui->action_Undo, SIGNAL(triggered(bool)), this, SLOT(undo()));
@@ -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();
}
}
+2 -1
View File
@@ -33,7 +33,7 @@
<x>0</x>
<y>0</y>
<width>653</width>
<height>25</height>
<height>16</height>
</rect>
</property>
<widget class="QMenu" name="menu_File">
@@ -148,6 +148,7 @@
<addaction name="separator"/>
<addaction name="menuTitle_Action_Safe_Area"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="actionFull_Screen"/>
</widget>
<widget class="QMenu" name="menuPlayback">
+6 -2
View File
@@ -96,7 +96,9 @@ SOURCES += \
project/effectgizmo.cpp \
io/clipboard.cpp \
dialogs/stabilizerdialog.cpp \
io/avtogl.cpp
io/avtogl.cpp \
ui/sourceiconview.cpp \
project/sourcescommon.cpp
HEADERS += \
mainwindow.h \
@@ -172,7 +174,9 @@ HEADERS += \
project/effectgizmo.h \
io/clipboard.h \
dialogs/stabilizerdialog.h \
io/avtogl.h
io/avtogl.h \
ui/sourceiconview.h \
project/sourcescommon.h
FORMS += \
mainwindow.ui \
+117 -30
View File
@@ -23,6 +23,8 @@
#include "io/clipboard.h"
#include "project/media.h"
#include "ui/sourcetable.h"
#include "ui/sourceiconview.h"
#include "project/sourcescommon.h"
#include "debug.h"
#include <QApplication>
@@ -38,7 +40,6 @@
#include <QSortFilterProxyModel>
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
#include <QListView>
#include <QSizePolicy>
#include <QVBoxLayout>
@@ -70,26 +71,73 @@ 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);
sources_common = new SourcesCommon(this);
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_container = new QWidget();
QVBoxLayout* icon_view_container_layout = new QVBoxLayout();
icon_view_container_layout->setMargin(0);
icon_view_container_layout->setSpacing(0);
icon_view_container->setLayout(icon_view_container_layout);
QHBoxLayout* icon_view_controls = new QHBoxLayout();
icon_view_controls->setMargin(0);
icon_view_controls->setSpacing(0);
QIcon directory_up_button;
directory_up_button.addFile(":/icons/dirup.png", QSize(), QIcon::Normal);
directory_up_button.addFile(":/icons/dirup-disabled.png", QSize(), QIcon::Disabled);
directory_up = new QPushButton();
directory_up->setIcon(directory_up_button);
directory_up->setEnabled(false);
icon_view_controls->addWidget(directory_up);
icon_view_controls->addStretch();
QSlider* icon_size_slider = new QSlider(Qt::Horizontal);
icon_size_slider->setMinimum(16);
icon_size_slider->setMaximum(120);
icon_view_controls->addWidget(icon_size_slider);
connect(icon_size_slider, SIGNAL(valueChanged(int)), this, SLOT(set_icon_view_size(int)));
icon_view_container_layout->addLayout(icon_view_controls);
icon_view = new SourceIconView(dockWidgetContents);
icon_view->project_parent = this;
icon_view->setModel(sorter);
icon_view->setIconSize(QSize(100, 100));
icon_view->setViewMode(QListView::IconMode);
icon_view->setUniformItemSizes(true);
icon_view_container_layout->addWidget(icon_view);
icon_size_slider->setValue(icon_view->iconSize().height());
verticalLayout->addWidget(icon_view_container);
connect(directory_up, SIGNAL(clicked(bool)), this, SLOT(go_up_dir()));
connect(icon_view, SIGNAL(changed_root()), this, SLOT(set_up_dir_enabled()));
//retranslateUi(Project);
setWindowTitle(QApplication::translate("Project", "Project", nullptr));
update_view_type();
}
Project::~Project() {
@@ -189,7 +237,7 @@ Sequence* create_sequence_from_media(QVector<Media*>& 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;j<items.size();j++) {
@@ -207,7 +255,7 @@ void Project::duplicate_selected() {
}
void Project::replace_selected_file() {
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_FOOTAGE) {
@@ -230,13 +278,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 +292,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 +350,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 +395,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<Media*> items;
for (int i=0;i<selected_items.size();i++) {
items.append(item_to_media(selected_items.at(i)));
@@ -356,8 +404,8 @@ void Project::delete_selected_media() {
bool redraw = false;
// correctly sort (fixes qt bug - see AddMediaCommand::redo() for info)
source_table->setSortingEnabled(false);
source_table->setSortingEnabled(true);
tree_view->setSortingEnabled(false);
tree_view->setSortingEnabled(true);
// check if media is in use
QVector<Media*> parents;
@@ -666,7 +714,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;
@@ -674,23 +722,25 @@ Media* Project::get_selected_folder() {
return NULL;
}
bool Project::reveal_media(void *media, QModelIndex parent) {
bool Project::reveal_media(Media *media, QModelIndex parent) {
for (int i=0;i<project_model.rowCount(parent);i++) {
const QModelIndex& item = project_model.index(i, 0, parent);
Media* m = project_model.getItem(item);
if (m->get_type() == MEDIA_TYPE_FOLDER) {
if (reveal_media(media, item)) return true;
} else if (m->to_object() == media) {
} else if (m == media) {
// expand all folders leading to this media
QModelIndex hierarchy = item.parent();
QModelIndex sorted_index = sorter->mapFromSource(item);
QModelIndex hierarchy = sorted_index.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(sorted_index, QItemSelectionModel::Select);
return true;
}
@@ -715,7 +765,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;i<sequence->clips.size();i++) {
Clip* c = sequence->clips.at(i);
if (c != NULL) {
@@ -984,6 +1034,30 @@ void Project::save_project(bool autorecovery) {
}
}
void Project::update_view_type() {
tree_view->setVisible(config.project_view_type == PROJECT_VIEW_TREE);
icon_view_container->setVisible(config.project_view_type == PROJECT_VIEW_ICON);
switch (config.project_view_type) {
case PROJECT_VIEW_TREE:
sources_common->view = tree_view;
break;
case PROJECT_VIEW_ICON:
sources_common->view = icon_view;
break;
}
}
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);
@@ -1003,7 +1077,20 @@ void Project::save_recent_projects() {
void Project::clear_recent_projects() {
recent_projects.clear();
save_recent_projects();
save_recent_projects();
}
void Project::set_icon_view_size(int s) {
icon_view->setIconSize(QSize(s, s));
}
void Project::set_up_dir_enabled() {
directory_up->setEnabled(icon_view->rootIndex().isValid());
}
void Project::go_up_dir() {
icon_view->setRootIndex(icon_view->rootIndex().parent());
set_up_dir_enabled();
}
void Project::add_recent_project(QString url) {
@@ -1094,7 +1181,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();
}
+17 -5
View File
@@ -20,6 +20,9 @@ class QXmlStreamReader;
class QFile;
class QSortFilterProxyModel;
class ComboAction;
class SourceIconView;
class QPushButton;
class SourcesCommon;
#define LOAD_TYPE_VERSION 69
#define LOAD_TYPE_URL 70
@@ -40,10 +43,8 @@ Sequence* create_sequence_from_media(QVector<Media *> &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();
@@ -54,7 +55,7 @@ public:
void process_file_list(QStringList& files, bool recursive = false, Media* replace = NULL, Media *parent = NULL);
void replace_media(Media* item, QString filename);
Media *get_selected_folder();
bool reveal_media(void* media, QModelIndex parent = QModelIndex());
bool reveal_media(Media *media, QModelIndex parent = QModelIndex());
void add_recent_project(QString url);
void new_project();
@@ -68,7 +69,10 @@ public:
QVector<Media*> list_all_project_sequences();
SourceTable* source_table;
SourceTable* tree_view;
SourceIconView* icon_view;
SourcesCommon* sources_common;
QSortFilterProxyModel* sorter;
QVector<Media*> last_imported_media;
@@ -93,8 +97,16 @@ private:
void list_all_sequences_worker(QVector<Media *> *list, Media* parent);
QString get_file_name_from_path(const QString &path);
QDir proj_dir;
QWidget* icon_view_container;
QPushButton* directory_up;
private slots:
void update_view_type();
void set_icon_view();
void set_tree_view();
void clear_recent_projects();
void set_icon_view_size(int);
void set_up_dir_enabled();
void go_up_dir();
};
class MediaThrobber : public QObject {
+6 -1
View File
@@ -109,7 +109,12 @@ void Clip::refresh() {
// validates media if it was replaced
if (replaced && media != NULL && media->get_type() == MEDIA_TYPE_FOOTAGE) {
Footage* m = media->to_footage();
media_stream = (track < 0) ? m->video_tracks.at(0)->file_index : m->audio_tracks.at(0)->file_index;
if (track < 0 && m->video_tracks.size() > 0) {
media_stream = m->video_tracks.at(0)->file_index;
} else if (track >= 0 && m->audio_tracks.size() > 0) {
media_stream = m->audio_tracks.at(0)->file_index;
}
}
replaced = false;
+14
View File
@@ -2,6 +2,7 @@
#include <QDebug>
#include <QtMath>
#include <QPainter>
#include "io/previewgenerator.h"
extern "C" {
@@ -55,3 +56,16 @@ FootageStream* Footage::get_stream_from_file_index(bool video, int index) {
}
return NULL;
}
void FootageStream::make_square_thumb() {
// generate square version for QListView?
int square_size = qMax(video_preview.width(), video_preview.height());
QPixmap pixmap(square_size, square_size);
pixmap.fill(Qt::transparent);
QPainter p(&pixmap);
int diff = (video_preview.width() - video_preview.height())>>1;
int sqx = (diff < 0) ? -diff : 0;
int sqy = (diff > 0) ? diff : 0;
p.drawImage(sqx, sqy, video_preview);
video_preview_square = QIcon(pixmap);
}
+3
View File
@@ -7,6 +7,7 @@
#include <QVariant>
#include <QMutex>
#include <QPixmap>
#include <QIcon>
#define VIDEO_PROGRESSIVE 0
#define VIDEO_TOP_FIELD_FIRST 1
@@ -32,7 +33,9 @@ struct FootageStream {
// preview thumbnail/waveform
bool preview_done;
QImage video_preview;
QIcon video_preview_square;
QVector<char> audio_preview;
void make_square_thumb();
};
struct Footage {
+10
View File
@@ -8,6 +8,8 @@
#include "panels/project.h"
#include "projectmodel.h"
#include <QPainter>
#include "debug.h"
extern "C" {
@@ -253,6 +255,14 @@ QVariant Media::data(int column, int role) {
switch (role) {
case Qt::DecorationRole:
if (column == 0) {
if (get_type() == MEDIA_TYPE_FOOTAGE) {
Footage* f = to_footage();
if (f->video_tracks.size() > 0
&& f->video_tracks.at(0)->preview_done) {
return f->video_tracks.at(0)->video_preview_square;
}
}
return icon;
}
break;
+280
View File
@@ -0,0 +1,280 @@
#include "sourcescommon.h"
#include "panels/panels.h"
#include "project/media.h"
#include "project/undo.h"
#include "panels/timeline.h"
#include "panels/project.h"
#include "project/footage.h"
#include "panels/viewer.h"
#include "io/config.h"
#include "mainwindow.h"
#include <QProcess>
#include <QMenu>
#include <QAbstractItemView>
#include <QMimeData>
#include <QMessageBox>
#include <QDesktopServices>
SourcesCommon::SourcesCommon(Project* parent) :
project_parent(parent),
editing_item(NULL)
{
rename_timer.setInterval(1000);
connect(&rename_timer, SIGNAL(timeout()), this, SLOT(rename_interval()));
}
void SourcesCommon::create_seq_from_selected() {
if (!selected_items.isEmpty()) {
QVector<Media*> media_list;
for (int i=0;i<selected_items.size();i++) {
media_list.append(project_parent->item_to_media(selected_items.at(i)));
}
ComboAction* ca = new ComboAction();
Sequence* s = create_sequence_from_media(media_list);
// add clips to it
panel_timeline->create_ghosts_from_media(s, 0, media_list);
panel_timeline->add_clips_from_ghosts(ca, s);
project_parent->new_sequence(ca, s, true, NULL);
undo_stack.push(ca);
}
}
void SourcesCommon::show_context_menu(QWidget* parent, const QModelIndexList& items) {
QMenu menu(parent);
selected_items = items;
QAction* import_action = menu.addAction("Import...");
QObject::connect(import_action, SIGNAL(triggered(bool)), project_parent, SLOT(import_dialog()));
QAction* new_folder_action = menu.addAction("New Folder...");
QObject::connect(new_folder_action, SIGNAL(triggered(bool)), mainWindow, SLOT(on_actionFolder_triggered()));
if (items.size() > 0) {
Media* m = project_parent->item_to_media(items.at(0));
if (items.size() == 1) {
// replace footage
int type = m->get_type();
if (type == MEDIA_TYPE_FOOTAGE) {
QAction* replace_action = menu.addAction("Replace/Relink Media");
QObject::connect(replace_action, SIGNAL(triggered(bool)), project_parent, SLOT(replace_selected_file()));
#if defined(Q_OS_WIN)
QAction* reveal_in_explorer = menu.addAction("Reveal in Explorer");
#elif defined(Q_OS_MAC)
QAction* reveal_in_explorer = menu.addAction("Reveal in Finder");
#else
QAction* reveal_in_explorer = menu.addAction("Reveal in File Manager");
#endif
QObject::connect(reveal_in_explorer, SIGNAL(triggered(bool)), this, SLOT(reveal_in_browser()));
}
if (type != MEDIA_TYPE_FOLDER) {
QAction* replace_clip_media = menu.addAction("Replace Clips Using This Media");
QObject::connect(replace_clip_media, SIGNAL(triggered(bool)), project_parent, SLOT(replace_clip_media()));
}
}
// duplicate item
bool all_sequences = true;
bool all_footage = true;
for (int i=0;i<items.size();i++) {
if (m->get_type() != MEDIA_TYPE_SEQUENCE) {
all_sequences = false;
}
if (m->get_type() != MEDIA_TYPE_FOOTAGE) {
all_footage = false;
}
}
// create sequence from
QAction* create_seq_from = menu.addAction("Create Sequence With This Media");
QObject::connect(create_seq_from, SIGNAL(triggered(bool)), this, SLOT(create_seq_from_selected()));
// ONLY sequences are selected
if (all_sequences) {
// ONLY sequences are selected
QAction* duplicate_action = menu.addAction("Duplicate");
QObject::connect(duplicate_action, SIGNAL(triggered(bool)), project_parent, SLOT(duplicate_selected()));
}
// ONLY footage is selected
if (all_footage) {
QAction* delete_footage_from_sequences = menu.addAction("Delete All Clips Using This Media");
QObject::connect(delete_footage_from_sequences, SIGNAL(triggered(bool)), project_parent, SLOT(delete_clips_using_selected_media()));
}
// delete media
QAction* delete_action = menu.addAction("Delete");
QObject::connect(delete_action, SIGNAL(triggered(bool)), project_parent, SLOT(delete_selected_media()));
if (items.size() == 1) {
QAction* properties_action = menu.addAction("Properties...");
QObject::connect(properties_action, SIGNAL(triggered(bool)), project_parent, SLOT(open_properties()));
}
}
menu.addSeparator();
QAction* tree_view_action = menu.addAction("Tree View");
connect(tree_view_action, SIGNAL(triggered(bool)), project_parent, SLOT(set_tree_view()));
QAction* icon_view_action = menu.addAction("Icon View");
connect(icon_view_action, SIGNAL(triggered(bool)), project_parent, SLOT(set_icon_view()));
menu.exec(QCursor::pos());
}
void SourcesCommon::mousePressEvent(QMouseEvent *) {
stop_rename_timer();
}
void SourcesCommon::item_click(Media *m, const QModelIndex& index) {
if (editing_item == m) {
rename_timer.start();
} else {
editing_item = m;
editing_index = index;
}
}
void SourcesCommon::mouseDoubleClickEvent(QMouseEvent *e, const QModelIndexList& selected_items) {
stop_rename_timer();
if (selected_items.size() == 0) {
project_parent->import_dialog();
} else if (selected_items.size() == 1) {
Media* item = project_parent->item_to_media(selected_items.at(0));
switch (item->get_type()) {
case MEDIA_TYPE_FOOTAGE:
panel_footage_viewer->set_media(item);
panel_footage_viewer->setFocus();
break;
case MEDIA_TYPE_SEQUENCE:
undo_stack.push(new ChangeSequenceAction(item->to_sequence()));
break;
}
}
}
void SourcesCommon::dropEvent(QWidget* parent, QDropEvent *event, const QModelIndex& drop_item, const QModelIndexList& items) {
const QMimeData* mimeData = event->mimeData();
Media* m = project_parent->item_to_media(drop_item);
if (mimeData->hasUrls()) {
// drag files in from outside
QList<QUrl> urls = mimeData->urls();
if (!urls.isEmpty()) {
QStringList paths;
for (int i=0;i<urls.size();i++) {
paths.append(urls.at(i).toLocalFile());
}
bool replace = false;
if (urls.size() == 1
&& drop_item.isValid()
&& m->get_type() == MEDIA_TYPE_FOOTAGE
&& !QFileInfo(paths.at(0)).isDir()
&& config.drop_on_media_to_replace
&& QMessageBox::question(parent, "Replace Media", "You dropped a file onto '" + m->get_name() + "'. Would you like to replace it with the dropped file?", QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::Yes) {
replace = true;
project_parent->replace_media(m, paths.at(0));
}
if (!replace) {
QModelIndex parent;
if (drop_item.isValid()) {
if (m->get_type() == MEDIA_TYPE_FOLDER) {
parent = drop_item;
} else {
parent = drop_item.parent();
}
}
project_parent->process_file_list(paths, false, NULL, panel_project->item_to_media(parent));
}
}
event->acceptProposedAction();
} else {
event->ignore();
// dragging files within project
// if we dragged to the root OR dragged to a folder
if (!drop_item.isValid() || (drop_item.isValid() && m->get_type() == MEDIA_TYPE_FOLDER)) {
QVector<Media*> move_items;
for (int i=0;i<items.size();i++) {
const QModelIndex& item = items.at(i);
const QModelIndex& parent = item.parent();
Media* s = project_parent->item_to_media(item);
if (parent != drop_item && item != drop_item) {
bool ignore = false;
if (parent.isValid()) {
// if child belongs to a selected parent, assume the user is just moving the parent and ignore the child
QModelIndex par = parent;
while (par.isValid() && !ignore) {
for (int j=0;j<items.size();j++) {
if (par == items.at(j)) {
ignore = true;
break;
}
}
par = par.parent();
}
}
if (!ignore) {
move_items.append(s);
}
}
}
if (move_items.size() > 0) {
MediaMove* mm = new MediaMove();
mm->to = m;
mm->items = move_items;
undo_stack.push(mm);
}
}
}
}
void SourcesCommon::reveal_in_browser() {
Media* media = project_parent->item_to_media(selected_items.at(0));
Footage* m = media->to_footage();
#if defined(Q_OS_WIN)
QStringList args;
args << "/select," << QDir::toNativeSeparators(m->url);
QProcess::startDetached("explorer", args);
#elif defined(Q_OS_MAC)
QStringList args;
args << "-e";
args << "tell application \"Finder\"";
args << "-e";
args << "activate";
args << "-e";
args << "select POSIX file \""+m->url+"\"";
args << "-e";
args << "end tell";
QProcess::startDetached("osascript", args);
#else
QDesktopServices::openUrl(QUrl::fromLocalFile(m->url.left(m->url.lastIndexOf('/'))));
#endif
}
void SourcesCommon::stop_rename_timer() {
rename_timer.stop();
}
void SourcesCommon::rename_interval() {
stop_rename_timer();
if (view->hasFocus() && editing_item != NULL) {
view->edit(editing_index);
}
}
void SourcesCommon::item_renamed(Media* item) {
if (editing_item == item) {
MediaRename* mr = new MediaRename(item, "idk");
undo_stack.push(mr);
editing_item = NULL;
}
}
+39
View File
@@ -0,0 +1,39 @@
#ifndef SOURCESCOMMON_H
#define SOURCESCOMMON_H
#include <QModelIndexList>
#include <QTimer>
class Project;
class QMouseEvent;
class Media;
class QAbstractItemView;
class QDropEvent;
class SourcesCommon : public QObject {
Q_OBJECT
public:
SourcesCommon(Project *parent);
QAbstractItemView* view;
void show_context_menu(QWidget* parent, const QModelIndexList &items);
void mousePressEvent(QMouseEvent* e);
void mouseDoubleClickEvent(QMouseEvent* e, const QModelIndexList& selected_items);
void dropEvent(QWidget *parent, QDropEvent* e, const QModelIndex& drop_item, const QModelIndexList &items);
void item_click(Media* m, const QModelIndex &index);
private slots:
void create_seq_from_selected();
void reveal_in_browser();
void rename_interval();
void item_renamed(Media *item);
private:
Media* editing_item;
QModelIndex editing_index;
QModelIndexList selected_items;
Project* project_parent;
void stop_rename_timer();
QTimer rename_timer;
};
#endif // SOURCESCOMMON_H
+2 -1
View File
@@ -592,6 +592,7 @@ void ReplaceMediaCommand::replace(QString& filename) {
// replace media
QStringList files;
files.append(filename);
item->to_footage()->ready_lock.lock();
panel_project->process_file_list(files, false, item, NULL);
}
@@ -694,7 +695,7 @@ void EffectDeleteCommand::redo() {
mainWindow->setWindowModified(true);
}
MediaMove::MediaMove(SourceTable *s) : table(s), old_project_changed(mainWindow->isWindowModified()) {}
MediaMove::MediaMove() : old_project_changed(mainWindow->isWindowModified()) {}
void MediaMove::undo() {
for (int i=0;i<items.size();i++) {
+1 -2
View File
@@ -302,14 +302,13 @@ private:
class MediaMove : public QUndoCommand {
public:
MediaMove(SourceTable* s);
MediaMove();
QVector<Media*> items;
Media* to;
void undo();
void redo();
private:
QVector<Media*> froms;
SourceTable* table;
bool old_project_changed;
};
+9
View File
@@ -0,0 +1,9 @@
#include "otreeview.h"
OTreeView::OTreeView(QWidget *parent) : QTreeView(parent) {
setSortingEnabled(true);
sortByColumn(0, Qt::AscendingOrder);
setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(show_context_menu()));
connect(this, SIGNAL(clicked(const QModelIndex&)), this, SLOT(item_click(const QModelIndex&)));
}
+16
View File
@@ -0,0 +1,16 @@
#ifndef OTREEVIEW_H
#define OTREEVIEW_H
#include <QTreeView>
#include "ui/sourcetable.h"
class OTreeView : public QTreeView {
Q_OBJECT
public:
OTreeView(QWidget* parent = 0);
private:
};
#endif // OTREEVIEW_H
+67
View File
@@ -0,0 +1,67 @@
#include "sourceiconview.h"
#include <QMimeData>
#include "panels/project.h"
#include "project/media.h"
#include "project/sourcescommon.h"
#include "debug.h"
SourceIconView::SourceIconView(QWidget *parent) : QListView(parent) {
setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, SIGNAL(clicked(const QModelIndex&)), this, SLOT(item_click(const QModelIndex&)));
connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(show_context_menu()));
}
void SourceIconView::show_context_menu() {
project_parent->sources_common->show_context_menu(this, selectedIndexes());
}
void SourceIconView::item_click(const QModelIndex& index) {
if (selectionModel()->selectedRows().size() == 1 && index.column() == 0) {
project_parent->sources_common->item_click(project_parent->item_to_media(index), index);
}
}
void SourceIconView::mousePressEvent(QMouseEvent* event) {
project_parent->sources_common->mousePressEvent(event);
if (!indexAt(event->pos()).isValid()) selectionModel()->clear();
QListView::mousePressEvent(event);
}
void SourceIconView::dragEnterEvent(QDragEnterEvent *event) {
if (event->mimeData()->hasUrls()) {
event->acceptProposedAction();
} else {
QListView::dragEnterEvent(event);
}
}
void SourceIconView::dragMoveEvent(QDragMoveEvent *event) {
if (event->mimeData()->hasUrls()) {
event->acceptProposedAction();
} else {
QListView::dragMoveEvent(event);
}
}
void SourceIconView::dropEvent(QDropEvent* event) {
QModelIndex drop_item = indexAt(event->pos());
if (!drop_item.isValid()) drop_item = rootIndex();
project_parent->sources_common->dropEvent(this, event, drop_item, selectedIndexes());
}
void SourceIconView::mouseDoubleClickEvent(QMouseEvent *event) {
bool default_behavior = true;
if (selectedIndexes().size() == 1) {
Media* m = project_parent->item_to_media(selectedIndexes().at(0));
if (m->get_type() == MEDIA_TYPE_FOLDER) {
default_behavior = false;
setRootIndex(selectedIndexes().at(0));
emit changed_root();
}
}
if (default_behavior) {
project_parent->sources_common->mouseDoubleClickEvent(event, selectedIndexes());
}
}
+26
View File
@@ -0,0 +1,26 @@
#ifndef SOURCEICONVIEW_H
#define SOURCEICONVIEW_H
#include <QListView>
class Project;
class SourceIconView : public QListView {
Q_OBJECT
public:
SourceIconView(QWidget* parent = 0);
Project* project_parent;
void mousePressEvent(QMouseEvent* event);
void mouseDoubleClickEvent(QMouseEvent *event);
void dragEnterEvent(QDragEnterEvent *event);
void dragMoveEvent(QDragMoveEvent *event);
void dropEvent(QDropEvent* event);
signals:
void changed_root();
private slots:
void show_context_menu();
void item_click(const QModelIndex& index);
};
#endif // SOURCEICONVIEW_H
+7 -243
View File
@@ -11,6 +11,7 @@
#include "mainwindow.h"
#include "io/config.h"
#include "project/media.h"
#include "project/sourcescommon.h"
#include "debug.h"
#include <QDragEnterEvent>
@@ -25,193 +26,30 @@
#include <QProcess>
SourceTable::SourceTable(QWidget* parent) : QTreeView(parent) {
editing_item = NULL;
setSortingEnabled(true);
sortByColumn(0, Qt::AscendingOrder);
rename_timer.setInterval(1000);
setContextMenuPolicy(Qt::CustomContextMenu);
connect(&rename_timer, SIGNAL(timeout()), this, SLOT(rename_interval()));
connect(this, SIGNAL(clicked(const QModelIndex&)), this, SLOT(item_click(const QModelIndex&)));
connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(show_context_menu()));
}
void SourceTable::show_context_menu() {
QMenu menu(this);
QAction* import_action = menu.addAction("Import...");
connect(import_action, SIGNAL(triggered(bool)), project_parent, SLOT(import_dialog()));
QAction* new_folder_action = menu.addAction("New Folder...");
connect(new_folder_action, SIGNAL(triggered(bool)), mainWindow, SLOT(on_actionFolder_triggered()));
QModelIndexList selected_items = selectionModel()->selectedRows();
if (selected_items.size() > 0) {
Media* m = project_parent->item_to_media(selected_items.at(0));
if (selected_items.size() == 1) {
// replace footage
int type = m->get_type();
if (type == MEDIA_TYPE_FOOTAGE) {
QAction* replace_action = menu.addAction("Replace/Relink Media");
connect(replace_action, SIGNAL(triggered(bool)), project_parent, SLOT(replace_selected_file()));
#if defined(Q_OS_WIN)
QAction* reveal_in_explorer = menu.addAction("Reveal in Explorer");
#elif defined(Q_OS_MAC)
QAction* reveal_in_explorer = menu.addAction("Reveal in Finder");
#else
QAction* reveal_in_explorer = menu.addAction("Reveal in File Manager");
#endif
connect(reveal_in_explorer, SIGNAL(triggered(bool)), this, SLOT(reveal_in_browser()));
}
if (type != MEDIA_TYPE_FOLDER) {
QAction* replace_clip_media = menu.addAction("Replace Clips Using This Media");
connect(replace_clip_media, SIGNAL(triggered(bool)), project_parent, SLOT(replace_clip_media()));
}
}
// duplicate item
bool all_sequences = true;
bool all_footage = true;
for (int i=0;i<selected_items.size();i++) {
if (m->get_type() != MEDIA_TYPE_SEQUENCE) {
all_sequences = false;
}
if (m->get_type() != MEDIA_TYPE_FOOTAGE) {
all_footage = false;
}
}
// create sequence from
QAction* create_seq_from = menu.addAction("Create Sequence With This Media");
connect(create_seq_from, SIGNAL(triggered(bool)), this, SLOT(create_seq_from_selected()));
// ONLY sequences are selected
if (all_sequences) {
// ONLY sequences are selected
QAction* duplicate_action = menu.addAction("Duplicate");
connect(duplicate_action, SIGNAL(triggered(bool)), project_parent, SLOT(duplicate_selected()));
}
// ONLY footage is selected
if (all_footage) {
QAction* delete_footage_from_sequences = menu.addAction("Delete All Clips Using This Media");
connect(delete_footage_from_sequences, SIGNAL(triggered(bool)), project_parent, SLOT(delete_clips_using_selected_media()));
}
// delete media
QAction* delete_action = menu.addAction("Delete");
connect(delete_action, SIGNAL(triggered(bool)), project_parent, SLOT(delete_selected_media()));
if (selected_items.size() == 1) {
QAction* properties_action = menu.addAction("Properties...");
connect(properties_action, SIGNAL(triggered(bool)), project_parent, SLOT(open_properties()));
}
}
menu.exec(QCursor::pos());
project_parent->sources_common->show_context_menu(this, selectionModel()->selectedRows());
}
void SourceTable::create_seq_from_selected() {
QModelIndexList selected_items = selectionModel()->selectedRows();
if (!selected_items.isEmpty()) {
QVector<Media*> media_list;
for (int i=0;i<selected_items.size();i++) {
media_list.append(project_parent->item_to_media(selected_items.at(i)));
}
ComboAction* ca = new ComboAction();
Sequence* s = create_sequence_from_media(media_list);
// add clips to it
panel_timeline->create_ghosts_from_media(s, 0, media_list);
panel_timeline->add_clips_from_ghosts(ca, s);
project_parent->new_sequence(ca, s, true, NULL);
undo_stack.push(ca);
}
}
void SourceTable::reveal_in_browser() {
QModelIndexList selected_items = selectionModel()->selectedRows();
Media* media = project_parent->item_to_media(selected_items.at(0));
Footage* m = media->to_footage();
#if defined(Q_OS_WIN)
QStringList args;
args << "/select," << QDir::toNativeSeparators(m->url);
QProcess::startDetached("explorer", args);
#elif defined(Q_OS_MAC)
QStringList args;
args << "-e";
args << "tell application \"Finder\"";
args << "-e";
args << "activate";
args << "-e";
args << "select POSIX file \""+m->url+"\"";
args << "-e";
args << "end tell";
QProcess::startDetached("osascript", args);
#else
QDesktopServices::openUrl(QUrl::fromLocalFile(m->url.left(m->url.lastIndexOf('/'))));
#endif
}
void SourceTable::item_renamed(Media* item) {
if (editing_item == item) {
MediaRename* mr = new MediaRename(item, "idk");
undo_stack.push(mr);
editing_item = NULL;
}
}
void SourceTable::stop_rename_timer() {
rename_timer.stop();
}
void SourceTable::rename_interval() {
stop_rename_timer();
if (hasFocus() && editing_item != NULL) {
edit(editing_index);
//editItem(editing_item, 0);
}
}
void SourceTable::item_click(const QModelIndex& index) {
if (selectionModel()->selectedRows().size() == 1 && index.column() == 0) {
Media* m = project_parent->item_to_media(index);
if (editing_item == m) {
rename_timer.start();
} else {
editing_item = m;
editing_index = index;
}
project_parent->sources_common->item_click(project_parent->item_to_media(index), index);
}
}
void SourceTable::mousePressEvent(QMouseEvent* event) {
stop_rename_timer();
project_parent->sources_common->mousePressEvent(event);
QTreeView::mousePressEvent(event);
}
void SourceTable::mouseDoubleClickEvent(QMouseEvent* e) {
stop_rename_timer();
QModelIndexList selected_items = selectionModel()->selectedRows();
if (selected_items.size() == 0) {
project_parent->import_dialog();
} else if (selected_items.size() == 1) {
Media* item = project_parent->item_to_media(selected_items.at(0));
switch (item->get_type()) {
case MEDIA_TYPE_FOOTAGE:
panel_footage_viewer->set_media(item);
panel_footage_viewer->setFocus();
break;
case MEDIA_TYPE_SEQUENCE:
undo_stack.push(new ChangeSequenceAction(item->to_sequence()));
break;
}
}
void SourceTable::mouseDoubleClickEvent(QMouseEvent* event) {
project_parent->sources_common->mouseDoubleClickEvent(event, selectionModel()->selectedRows());
}
void SourceTable::dragEnterEvent(QDragEnterEvent *event) {
@@ -231,79 +69,5 @@ void SourceTable::dragMoveEvent(QDragMoveEvent *event) {
}
void SourceTable::dropEvent(QDropEvent* event) {
const QMimeData* mimeData = event->mimeData();
const QModelIndex& drop_item = indexAt(event->pos());
Media* m = project_parent->item_to_media(drop_item);
if (mimeData->hasUrls()) {
// drag files in from outside
QList<QUrl> urls = mimeData->urls();
if (!urls.isEmpty()) {
QStringList paths;
for (int i=0;i<urls.size();i++) {
paths.append(urls.at(i).toLocalFile());
}
bool replace = false;
if (urls.size() == 1
&& drop_item.isValid()
&& m->get_type() == MEDIA_TYPE_FOOTAGE
&& !QFileInfo(paths.at(0)).isDir()
&& config.drop_on_media_to_replace
&& QMessageBox::question(this, "Replace Media", "You dropped a file onto '" + m->get_name() + "'. Would you like to replace it with the dropped file?", QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::Yes) {
replace = true;
project_parent->replace_media(m, paths.at(0));
}
if (!replace) {
QModelIndex parent;
if (drop_item.isValid()) {
if (m->get_type() == MEDIA_TYPE_FOLDER) {
parent = drop_item;
} else {
parent = drop_item.parent();
}
}
if (parent.isValid()) setExpanded(parent, true);
project_parent->process_file_list(paths, false, NULL, panel_project->item_to_media(parent));
}
}
event->acceptProposedAction();
} else {
event->ignore();
// dragging files within project
// if we dragged to the root OR dragged to a folder
if (!drop_item.isValid() || (drop_item.isValid() && m->get_type() == MEDIA_TYPE_FOLDER)) {
QVector<Media*> move_items;
QModelIndexList selected_items = selectionModel()->selectedRows();
for (int i=0;i<selected_items.size();i++) {
const QModelIndex& item = selected_items.at(i);
const QModelIndex& parent = item.parent();
Media* s = project_parent->item_to_media(item);
if (parent != drop_item && item != drop_item) {
bool ignore = false;
if (parent.isValid()) {
// if child belongs to a selected parent, assume the user is just moving the parent and ignore the child
QModelIndex par = parent;
while (par.isValid() && !ignore) {
for (int j=0;j<selected_items.size();j++) {
if (par == selected_items.at(j)) {
ignore = true;
break;
}
}
par = par.parent();
}
}
if (!ignore) {
move_items.append(s);
}
}
}
if (move_items.size() > 0) {
MediaMove* mm = new MediaMove(this);
mm->to = m;
mm->items = move_items;
undo_stack.push(mm);
}
}
}
project_parent->sources_common->dropEvent(this, event, indexAt(event->pos()), selectionModel()->selectedRows());
}
+3 -12
View File
@@ -12,26 +12,17 @@ class SourceTable : public QTreeView
{
Q_OBJECT
public:
SourceTable(QWidget* parent = 0);
SourceTable(QWidget* parent = 0);
Project* project_parent;
protected:
void mousePressEvent(QMouseEvent*);
void mouseDoubleClickEvent(QMouseEvent *event);
void mouseDoubleClickEvent(QMouseEvent *);
void dragEnterEvent(QDragEnterEvent *event);
void dragMoveEvent(QDragMoveEvent *event);
void dropEvent(QDropEvent *event);
private:
QTimer rename_timer;
Media* editing_item;
QModelIndex editing_index;
private slots:
void rename_interval();
void item_click(const QModelIndex& index);
void stop_rename_timer();
void item_renamed(Media *item);
void show_context_menu();
void create_seq_from_selected();
void reveal_in_browser();
void show_context_menu();
};
#endif // SOURCETABLE_H
+5 -2
View File
@@ -10,6 +10,7 @@
#include "panels/timeline.h"
#include "project/footage.h"
#include "ui/sourcetable.h"
#include "ui/sourceiconview.h"
#include "panels/effectcontrols.h"
#include "panels/viewer.h"
#include "project/undo.h"
@@ -265,8 +266,10 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) {
QVector<Media*> 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 || event->source() == panel_project->icon_view) {
QModelIndexList items = (event->source() == panel_project->tree_view)
? panel_project->tree_view->selectionModel()->selectedRows()
: panel_project->icon_view->selectionModel()->selectedIndexes();
media_list.resize(items.size());
for (int i=0;i<items.size();i++) {
media_list[i] = panel_project->item_to_media(items.at(i));
+2 -1
View File
@@ -19,6 +19,7 @@ class TimelineAction;
class QScrollBar;
class SetSelectionsCommand;
class QPainter;
class Media;
bool same_sign(int a, int b);
void draw_waveform(Clip* clip, FootageStream* ms, long media_length, QPainter* p, const QRect& clip_rect, int waveform_start, int waveform_limit, double zoom);
@@ -65,7 +66,7 @@ private:
// used for "right click ripple"
long rc_ripple_min;
long rc_ripple_max;
void* rc_reveal_media;
Media* rc_reveal_media;
QTimer tooltip_timer;
int tooltip_clip;