~ubuntu-branches/debian/sid/kde-baseapps/sid

« back to all changes in this revision

Viewing changes to dolphin/src/views/dolphinmodel.cpp

  • Committer: Package Import Robot
  • Author(s): Modestas Vainius, Eshat Cakar, Pino Toscano
  • Date: 2012-06-09 22:18:08 UTC
  • mfrom: (4.2.1) (6.1.1 experimental)
  • Revision ID: package-import@ubuntu.com-20120609221808-h1l0ekd5qmb8nefr
Tags: 4:4.8.4-1
* New upstream release.

[ Eshat Cakar ]
* Add watch file.
* Bump kde-sc-dev-latest build dependency to version 4:4.8.4.
* Update installed files.

[ Pino Toscano ]
* Move files of the konqueror documentation from kde-baseapps-data to
  konqueror itself.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
  * This file is part of the KDE project
3
 
  * Copyright (C) 2007 Rafael Fernández López <ereslibre@kde.org>
4
 
  *
5
 
  * This library is free software; you can redistribute it and/or
6
 
  * modify it under the terms of the GNU Library General Public
7
 
  * License as published by the Free Software Foundation; either
8
 
  * version 2 of the License, or (at your option) any later version.
9
 
  *
10
 
  * This library is distributed in the hope that it will be useful,
11
 
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 
  * Library General Public License for more details.
14
 
  *
15
 
  * You should have received a copy of the GNU Library General Public License
16
 
  * along with this library; see the file COPYING.LIB.  If not, write to
17
 
  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18
 
  * Boston, MA 02110-1301, USA.
19
 
  */
20
 
 
21
 
#include "dolphinmodel.h"
22
 
 
23
 
#include "dolphinsortfilterproxymodel.h"
24
 
 
25
 
#include <KCategorizedView>
26
 
#include <KDateTime>
27
 
#include <KDirModel>
28
 
#include <KFileItem>
29
 
#include <KIconLoader>
30
 
#include <KLocale>
31
 
#include <KUrl>
32
 
#include <KUser>
33
 
#include <KMimeType>
34
 
#include <KStandardDirs>
35
 
 
36
 
#include <QList>
37
 
#include <QSortFilterProxyModel>
38
 
#include <QPainter>
39
 
#include <QPersistentModelIndex>
40
 
#include <QDir>
41
 
#include <QFileInfo>
42
 
 
43
 
const char* const DolphinModel::m_others = I18N_NOOP2("@title:group Name", "Others");
44
 
 
45
 
DolphinModel::DolphinModel(QObject* parent) :
46
 
    KDirModel(parent),
47
 
    m_hasVersionData(false),
48
 
    m_revisionHash()
49
 
{
50
 
    setJobTransfersVisible(true);
51
 
}
52
 
 
53
 
DolphinModel::~DolphinModel()
54
 
{
55
 
}
56
 
 
57
 
bool DolphinModel::setData(const QModelIndex& index, const QVariant& value, int role)
58
 
{
59
 
    if ((index.column() == DolphinModel::Version) && (role == Qt::DecorationRole)) {
60
 
        // TODO: remove data again when items are deleted...
61
 
 
62
 
        const QPersistentModelIndex key = index;
63
 
        const KVersionControlPlugin::VersionState state = static_cast<KVersionControlPlugin::VersionState>(value.toInt());
64
 
        if (m_revisionHash.value(key, KVersionControlPlugin::UnversionedVersion) != state) {
65
 
            if (!m_hasVersionData) {
66
 
                connect(this, SIGNAL(rowsRemoved (const QModelIndex&, int, int)),
67
 
                        this, SLOT(slotRowsRemoved(const QModelIndex&, int, int)));
68
 
                m_hasVersionData = true;
69
 
            }
70
 
 
71
 
            m_revisionHash.insert(key, state);
72
 
            emit dataChanged(index, index);
73
 
            return true;
74
 
        }
75
 
    }
76
 
 
77
 
    return KDirModel::setData(index, value, role);
78
 
}
79
 
 
80
 
QVariant DolphinModel::data(const QModelIndex& index, int role) const
81
 
