• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

kmail

  • sources
  • kde-4.12
  • kdepim
  • kmail
  • searchdialog
  • debug
searchdebugwidget.cpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 2013 Montel Laurent <montel@kde.org>
3 
4  This program is free software; you can redistribute it and/or modify it
5  under the terms of the GNU General Public License, version 2, as
6  published by the Free Software Foundation.
7 
8  This program is distributed in the hope that it will be useful, but
9  WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License along
14  with this program; if not, write to the Free Software Foundation, Inc.,
15  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 #include "searchdebugwidget.h"
19 #include "sparqlsyntaxhighlighter.h"
20 #include "searchdebugnepomukshowdialog.h"
21 
22 #include "util.h"
23 
24 #include "pimcommon/texteditor/plaintexteditor/plaintexteditorwidget.h"
25 #include "pimcommon/texteditor/plaintexteditor/plaintexteditor.h"
26 
27 
28 #include <KPIMUtils/ProgressIndicatorLabel>
29 
30 #include <akonadi/itemfetchjob.h>
31 #include <akonadi/itemfetchscope.h>
32 #include <akonadi/itemsearchjob.h>
33 
34 #include <KMessageBox>
35 #include <KLocale>
36 
37 #include <QPlainTextEdit>
38 #include <QGridLayout>
39 #include <QVBoxLayout>
40 #include <QLabel>
41 #include <QStringListModel>
42 #include <QPushButton>
43 #include <QShortcut>
44 #include <QContextMenuEvent>
45 #include <QMenu>
46 #include <QPointer>
47 
48 SearchResultListView::SearchResultListView(QWidget *parent)
49  : QListView(parent)
50 {
51 
52 }
53 
54 SearchResultListView::~SearchResultListView()
55 {
56 
57 }
58 
59 void SearchResultListView::contextMenuEvent( QContextMenuEvent * event )
60 {
61  const QModelIndex index = indexAt( event->pos() );
62  if (!index.isValid())
63  return;
64 
65  QMenu *popup = new QMenu(this);
66  QAction *searchNepomukShow = new QAction(i18n("Search with nepomuk show..."), popup);
67  popup->addAction(searchNepomukShow);
68  QAction *act = popup->exec( event->globalPos() );
69  delete popup;
70  if (act == searchNepomukShow) {
71  const QString uid = QLatin1String("akonadi:?item=") + index.data( Qt::DisplayRole ).toString();
72  QPointer<SearchDebugNepomukShowDialog> dlg = new SearchDebugNepomukShowDialog(uid, this);
73  dlg->exec();
74  delete dlg;
75  }
76 }
77 
78 SearchDebugListDelegate::SearchDebugListDelegate( QObject *parent )
79  : QStyledItemDelegate ( parent )
80 {
81 }
82 
83 SearchDebugListDelegate::~SearchDebugListDelegate()
84 {
85 }
86 
87 QWidget *SearchDebugListDelegate::createEditor( QWidget *, const QStyleOptionViewItem &, const QModelIndex & ) const
88 {
89  return 0;
90 }
91 
92 SearchDebugWidget::SearchDebugWidget(const QString &query, QWidget *parent)
93  : QWidget(parent)
94 {
95  QGridLayout *layout = new QGridLayout;
96 
97  mTextEdit = new PimCommon::PlainTextEditorWidget( this );
98  // we install an event filter to catch Ctrl+Return for quick query execution
99  mTextEdit->installEventFilter( this );
100 
101  indentQuery(query);
102  new Nepomuk2::SparqlSyntaxHighlighter( mTextEdit->editor()->document() );
103 
104  mResultView = new SearchResultListView;
105  mResultView->setItemDelegate(new SearchDebugListDelegate(this));
106 
107  mItemView = new PimCommon::PlainTextEditorWidget;
108  mItemView->setReadOnly(true);
109 
110  layout->addWidget( mTextEdit, 0, 0, 1, 2);
111  layout->addWidget( new QLabel( i18n("Akonadi Id:") ), 1, 0 );
112  layout->addWidget( new QLabel( i18n("Messages:") ), 1, 1 );
113 
114  layout->addWidget( mResultView, 2, 0, 1, 1 );
115  layout->addWidget( mItemView, 2, 1, 1, 1 );
116 
117  mReduceQuery = new QPushButton( i18n("Reduce query") );
118  connect(mReduceQuery, SIGNAL(clicked()), SLOT(slotReduceQuery()));
119 
120  mSearchButton = new QPushButton( i18n("Search") );
121  mSearchButton->setEnabled(false);
122  connect( mSearchButton, SIGNAL(clicked()), this, SLOT(slotSearch()) );
123  mProgressIndicator = new KPIMUtils::ProgressIndicatorLabel(i18n("Searching..."));
124 
125  mResultLabel = new QLabel;
126  layout->addWidget( mResultLabel, 3, 0, Qt::AlignLeft );
127 
128  layout->addWidget( mProgressIndicator, 4, 0, Qt::AlignLeft );
129  layout->addWidget( mSearchButton, 4, 1, Qt::AlignRight );
130  layout->addWidget( mReduceQuery, 5, 1, Qt::AlignRight );
131  setLayout(layout);
132 
133  connect( mResultView, SIGNAL(activated(QModelIndex)), this, SLOT(slotFetchItem(QModelIndex)) );
134  connect(mTextEdit->editor(), SIGNAL(textChanged()), SLOT(slotUpdateSearchButton()));
135  mResultModel = new QStringListModel( this );
136  mResultView->setModel( mResultModel );
137 
138  slotSearch();
139 }
140 
141 SearchDebugWidget::~SearchDebugWidget()
142 {
143 }
144 
145 bool SearchDebugWidget::eventFilter( QObject *watched, QEvent *event )
146 {
147  if( watched == mTextEdit && event->type() == QEvent::KeyPress ) {
148  QKeyEvent* kev = static_cast<QKeyEvent*>(event);
149  if( kev->key() == Qt::Key_Return &&
150  kev->modifiers() == Qt::ControlModifier ) {
151  slotSearch();
152  return true;
153  }
154  }
155 
156  return QWidget::eventFilter( watched, event );
157 }
158 
159 void SearchDebugWidget::slotUpdateSearchButton()
160 {
161  mSearchButton->setEnabled(!mTextEdit->editor()->toPlainText().isEmpty());
162 }
163 
164 QString SearchDebugWidget::queryStr() const
165 {
166  return mTextEdit->editor()->toPlainText();
167 }
168 
169 void SearchDebugWidget::slotSearch()
170 {
171  const QString query = mTextEdit->editor()->toPlainText();
172 
173  if (query.isEmpty()) {
174  mResultLabel->setText(i18n("Query is empty."));
175  mSearchButton->setEnabled(false);
176  mReduceQuery->setEnabled(false);
177  return;
178  }
179 
180  mResultModel->setStringList( QStringList() );
181  mItemView->editor()->clear();
182  mResultLabel->clear();
183  mProgressIndicator->start();
184  mSearchButton->setEnabled(false);
185  mReduceQuery->setEnabled(false);
186 
187  Akonadi::ItemSearchJob *job = new Akonadi::ItemSearchJob( query );
188  connect( job, SIGNAL(result(KJob*)), this, SLOT(slotSearchFinished(KJob*)) );
189 }
190 
191 void SearchDebugWidget::indentQuery(QString query)
192 {
193  query = query.simplified();
194  QString newQuery;
195  int i = 0;
196  int indent = 0;
197  const int space = 4;
198 
199  while(i < query.size()) {
200  newQuery.append(query[i]);
201  if (query[i] != QLatin1Char('"') && query[i] != QLatin1Char('<') && query[i] != QLatin1Char('\'')) {
202  if (query[i] == QLatin1Char('{')) {
203  ++indent;
204  newQuery.append(QLatin1Char('\n'));
205  newQuery.append(QString().fill(QLatin1Char(' '), indent*space));
206  } else if (query[i] == QLatin1Char('.')) {
207  if(i+2<query.size()) {
208  if(query[i+1] == QLatin1Char('}')||query[i+2] == QLatin1Char('}')) {
209  newQuery.append(QLatin1Char('\n'));
210  newQuery.append(QString().fill(QLatin1Char(' '), (indent-1)*space));
211  } else {
212  newQuery.append(QLatin1Char('\n'));
213  newQuery.append(QString().fill(QLatin1Char(' '), indent*space));
214  }
215  } else {
216  newQuery.append(QLatin1Char('\n'));
217  newQuery.append(QString().fill(QLatin1Char(' '), indent*space));
218  }
219  } else if (query[i] == QLatin1Char('}')) {
220  indent--;
221  if (i+2<query.size()) {
222  if (query[i+2] == QLatin1Char('.')||query[i+1] == QLatin1Char('.')) {
223  newQuery.append(QString().fill(QLatin1Char(' '), 1));
224  } else {
225  newQuery.append(QLatin1Char('\n'));
226  newQuery.append(QString().fill(QLatin1Char(' '), indent*space));
227  }
228  } else {
229  newQuery.append(QLatin1Char('\n'));
230  newQuery.append(QString().fill(QLatin1Char(' '), indent*space));
231  }
232  }
233  } else {
234  ++i;
235  while(i < query.size()) {
236  if (query[i] == QLatin1Char('"') || query[i] == QLatin1Char('>') || query[i] == QLatin1Char('\'')) {
237  newQuery.append(query[i]);
238  break;
239  }
240  newQuery.append(query[i]);
241  ++i;
242  }
243  }
244  ++i;
245  }
246  mTextEdit->editor()->setPlainText( newQuery );
247 }
248 
249 void SearchDebugWidget::slotReduceQuery()
250 {
251  QString query = mTextEdit->editor()->toPlainText();
252  KMail::Util::reduceQuery(query);
253  indentQuery(query);
254 }
255 
256 void SearchDebugWidget::slotSearchFinished(KJob *job)
257 {
258  mProgressIndicator->stop();
259  mSearchButton->setEnabled(true);
260  mReduceQuery->setEnabled(true);
261 
262  if ( job->error() ) {
263  KMessageBox::error( this, job->errorString() );
264  return;
265  }
266 
267  QStringList uidList;
268  Akonadi::ItemSearchJob *searchJob = qobject_cast<Akonadi::ItemSearchJob*>( job );
269  const Akonadi::Item::List items = searchJob->items();
270  Q_FOREACH ( const Akonadi::Item &item, items ) {
271  uidList << QString::number( item.id() );
272  }
273 
274  mResultModel->setStringList( uidList );
275  if (uidList.isEmpty()) {
276  mResultLabel->setText(i18n("No message found"));
277  } else {
278  mResultLabel->setText(i18np("1 message found", "%1 messages found", uidList.count()));
279  }
280 }
281 
282 void SearchDebugWidget::slotFetchItem( const QModelIndex &index )
283 {
284  if ( !index.isValid() )
285  return;
286 
287  const QString uid = index.data( Qt::DisplayRole ).toString();
288  Akonadi::ItemFetchJob *fetchJob = new Akonadi::ItemFetchJob( Akonadi::Item( uid.toLongLong() ) );
289  fetchJob->fetchScope().fetchFullPayload();
290  connect( fetchJob, SIGNAL(result(KJob*)), this, SLOT(slotItemFetched(KJob*)) );
291 }
292 
293 void SearchDebugWidget::slotItemFetched( KJob *job )
294 {
295  mItemView->editor()->clear();
296 
297  if ( job->error() ) {
298  KMessageBox::error( this, i18n("Error on fetching item") );
299  return;
300  }
301 
302  Akonadi::ItemFetchJob *fetchJob = qobject_cast<Akonadi::ItemFetchJob*>( job );
303  if ( !fetchJob->items().isEmpty() ) {
304  const Akonadi::Item item = fetchJob->items().first();
305  mItemView->editor()->setPlainText( QString::fromUtf8( item.payloadData() ) );
306  }
307 }
308 
309 
310 #include "searchdebugwidget.moc"
SearchResultListView::SearchResultListView
SearchResultListView(QWidget *parent=0)
Definition: searchdebugwidget.cpp:48
SearchDebugListDelegate::~SearchDebugListDelegate
~SearchDebugListDelegate()
Definition: searchdebugwidget.cpp:83
QWidget
QObject
sparqlsyntaxhighlighter.h
QStyledItemDelegate
SearchDebugListDelegate::createEditor
QWidget * createEditor(QWidget *, const QStyleOptionViewItem &, const QModelIndex &) const
Definition: searchdebugwidget.cpp:87
SearchDebugWidget::eventFilter
bool eventFilter(QObject *watched, QEvent *event)
Definition: searchdebugwidget.cpp:145
SearchDebugWidget::SearchDebugWidget
SearchDebugWidget(const QString &query, QWidget *parent=0)
Definition: searchdebugwidget.cpp:92
KMail::Util::reduceQuery
void reduceQuery(QString &query)
Definition: util.cpp:227
searchdebugwidget.h
SearchDebugListDelegate
Definition: searchdebugwidget.h:51
util.h
SearchResultListView
Definition: searchdebugwidget.h:40
SearchDebugWidget::queryStr
QString queryStr() const
Definition: searchdebugwidget.cpp:164
SearchResultListView::contextMenuEvent
void contextMenuEvent(QContextMenuEvent *event)
Definition: searchdebugwidget.cpp:59
QListView
QMenu
SearchDebugListDelegate::SearchDebugListDelegate
SearchDebugListDelegate(QObject *parent=0)
Definition: searchdebugwidget.cpp:78
QLabel
Nepomuk2::SparqlSyntaxHighlighter
Definition: sparqlsyntaxhighlighter.h:28
searchdebugnepomukshowdialog.h
SearchDebugWidget::~SearchDebugWidget
~SearchDebugWidget()
Definition: searchdebugwidget.cpp:141
SearchResultListView::~SearchResultListView
~SearchResultListView()
Definition: searchdebugwidget.cpp:54
SearchDebugNepomukShowDialog
Definition: searchdebugnepomukshowdialog.h:27
KJob
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:58:52 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kmail

Skip menu "kmail"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal