2 * Copyright (C) 2013 Canonical, Ltd.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 * Author: Nick Dedekind <nick.dedekind@canonical.com>
19#include "indicatorsmanager.h"
30class IndicatorsManager::IndicatorData
33 IndicatorData(const QString& name, const QFileInfo& fileInfo)
35 , m_fileInfo(fileInfo)
44 Indicator::Ptr m_indicator;
47IndicatorsManager::IndicatorsManager(QObject* parent)
52 auto upstartsession = qgetenv("UPSTART_SESSION");
53 if (!upstartsession.isNull()) {
54 DBusConnection * conn = NULL;
55 conn = dbus_connection_open(upstartsession.constData(), NULL);
57 m_upstart = nih_dbus_proxy_new(NULL, conn,
61 dbus_connection_unref(conn);
65 if (m_upstart != NULL) {
66 m_upstart->auto_start = FALSE;
70IndicatorsManager::~IndicatorsManager()
74 if (m_upstart != NULL) {
75 nih_unref(m_upstart, NULL);
80void IndicatorsManager::load()
83 QStringList xdgLocations = shellDataDirs();//QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
85 m_fsWatcher.reset(new QFileSystemWatcher(this));
87 Q_FOREACH(const QString& xdgLocation, xdgLocations)
89 QString indicator_path = QDir::cleanPath(xdgLocation + "/unity/indicators");
90 QDir indicator_dir(indicator_path);
91 if (indicator_dir.exists())
93 // watch folder for changes.
94 m_fsWatcher->addPath(indicator_path);
96 loadDir(indicator_dir);
100 QObject::connect(m_fsWatcher.data(), SIGNAL(directoryChanged(const QString&)), this, SLOT(onDirectoryChanged(const QString&)));
101 QObject::connect(m_fsWatcher.data(), SIGNAL(fileChanged(const QString&)), this, SLOT(onFileChanged(const QString&)));
105void IndicatorsManager::onDirectoryChanged(const QString& directory)
107 loadDir(QDir(directory));
110void IndicatorsManager::onFileChanged(const QString& file)
112 QFileInfo file_info(file);
113 if (!file_info.exists())
115 unloadFile(file_info);
120 loadFile(QFileInfo(file));
124void IndicatorsManager::loadDir(const QDir& dir)
126 startVerify(dir.canonicalPath());
128 QFileInfoList indicator_files = dir.entryInfoList(QStringList(), QDir::Files|QDir::NoDotAndDotDot);
129 Q_FOREACH(const QFileInfo& indicator_file, indicator_files)
131 loadFile(indicator_file);
134 endVerify(dir.canonicalPath());
137void IndicatorsManager::loadFile(const QFileInfo& file_info)
139 QSettings indicator_settings(file_info.absoluteFilePath(), QSettings::IniFormat, this);
140 QString name = indicator_settings.value("Indicator Service/Name").toString();
142 auto iter = m_indicatorsData.find(name);
143 if (iter != m_indicatorsData.end())
145 QString newFileInfoDir = QDir::cleanPath(file_info.canonicalPath());
146 IndicatorData* currentData = (*iter);
147 currentData->m_verified = true;
149 int file_info_location = -1;
150 int current_data_location = -1;
152 QString currentDataDir = QDir::cleanPath(currentData->m_fileInfo.canonicalPath());
154 // if we've already got this indicator, we need to make sure we're not overwriting data which is
155 // from a lower priority standard path
156 QStringList xdgLocations = shellDataDirs();
157 for (int i = 0; i < xdgLocations.size(); i++)
159 QString indicatorDir = QDir::cleanPath(xdgLocations[i] + "/unity/indicators");
161 if (newFileInfoDir == indicatorDir)
163 file_info_location = i;
165 if (currentDataDir == indicatorDir)
167 current_data_location = i;
170 if (file_info_location != -1 && current_data_location != -1)
176 // file location is higher (or of equal) priority. overwrite.
177 if (file_info_location <= current_data_location &&
178 file_info != currentData->m_fileInfo)
180 currentData->m_fileInfo = file_info;
181 Q_EMIT indicatorLoaded(name);
186 IndicatorData* data = new IndicatorData(name, file_info);
187 data->m_verified = true;
188 m_indicatorsData[name]= data;
189 Q_EMIT indicatorLoaded(name);
193void IndicatorsManager::unload()
195 QHashIterator<QString, IndicatorData*> iter(m_indicatorsData);
196 while(iter.hasNext())
199 Q_EMIT indicatorAboutToBeUnloaded(iter.key());
202 qDeleteAll(m_indicatorsData);
203 m_indicatorsData.clear();
208void IndicatorsManager::unloadFile(const QFileInfo& file)
210 QMutableHashIterator<QString, IndicatorData*> iter(m_indicatorsData);
211 while(iter.hasNext())
214 IndicatorData* data = iter.value();
215 if (data->m_fileInfo.absoluteFilePath() == file.absoluteFilePath())
217 if (!data->m_verified)
219 QString name = data->m_name;
220 Q_EMIT indicatorAboutToBeUnloaded(name);
228 setLoaded(m_indicatorsData.size() > 0);
231void IndicatorsManager::setLoaded(bool loaded)
233 if (loaded != m_loaded)
236 Q_EMIT loadedChanged(m_loaded);
238 if (m_upstart != NULL) {
241 event_sent = upstart_emit_event_sync(NULL, m_upstart, "indicator-services-start", NULL, 0);
243 event_sent = upstart_emit_event_sync(NULL, m_upstart, "indicator-services-end", NULL, 0);
246 if (event_sent != 0) {
247 qWarning() << "Unable to send indicator event to Upstart";
253void IndicatorsManager::startVerify(const QString& path)
255 QHashIterator<QString, IndicatorData*> iter(m_indicatorsData);
256 while(iter.hasNext())
259 IndicatorData* data = iter.value();
260 if (data->m_fileInfo.canonicalPath() == path)
262 data->m_verified = false;
267void IndicatorsManager::endVerify(const QString& path)
269 QMutableHashIterator<QString, IndicatorData*> iter(m_indicatorsData);
270 while(iter.hasNext())
273 IndicatorData* data = iter.value();
274 if (data->m_fileInfo.canonicalPath() == path)
276 if (!data->m_verified)
278 QString name = data->m_name;
279 Q_EMIT indicatorAboutToBeUnloaded(name);
288Indicator::Ptr IndicatorsManager::indicator(const QString& indicator_name)
290 if (!m_indicatorsData.contains(indicator_name))
292 qWarning() << Q_FUNC_INFO << "Invalid indicator name: " << indicator_name;
293 return Indicator::Ptr();
296 IndicatorData *data = m_indicatorsData[indicator_name];
297 if (data->m_indicator)
299 return data->m_indicator;
302 Indicator::Ptr new_indicator(new Indicator(this));
303 data->m_indicator = new_indicator;
304 QSettings settings(data->m_fileInfo.absoluteFilePath(), QSettings::IniFormat, this);
305 new_indicator->init(data->m_fileInfo.fileName(), settings);
306 return new_indicator;
309QList<Indicator::Ptr> IndicatorsManager::indicators()
311 QList<Indicator::Ptr> list;
312 Q_FOREACH(IndicatorData* data, m_indicatorsData)
314 Indicator::Ptr ret = indicator(data->m_name);
321bool IndicatorsManager::isLoaded() const
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list