{
82
 
    switch (role) {
83
 
    case KCategorizedSortFilterProxyModel::CategoryDisplayRole:
84
 
        return displayRoleData(index);
85
 
 
86
 
    case KCategorizedSortFilterProxyModel::CategorySortRole:
87
 
        return sortRoleData(index);
88
 
 
89
 
    case Qt::DecorationRole:
90
 
        if (index.column() == DolphinModel::Version) {
91
 
            return m_revisionHash.value(index, KVersionControlPlugin::UnversionedVersion);
92
 
        }
93
 
        break;
94
 
 
95
 
    case Qt::DisplayRole:
96
 
        switch (index.column()) {
97
 
        case DolphinModel::LinkDest: {
98
 
            const KDirModel *dirModel = qobject_cast<const KDirModel*>(index.model());
99
 
            const KFileItem item = dirModel->itemForIndex(index);
100
 
            return item.linkDest();
101
 
        }
102
 
 
103
 
        case DolphinModel::LocalPathOrUrl:
104
 
            const KDirModel *dirModel = qobject_cast<const KDirModel*>(index.model());
105
 
            const KFileItem item = dirModel->itemForIndex(index);
106
 
            const KUrl url = item.mostLocalUrl();
107
 
            if (url.protocol() == QLatin1String("trash")) {
108
 
                const KIO::UDSEntry udsEntry = item.entry();
109
 
                return udsEntry.stringValue(KIO::UDSEntry::UDS_EXTRA);
110
 
            }
111
 
            return url.directory();
112
 
        }
113
 
        break;
114
 
 
115
 
    default:
116
 
        break;
117
 
    }
118
 
 
119
 
    return KDirModel::data(index, role);
120
 
}
121
 
 
122
 
QVariant DolphinModel::headerData(int section, Qt::Orientation orientation, int role) const
123
 
{
124
 
    if ((orientation == Qt::Horizontal) && (role == Qt::DisplayRole)) {
125
 
        switch (section) {
126
 
        case DolphinModel::LinkDest:
127
 
            return i18nc("@title::column", "Link Destination");
128
 
        case DolphinModel::LocalPathOrUrl:
129
 
            return i18nc("@title::column", "Path");
130
 
        default:
131
 
            return KDirModel::headerData(section, orientation, role);
132
 
        }
133
 
    }
134
 
    return QVariant();
135
 
}
136
 
 
137
 
int DolphinModel::columnCount(const QModelIndex& parent) const
138
 
{
139
 
    return KDirModel::columnCount(parent) + (ExtraColumnCount - ColumnCount);
140
 
}
141
 
 
142
 
void DolphinModel::clearVersionData()
143
 
{
144
 
    m_revisionHash.clear();
145
 
    m_hasVersionData = false;
146
 
}
147
 
 
148
 
bool DolphinModel::hasVersionData() const
149
 
{
150
 
    return m_hasVersionData;
151
 
}
152
 
 
153
 
void DolphinModel::slotRowsRemoved(const QModelIndex& parent, int start, int end)
154
 
{
155
 
    if (m_hasVersionData) {
156
 
        const int column = parent.column();
157
 
        for (int row = start; row <= end; ++row) {
158
 
            m_revisionHash.remove(parent.child(row, column));
159
 
        }
160
 
    }
161
 
}
162
 
 
163
 
QVariant DolphinModel::displayRoleData(const QModelIndex& index) const
164
 
