~ubuntu-branches/ubuntu/precise/gwenview/precise-proposed

« back to all changes in this revision

Viewing changes to app/contextmanager.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2011-12-15 14:17:54 UTC
  • mto: This revision was merged to the branch mainline in revision 12.
  • Revision ID: package-import@ubuntu.com-20111215141754-z043hyx69dulbggf
Tags: upstream-4.7.90
ImportĀ upstreamĀ versionĀ 4.7.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
#include <lib/document/documentfactory.h>
35
35
#include <lib/semanticinfo/sorteddirmodel.h>
36
36
 
37
 
namespace Gwenview {
 
37
namespace Gwenview
 
38
{
38
39
 
39
40
struct ContextManagerPrivate {
40
 
        QList<AbstractContextManagerItem*> mList;
41
 
        SortedDirModel* mDirModel;
42
 
        QItemSelectionModel* mSelectionModel;
43
 
        KUrl mCurrentDirUrl;
44
 
        KUrl mCurrentUrl;
45
 
 
46
 
        bool mOnlyCurrentUrl;
47
 
        bool mSelectedFileItemListNeedsUpdate;
48
 
        QSet<QByteArray> mQueuedSignals;
49
 
        KFileItemList mSelectedFileItemList;
50
 
 
51
 
        QTimer* mQueuedSignalsTimer;
52
 
 
53
 
        void queueSignal(const QByteArray& signal) {
54
 
                mQueuedSignals << signal;
55
 
                mQueuedSignalsTimer->start();
56
 
        }
57
 
 
58
 
        void updateSelectedFileItemList() {
59
 
                if (!mSelectedFileItemListNeedsUpdate) {
60
 
                        return;
61
 
                }
62
 
                mSelectedFileItemList.clear();
63
 
                if (!mOnlyCurrentUrl) {
64
 
                        QItemSelection selection = mSelectionModel->selection();
65
 
                        Q_FOREACH(const QModelIndex& index, selection.indexes()) {
66
 
                                mSelectedFileItemList << mDirModel->itemForIndex(index);
67
 
                        }
68
 
                }
69
 
 
70
 
                // At least add current url if it's valid (it may not be in
71
 
                // the list if we are viewing a non-browsable url, for example
72
 
                // using http protocol)
73
 
                if (mSelectedFileItemList.isEmpty() && mCurrentUrl.isValid()) {
74
 
                        KFileItem item(KFileItem::Unknown, KFileItem::Unknown, mCurrentUrl);
75
 
                        mSelectedFileItemList << item;
76
 
                }
77
 
 
78
 
                mSelectedFileItemListNeedsUpdate = false;
79
 
        }
 
41
    QList<AbstractContextManagerItem*> mList;
 
42
    SortedDirModel* mDirModel;
 
43
    QItemSelectionModel* mSelectionModel;
 
44
    KUrl mCurrentDirUrl;
 
45
    KUrl mCurrentUrl;
 
46
 
 
47
    bool mOnlyCurrentUrl;
 
48
    bool mSelectedFileItemListNeedsUpdate;
 
49
    QSet<QByteArray> mQueuedSignals;
 
50
    KFileItemList mSelectedFileItemList;
 
51
 
 
52
    QTimer* mQueuedSignalsTimer;
 
53
 
 
54
    void queueSignal(const QByteArray& signal)
 
55
    {
 
56
        mQueuedSignals << signal;
 
57
        mQueuedSignalsTimer->start();
 
58
    }
 
59
 
 
60
    void updateSelectedFileItemList()
 
61
    {
 
62
        if (!mSelectedFileItemListNeedsUpdate) {
 
63
            return;
 
64
        }
 
65
        mSelectedFileItemList.clear();
 
66
        if (!mOnlyCurrentUrl) {
 
67
            QItemSelection selection = mSelectionModel->selection();
 
68
            Q_FOREACH(const QModelIndex & index, selection.indexes()) {
 
69
                mSelectedFileItemList << mDirModel->itemForIndex(index);
 
70
            }
 
71
        }
 
72
 
 
73
        // At least add current url if it's valid (it may not be in
 
74
        // the list if we are viewing a non-browsable url, for example
 
75
        // using http protocol)
 
76
        if (mSelectedFileItemList.isEmpty() && mCurrentUrl.isValid()) {
 
77
            KFileItem item(KFileItem::Unknown, KFileItem::Unknown, mCurrentUrl);
 
78
            mSelectedFileItemList << item;
 
79
        }
 
80
 
 
81
        mSelectedFileItemListNeedsUpdate = false;
 
82
    }
80
83
};
81
84
 
82
 
 
83
85
ContextManager::ContextManager(SortedDirModel* dirModel, QItemSelectionModel* selectionModel, QObject* parent)
84
86
: QObject(parent)
85
87
, d(new ContextManagerPrivate)
86
88
{
87
 
        d->mQueuedSignalsTimer = new QTimer(this);
88
 
        d->mQueuedSignalsTimer->setInterval(100);
89
 
        d->mQueuedSignalsTimer->setSingleShot(true);
90
 
        connect(d->mQueuedSignalsTimer, SIGNAL(timeout()),
91
 
                SLOT(emitQueuedSignals()) );
92
 
 
93
 
        d->mDirModel = dirModel;
94
 
        connect(d->mDirModel, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)),
95
 
                SLOT(slotDirModelDataChanged(const QModelIndex&, const QModelIndex&)) );
96
 
 
97
 
