1 /*
2     SPDX-FileCopyrightText: 2008, 2009 Fredrik Höglund <fredrik@kde.org>
3     SPDX-FileCopyrightText: 2013-2014 Eike Hein <hein@kde.org>
4 
5     SPDX-License-Identifier: GPL-2.0-or-later
6 */
7 
8 #include "labelgenerator.h"
9 
10 #include <KFilePlacesModel>
11 #include <KShell>
12 
13 #include "foldermodel.h"
14 
15 int LabelGenerator::s_instanceCount = 0;
16 KFilePlacesModel *LabelGenerator::s_placesModel = nullptr;
17 
LabelGenerator(QObject * parent)18 LabelGenerator::LabelGenerator(QObject *parent)
19     : QObject(parent)
20     , m_rtl(false)
21     , m_labelMode(1)
22 {
23     ++s_instanceCount;
24 }
25 
~LabelGenerator()26 LabelGenerator::~LabelGenerator()
27 {
28     --s_instanceCount;
29     if (!s_instanceCount) {
30         delete s_placesModel;
31         s_placesModel = nullptr;
32     }
33 }
34 
folderModel() const35 FolderModel *LabelGenerator::folderModel() const
36 {
37     return m_folderModel.data();
38 }
39 
setFolderModel(FolderModel * folderModel)40 void LabelGenerator::setFolderModel(FolderModel *folderModel)
41 {
42     if (m_folderModel.data() != folderModel) {
43         if (m_folderModel.data()) {
44             disconnect(m_folderModel.data(), nullptr, this, nullptr);
45         }
46 
47         m_folderModel = folderModel;
48 
49         connect(m_folderModel.data(), &FolderModel::listingCompleted, this, &LabelGenerator::updateDisplayLabel);
50         connect(m_folderModel.data(), &FolderModel::listingCanceled, this, &LabelGenerator::updateDisplayLabel);
51 
52         Q_EMIT folderModelChanged();
53         updateDisplayLabel();
54     }
55 }
56 
rtl() const57 bool LabelGenerator::rtl() const
58 {
59     return m_rtl;
60 }
61 
setRtl(bool rtl)62 void LabelGenerator::setRtl(bool rtl)
63 {
64     if (rtl != m_rtl) {
65         m_rtl = rtl;
66         Q_EMIT rtlChanged();
67         updateDisplayLabel();
68     }
69 }
70 
labelMode() const71 int LabelGenerator::labelMode() const
72 {
73     return m_labelMode;
74 }
75 
setLabelMode(int mode)76 void LabelGenerator::setLabelMode(int mode)
77 {
78     if (mode != m_labelMode) {
79         m_labelMode = mode;
80         Q_EMIT labelModeChanged();
81         updateDisplayLabel();
82     }
83 }
84 
labelText() const85 QString LabelGenerator::labelText() const
86 {
87     return m_labelText;
88 }
89 
setLabelText(const QString & text)90 void LabelGenerator::setLabelText(const QString &text)
91 {
92     if (text != m_labelText) {
93         m_labelText = text;
94         Q_EMIT labelTextChanged();
95         updateDisplayLabel();
96     }
97 }
98 
displayLabel() const99 QString LabelGenerator::displayLabel() const
100 {
101     return m_displayLabel;
102 }
103 
updateDisplayLabel()104 void LabelGenerator::updateDisplayLabel()
105 {
106     const QString displayLabel = generatedDisplayLabel();
107     if (m_displayLabel != displayLabel) {
108         m_displayLabel = displayLabel;
109         Q_EMIT displayLabelChanged();
110     }
111 }
112 
generatedDisplayLabel()113 QString LabelGenerator::generatedDisplayLabel()
114 {
115     if (!m_folderModel) {
116         return QString();
117     }
118 
119     QUrl url = m_folderModel->resolvedUrl();
120 
121     if (m_labelMode == 1 /* Default */) {
122         if (url.path().length() <= 1) {
123             const KFileItem &rootItem = m_folderModel->rootItem();
124 
125             if (rootItem.text() != QLatin1String(".")) {
126                 return rootItem.text();
127             }
128         }
129 
130         QString label(url.toDisplayString(QUrl::PreferLocalFile | QUrl::StripTrailingSlash));
131 
132         if (!s_placesModel) {
133             s_placesModel = new KFilePlacesModel();
134         }
135 
136         connectPlacesModel();
137 
138         const QModelIndex index = s_placesModel->closestItem(url);
139 
140         if (index.isValid()) {
141             QString root = s_placesModel->url(index).toDisplayString(QUrl::PreferLocalFile | QUrl::StripTrailingSlash);
142 
143             label = label.right(label.length() - root.length());
144 
145             if (!label.isEmpty()) {
146                 if (label.at(0) == QLatin1Char('/')) {
147                     label.remove(0, 1);
148                 }
149 
150                 if (m_rtl) {
151                     label.prepend(QLatin1String(" < "));
152                 } else {
153                     label.prepend(QLatin1String(" > "));
154                 }
155             }
156 
157             label.prepend(s_placesModel->text(index));
158         }
159 
160         return label;
161     } else if (m_labelMode == 2 /* Full path */) {
162         return QUrl(url).toDisplayString(QUrl::PreferLocalFile | QUrl::StripTrailingSlash);
163     } else if (m_labelMode == 3 /* Custom title */) {
164         return m_labelText;
165     }
166 
167     return QString();
168 }
169 
connectPlacesModel()170 void LabelGenerator::connectPlacesModel()
171 {
172     connect(s_placesModel, &KFilePlacesModel::rowsInserted, this, &LabelGenerator::updateDisplayLabel, Qt::UniqueConnection);
173     connect(s_placesModel, &KFilePlacesModel::rowsRemoved, this, &LabelGenerator::updateDisplayLabel, Qt::UniqueConnection);
174     connect(s_placesModel, &KFilePlacesModel::dataChanged, this, &LabelGenerator::updateDisplayLabel, Qt::UniqueConnection);
175 }
176