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.
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.
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.
17
Copyright (C) 2007,2009 Joseph Wenninger <jowenn@kde.org>
20
#include "katequickopen.h"
22
#include "katemainwindow.h"
23
#include "kateviewmanager.h"
26
#include <ktexteditor/document.h>
27
#include <ktexteditor/view.h>
29
#include <KPluginFactory>
30
#include <KPluginLoader>
33
#include <KActionCollection>
34
#include <KLocalizedString>
38
#include <QSortFilterProxyModel>
39
#include <QCoreApplication>
41
#include <QStandardItemModel>
42
#include <QDesktopWidget>
47
Q_DECLARE_METATYPE(QPointer<KTextEditor::Document>)
49
static const int DocumentRole = Qt::UserRole + 1;
50
static const int UrlRole = Qt::UserRole + 2;
51
static const int SortFilterRole = Qt::UserRole + 3;
53
KateQuickOpen::KateQuickOpen(QWidget *parent, KateMainWindow *mainWindow)
55
, m_mainWindow(mainWindow)
57
QVBoxLayout *layout = new QVBoxLayout();
58
layout->setSpacing(0);
62
m_inputLine = new KLineEdit();
63
setFocusProxy(m_inputLine);
64
m_inputLine->setPlaceholderText(i18n("Quick Open Search"));
66
layout->addWidget(m_inputLine);
68
m_listView = new QTreeView();
69
layout->addWidget(m_listView, 1);
70
m_listView->setTextElideMode(Qt::ElideLeft);
72
m_base_model = new QStandardItemModel(0, 2, this);
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);
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);
85
connect(m_listView, &QTreeView::activated, this, &KateQuickOpen::slotReturnPressed);
87
m_listView->setModel(m_model);
88
m_model->setSourceModel(m_base_model);
90
m_inputLine->installEventFilter(this);
91
m_listView->installEventFilter(this);
92
m_listView->setHeaderHidden(true);
93
m_listView->setRootIsDecorated(false);
96
bool KateQuickOpen::eventFilter(QObject *obj, QEvent *event)
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);
106
QCoreApplication::sendEvent(m_listView, event);
110
if (keyEvent->key() == Qt::Key_Escape) {
111
m_mainWindow->slotWindowActivated();
112
m_inputLine->clear();
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);
123
QCoreApplication::sendEvent(m_inputLine, event);
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();
136
return QWidget::eventFilter(obj, event);
139
void KateQuickOpen::reselectFirst()
141
QModelIndex index = m_model->index(0, 0);
142
m_listView->setCurrentIndex(index);
145
void KateQuickOpen::update()
148
* new base mode creation
150
QStandardItemModel *base_model = new QStandardItemModel(0, 2, this);
153
* remember local file names to avoid dupes with project files
155
QSet<QString> alreadySeenFiles;
156
QSet<KTextEditor::Document *> alreadySeenDocs;
159
* get views in lru order
161
QMap<qint64, KTextEditor::View *> sortedViews;
162
QHashIterator<KTextEditor::View *, QPair<bool, qint64> > i(m_mainWindow->viewManager()->views());
163
while (i.hasNext()) {
165
sortedViews[i.value().second] = i.key();
169
* now insert them in order
171
QModelIndex idxToSelect;
173
QMapIterator<qint64, KTextEditor::View *> i2(sortedViews);
174
while (i2.hasNext()) {
177
KTextEditor::Document *doc = i2.value()->document();
179
if (alreadySeenDocs.contains(doc)) {
183
alreadySeenDocs.insert(doc);
185
//QStandardItem *item=new QStandardItem(i18n("%1: %2",doc->documentName(),doc->url().toString()));
186
QStandardItem *itemName = new QStandardItem(doc->documentName());
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();
193
itemName->setFont(font);
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);
201
if (!doc->url().isEmpty() && doc->url().isLocalFile()) {
202
alreadySeenFiles.insert(doc->url().toLocalFile());
205
// select second document, that is the last used (beside the active one)
206
if (linecount == 2) {
207
idxToSelect = itemName->index();
212
* get all open documents
214
QList<KTextEditor::Document *> docs = KateApp::self()->documentManager()->documentList();
215
foreach(KTextEditor::Document * doc, docs) {
217
* skip docs already open
219
if (alreadySeenDocs.contains(doc)) {
223
//QStandardItem *item=new QStandardItem(i18n("%1: %2",doc->documentName(),doc->url().toString()));
224
QStandardItem *itemName = new QStandardItem(doc->documentName());
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();
231
itemName->setFont(font);
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);
239
if (!doc->url().isEmpty() && doc->url().isLocalFile()) {
240
alreadySeenFiles.insert(doc->url().toLocalFile());
245
* insert all project files, if any project around
247
if (QObject *projectView = m_mainWindow->pluginView(QStringLiteral("kateprojectplugin"))) {
248
QStringList projectFiles = projectView->property("projectFiles").toStringList();
249
foreach(const QString & file, projectFiles) {
251
* skip files already open
253
if (alreadySeenFiles.contains(file)) {
258
QStandardItem *itemName = new QStandardItem(fi.fileName());
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();
265
itemName->setFont(font);
267
QStandardItem *itemUrl = new QStandardItem(file);
268
itemUrl->setEditable(false);
269
base_model->setItem(linecount, 0, itemName);
270
base_model->setItem(linecount, 1, itemUrl);
276
* swap models and kill old one
278
m_model->setSourceModel(base_model);
280
m_base_model = base_model;
282
if (idxToSelect.isValid()) {
283
m_listView->setCurrentIndex(m_model->mapFromSource(idxToSelect));
291
m_listView->resizeColumnToContents(0);
294
void KateQuickOpen::slotReturnPressed()
297
* open document for first element, if possible
298
* prefer to use the document pointer
300
KTextEditor::Document *doc = m_listView->currentIndex().data(DocumentRole).value<QPointer<KTextEditor::Document> >();
302
m_mainWindow->wrapper()->activateView(doc);
304
QUrl url = m_listView->currentIndex().data(UrlRole).value<QUrl>();
305
if (!url.isEmpty()) {
306
m_mainWindow->wrapper()->openUrl(url);
311
* in any case, switch back to view manager
313
m_mainWindow->slotWindowActivated();
314
m_inputLine->clear();