~ubuntu-branches/ubuntu/quantal/kde-runtime/quantal

« back to all changes in this revision

Viewing changes to plasma/declarativeimports/krunnermodel/runnermodel.cpp

  • Committer: Package Import Robot
  • Author(s): Philip Muškovac
  • Date: 2012-06-03 21:50:00 UTC
  • mto: This revision was merged to the branch mainline in revision 21.
  • Revision ID: package-import@ubuntu.com-20120603215000-vn7oarsq0ynrydj5
Tags: upstream-4.8.80
Import upstream version 4.8.80

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    Copyright 2011 Aaron Seigo <aseigo@kde.org>
 
3
 
 
4
    This library is free software; you can redistribute it and/or
 
5
    modify it under the terms of the GNU Library General Public
 
6
    License as published by the Free Software Foundation; either
 
7
    version 2 of the License, or (at your option) any later version.
 
8
 
 
9
    This library is distributed in the hope that it will be useful,
 
10
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
12
    Library General Public License for more details.
 
13
 
 
14
    You should have received a copy of the GNU Library General Public License
 
15
    along with this library; see the file COPYING.LIB.  If not, write to
 
16
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 
17
    Boston, MA 02110-1301, USA.
 
18
*/
 
19
 
 
20
#include "runnermodel.h"
 
21
 
 
22
#include <QIcon>
 
23
#include <QAction>
 
24
#include <QTimer>
 
25
 
 
26
#include <KDebug>
 
27
 
 
28
#include <Plasma/RunnerManager>
 
29
 
 
30
RunnerModel::RunnerModel(QObject *parent)
 
31
    : QAbstractListModel(parent),
 
32
      m_manager(0),
 
33
      m_startQueryTimer(new QTimer(this)),
 
34
      m_runningChangedTimeout(new QTimer(this)),
 
35
      m_running(false)
 
36
{
 
37
    QHash<int, QByteArray> roles;
 
38
    roles.insert(Qt::DisplayRole, "label");
 
39
    roles.insert(Qt::DecorationRole, "icon");
 
40
    roles.insert(Type, "type");
 
41
    roles.insert(Relevance, "relevance");
 
42
    roles.insert(Data, "data");
 
43
    roles.insert(Id, "id");
 
44
    roles.insert(SubText, "description");
 
45
    roles.insert(Enabled, "enabled");
 
46
    roles.insert(RunnerId, "runnerid");
 
47
    roles.insert(RunnerName, "runnerName");
 
48
    roles.insert(Actions, "actions");
 
49
    setRoleNames(roles);
 
50
 
 
51
    m_startQueryTimer->setSingleShot(true);
 
52
    m_startQueryTimer->setInterval(10);
 
53
    connect(m_startQueryTimer, SIGNAL(timeout()), this, SLOT(startQuery()));
 
54
 
 
55
    //FIXME: HACK: some runners stay in a running but finished state, not possible to say if it's actually over
 
56
    m_runningChangedTimeout->setSingleShot(true);
 
57
    connect(m_runningChangedTimeout, SIGNAL(timeout()), this, SLOT(queryHasFinished()));
 
58
}
 
59
 
 
60
int RunnerModel::rowCount(const QModelIndex& index) const
 
61
{
 
62
    return index.isValid() ? 0 : m_matches.count();
 
63
}
 
64
 
 
65
int RunnerModel::count() const
 
66
{
 
67
    return m_matches.count();
 
68
}
 
69
 
 
70
QStringList RunnerModel::runners() const
 
71
{
 
72
    return m_manager ? m_manager->allowedRunners() : m_pendingRunnersList;
 
73
}
 
74
 
 
75
void RunnerModel::setRunners(const QStringList &allowedRunners)
 
76
{
 
77
    //use sets to ensure comparison is order-independent
 
78
    if (allowedRunners.toSet() == runners().toSet()) {
 
79
        return;
 
80
    }
 
81
    if (m_manager) {
 
82
        m_manager->setAllowedRunners(allowedRunners);
 
83
 
 
84
        //automagically enter single runner mode if there's only 1 allowed runner
 
85
        m_manager->setSingleMode(allowedRunners.count() == 1);
 
86
    } else {
 
87
        m_pendingRunnersList = allowedRunners;
 
88
        kDebug() << "runners set" << m_pendingRunnersList.count();
 
89
    }
 
90
 
 
91
    // to trigger single runner fun!
 
92
    if (allowedRunners.count() == 1) {
 
93
        m_singleRunnerId = allowedRunners.first();
 
94
        scheduleQuery(QString());
 
95
    } else {
 
96
        m_singleRunnerId.clear();
 
97
    }
 
98
    emit runnersChanged();
 
99
}
 
100
 
 
101
void RunnerModel::run(int index)
 
102
{
 
103
    if (index >= 0 && index < m_matches.count()) {
 
104
        m_manager->run(m_matches.at(index));
 
105
    }
 
106
}
 
107
 
 
108
bool RunnerModel::isRunning() const
 
109
{
 
110
    return m_running;
 
111
}
 
112
 
 
113
QVariant RunnerModel::data(const QModelIndex &index, int role) const
 
