~ubuntu-branches/ubuntu/vivid/kate/vivid-proposed

« back to all changes in this revision

Viewing changes to kate/src/katequickopen.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2014-12-04 16:49:41 UTC
  • mfrom: (1.6.6)
  • Revision ID: package-import@ubuntu.com-20141204164941-l3qbvsly83hhlw2v
Tags: 4:14.11.97-0ubuntu1
* New upstream release
* Update build-deps and use pkg-kde v3 for Qt 5 build
* kate-data now kate5-data for co-installability

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    This library is free software; you can redistribute it and/or
 
3
    modify it under the terms of the GNU Library General Public
 
4
    License as published by the Free Software Foundation; either
 
5
    version 2 of the License, or (at your option) any later version.
 
6
 
 
7
    This library is distributed in the hope that it will be useful,
 
8
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
10
    Library General Public License for more details.
 
11
 
 
12
    You should have received a copy of the GNU Library General Public License
 
13
    along with this library; see the file COPYING.LIB.  If not, write to
 
14
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 
15
    Boston, MA 02110-1301, USA.
 
16
    ---
 
17
    Copyright (C) 2007,2009 Joseph Wenninger <jowenn@kde.org>
 
18
*/
 
19
 
 
20
#include "katequickopen.h"
 
21
 
 
22
#include "katemainwindow.h"
 
23
#include "kateviewmanager.h"
 
24
#include "kateapp.h"
 
25
 
 
26
#include <ktexteditor/document.h>
 
27
#include <ktexteditor/view.h>
 
28
 
 
29
#include <KPluginFactory>
 
30
#include <KPluginLoader>
 
31
#include <KAboutData>
 
32
#include <KLineEdit>
 
33
#include <KActionCollection>
 
34
#include <KLocalizedString>
 
35
 
 
36
#include <QEvent>
 
37
#include <QFileInfo>
 
38
#include <QSortFilterProxyModel>
 
39
#include <QCoreApplication>
 
40
#include <QPointer>
 
41
#include <QStandardItemModel>
 
42
#include <QDesktopWidget>
 
43
#include <QBoxLayout>
 
44
#include <QLabel>
 
45
#include <QTreeView>
 
46
 
 
47
Q_DECLARE_METATYPE(QPointer<KTextEditor::Document>)
 
48
 
 
49
static const int DocumentRole = Qt::UserRole + 1;
 
50
static const int UrlRole = Qt::UserRole + 2;
 
51
static const int SortFilterRole = Qt::UserRole + 3;
 
52
 
 
53
KateQuickOpen::KateQuickOpen(QWidget *parent, KateMainWindow *mainWindow)
 
54
    : QWidget(parent)
 
55
    , m_mainWindow(mainWindow)
 
56
{
 
57
    QVBoxLayout *layout = new QVBoxLayout();
 
58
    layout->setSpacing(0);
 
59
    layout->setMargin(0);
 
60
    setLayout(layout);
 
61
 
 
62
    m_inputLine = new KLineEdit();
 
63
    setFocusProxy(m_inputLine);
 
64
    m_inputLine->setPlaceholderText(i18n("Quick Open Search"));
 
65
 
 
66
    layout->addWidget(m_inputLine);
 
67
 
 
68
    m_listView = new QTreeView();
 
69
    layout->addWidget(m_listView, 1);
 
70
    m_listView->setTextElideMode(Qt::ElideLeft);
 
71
 
 
72
    m_base_model = new QStandardItemModel(0, 2, this);
 
73
 
 
74
    m_model = new QSortFilterProxyModel(this);
 
75
    m_model->setFilterRole(SortFilterRole);
 
76
    m_model->setSortRole(SortFilterRole);
 
77
    m_model->setFilterCaseSensitivity(Qt::CaseInsensitive);
 
78
    m_model->setSortCaseSensitivity(Qt::CaseInsensitive);
 
79
 
 
80
    connect(m_inputLine, &KLineEdit::textChanged, m_model, &QSortFilterProxyModel::setFilterFixedString);
 
81
    connect(m_inputLine, &KLineEdit::returnPressed, this, &KateQuickOpen::slotReturnPressed);
 
82
    connect(m_model, &QSortFilterProxyModel::rowsInserted, this, &KateQuickOpen::reselectFirst);
 
83
    connect(m_model, &QSortFilterProxyModel::rowsRemoved, this, &KateQuickOpen::reselectFirst);
 
84
 
 
85
    connect(m_listView, &QTreeView::activated, this, &KateQuickOpen::slotReturnPressed);
 
86
 
 
87
    m_listView->setModel(m_model);
 
88
    m_model->setSourceModel(m_base_model);
 
89
 
 
90
    m_inputLine->installEventFilter(this);
 
91
    m_listView->installEventFilter(this);
 
92
    m_listView->setHeaderHidden(true);
 
93
    m_listView->setRootIsDecorated(false);
 
94
}
 