{
165
 
    QString retString;
166
 
 
167
 
    if (!index.isValid()) {
168
 
        return retString;
169
 
    }
170
 
 
171
 
    const KDirModel *dirModel = qobject_cast<const KDirModel*>(index.model());
172
 
    KFileItem item = dirModel->itemForIndex(index);
173
 
 
174
 
    switch (index.column()) {
175
 
    case KDirModel::Name: {
176
 
        // KDirModel checks columns to know to which role are
177
 
        // we talking about
178
 
        const QModelIndex nameIndex = index.model()->index(index.row(), KDirModel::Name, index.parent());
179
 
        if (!nameIndex.isValid()) {
180
 
            return retString;
181
 
        }
182
 
        const QVariant data = nameIndex.model()->data(nameIndex, Qt::DisplayRole);
183
 
        const QString name = data.toString();
184
 
        if (!name.isEmpty()) {
185
 
            if (!item.isHidden() && name.at(0).isLetter())
186
 
                retString = name.at(0).toUpper();
187
 
            else if (item.isHidden()) {
188
 
                if (name.at(0) == '.') {
189
 
                    if (name.size() > 1 && name.at(1).isLetter()) {
190
 
                        retString = name.at(1).toUpper();
191
 
                    } else {
192
 
                        retString = i18nc("@title:group Name", m_others);
193
 
                    }
194
 
                } else {
195
 
                    retString = name.at(0).toUpper();
196
 
                }
197
 
            } else {
198
 
                bool validCategory = false;
199
 
 
200
 
                const QString str(name.toUpper());
201
 
                const QChar* currA = str.unicode();
202
 
                while (!currA->isNull() && !validCategory) {
203
 
                    if (currA->isLetter()) {
204
 
                        validCategory = true;
205
 
                    } else if (currA->isDigit()) {
206
 
                        return i18nc("@title:group Name", m_others);
207
 
                    } else {
208
 
                        ++currA;
209
 
                    }
210
 
                }
211
 
 
212
 
                retString = validCategory ? *currA : i18nc("@title:group Name", m_others);
213
 
            }
214
 
        }
215
 
        break;
216
 
    }
217
 
 
218
 
    case KDirModel::Size: {
219
 
        const KIO::filesize_t fileSize = !item.isNull() ? item.size() : ~0U;
220
 
        if (!item.isNull() && item.isDir()) {
221
 
            retString = i18nc("@title:group Size", "Folders");
222
 
        } else if (fileSize < 5242880) {
223
 
            retString = i18nc("@title:group Size", "Small");
224
 
        } else if (fileSize < 10485760) {
225
 
            retString = i18nc("@title:group Size", "Medium");
226
 
        } else {
227
 
            retString = i18nc("@title:group Size", "Big");
228
 
        }
229
 
        break;
230
 
    }
231
 
 
232
 
    case KDirModel::ModifiedTime: {
233
 
        KDateTime modifiedTime = item.time(KFileItem::ModificationTime);
234
 
        modifiedTime = modifiedTime.toLocalZone();
235
 
 
236
 
        const QDate currentDate = KDateTime::currentLocalDateTime().date();
237
 
        const QDate modifiedDate = modifiedTime.date();
238
 
 
239
 
        const int daysDistance = modifiedDate.daysTo(currentDate);
240
 
 
241
 
        int yearForCurrentWeek = 0;
242
 
        int currentWeek = currentDate.weekNumber(&yearForCurrentWeek);
243
 
        if (yearForCurrentWeek == currentDate.year() + 1) {
244
 
            currentWeek = 53;
245
 
        }
246
 
 
247
 
        int yearForModifiedWeek = 0;
248
 
        int modifiedWeek = modifiedDate.weekNumber(&yearForModifiedWeek);
249
 
        if (yearForModifiedWeek == modifiedDate.year() + 1) {
250
 
            modifiedWeek = 53;
251
 
        }
252
 
 
253
 
        if (currentDate.year() == modifiedDate.year() && currentDate.month() == modifiedDate.month()) {
254
 
            if (modifiedWeek > currentWeek) {
255
 
                // use case: modified date = 2010-01-01, current date = 2010-01-22
256
 
                //           modified week = 53,         current week = 3
257
 
                modifiedWeek = 0;
258
 
            }
259
 
            switch (currentWeek - modifiedWeek) {
260
 
            case 0:
261
 
                switch (daysDistance) {
262
 
                case 0:  retString = i18nc("@title:group Date", "Today"); break;
263
 
                case 1:  retString = i18nc("@title:group Date", "Yesterday"); break;
264
 
                default: retString = modifiedTime.toString(i18nc("@title:group The week day name: %A", "%A"));
265
 
                }
266
 
                break;
267
 
            case 1:
268
 
                retString = i18nc("@title:group Date", "Last Week");
269
 
                break;
270
 
            case 2:
271
 
                retString = i18nc("@title:group Date", "Two Weeks Ago");
272
 
                break;
273
 
            case 3:
274
 
                retString = i18nc("@title:group Date", "Three Weeks Ago");
275
 
                break;
276
 
            case 4:
277
 
            case 5:
278
 
                retString = i18nc("@title:group Date", "Earlier this Month");
279
 
                break;
280
 
            default:
281
 
                Q_ASSERT(false);
282
 
            }
283
 
        } else {
284
 
            const QDate lastMonthDate = currentDate.addMonths(-1);
285
 
            if  (lastMonthDate.year() == modifiedDate.year() && lastMonthDate.month() == modifiedDate.month()) {
286
 
                if (daysDistance == 1) {
287
 
                    retString = modifiedTime.toString(i18nc("@title:group Date: %B is full month name in current locale, and %Y is full year number", "Yesterday (%B, %Y)"));
288
 
                } else if (daysDistance <= 7) {
289
 
                    retString = modifiedTime.toString(i18nc("@title:group The week day name: %A, %B is full month name in current locale, and %Y is full year number", "%A (%B, %Y)"));
290
 
                } else if (daysDistance <= 7 * 2) {
291
 
                    retString = modifiedTime.toString(i18nc("@title:group Date: %B is full month name in current locale, and %Y is full year number", "Last Week (%B, %Y)"));
292
 
                } else if (daysDistance <= 7 * 3) {
293
 
                    retString = modifiedTime.toString(i18nc("@title:group Date: %B is full month name in current locale, and %Y is full year number", "Two Weeks Ago (%B, %Y)"));
294
 
                } else if (daysDistance <= 7 * 4) {
295
 
                    retString = modifiedTime.toString(i18nc("@title:group Date: %B is full month name in current locale, and %Y is full year number", "Three Weeks Ago (%B, %Y)"));
296
 
                } else {
297
 
                    retString = modifiedTime.toString(i18nc("@title:group Date: %B is full month name in current locale, and %Y is full year number", "Earlier on %B, %Y"));
298
 
                }
299
 
            } else {
300
 
                retString = modifiedTime.toString(i18nc("@title:group The month and year: %B is full month name in current locale, and %Y is full year number", "%B, %Y"));
301
 
            }
302
 
        }
303
 
        break;
304
 
    }
305
 
 
306
 
    case KDirModel::Permissions: {
307
 
        QString user;
308
 
        QString group;
309
 
        QString others;
310
 
 
311
 
        QFileInfo info(item.url().pathOrUrl());
312
 
 
313
 
        // set user string
314
 
        if (info.permission(QFile::ReadUser)) {
315
 
            user = i18nc("@item:intext Access permission, concatenated", "Read, ");
316
 
        }
317
 
        if (info.permission(QFile::WriteUser)) {
318
 
            user += i18nc("@item:intext Access permission, concatenated", "Write, ");
319
 
        }
320
 
        if (info.permission(QFile::ExeUser)) {
321
 
            user += i18nc("@item:intext Access permission, concatenated", "Execute, ");
322
 
        }
323
 
        user = user.isEmpty() ? i18nc("@item:intext Access permission, concatenated", "Forbidden") : user.mid(0, user.count() - 2);
324
 
 
325
 
        // set group string
326
 
        if (info.permission(QFile::ReadGroup)) {
327
 
            group = i18nc("@item:intext Access permission, concatenated", "Read, ");
328
 
        }
329
 
        if (info.permission(QFile::WriteGroup)) {
330
 
            group += i18nc("@item:intext Access permission, concatenated", "Write, ");
331
 
        }
332
 
        if (info.permission(QFile::ExeGroup)) {
333
 
            group += i18nc("@item:intext Access permission, concatenated", "Execute, ");
334
 
        }
335
 
        group = group.isEmpty() ? i18nc("@item:intext Access permission, concatenated", "Forbidden") : group.mid(0, group.count() - 2);
336
 
 
337
 
        // set permission string
338
 
        if (info.permission(QFile::ReadOther)) {
339
 
            others = i18nc("@item:intext Access permission, concatenated", "Read, ");
340
 
        }
341
 
        if (info.permission(QFile::WriteOther)) {
342
 
            others += i18nc("@item:intext Access permission, concatenated", "Write, ");
343
 
        }
344
 
        if (info.permission(QFile::ExeOther)) {
345
 
            others += i18nc("@item:intext Access permission, concatenated", "Execute, ");
346
 
        }
347
 
        others = others.isEmpty() ? i18nc("@item:intext Access permission, concatenated", "Forbidden") : others.mid(0, others.count() - 2);
348
 
 
349
 
        retString = i18nc("@title:group Files and folders by permissions", "(User: %1) (Group: %2) (Others: %3)", user, group, others);
350
 
        break;
351
 
    }
352
 
 
353
 
    case KDirModel::Owner:
354
 
        retString = item.user();
355
 
        break;
356
 
 
357
 
    case KDirModel::Group:
358
 
        retString = item.group();
359
 
        break;
360
 
 
361
 
    case KDirModel::Type:
362
 
        retString = item.mimeComment();
363
 
        break;
364
 
 
365
 
    case DolphinModel::Version:
366
 
        retString = "test";
367
 
        break;
368
 
    }
369
 
 
370
 
    return retString;
371
 
}
372
 
 
373
 
