1 /*
2 
3 Pencil2D - Traditional Animation Software
4 Copyright (C) 2005-2007 Patrick Corrieri & Pascal Naidon
5 Copyright (C) 2012-2020 Matthew Chiawen Chang
6 
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; version 2 of the License.
10 
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15 
16 */
17 
18 #include "recentfilemenu.h"
19 
20 #include <QSettings>
21 #include <QVariant>
22 #include <QDebug>
23 
24 
RecentFileMenu(QString title,QWidget * parent)25 RecentFileMenu::RecentFileMenu(QString title, QWidget *parent) :
26     QMenu(title, parent)
27 {
28     mClearSeparator = new QAction(this);
29     mClearSeparator->setSeparator(true);
30 
31     mClearAction = new QAction(tr("Clear", "Clear Recent File menu"), this); // share the same translation
32     mEmptyAction = new QAction(tr("Empty", "Showing when Recent File Menu is empty"), this);
33     mEmptyAction->setEnabled(false);
34 }
35 
~RecentFileMenu()36 RecentFileMenu::~RecentFileMenu()
37 {
38     delete mClearSeparator;
39     delete mClearAction;
40     delete mEmptyAction;
41 }
42 
clear()43 void RecentFileMenu::clear()
44 {
45     for (const QString& filename : mRecentFiles)
46     {
47         removeRecentFile(filename);
48     }
49     removeAction(mClearSeparator);
50     removeAction(mClearAction);
51     mRecentFiles.clear();
52     mRecentActions.clear();
53     addAction(mEmptyAction);
54 }
55 
setRecentFiles(const QStringList & filenames)56 void RecentFileMenu::setRecentFiles(const QStringList& filenames)
57 {
58     clear();
59 
60     // Iterate in reverse because items are prepended to the list when first added
61     for (auto filename = filenames.crbegin(); filename != filenames.crend(); filename++)
62     {
63         if (!filename->isEmpty())
64         {
65             addRecentFile(*filename);
66         }
67     }
68 }
69 
loadFromDisk()70 bool RecentFileMenu::loadFromDisk()
71 {
72     QSettings settings(PENCIL2D, PENCIL2D);
73     QVariant recent = settings.value("RecentFiles");
74     if (recent.isNull())
75     {
76         clear();
77         return false;
78     }
79     QStringList recentFileList = recent.toStringList();
80     setRecentFiles(recentFileList);
81     return true;
82 }
83 
saveToDisk()84 bool RecentFileMenu::saveToDisk()
85 {
86     QSettings settings(PENCIL2D, PENCIL2D);
87     settings.setValue("RecentFiles", QVariant(mRecentFiles));
88     return true;
89 }
90 
addRecentFile(QString filename)91 void RecentFileMenu::addRecentFile(QString filename)
92 {
93     if (mRecentFiles.contains(filename))
94     {
95         removeRecentFile(filename);
96     }
97 
98     while (mRecentFiles.size() >= MAX_RECENT_FILES)
99     {
100         removeRecentFile(mRecentFiles.last());
101     }
102 
103     mRecentFiles.prepend(filename);
104 
105     QAction* action = new QAction(filename, this);
106     action->setData(QVariant(filename));
107 
108     QObject::connect(action, &QAction::triggered, this, &RecentFileMenu::onRecentFileTriggered);
109 
110     mRecentActions.emplace(filename, action);
111     if (mRecentFiles.size() == 1)
112     {
113         removeAction(mEmptyAction);
114         addAction(action);
115         addAction(mClearSeparator);
116         addAction(mClearAction);
117         QObject::connect(mClearAction, &QAction::triggered, [this]
118         {
119             clear();
120             saveToDisk();
121         });
122     }
123     else
124     {
125         QString firstFile = mRecentFiles[1];
126         insertAction(mRecentActions[firstFile], action);
127     }
128 }
129 
removeRecentFile(QString filename)130 void RecentFileMenu::removeRecentFile(QString filename)
131 {
132     if (mRecentFiles.contains(filename))
133     {
134         QAction* action = mRecentActions.at(filename);
135         removeAction(action);
136 
137         mRecentActions.erase(filename);
138         mRecentFiles.removeOne(filename);
139         delete action;
140     }
141 }
142 
onRecentFileTriggered()143 void RecentFileMenu::onRecentFileTriggered()
144 {
145     QAction* action = static_cast<QAction*>(QObject::sender());
146     QString filePath = action->data().toString();
147 
148     if (!filePath.isEmpty())
149     {
150         emit loadRecentFile(filePath);
151     }
152 }
153