95
 
 
96
bool KateQuickOpen::eventFilter(QObject *obj, QEvent *event)
 
97
{
 
98
    if (event->type() == QEvent::KeyPress) {
 
99
        QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
 
100
        if (obj == m_inputLine) {
 
101
            const bool forward2list = (keyEvent->key() == Qt::Key_Up)
 
102
                                      || (keyEvent->key() == Qt::Key_Down)
 
103
                                      || (keyEvent->key() == Qt::Key_PageUp)
 
104
                                      || (keyEvent->key() == Qt::Key_PageDown);
 
105
            if (forward2list) {
 
106
                QCoreApplication::sendEvent(m_listView, event);
 
107
                return true;
 
108
            }
 
109
 
 
110
            if (keyEvent->key() == Qt::Key_Escape) {
 
111
                m_mainWindow->slotWindowActivated();
 
112
                m_inputLine->clear();
 
113
                return true;
 
114
            }
 
115
        } else {
 
116
            const bool forward2input = (keyEvent->key() != Qt::Key_Up)
 
117
                                       && (keyEvent->key() != Qt::Key_Down)
 
118
                                       && (keyEvent->key() != Qt::Key_PageUp)
 
119
                                       && (keyEvent->key() != Qt::Key_PageDown)
 
120
                                       && (keyEvent->key() != Qt::Key_Tab)
 
121
                                       && (keyEvent->key() != Qt::Key_Backtab);
 
122
            if (forward2input) {
 
123
                QCoreApplication::sendEvent(m_inputLine, event);
 
124
                return true;
 
125
            }
 
126
        }
 
127
    }
 
128
 
 
129
    // hide on focus out, if neither input field nor list have focus!
 
130
    else if (event->type() == QEvent::FocusOut && !(m_inputLine->hasFocus() || m_listView->hasFocus())) {
 
131
        m_mainWindow->slotWindowActivated();
 
132
        m_inputLine->clear();
 
133
        return true;
 
134
    }
 
135
 
 
136
    return QWidget::eventFilter(obj, event);
 
137
}
 
138
 
 
139
void KateQuickOpen::reselectFirst()
 
140
{
 
141
    QModelIndex index = m_model->index(0, 0);
 
142
    m_listView->setCurrentIndex(index);
 
143
}
 
144
 
 
145
void KateQuickOpen::update()
 