        d->mSelectionModel = selectionModel;
98
 
        connect(d->mSelectionModel, SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
99
 
                SLOT(slotSelectionChanged()) );
100
 
        connect(d->mSelectionModel, SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)),
101
 
                SLOT(slotCurrentChanged(const QModelIndex&)) );
102
 
 
103
 
        d->mSelectedFileItemListNeedsUpdate = false;
104
 
        d->mOnlyCurrentUrl = false;
105
 
}
106
 
 
107
 
 
108
 
ContextManager::~ContextManager() {
109
 
        qDeleteAll(d->mList);
110
 
        delete d;
111
 
}
112
 
 
113
 
 
114
 
void ContextManager::addItem(AbstractContextManagerItem* item) {
115
 
        d->mList << item;
116
 
}
117
 
 
118
 
 
119
 
void ContextManager::setCurrentUrl(const KUrl& currentUrl) {
120
 
        if (d->mCurrentUrl == currentUrl) {
121
 
                return;
122
 
        }
123
 
 
124
 
        d->mCurrentUrl = currentUrl;
125
 
        Document::Ptr doc = DocumentFactory::instance()->load(currentUrl);
126
 
        QUndoGroup* undoGroup = DocumentFactory::instance()->undoGroup();
127
 
        undoGroup->addStack(doc->undoStack());
128
 
        undoGroup->setActiveStack(doc->undoStack());
129
 
 
130
 
        if (d->mOnlyCurrentUrl) {
131
 
                d->mSelectedFileItemListNeedsUpdate = true;
132
 
        }
133
 
 
134
 
        d->queueSignal("selectionChanged");
135
 
}
136
 
 
137
 
 
138
 
KFileItemList ContextManager::selectedFileItemList() const {
139
 
        d->updateSelectedFileItemList();
140
 
        return d->mSelectedFileItemList;
141
 
}
142
 
 
143
 
 
144
 
void ContextManager::setCurrentDirUrl(const KUrl& url) {
145
 
        if (url.equals(d->mCurrentDirUrl, KUrl::CompareWithoutTrailingSlash)) {
146
 
                return;
147
 
        }
148
 
        d->mCurrentDirUrl = url;
149
 
        currentDirUrlChanged();
150
 
}
151
 
 
152
 
 
153
 
KUrl ContextManager::currentDirUrl() const {
154
 
        return d->mCurrentDirUrl;
155
 
}
156
 
 
157
 
 
158
 
KUrl ContextManager::currentUrl() const {
159
 
        return d->mCurrentUrl;
160
 
}
161
 
 
162
 
 
163
 
SortedDirModel* ContextManager::dirModel() const {
164
 
        return d->mDirModel;
165
 
}
166
 
 
167
 
 
168
 
