Change doubleClicked() to activated() to honor user single-or-double
[kate:dimsuz-kate.git] / kate / plugins / quickdocumentswitcher / plugin_katequickdocumentswitcher.cpp
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 "plugin_katequickdocumentswitcher.h"
21 #include "plugin_katequickdocumentswitcher.moc"
22
23 #include <ktexteditor/document.h>
24 #include <ktexteditor/view.h>
25
26 #include <kpluginfactory.h>
27 #include <kpluginloader.h>
28 #include <kaboutdata.h>
29
30 #include <klineedit.h>
31 #include <kactioncollection.h>
32 #include <kaction.h>
33 #include <qtreeview.h>
34 #include <qwidget.h>
35 #include <qboxlayout.h>
36 #include <qstandarditemmodel.h>
37 #include <qpointer.h>
38 #include <qevent.h>
39 #include <qlabel.h>
40 #include <qcoreapplication.h>
41 #include <QDesktopWidget>
42
43 Q_DECLARE_METATYPE(QPointer<KTextEditor::Document>)
44
45 const int DocumentRole=Qt::UserRole+1;
46 const int SortFilterRole=Qt::UserRole+2;
47
48 K_PLUGIN_FACTORY(KateQuickDocumentSwitcherFactory, registerPlugin<PluginKateQuickDocumentSwitcher>();)
49 K_EXPORT_PLUGIN(KateQuickDocumentSwitcherFactory(KAboutData("katequickdocumentswitcher","katequickdocumentswitcherplugin",ki18n("Quick Document Switcher"), "0.1", ki18n("Quickly switch between documents"), KAboutData::License_LGPL_V2)) )
50
51 //BEGIN: Plugin
52
53 PluginKateQuickDocumentSwitcher::PluginKateQuickDocumentSwitcher( QObject* parent , const QList<QVariant>&):
54     Kate::Plugin ( (Kate::Application *)parent, "kate-quick-document-switcher-plugin" ) {
55 }
56
57 PluginKateQuickDocumentSwitcher::~PluginKateQuickDocumentSwitcher() {
58 }
59
60 Kate::PluginView *PluginKateQuickDocumentSwitcher::createView (Kate::MainWindow *mainWindow) {
61     return new PluginViewKateQuickDocumentSwitcher(mainWindow);
62 }
63
64 //END: Plugin
65
66 //BEGIN: View
67 PluginViewKateQuickDocumentSwitcher::PluginViewKateQuickDocumentSwitcher(Kate::MainWindow *mainwindow):
68     Kate::PluginView(mainwindow),
69     Kate::XMLGUIClient(KateQuickDocumentSwitcherFactory::componentData()),
70     m_prevDoc(0) {
71
72     KAction *a = actionCollection()->addAction("documents_quickswitch");
73     a->setText(i18n("Quickswitch"));
74     a->setShortcut(QKeySequence(Qt::CTRL+Qt::Key_1) );
75     connect( a, SIGNAL( triggered(bool) ), this, SLOT( slotQuickSwitch() ) );
76
77     mainwindow->guiFactory()->addClient (this);
78
79 }
80
81 PluginViewKateQuickDocumentSwitcher::~PluginViewKateQuickDocumentSwitcher() {
82       mainWindow()->guiFactory()->removeClient (this);
83 }
84
85 void PluginViewKateQuickDocumentSwitcher::slotQuickSwitch() {
86     KTextEditor::Document *doc=PluginViewKateQuickDocumentSwitcherDialog::document(mainWindow()->window(), m_prevDoc);
87     if (doc) {
88         // before switching save current document as alternate one so it
89         // would be preselected on a next switch for convenience
90         KTextEditor::Document* currentDocument = mainWindow()->activeView() ? mainWindow()->activeView()->document() : 0;
91         if(currentDocument != m_prevDoc)
92             m_prevDoc = currentDocument;
93
94         mainWindow()->activateView(doc);
95     }
96 }
97 //END: View
98
99 //BEGIN: Dialog
100 KTextEditor::Document *PluginViewKateQuickDocumentSwitcherDialog::document(QWidget *parent, KTextEditor::Document* docToSelect) {
101     PluginViewKateQuickDocumentSwitcherDialog dlg(parent, docToSelect);
102     if (QDialog::Accepted==dlg.exec()) {
103         // document ptr is held in the (row,0) , while item at (row, 1) might be selected,
104         // we need to obtain an index in (row,0)
105         QModelIndex selectedIdx = dlg.m_listView->currentIndex();
106         QModelIndex idx(dlg.m_listView->model()->index(selectedIdx.row(), 0));
107         if (idx.isValid()) {
108             QVariant _doc=idx.data(DocumentRole);
109             QPointer<KTextEditor::Document> doc=_doc.value<QPointer<KTextEditor::Document> >();
110             return (KTextEditor::Document*)doc;
111         }
112     }
113     return 0;
114 }
115
116 PluginViewKateQuickDocumentSwitcherDialog::PluginViewKateQuickDocumentSwitcherDialog(QWidget *parent, KTextEditor::Document* docToSelect):
117     KDialog(parent) {
118     setModal(true);
119
120     setButtons( KDialog::Ok | KDialog::Cancel);
121     setButtonGuiItem( KDialog::User1 , KGuiItem("Switch to") );
122     showButtonSeparator(true);
123     setCaption(i18n("Document Quick Switch"));
124
125     QWidget *mainwidget=new QWidget(this);
126
127     QVBoxLayout *layout=new QVBoxLayout(mainwidget);
128     layout->setSpacing(spacingHint());
129
130
131     m_inputLine=new KLineEdit(mainwidget);
132
133
134     QLabel *label=new QLabel(i18n("&Filter:"),this);
135     label->setBuddy(m_inputLine);
136
137     QHBoxLayout *subLayout=new QHBoxLayout();
138     subLayout->setSpacing(spacingHint());
139
140     subLayout->addWidget(label);
141     subLayout->addWidget(m_inputLine,1);
142
143     layout->addLayout(subLayout,0);
144
145     m_listView=new QTreeView(mainwidget);
146     layout->addWidget(m_listView,1);
147     m_listView->setTextElideMode(Qt::ElideLeft);
148
149     setMainWidget(mainwidget);
150     m_inputLine->setFocus(Qt::OtherFocusReason);
151
152     QStandardItemModel *base_model=new QStandardItemModel(0,2,this);
153     QList<KTextEditor::Document*> docs=Kate::application()->documentManager()->documents();
154     int linecount=0;
155     QModelIndex idxToSelect;
156     foreach(KTextEditor::Document *doc,docs) {
157         //QStandardItem *item=new QStandardItem(i18n("%1: %2",doc->documentName(),doc->url().prettyUrl()));
158         QStandardItem *itemName=new QStandardItem(doc->documentName());
159
160         itemName->setData(qVariantFromValue(QPointer<KTextEditor::Document>(doc)),DocumentRole);
161         itemName->setData(QString("%1: %2").arg(doc->documentName()).arg(doc->url().prettyUrl()),SortFilterRole);
162         itemName->setEditable(false);
163         QFont font=itemName->font();
164         font.setBold(true);
165         itemName->setFont(font);
166
167         QStandardItem *itemUrl = new QStandardItem(doc->url().prettyUrl());
168         itemUrl->setEditable(false);
169         base_model->setItem(linecount,0,itemName);
170         base_model->setItem(linecount,1,itemUrl);
171         linecount++;
172
173         if(doc == docToSelect)
174             idxToSelect = itemName->index();
175     }
176
177     m_model=new QSortFilterProxyModel(this);
178     m_model->setFilterRole(SortFilterRole);
179     m_model->setSortRole(SortFilterRole);
180     m_model->setFilterCaseSensitivity(Qt::CaseInsensitive);
181     m_model->setSortCaseSensitivity(Qt::CaseInsensitive);
182
183     connect(m_inputLine,SIGNAL(textChanged(const QString&)),m_model,SLOT(setFilterFixedString(const QString&)));
184     connect(m_model,SIGNAL(rowsInserted(const QModelIndex &,int,int)),this,SLOT(reselectFirst()));
185     connect(m_model,SIGNAL(rowsRemoved(const QModelIndex &,int,int)),this,SLOT(reselectFirst()));
186
187     connect(m_listView,SIGNAL(activated(const QModelIndex &)),this,SLOT(accept()));
188
189     m_listView->setModel(m_model);
190     m_model->setSourceModel(base_model);
191
192     if(idxToSelect.isValid())
193         m_listView->setCurrentIndex(m_model->mapFromSource(idxToSelect));
194     else
195         reselectFirst();
196
197     m_inputLine->installEventFilter(this);
198     m_listView->installEventFilter(this);
199     m_listView->setHeaderHidden(true);
200     m_listView->setRootIsDecorated(false);
201     QDesktopWidget *desktop=new QDesktopWidget();
202     setMinimumWidth(desktop->screenGeometry(parent).width()/2);
203     delete desktop;
204     m_listView->resizeColumnToContents(0);
205 }
206
207 bool PluginViewKateQuickDocumentSwitcherDialog::eventFilter(QObject *obj, QEvent *event) {
208     if (event->type()==QEvent::KeyPress) {
209         QKeyEvent *keyEvent=static_cast<QKeyEvent*>(event);
210         if (obj==m_inputLine) {
211             if ( (keyEvent->key()==Qt::Key_Up) || (keyEvent->key()==Qt::Key_Down) ) {
212                 QCoreApplication::sendEvent(m_listView,event);
213                 return true;
214             }
215         } else {
216             if ( (keyEvent->key()!=Qt::Key_Up) && (keyEvent->key()!=Qt::Key_Down) && (keyEvent->key()!=Qt::Key_Tab) && (keyEvent->key()!=Qt::Key_Backtab)) {
217                 QCoreApplication::sendEvent(m_inputLine,event);
218                 return true;
219             }
220         }
221     }
222     return KDialog::eventFilter(obj,event);
223 }
224
225 void PluginViewKateQuickDocumentSwitcherDialog::reselectFirst() {
226     QModelIndex index=m_model->index(0,0);
227     m_listView->setCurrentIndex(index);
228     enableButton(KDialog::Ok,index.isValid());
229 }
230
231 PluginViewKateQuickDocumentSwitcherDialog::~PluginViewKateQuickDocumentSwitcherDialog() {
232 }
233
234
235 //END: Dialog
236