146
{
 
147
    /**
 
148
     * new base mode creation
 
149
     */
 
150
    QStandardItemModel *base_model = new QStandardItemModel(0, 2, this);
 
151
 
 
152
    /**
 
153
     * remember local file names to avoid dupes with project files
 
154
     */
 
155
    QSet<QString> alreadySeenFiles;
 
156
    QSet<KTextEditor::Document *> alreadySeenDocs;
 
157
 
 
158
    /**
 
159
     * get views in lru order
 
160
     */
 
161
    QMap<qint64, KTextEditor::View *> sortedViews;
 
162
    QHashIterator<KTextEditor::View *, QPair<bool, qint64> > i(m_mainWindow->viewManager()->views());
 
163
    while (i.hasNext()) {
 
164
        i.next();
 
165
        sortedViews[i.value().second] = i.key();
 
166
    }
 
167
 
 
168
    /**
 
169
     * now insert them in order
 
170
     */
 
171
    QModelIndex idxToSelect;
 
172
    int linecount = 0;
 
173
    QMapIterator<qint64, KTextEditor::View *> i2(sortedViews);
 
174
    while (i2.hasNext()) {
 
175
        i2.next();
 
176
 
 
177
        KTextEditor::Document *doc = i2.value()->document();
 
178
 
 
179
        if (alreadySeenDocs.contains(doc)) {
 
180
            continue;
 
181
        }
 
182
 
 
183
        alreadySeenDocs.insert(doc);
 
184
 
 
185
        //QStandardItem *item=new QStandardItem(i18n("%1: %2",doc->documentName(),doc->url().toString()));
 
186
        QStandardItem *itemName = new QStandardItem(doc->documentName());
 
187
 
 
188
        itemName->setData(qVariantFromValue(QPointer<KTextEditor::Document> (doc)), DocumentRole);
 
189
        itemName->setData(QString::fromLatin1("%1: %2").arg(doc->documentName()).arg(doc->url().toString()), SortFilterRole);
 
190
        itemName->setEditable(false);
 
191
        QFont font = itemName->font();
 
192
        font.setBold(true);
 
193
        itemName->setFont(font);
 
194
 
 
195
        QStandardItem *itemUrl = new QStandardItem(doc->url().toString());
 
196
        itemUrl->setEditable(false);
 
197
        base_model->setItem(linecount, 0, itemName);
 
198
        base_model->setItem(linecount, 1, itemUrl);
 
199
        linecount++;
 
200
 
 
201
        if (!doc->url().isEmpty() && doc->url().isLocalFile()) {
 
202
            alreadySeenFiles.insert(doc->url().toLocalFile());
 
203
        }
 
204
 
 
205
        // select second document, that is the last used (beside the active one)
 
206
        if (linecount == 2) {
 
207
            idxToSelect = itemName->index();
 
208
        }
 
209
    }
 
210
 
 
211
    /**
 
212
     * get all open documents
 
213
     */
 
214
    QList<KTextEditor::Document *> docs = KateApp::self()->documentManager()->documentList();
 
215
    foreach(KTextEditor::Document * doc, docs) {
 
216
        /**
 
217
         * skip docs already open
 
218
         */
 
219
        if (alreadySeenDocs.contains(doc)) {
 
220
            continue;
 
221
        }
 
222
 
 
223
        //QStandardItem *item=new QStandardItem(i18n("%1: %2",doc->documentName(),doc->url().toString()));
 
224
        QStandardItem *itemName = new QStandardItem(doc->documentName());
 
225
 
 
226
        itemName->setData(qVariantFromValue(QPointer<KTextEditor::Document> (doc)), DocumentRole);
 
227
        itemName->setData(QString::fromLatin1("%1: %2").arg(doc->documentName()).arg(doc->url().toString()), SortFilterRole);
 
228
        itemName->setEditable(false);
 
229
        QFont font = itemName->font();
 
230
        font.setBold(true);
 
231
        itemName->setFont(font);
 
232
 
 
233
        QStandardItem *itemUrl = new QStandardItem(doc->url().toString());
 
234
        itemUrl->setEditable(false);
 
235
        base_model->setItem(linecount, 0, itemName);
 
236
        base_model->setItem(linecount, 1, itemUrl);
 
237
        linecount++;
 
238
 
 
239
        if (!doc->url().isEmpty() && doc->url().isLocalFile()) {
 
240
            alreadySeenFiles.insert(doc->url().toLocalFile());
 
241
        }
 
242
    }
 
243
 
 
244
    /**
 
245
     * insert all project files, if any project around
 
246
     */
 
247
    if (QObject *projectView = m_mainWindow->pluginView(QStringLiteral("kateprojectplugin"))) {
 
248
        QStringList projectFiles = projectView->property("projectFiles").toStringList();
 
249
        foreach(const QString & file, projectFiles) {
 
250
            /**
 
251
             * skip files already open
 
252
             */
 
253
            if (alreadySeenFiles.contains(file)) {
 
254
                continue;
 
255
            }
 
256
 
 
257
            QFileInfo fi(file);
 
258
            QStandardItem *itemName = new QStandardItem(fi.fileName());
 
259
 
 
260
            itemName->setData(qVariantFromValue(QUrl::fromLocalFile(file)), UrlRole);
 
261
            itemName->setData(QString::fromLatin1("%1: %2").arg(fi.fileName()).arg(file), SortFilterRole);
 
262
            itemName->setEditable(false);
 
263
            QFont font = itemName->font();
 
264
            font.setBold(true);
 
265
            itemName->setFont(font);
 
266
 
 
267
            QStandardItem *itemUrl = new QStandardItem(file);
 
268
            itemUrl->setEditable(false);
 
269
            base_model->setItem(linecount, 0, itemName);
 
270
            base_model->setItem(linecount, 1, itemUrl);
 
271
            linecount++;
 
272
        }
 
273
    }
 
274
 
 
275
    /**
 
276
     * swap models and kill old one
 
277
     */
 
278
    m_model->setSourceModel(base_model);
 
279
    delete m_base_model;
 
280
    m_base_model = base_model;
 
281
 
 
282
    if (idxToSelect.isValid()) {
 
283
        m_listView->setCurrentIndex(m_model->mapFromSource(idxToSelect));
 
284
    } else {
 
285
        reselectFirst();
 
286
    }
 
287
 
 
288
    /**
 
289
     * adjust view
 
290
     */
 
291
    m_listView->resizeColumnToContents(0);
 
292
}
 
293
 
 
294
void KateQuickOpen::slotReturnPressed()
 
295
{
 
296
    /**
 
297
     * open document for first element, if possible
 
298
     * prefer to use the document pointer
 
299
     */
 
300
    KTextEditor::Document *doc = m_listView->currentIndex().data(DocumentRole).value<QPointer<KTextEditor::Document> >();
 
301
    if (doc) {
 
302
        m_mainWindow->wrapper()->activateView(doc);
 
303
    } else {
 
304
        QUrl url = m_listView->currentIndex().data(UrlRole).value<QUrl>();
 
305
        if (!url.isEmpty()) {
 
306
            m_mainWindow->wrapper()->openUrl(url);
 
307
        }
 
308
    }
 
309
 
 
310
    /**
 
311
     * in any case, switch back to view manager
 
312
     */
 
313
    m_mainWindow->slotWindowActivated();
 
314
    m_inputLine->clear();
 
315
}