void ContextManager::slotDirModelDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) {
169
 
        // Data change can happen in the following cases:
170
 
        // - items have been renamed
171
 
        // - item bytes have been modified
172
 
        // - item meta info has been retrieved or modified
173
 
        //
174
 
        // If a selected item is affected, schedule emission of a
175
 
        // selectionDataChanged() signal. Don't emit it directly to avoid spamming
176
 
        // the context items in case of a mass change.
177
 
        QModelIndexList selectionList = d->mSelectionModel->selectedIndexes();
178
 
        if (selectionList.isEmpty()) {
179
 
                return;
180
 
        }
181
 
 
182
 
        QModelIndexList changedList;
183
 
        for (int row=topLeft.row(); row <= bottomRight.row(); ++row) {
184
 
                changedList << d->mDirModel->index(row, 0);
185
 
        }
186
 
 
187
 
        QModelIndexList& shortList = selectionList;
188
 
        QModelIndexList& longList = changedList;
189
 
        if (shortList.length() > longList.length()) {
190
 
                qSwap(shortList, longList);
191
 
        }
192
 
        Q_FOREACH(const QModelIndex& index, shortList) {
193
 
                if (longList.contains(index)) {
194
 
                        d->mSelectedFileItemListNeedsUpdate = true;
195
 
                        d->queueSignal("selectionDataChanged");
196
 
                        return;
197
 
                }
198
 
        }
199
 
}
200
 
 
201
 
 
202
 
void ContextManager::slotSelectionChanged() {
203
 
        d->mSelectedFileItemListNeedsUpdate = true;
204
 
        d->queueSignal("selectionChanged");
205
 
}
206
 
 
207
 
 
208
 
void Gwenview::ContextManager::slotCurrentChanged(const QModelIndex& index) {
209
 
        KUrl url = d->mDirModel->urlForIndex(index);
210
 
        setCurrentUrl(url);
211
 
}
212
 
 
213
 
 
214
 
void ContextManager::emitQueuedSignals() {
215
 
        Q_FOREACH(const QByteArray& signal, d->mQueuedSignals) {
216
 
                QMetaObject::invokeMethod(this, signal.data());
217
 
        }
218
 
        d->mQueuedSignals.clear();
219
 
}
220
 
 
221
 
 
222
 
void ContextManager::setOnlyCurrentUrl(bool onlyCurrentUrl) {
223
 
        if (d->mOnlyCurrentUrl != onlyCurrentUrl) {
224
 
                d->mOnlyCurrentUrl = onlyCurrentUrl;
225
 
                d->mSelectedFileItemListNeedsUpdate = true;
226
 
                d->queueSignal("selectionChanged");
227
 
        }
228
 
}
229
 
 
 
89
    d->mQueuedSignalsTimer = new QTimer(this);
 
90
    d->mQueuedSignalsTimer->setInterval(100);
 
91
    d->mQueuedSignalsTimer->setSingleShot(true);
 
92
    connect(d->mQueuedSignalsTimer, SIGNAL(timeout()),
 
93
            SLOT(emitQueuedSignals()));
 
94
 
 
95
    d->mDirModel = dirModel;
 
96
    connect(d->mDirModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)),
 
97
            SLOT(slotDirModelDataChanged(QModelIndex, QModelIndex)));
 
98
 
 
99
    d->mSelectionModel = selectionModel;
 
100
    connect(d->mSelectionModel, SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
 
101
            SLOT(slotSelectionChanged()));
 
102
    connect(d->mSelectionModel, SIGNAL(currentChanged(QModelIndex, QModelIndex)),
 
103
            SLOT(slotCurrentChanged(QModelIndex)));
 
104
 
 
105
    d->mSelectedFileItemListNeedsUpdate = false;
 
106
    d->mOnlyCurrentUrl = false;
 
107
}
 
108
 
 
109
ContextManager::~ContextManager()
 
110
{
 
111
    qDeleteAll(d->mList);
 
112
    delete d;
 
113
}
 
114
 
 
115
void ContextManager::addItem(AbstractContextManagerItem* item)
 
116
{
 
117
    d->mList << item;
 
118
}
 
119
 
 
120
void ContextManager::setCurrentUrl(const KUrl& currentUrl)
 
