started on #83 and added open recent menu

This commit is contained in:
itsmattkc
2018-07-13 20:12:41 +01:00
parent c957780a9c
commit 67944b4c2d
9 changed files with 141 additions and 193 deletions
+25 -7
View File
@@ -351,13 +351,31 @@ void ExportDialog::on_pushButton_clicked()
case FORMAT_GIF:
ext = "gif";
break;
case FORMAT_IMG:
// ext_name = "";
// ext = "";
// ext is determined from codec, but we prevent the switch from going to 'default' here
qDebug() << "[INFO] Image export not implemented yet";
QMessageBox::information(this, "Image sequence support coming soon", "Sorry, image sequence exporting is currently unsupported. Check back soon (or hound GitHub issue #83).", QMessageBox::Ok);
return;
case FORMAT_IMG:
switch (format_vcodecs.at(ui->vcodecCombobox->currentIndex())) {
case AV_CODEC_ID_BMP:
ext = "bmp";
break;
case AV_CODEC_ID_MJPEG:
ext = "jpg";
break;
case AV_CODEC_ID_JPEG2000:
ext = "jp2";
break;
case AV_CODEC_ID_PSD:
ext = "psd";
break;
case AV_CODEC_ID_PNG:
ext = "png";
break;
case AV_CODEC_ID_TIFF:
ext = "tif";
break;
default:
qDebug() << "[ERROR] Invalid codec selection for an image sequence";
QMessageBox::critical(this, "Invalid codec", "Couldn't determine output parameters for the selected codec. This is a bug, please contact the developers.", QMessageBox::Ok);
return;
}
break;
case FORMAT_MP3:
ext = "mp3";
+42
View File
@@ -94,12 +94,14 @@ MainWindow::MainWindow(QWidget *parent) :
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()));
connect(ui->menuEdit, SIGNAL(aboutToShow()), this, SLOT(editMenu_About_To_Be_Shown()));
connect(ui->menu_File, SIGNAL(aboutToShow()), this, SLOT(fileMenu_About_To_Be_Shown()));
QString data_dir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
if (!data_dir.isEmpty()) {
QDir dir(data_dir);
dir.mkpath(".");
if (dir.exists()) {
// detect auto-recovery file
autorecovery_filename = data_dir + "/autorecovery.ove";
if (QFile::exists(autorecovery_filename)) {
if (QMessageBox::question(NULL, "Auto-recovery", "Olive didn't close properly and an autorecovery file was detected. Would you like to open it?", QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) {
@@ -110,6 +112,22 @@ MainWindow::MainWindow(QWidget *parent) :
autorecovery_timer.setInterval(60000);
QObject::connect(&autorecovery_timer, SIGNAL(timeout()), this, SLOT(autorecover_interval()));
autorecovery_timer.start();
// search for open recents list
recent_proj_file = data_dir + "/recents";
QFile f(recent_proj_file);
if (f.exists() && f.open(QFile::ReadOnly | QFile::Text)) {
QTextStream text_stream(&f);
while (true) {
QString line = text_stream.readLine();
if (line.isNull()) {
break;
} else {
recent_projects.append(line);
}
}
f.close();
}
}
}
}
@@ -556,3 +574,27 @@ void MainWindow::on_actionFolder_triggered()
{
panel_project->new_folder();
}
void MainWindow::fileMenu_About_To_Be_Shown() {
if (recent_projects.size() > 0) {
ui->menuOpen_Recent->clear();
ui->menuOpen_Recent->setEnabled(true);
for (int i=0;i<recent_projects.size();i++) {
QAction* action = ui->menuOpen_Recent->addAction(recent_projects.at(i));
action->setData(i);
connect(action, SIGNAL(triggered()), this, SLOT(load_recent_project()));
}
ui->menuOpen_Recent->addSeparator();
QAction* clear_action = ui->menuOpen_Recent->addAction("Clear Recent List");
connect(clear_action, SIGNAL(triggered()), panel_project, SLOT(clear_recent_projects()));
} else {
ui->menuOpen_Recent->setEnabled(false);
}
}
void MainWindow::load_recent_project() {
if (can_close_project()) {
project_url = recent_projects.at(static_cast<QAction*>(sender())->data().toInt());
panel_project->load_project();
}
}
+5 -1
View File
@@ -18,7 +18,7 @@ class MainWindow : public QMainWindow
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
~MainWindow();
protected:
void closeEvent(QCloseEvent *);
@@ -146,6 +146,10 @@ private slots:
void editMenu_About_To_Be_Shown();
void fileMenu_About_To_Be_Shown();
void load_recent_project();
private:
Ui::MainWindow *ui;
void setup_layout();
+11
View File
@@ -40,8 +40,14 @@
<addaction name="actionSequence"/>
<addaction name="actionFolder"/>
</widget>
<widget class="QMenu" name="menuOpen_Recent">
<property name="title">
<string>Open Recent</string>
</property>
</widget>
<addaction name="menu_New"/>
<addaction name="action_Open_Project"/>
<addaction name="menuOpen_Recent"/>
<addaction name="action_Save_Project"/>
<addaction name="actionSave_Project_As"/>
<addaction name="separator"/>
@@ -589,6 +595,11 @@
<string>Folder</string>
</property>
</action>
<action name="actionClear_Recent_List">
<property name="text">
<string>Clear Recent List</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>
+51 -184
View File
@@ -12,6 +12,7 @@
#include "project/effect.h"
#include "effects/transition.h"
#include "io/previewgenerator.h"
#include "mainwindow.h"
#include <QFileDialog>
#include <QString>
@@ -30,8 +31,12 @@ extern "C" {
#include <libavcodec/avcodec.h>
}
#define MAXIMUM_RECENT_PROJECTS 10
bool project_changed = false;
QString project_url = "";
QStringList recent_projects;
QString recent_proj_file;
Project::Project(QWidget *parent) :
QDockWidget(parent),
@@ -647,190 +652,6 @@ void Project::load_project() {
cont = load_worker(file, stream, MEDIA_TYPE_SEQUENCE);
}
/*int state = LOAD_STATE_IDLE;
while (!error && !stream.atEnd()) {
stream.readNext();
switch (state) {
case LOAD_STATE_IDLE:
if (stream.isStartElement()) {
if (stream.name() == "footage") {
for (int j=0;j<stream.attributes().size();j++) {
const QXmlStreamAttribute& attr = stream.attributes().at(j);
if (attr.name() == "id") {
temp_media_id = attr.value().toInt();
}
}
state = LOAD_STATE_FOOTAGE;
} else if (stream.name() == "sequence") {
temp_seq = new Sequence();
state = LOAD_STATE_SEQUENCE;
}
}
break;
case LOAD_STATE_FOOTAGE:
if (stream.isEndElement() && stream.name() == "footage") {
Media* m = import_file(temp_url);
if (m == NULL) {
error = (QMessageBox::warning(this, "Source load error", "Couldn't load source file '" + temp_url + "'. This is unsupported and may lead to crashes. Do you wish to continue?", QMessageBox::Yes, QMessageBox::No) == QMessageBox::No);
} else {
m->save_id = temp_media_id;
m->name = temp_name;
temp_media_list.append(m);
}
state = LOAD_STATE_IDLE;
} else if (stream.isStartElement()) {
if (stream.name() == "name") {
stream.readNext();
temp_name = stream.text().toString();
} else if (stream.name() == "url") {
stream.readNext();
temp_url = stream.text().toString();
}
}
break;
case LOAD_STATE_SEQUENCE:
if (stream.isEndElement() && stream.name() == "sequence") {
// correct IDs
for (int i=0;i<temp_seq->clip_count();i++) {
Clip* clip = temp_seq->get_clip(i);
// correct IDs in linked clips
for (int j=0;j<clip->linked.size();j++) {
bool found = false;
for (int k=0;k<temp_seq->clip_count();k++) {
if (temp_seq->get_clip(k)->load_id == clip->linked.at(j)) {
clip->linked[j] = k;
found = true;
break;
}
}
if (!found) {
if (QMessageBox::warning(this, "Corrupt clip link", "Project contains a non-existent clip link. It may be corrupt. Would you like to load it anyway?", QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) {
clip->linked.removeAt(j);
} else {
error = true;
}
}
}
}
temp_seq->reset_undo();
new_sequence(temp_seq, false);
state = LOAD_STATE_IDLE;
} else if (stream.isStartElement()) {
if (stream.name() == "name") {
stream.readNext();
temp_seq->name = stream.text().toString();
} else if (stream.name() == "width") {
stream.readNext();
temp_seq->width = stream.text().toInt();
} else if (stream.name() == "height") {
stream.readNext();
temp_seq->height = stream.text().toInt();
} else if (stream.name() == "framerate") {
stream.readNext();
temp_seq->frame_rate = stream.text().toFloat();
} else if (stream.name() == "afreq") {
stream.readNext();
temp_seq->audio_frequency = stream.text().toInt();
} else if (stream.name() == "alayout") {
stream.readNext();
temp_seq->audio_layout = stream.text().toInt();
} else if (stream.name() == "clip") {
temp_clip = new Clip();
temp_clip->sequence = temp_seq;
state = LOAD_STATE_CLIP;
}
}
break;
case LOAD_STATE_CLIP:
if (stream.isEndElement() && stream.name() == "clip") {
temp_seq->add_clip(temp_clip);
state = LOAD_STATE_SEQUENCE;
} else if (stream.isStartElement()) {
if (stream.name() == "name") {
stream.readNext();
temp_clip->name = stream.text().toString();
} else if (stream.name() == "id") {
stream.readNext();
temp_clip->load_id = stream.text().toInt();
} else if (stream.name() == "clipin") {
stream.readNext();
temp_clip->clip_in = stream.text().toInt();
} else if (stream.name() == "in") {
stream.readNext();
temp_clip->timeline_in = stream.text().toInt();
} else if (stream.name() == "out") {
stream.readNext();
temp_clip->timeline_out = stream.text().toInt();
} else if (stream.name() == "track") {
stream.readNext();
temp_clip->track = stream.text().toInt();
} else if (stream.name() == "opening") {
stream.readNext();
temp_clip->opening_transition = create_transition(stream.text().toInt(), temp_clip);
} else if (stream.name() == "closing") {
stream.readNext();
temp_clip->closing_transition = create_transition(stream.text().toInt(), temp_clip);
} else if (stream.name() == "color") {
for (int j=0;j<stream.attributes().size();j++) {
const QXmlStreamAttribute& attr = stream.attributes().at(j);
if (attr.name().toString() == QLatin1String("r")) {
temp_clip->color_r = attr.value().toInt();
} else if (attr.name().toString() == QLatin1String("g")) {
temp_clip->color_g = attr.value().toInt();
} else if (attr.name().toString() == QLatin1String("b")) {
temp_clip->color_b = attr.value().toInt();
}
}
} else if (stream.name() == "media") {
stream.readNext();
for (int i=0;i<temp_media_list.size();i++) {
Media* m = temp_media_list.at(i);
if (m->save_id == stream.text().toInt()) {
temp_clip->media = m;
break;
}
}
} else if (stream.name() == "stream") {
stream.readNext();
int stream_index = stream.text().toInt();
if (temp_clip->media != NULL) {
temp_clip->media_stream = temp_clip->media->get_stream_from_file_index(stream_index);
if (temp_clip->media_stream == NULL) {
if (QMessageBox::warning(this, "Source changed", "Source file '" + temp_clip->media->url + "' appears to have changed since last saving the project. This is unsupported and may lead to crashes. Do you wish to continue?", QMessageBox::Yes, QMessageBox::No) == QMessageBox::No) {
error = true;
}
}
}
} else if (stream.name() == "linked") {
state = LOAD_STATE_CLIP_LINKS;
} else if (stream.name() == "effect") {
int effect_id = -1;
for (int j=0;j<stream.attributes().size();j++) {
const QXmlStreamAttribute& attr = stream.attributes().at(j);
if (attr.name().toString() == QLatin1String("id")) {
effect_id = attr.value().toInt();
}
}
if (effect_id != -1) {
Effect* e = create_effect(effect_id, temp_clip);
e->load(&stream);
temp_clip->effects.append(e);
}
}
}
break;
case LOAD_STATE_CLIP_LINKS:
if (stream.name() == "linked" && stream.isEndElement()) {
state = LOAD_STATE_CLIP;
} else if (stream.isStartElement() && stream.name() == "link") {
stream.readNext();
temp_clip->linked.append(stream.text().toInt());
}
break;
}
}*/
if (!cont) {
QMessageBox::critical(this, "Project Load Error", "Error loading project: " + error_str, QMessageBox::Ok);
} else if (stream.hasError()) {
@@ -845,6 +666,10 @@ void Project::load_project() {
} else {
new_project();
}
file.close();
add_recent_project(project_url);
}
void Project::save_folder(QXmlStreamWriter& stream, QTreeWidgetItem* parent, int type) {
@@ -970,5 +795,47 @@ void Project::save_project() {
file.close();
add_recent_project(project_url);
project_changed = false;
}
void Project::save_recent_projects() {
// save to file
QFile f(recent_proj_file);
if (f.open(QFile::WriteOnly | QFile::Truncate | QFile::Text)) {
QTextStream out(&f);
for (int i=0;i<recent_projects.size();i++) {
if (i > 0) {
out << "\n";
}
out << recent_projects.at(i);
}
f.close();
} else {
qDebug() << "[WARNING] Could not save recent projects";
}
}
void Project::clear_recent_projects() {
recent_projects.clear();
save_recent_projects();
}
void Project::add_recent_project(QString url) {
bool found = false;
for (int i=0;i<recent_projects.size();i++) {
if (url == recent_projects.at(i)) {
found = true;
recent_projects.move(i, 0);
break;
}
}
if (!found) {
recent_projects.insert(0, url);
if (recent_projects.size() > MAXIMUM_RECENT_PROJECTS) {
recent_projects.removeLast();
}
}
save_recent_projects();
}
+5
View File
@@ -29,6 +29,8 @@ class Project;
extern bool project_changed;
extern QString project_url;
extern QStringList recent_projects;
extern QString recent_proj_file;
class Project : public QDockWidget
{
@@ -73,8 +75,11 @@ private:
QVector<QTreeWidgetItem*> loaded_folders;
QVector<Media*> loaded_media;
QTreeWidgetItem* find_loaded_folder_by_id(int id);
void add_recent_project(QString url);
void save_recent_projects();
private slots:
void rename_media(QTreeWidgetItem* item, int column);
void clear_recent_projects();
};
#endif // PROJECT_H
+1
View File
@@ -267,4 +267,5 @@ void set_sequence(Sequence* s) {
sequence = s;
panel_timeline->update_sequence();
panel_viewer->update_sequence();
panel_timeline->setFocus();
}
+1
View File
@@ -41,6 +41,7 @@ void SourceTable::mousePressEvent(QMouseEvent* event) {
}
void SourceTable::mouseDoubleClickEvent(QMouseEvent* ) {
stop_rename_timer();
if (selectedItems().count() == 0) {
panel_project->import_dialog();
} else if (selectedItems().count() == 1) {
-1
View File
@@ -985,7 +985,6 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) {
for (int i=0;i<track_size;i++) {
int clip_index = getClipIndexFromCoords(panel_timeline->drag_frame_start, panel_timeline->split_tracks[i]);
if (clip_index > -1) {
Clip* c = sequence->get_clip(clip_index);
QVector<int> tracks = panel_timeline->get_tracks_of_linked_clips(clip_index);
for (int j=0;j<tracks.size();j++) {
// check if this track is already included