QVariant DolphinModel::sortRoleData(const QModelIndex& index) const
374
 
{
375
 
    QVariant retVariant;
376
 
 
377
 
    if (!index.isValid()) {
378
 
        return retVariant;
379
 
    }
380
 
 
381
 
    const KDirModel *dirModel = qobject_cast<const KDirModel*>(index.model());
382
 
    KFileItem item = dirModel->itemForIndex(index);
383
 
 
384
 
    switch (index.column()) {
385
 
    case KDirModel::Name: {
386
 
        retVariant = data(index, KCategorizedSortFilterProxyModel::CategoryDisplayRole);
387
 
        if (retVariant == i18nc("@title:group Name", m_others)) {
388
 
            // assure that the "Others" group is always the last categorization
389
 
            retVariant = QString('Z').append(QChar::ReplacementCharacter);
390
 
        }
391
 
        break;
392
 
    }
393
 
 
394
 
    case KDirModel::Size: {
395
 
        const KIO::filesize_t fileSize = !item.isNull() ? item.size() : ~0U;
396
 
        if (item.isDir()) {
397
 
            retVariant = 0;
398
 
        } else if (fileSize < 5242880) {
399
 
            retVariant = 1;
400
 
        } else if (fileSize < 10485760) {
401
 
            retVariant = 2;
402
 
        } else {
403
 
            retVariant = 3;
404
 
        }
405
 
        break;
406
 
    }
407
 
 
408
 
    case KDirModel::ModifiedTime: {
409
 
        KDateTime modifiedTime = item.time(KFileItem::ModificationTime);
410
 
        modifiedTime = modifiedTime.toLocalZone();
411
 
 
412
 
        const QDate currentDate = KDateTime::currentLocalDateTime().date();
413
 
        const QDate modifiedDate = modifiedTime.date();
414
 
 
415
 
        retVariant = -modifiedDate.daysTo(currentDate);
416
 
        break;
417
 
    }
418
 
 
419
 
    case KDirModel::Permissions: {
420
 
        QFileInfo info(item.url().pathOrUrl());
421
 
 
422
 
        retVariant = -KDirSortFilterProxyModel::pointsForPermissions(info);
423
 
        break;
424
 
    }
425
 
 
426
 
    case KDirModel::Owner:
427
 
        retVariant = item.user();
428
 
        break;
429
 
 
430
 
    case KDirModel::Group:
431
 
        retVariant = item.group();
432
 
        break;
433
 
 
434
 
    case KDirModel::Type:
435
 
        if (item.isDir()) {
436
 
            // when sorting we want folders to be placed first
437
 
            retVariant = QString(); // krazy:exclude=nullstrassign
438
 
        } else {
439
 
            retVariant = item.mimeComment();
440
 
        }
441
 
        break;
442
 
 
443
 
    default:
444
 
        break;
445
 
    }
446
 
 
447
 
    return retVariant;
448
 
}