114
{
 
115
    if (!index.isValid() || index.parent().isValid() ||
 
116
        index.column() > 0 || index.row() < 0 || index.row() >= m_matches.count()) {
 
117
        // index requested must be valid, but we have no child items!
 
118
        //kDebug() << "invalid index requested";
 
119
        return QVariant();
 
120
    }
 
121
 
 
122
    if (role == Qt::DisplayRole) {
 
123
        return m_matches.at(index.row()).text();
 
124
    } else if (role == Qt::DecorationRole) {
 
125
        return m_matches.at(index.row()).icon();
 
126
    } else if (role == Type) {
 
127
        return m_matches.at(index.row()).type();
 
128
    } else if (role == Relevance) {
 
129
        return m_matches.at(index.row()).relevance();
 
130
    } else if (role == Data) {
 
131
        return m_matches.at(index.row()).data();
 
132
    } else if (role == Id) {
 
133
        return m_matches.at(index.row()).id();
 
134
    } else if (role == SubText) {
 
135
        return m_matches.at(index.row()).subtext();
 
136
    } else if (role == Enabled) {
 
137
        return m_matches.at(index.row()).isEnabled();
 
138
    } else if (role == RunnerId) {
 
139
        return m_matches.at(index.row()).runner()->id();
 
140
    } else if (role == RunnerName) {
 
141
        return m_matches.at(index.row()).runner()->name();
 
142
    } else if (role == Actions) {
 
143
        QVariantList actions;
 
144
        Plasma::QueryMatch amatch = m_matches.at(index.row());
 
145
        QList<QAction*> theactions = m_manager->actionsForMatch(amatch);
 
146
        foreach(QAction* action, theactions) {
 
147
            actions += qVariantFromValue<QObject*>(action);
 
148
        }
 
149
        return actions;
 
150
    }
 
151
 
 
152
    return QVariant();
 
153
}
 
154
 
 
155
QString RunnerModel::currentQuery() const
 
156
{
 
157
    return m_manager ? m_manager->query() : QString();
 
158
}
 
159
 
 
160
void RunnerModel::scheduleQuery(const QString &query)
 
161
{
 
162
    m_pendingQuery = query;
 
163
    m_startQueryTimer->start();
 
164
}
 
165
 
 
166
void RunnerModel::startQuery()
 
167
{
 
168
    // avoid creating a manager just so we can run nothing
 
169
    // however, if we have one pending runner, then we'll be in single query mode
 
170
    // and a null query is a valid query
 
171
    if (!m_manager && m_pendingRunnersList.count() != 1 && m_pendingQuery.isEmpty()) {
 
172
        return;
 
173
    }
 
174
 
 
175
    //kDebug() << "!!!!!!!!!!!!!" << m_pendingQuery << m_manager;
 
176
 
 
177
    if (createManager() || m_pendingQuery != m_manager->query()) {
 
178
        //kDebug() << "running query" << m_pendingQuery << m_manager;
 
179
        m_manager->launchQuery(m_pendingQuery, m_singleRunnerId);
 
180
        emit queryChanged();
 
181
        m_running = true;
 
182
        emit runningChanged(true);
 
183
    }
 
184
}
 
185
 
 
186
bool RunnerModel::createManager()
 
187
{
 
188
    if (!m_manager) {
 
189
        m_manager = new Plasma::RunnerManager(this);
 
190
        connect(m_manager, SIGNAL(matchesChanged(QList<Plasma::QueryMatch>)),
 
191
                this, SLOT(matchesChanged(QList<Plasma::QueryMatch>)));
 
192
        connect(m_manager, SIGNAL(queryFinished()),
 
193
                this, SLOT(queryHasFinished()));
 
194
 
 
195
        if (!m_pendingRunnersList.isEmpty()) {
 
196
            setRunners(m_pendingRunnersList);
 
197
            m_pendingRunnersList.clear();
 
198
        }
 
199
        //connect(m_manager, SIGNAL(queryFinished()), this, SLOT(queryFinished()));
 
200
        return true;
 
201
    }
 
202
 
 
203
    return false;
 
204
}
 
205
 
 
206
void RunnerModel::matchesChanged(const QList<Plasma::QueryMatch> &matches)
 
207
{
 
208
    //kDebug() << "got matches:" << matches.count();
 
209
    bool fullReset = false;
 
210
    int oldCount = m_matches.count();
 
211
    int newCount = matches.count();
 
212
    if (newCount > oldCount) {
 
213
        // We received more matches than we had. If all common matches are the
 
214
        // same, we can just append new matches instead of resetting the whole
 
215
        // model
 
216
        for (int row = 0; row < oldCount; ++row) {
 
217
            if (!(m_matches.at(row) == matches.at(row))) {
 
218
                fullReset = true;
 
219
                break;
 
220
            }
 
221
        }
 
222
        if (!fullReset) {
 
223
            // Not a full reset, inserting rows
 
224
            beginInsertRows(QModelIndex(), oldCount, newCount);
 
225
            m_matches = matches;
 
226
            endInsertRows();
 
227
            emit countChanged();
 
228
        }
 
229
    } else {
 
230
        fullReset = true;
 
231
    }
 
232
 
 
233
    if (fullReset) {
 
234
        beginResetModel();
 
235
        m_matches = matches;
 
236
        endResetModel();
 
237
        emit countChanged();
 
238
    }
 
239
    m_runningChangedTimeout->start(3000);
 
240
}
 
241
 
 
242
void RunnerModel::queryHasFinished()
 
243
{
 
244
    m_running = false;
 
245
    emit runningChanged(false);
 
246
}
 
247
 
 
248
#include "runnermodel.moc"
 
249