Skip to content

Commit

Permalink
separate Projects from Recent
Browse files Browse the repository at this point in the history
The goal is to prevent projects unexpectedly disappearing in the Shotcut
UI because a lot of files have been opened. A number of users have
expressed alarm or concern for missing projects. Thus, projects are
saved indefinitely and with no limit. But also still listed in Recent
because Recent represents user file activity regardless of type.

Projects are saved under config key `projects` but still in the
`recent.ini` file in the app data dir.
  • Loading branch information
ddennedy committed Oct 6, 2024
1 parent 4a49c74 commit fbd2c56
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 25 deletions.
14 changes: 12 additions & 2 deletions src/docks/recentdock.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2023 Meltytech, LLC
* Copyright (c) 2012-2024 Meltytech, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand All @@ -26,7 +26,7 @@
#include <QMenu>
#include <Logger.h>

static const int MaxItems = 100;
static const int MaxItems = 200;

RecentDock::RecentDock(QWidget *parent) :
QDockWidget(parent),
Expand Down Expand Up @@ -89,6 +89,11 @@ void RecentDock::add(const QString &s)
while (m_recent.count() > MaxItems)
m_recent.removeLast();
Settings.setRecent(m_recent);
if (filePath.endsWith(".mlt")) {
auto projects = Settings.projects();
projects.prepend(filePath);
Settings.setProjects(projects);
}
}

void RecentDock::on_listWidget_activated(const QModelIndex &i)
Expand Down Expand Up @@ -138,6 +143,11 @@ void RecentDock::on_actionDelete_triggered()
m_recent.removeAt(row);
Settings.setRecent(m_recent);
m_model.removeRow(row);
if (url.endsWith(".mlt")) {
auto ls = Settings.projects();
if (ls.removeAll(url) > 0)
Settings.setProjects(ls);
}
emit deleted(url);
}
}
Expand Down
25 changes: 25 additions & 0 deletions src/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ static QScopedPointer<ShotcutSettings> instance;
static QString appDataForSession;
static const int kMaximumTrackHeight = 125;
static const QString kRecentKey("recent");
static const QString kProjectsKey("projects");

ShotcutSettings &ShotcutSettings::singleton()
{
Expand Down Expand Up @@ -179,6 +180,30 @@ void ShotcutSettings::setRecent(const QStringList &ls)
m_recent.setValue(kRecentKey, ls);
}

QStringList ShotcutSettings::projects()
{
auto ls = m_recent.value(kProjectsKey).toStringList();
if (ls.isEmpty()) {
for (auto &r : recent()) {
if (r.endsWith(".mlt"))
ls << r;
}
// Prevent entering this block repeatedly
if (ls.isEmpty())
ls << QString();
setProjects(ls);
}
return ls;
}

void ShotcutSettings::setProjects(const QStringList &ls)
{
if (ls.isEmpty())
m_recent.remove(kProjectsKey);
else if (!clearRecent())
m_recent.setValue(kProjectsKey, ls);
}

