1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Linguist of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29#include "recentfiles.h"
30#include "globals.h"
31
32#include <QtCore/QDebug>
33#include <QtCore/QFileInfo>
34#include <QtCore/QSettings>
35#include <QtCore/QString>
36#include <QtCore/QStringList>
37
38QT_BEGIN_NAMESPACE
39
40static QString configKey()
41{
42 return settingPath("RecentlyOpenedFiles");
43}
44
45
46RecentFiles::RecentFiles(const int maxEntries)
47 : m_groupOpen(false),
48 m_clone1st(false),
49 m_maxEntries(maxEntries)
50{
51 m_timer.setSingleShot(true);
52 m_timer.setInterval(3 * 60 * 1000);
53 connect(asender: &m_timer, SIGNAL(timeout()), SLOT(closeGroup()));
54}
55
56/*
57 * The logic is as follows:
58 * - The most recent (i.e., topmost) item can be open ("in flux")
59 * - The item is closed by either a timeout (3 min or so) or a
60 * "terminal action" (e.g., closing all files)
61 * - While the item is open, modifications to the set of open files
62 * will modify that item instead of creating new items
63 * - If the open item is modified to be equal to an existing item,
64 * the existing item is deleted, but will be re-created when the
65 * open item is modified even further
66 * Cases (actions in parentheses are no-ops):
67 * - identical to top item => (do nothing)
68 * - closed, new item => insert at top, (clear marker)
69 * - closed, existing item => move to top, mark for cloning
70 * - open, new item, not marked => replace top, (clear marker)
71 * - open, new item, marked => insert at top, clear marker
72 * - open, existing item, not marked => replace top, delete copy, mark for cloning
73 * - open, existing item, marked => insert at top, delete copy, (mark for cloning)
74 * - closing clears marker
75 */
76void RecentFiles::addFiles(const QStringList &names)
77{
78 if (m_strLists.isEmpty() || names != m_strLists.first()) {
79 if (m_groupOpen && !m_clone1st)
80 // Group being open implies at least one item in the list
81 m_strLists.removeFirst();
82 m_groupOpen = true;
83
84 // We do *not* sort the actual entries, as that would destroy the user's
85 // chosen arrangement. However, we do the searching on sorted lists, so
86 // we throw out (probably) obsolete arrangements.
87 QList<QStringList> sortedLists = m_strLists;
88 for (int i = 0; i < sortedLists.size(); ++i)
89 sortedLists[i].sort();
90 QStringList sortedNames = names;
91 sortedNames.sort();
92
93 int index = sortedLists.indexOf(t: sortedNames);
94 if (index >= 0) {
95 m_strLists.removeAt(i: index);
96 m_clone1st = true;
97 } else {
98 if (m_strLists.count() >= m_maxEntries)
99 m_strLists.removeLast();
100 m_clone1st = false;
101 }
102 m_strLists.prepend(t: names);
103 }
104 m_timer.start();
105}
106
107void RecentFiles::closeGroup()
108{
109 m_timer.stop();
110 m_groupOpen = false;
111}
112
113void RecentFiles::readConfig()
114{
115 m_strLists.clear();
116 QVariant val = QSettings().value(key: configKey());
117 if (val.type() == QVariant::StringList) // Backwards compat to Qt < 4.5
118 foreach (const QString &s, val.toStringList())
119 m_strLists << QStringList(QFileInfo(s).canonicalFilePath());
120 else
121 foreach (const QVariant &v, val.toList())
122 m_strLists << v.toStringList();
123}
124
125void RecentFiles::writeConfig() const
126{
127 QList<QVariant> vals;
128 foreach (const QStringList &sl, m_strLists)
129 vals << sl;
130 QSettings().setValue(key: configKey(), value: vals);
131}
132
133QT_END_NAMESPACE
134

source code of qttools/src/linguist/linguist/recentfiles.cpp