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

Nepomuk-Core

  • tools
  • debugger
debug-message-view.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2011 Collabora Ltd. <info@collabora.com>
3  @author George Kiagiadakis <george.kiagiadakis@collabora.com>
4 
5  This library is free software; you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published
7  by the Free Software Foundation; either version 2.1 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 #include "debug-message-view.h"
19 
20 #include <TelepathyQt/PendingReady>
21 #include <TelepathyQt/Constants>
22 #include <TelepathyQt/DebugReceiver>
23 #include <TelepathyQt/PendingDebugMessageList>
24 
25 #include <KDebug>
26 #include <KIcon>
27 #include <KColorScheme>
28 #include <KStandardAction>
29 #include <KAction>
30 #include <KLocalizedString>
31 #include <KFindDialog>
32 #include <kfind.h>
33 
34 #include <ctime>
35 #include <QDate>
36 #include <QPointer>
37 
38 DebugMessageView::DebugMessageView(QWidget *parent)
39  : QTextEdit(parent),
40  m_ready(false)
41 {
42  setReadOnly(true);
43  setContextMenuPolicy(Qt::ActionsContextMenu);
44  KAction* addMark = new KAction(i18n("Add Mark"), this);
45  connect(addMark, SIGNAL(triggered(bool)), SLOT(onAddMark()));
46  addAction(KStandardAction::find(this, SLOT(openFindDialog()), this));
47  addAction(addMark);
48  addAction(KStandardAction::copy(this, SLOT(copy()), this));
49  addAction(KStandardAction::selectAll(this, SLOT(selectAll()), this));
50 }
51 
52 
53 DebugMessageView::~DebugMessageView()
54 {
55  if (m_debugReceiver && m_ready) {
56  //disable monitoring and do it synchronously before all the objects are destroyed
57  Tp::PendingOperation *op = m_debugReceiver->setMonitoringEnabled(false);
58  QEventLoop loop;
59  connect(op, SIGNAL(finished(Tp::PendingOperation*)), &loop, SLOT(quit()));
60  loop.exec();
61  }
62 }
63 
64 void DebugMessageView::setService(const QString &service)
65 {
66  m_serviceName = service;
67  m_serviceWatcher = new QDBusServiceWatcher(service, QDBusConnection::sessionBus(),
68  QDBusServiceWatcher::WatchForRegistration, this);
69  connect(m_serviceWatcher, SIGNAL(serviceRegistered(QString)),
70  SLOT(onServiceRegistered(QString)));
71 
72  if (QDBusConnection::sessionBus().interface()->isServiceRegistered(service)) {
73  onServiceRegistered(service);
74  }
75 }
76 
77 
78 void DebugMessageView::onServiceRegistered(const QString & service)
79 {
80  kDebug() << "Service" << service << "registered. Introspecting Debug interface...";
81 
82  m_debugReceiver = Tp::DebugReceiver::create(service);
83 
84  Tp::PendingReady *op = m_debugReceiver->becomeReady();
85  connect(op, SIGNAL(finished(Tp::PendingOperation*)),
86  SLOT(onDebugReceiverReady(Tp::PendingOperation*)));
87 }
88 
89 void DebugMessageView::onDebugReceiverInvalidated(Tp::DBusProxy *proxy,
90  const QString &errorName, const QString &errorMessage)
91 {
92  Q_UNUSED(proxy);
93  kDebug() << "DebugReceiver invalidated" << errorName << errorMessage;
94  m_ready = false;
95  m_debugReceiver.reset();
96 }
97 
98 void DebugMessageView::onDebugReceiverReady(Tp::PendingOperation *op)
99 {
100  if (op->isError()) {
101  kDebug() << "Failed to introspect Debug interface for" << m_serviceName
102  << "Error was:" << op->errorName() << "-" << op->errorMessage();
103  m_debugReceiver.reset();
104  } else {
105  connect(m_debugReceiver.data(), SIGNAL(newDebugMessage(Tp::DebugMessage)),
106  SLOT(onNewDebugMessage(Tp::DebugMessage)));
107 
108  connect(m_debugReceiver->setMonitoringEnabled(true),
109  SIGNAL(finished(Tp::PendingOperation*)),
110  SLOT(onDebugReceiverMonitoringEnabled(Tp::PendingOperation*)));
111  }
112 }
113 
114 void DebugMessageView::onDebugReceiverMonitoringEnabled(Tp::PendingOperation* op)
115 {
116  if (op->isError()) {
117  kError() << "Failed to enable monitoring on the Debug object of" << m_serviceName
118  << "Error was:" << op->errorName() << "-" << op->errorMessage();
119  m_tmpCache.clear();
120  m_debugReceiver.reset();
121  } else {
122  connect(m_debugReceiver->fetchMessages(), SIGNAL(finished(Tp::PendingOperation*)),
123  SLOT(onFetchMessagesFinished(Tp::PendingOperation*)));
124  }
125 }
126 
127 void DebugMessageView::onFetchMessagesFinished(Tp::PendingOperation* op)
128 {
129  if (op->isError()) {
130  kError() << "Failed to fetch messages from" << m_serviceName
131  << "Error was:" << op->errorName() << "-" << op->errorMessage();
132  m_tmpCache.clear();
133  m_debugReceiver.reset();
134  } else {
135  Tp::PendingDebugMessageList *pdml = qobject_cast<Tp::PendingDebugMessageList*>(op);
136  Tp::DebugMessageList messages = pdml->result();
137  messages.append(m_tmpCache); //append any messages that were received from onNewDebugMessage()
138  m_tmpCache.clear();
139 
140  Q_FOREACH(const Tp::DebugMessage &msg, messages) {
141  appendMessage(msg);
142  }
143 
144  //TODO limit m_messages size
145 
146  m_ready = true;
147  connect(m_debugReceiver.data(),
148  SIGNAL(invalidated(Tp::DBusProxy*,QString,QString)),
149  SLOT(onDebugReceiverInvalidated(Tp::DBusProxy*,QString,QString)));
150  }
151 }
152 
153 void DebugMessageView::onNewDebugMessage(const Tp::DebugMessage & msg)
154 {
155  if (m_ready) {
156  appendMessage(msg);
157  } else {
158  //cache until we are ready
159  m_tmpCache.append(msg);
160  }
161 }
162 
163 
164 //taken from empathy
165 static inline QString formatTimestamp(double timestamp)
166 {
167  struct tm *tstruct;
168  char time_str[32];
169  int ms;
170  time_t sec;
171 
172  ms = (int) ((timestamp - (int) timestamp)*1e6);
173  sec = (long) timestamp;
174  tstruct = std::localtime((time_t *) &sec);
175  if (!std::strftime(time_str, sizeof(time_str), "%x %T", tstruct)) {
176  kDebug() << "Failed to format timestamp" << timestamp;
177  time_str[0] = '\0';
178  }
179 
180  QString str;
181  str.sprintf("%s.%d", time_str, ms);
182  return str;
183 }
184 
185 void DebugMessageView::appendMessage(const Tp::DebugMessage &msg)
186 {
187  QString message = QString(formatTimestamp(msg.timestamp) %
188  QLatin1Literal(" - [") % msg.domain % QLatin1Literal("] ") %
189  msg.message);
190  append(message);
191 }
192 
193 void DebugMessageView::onAddMark()
194 {
195  append(QString(QLatin1String("%1 -----------------------------")).arg(QDate::currentDate().toString()));
196 }
197 
198 void DebugMessageView::openFindDialog()
199 {
200  QPointer<KFindDialog> dialog(new KFindDialog(this));
201  dialog->setPattern(textCursor().selectedText());
202  if(dialog->exec()==QDialog::Accepted) {
203  QTextDocument::FindFlags flags=0;
204  if(dialog->options() & KFind::FindBackwards) flags |= QTextDocument::FindBackward;
205  if(dialog->options() & KFind::WholeWordsOnly) flags |= QTextDocument::FindWholeWords;
206  if(dialog->options() & KFind::CaseSensitive) flags |= QTextDocument::FindCaseSensitively;
207  bool ret = find(dialog->pattern(), flags);
208  if(!ret) {
209  Q_EMIT statusMessage(i18n("Could not find '%1'", dialog->pattern()));
210  }
211  }
212  delete dialog;
213 }
This file is part of the KDE documentation.
Documentation copyright © 1996-2013 The KDE developers.
Generated on Fri Mar 22 2013 10:58:52 by doxygen 1.8.1.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

ktp-common-internals API Reference

Skip menu "ktp-common-internals API Reference"
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