121
{
 
122
    if (d->mCurrentUrl == currentUrl) {
 
123
        return;
 
124
    }
 
125
 
 
126
    d->mCurrentUrl = currentUrl;
 
127
    Document::Ptr doc = DocumentFactory::instance()->load(currentUrl);
 
128
    QUndoGroup* undoGroup = DocumentFactory::instance()->undoGroup();
 
129
    undoGroup->addStack(doc->undoStack());
 
130
    undoGroup->setActiveStack(doc->undoStack());
 
131
 
 
132
    if (d->mOnlyCurrentUrl) {
 
133
        d->mSelectedFileItemListNeedsUpdate = true;
 
134
    }
 
135
 
 
136
    d->queueSignal("selectionChanged");
 
137
}
 
138
 
 
139
KFileItemList ContextManager::selectedFileItemList() const
 
140
{
 
141
    d->updateSelectedFileItemList();
 
142
    return d->mSelectedFileItemList;
 
143
}
 
144
 
 
145
void ContextManager::setCurrentDirUrl(const KUrl& url)
 
146
{
 
147
    if (url.equals(d->mCurrentDirUrl, KUrl::CompareWithoutTrailingSlash)) {
 
148
        return;
 
149
    }
 
150
    d->mCurrentDirUrl = url;
 
151
    currentDirUrlChanged();
 
152
}
 
153
 
 
154
KUrl ContextManager::currentDirUrl() const
 
155
{
 
156
    return d->mCurrentDirUrl;
 
157
}
 
158
 
 
159
KUrl ContextManager::currentUrl() const
 
160
{
 
161
    return d->mCurrentUrl;
 
162
}
 
163
 
 
164
SortedDirModel* ContextManager::dirModel() const
 
165
{
 
166
    return d->mDirModel;
 
167
}
 
168
 
 
169
void ContextManager::slotDirModelDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight)
 
170
{
 
171
    // Data change can happen in the following cases:
 
172
    // - items have been renamed
 
173
    // - item bytes have been modified
 
174
    // - item meta info has been retrieved or modified
 
175
    //
 
176
    // If a selected item is affected, schedule emission of a
 
177
    // selectionDataChanged() signal. Don't emit it directly to avoid spamming
 
178
    // the context items in case of a mass change.
 
179
    QModelIndexList selectionList = d->mSelectionModel->selectedIndexes();
 
180
    if (selectionList.isEmpty()) {
 
181
        return;
 
182
    }
 
183
 
 
184
    QModelIndexList changedList;
 
185
    for (int row = topLeft.row(); row <= bottomRight.row(); ++row) {
 
186
        changedList << d->mDirModel->index(row, 0);
 
187
    }
 
188
 
 
189
    QModelIndexList& shortList = selectionList;
 
190
    QModelIndexList& longList = changedList;
 
191
    if (shortList.length() > longList.length()) {
 
192
        qSwap(shortList, longList);
 
193
    }
 
194
    Q_FOREACH(const QModelIndex & index, shortList) {
 
195
        if (longList.contains(index)) {
 
196
            d->mSelectedFileItemListNeedsUpdate = true;
 
197
            d->queueSignal("selectionDataChanged");
 
198
            return;
 
199
        }
 
200
    }
 
201
}
 
202
 
 
203
void ContextManager::slotSelectionChanged()
 
204
{
 
205
    d->mSelectedFileItemListNeedsUpdate = true;
 
206
    d->queueSignal("selectionChanged");
 
207
}
 
208
 
 
209
void Gwenview::ContextManager::slotCurrentChanged(const QModelIndex& index)
 
210
{
 
211
    KUrl url = d->mDirModel->urlForIndex(index);
 
212
    setCurrentUrl(url);
 
213
}
 
214
 
 
215
void ContextManager::emitQueuedSignals()
 
216
{
 
217
    Q_FOREACH(const QByteArray & signal, d->mQueuedSignals) {
 
218
        QMetaObject::invokeMethod(this, signal.data());
 
219
    }
 
220
    d->mQueuedSignals.clear();
 
221
}
 
222
 
 
223
void ContextManager::setOnlyCurrentUrl(bool onlyCurrentUrl)
 
224
{
 
225
    if (d->mOnlyCurrentUrl != onlyCurrentUrl) {
 
226
        d->mOnlyCurrentUrl = onlyCurrentUrl;
 
227
        d->mSelectedFileItemListNeedsUpdate = true;
 
228
        d->queueSignal("selectionChanged");
 
229
    }
 
230
}
230
231
 
231
232
} // namespace