QString ShotcutSettings::theme() const
{
return settings.value("theme", "dark").toString();
Expand Down
2 changes: 2 additions & 0 deletions src/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ class ShotcutSettings : public QObject
void setSavePath(const QString &);
QStringList recent() const;
void setRecent(const QStringList &);
QStringList projects();
void setProjects(const QStringList &);
QString theme() const;
void setTheme(const QString &);
QThread::Priority jobPriority() const;
Expand Down
35 changes: 32 additions & 3 deletions src/widgets/newprojectfolder.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2022 Meltytech, LLC
* Copyright (c) 2018-2024 Meltytech, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -111,8 +111,8 @@ bool NewProjectFolder::event(QEvent *event)
void NewProjectFolder::updateRecentProjects()
{
m_model.clear();
foreach (QString s, Settings.recent()) {
if (s.endsWith(".mlt")) {
for (auto &s : Settings.projects()) {
if (!s.isEmpty()) {
QStandardItem *item = new QStandardItem(Util::baseName(s));
item->setToolTip(QDir::toNativeSeparators(s));
m_model.appendRow(item);
Expand Down Expand Up @@ -293,3 +293,32 @@ void NewProjectFolder::on_recentListView_doubleClicked(const QModelIndex &index)
{
on_recentListView_clicked(index);
}

void NewProjectFolder::on_recentListView_customContextMenuRequested(const QPoint &pos)
{
if (ui->recentListView->currentIndex().isValid()) {
QMenu menu(this);
menu.addAction(ui->actionRecentRemove);
menu.exec(ui->recentListView->mapToGlobal(pos));
}
}


void NewProjectFolder::on_actionRecentRemove_triggered()
{
if (ui->recentListView->currentIndex().isValid()) {
auto index = ui->recentListView->currentIndex();
auto data = m_model.itemData(index);
auto projects = Settings.projects();
auto url = data[Qt::ToolTipRole].toString();
url = QDir::fromNativeSeparators(url);
if (projects.removeAll(url) > 0) {
m_model.removeRow(index.row());
Settings.setProjects(projects);
emit deletedProject(url);
} else {
LOG_WARNING() << "Failed to remove project" << url;
}
}
}

9 changes: 8 additions & 1 deletion src/widgets/newprojectfolder.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Meltytech, LLC
* Copyright (c) 2018-2024 Meltytech, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -47,6 +47,9 @@ class NewProjectFolder : public QWidget
public slots:
void updateRecentProjects();

signals:
void deletedProject(const QString &);

private slots:
void on_projectsFolderButton_clicked();

Expand All @@ -66,6 +69,10 @@ private slots:

void on_recentListView_doubleClicked(const QModelIndex &index);

void on_recentListView_customContextMenuRequested(const QPoint &pos);

void on_actionRecentRemove_triggered();

private:
void setColors();
void setProjectFolderButtonText(const QString &text);
Expand Down
49 changes: 30 additions & 19 deletions src/widgets/newprojectfolder.ui
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
<enum>QFrame::Shape::Box</enum>
</property>
<property name="lineWidth">
<number>2</number>
Expand Down Expand Up @@ -58,10 +58,10 @@
</font>
</property>
<property name="text">
<string>Recent Projects</string>
<string>Projects</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
<property name="margin">
<number>4</number>
Expand All @@ -85,11 +85,14 @@
</property>
<item>
<widget class="QListView" name="recentListView">
<property name="contextMenuPolicy">
<enum>Qt::ContextMenuPolicy::CustomContextMenu</enum>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
<enum>QFrame::Shape::NoFrame</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
<set>QAbstractItemView::EditTrigger::NoEditTriggers</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
Expand All @@ -108,7 +111,7 @@
<item row="0" column="0">
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::Panel</enum>
<enum>QFrame::Shape::Panel</enum>
</property>
<property name="lineWidth">
<number>2</number>
Expand Down Expand Up @@ -140,7 +143,7 @@
<string>New Project</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
<property name="margin">
<number>4</number>
Expand All @@ -156,14 +159,14 @@
<string>Projects folder</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
<item row="5" column="1">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
Expand Down Expand Up @@ -232,7 +235,7 @@ a project file with the same name.</string>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
Expand All @@ -250,7 +253,7 @@ a project file with the same name.</string>
<string>Video mode</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
Expand All @@ -260,7 +263,7 @@ a project file with the same name.</string>
<string>Project name</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
Expand All @@ -273,13 +276,13 @@ a project file with the same name.</string>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
<enum>QFrame::Shape::NoFrame</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
<enum>Qt::ScrollBarPolicy::ScrollBarAlwaysOff</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContents</enum>
<enum>QAbstractScrollArea::SizeAdjustPolicy::AdjustToContents</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
Expand All @@ -289,8 +292,8 @@ a project file with the same name.</string>
<rect>
<x>0</x>
<y>0</y>
<width>146</width>
<height>144</height>
<width>153</width>
<height>220</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
Expand All @@ -312,7 +315,7 @@ a project file with the same name.</string>
<string>Automatic means the resolution and frame rate are based on the &lt;b&gt;first&lt;/b&gt; file you &lt;b&gt;add&lt;/b&gt; to your project. If the first file is not a video clip (for example, image or audio), then it will be 1920x1080p 25 fps.</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set>
</property>
<property name="wordWrap">
<bool>true</bool>
Expand All @@ -332,7 +335,7 @@ a project file with the same name.</string>
<item row="1" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
Expand Down Expand Up @@ -364,6 +367,14 @@ a project file with the same name.</string>
<string>Remove...</string>
</property>
</action>
<action name="actionRecentRemove">
<property name="text">
<string>Remove</string>
</property>
<property name="menuRole">
<enum>QAction::MenuRole::NoRole</enum>
</property>
</action>
</widget>
<tabstops>
<tabstop>projectsFolderButton</tabstop>
Expand Down

0 comments on commit fbd2c56

Please sign in to comment.