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

Kate

  • kde-4.14
  • applications
  • kate
  • part
  • view
katemessagewidget.cpp
Go to the documentation of this file.
1 /* This file is part of the KDE and the Kate project
2  *
3  * Copyright (C) 2012 Dominik Haumann <dhaumann@kde.org>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library 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 GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB. If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20 
21 #include "katemessagewidget.h"
22 #include "katemessagewidget.moc"
23 
24 #include <ktexteditor/messageinterface.h>
25 #include <kmessagewidget.h>
26 #include <kateanimation.h>
27 
28 #include <kdeversion.h>
29 #include <kdebug.h>
30 
31 #include <QtCore/QEvent>
32 #include <QtCore/QTimer>
33 #include <QtGui/QVBoxLayout>
34 #include <QToolTip>
35 #include <QShowEvent>
36 
37 static const int s_defaultAutoHideTime = 6 * 1000;
38 
39 KateMessageWidget::KateMessageWidget(QWidget* parent, bool applyFadeEffect)
40  : QWidget(parent)
41  , m_animation(0)
42  , m_autoHideTimer(new QTimer(this))
43  , m_autoHideTime(-1)
44 {
45  QVBoxLayout* l = new QVBoxLayout();
46  l->setMargin(0);
47 
48  m_messageWidget = new KMessageWidget(this);
49  m_messageWidget->setCloseButtonVisible(false);
50 
51  l->addWidget(m_messageWidget);
52  setLayout(l);
53 
54  // tell the widget to always use the minimum size.
55  setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);
56 
57  // install event filter so we catch the end of the hide animation
58  m_messageWidget->installEventFilter(this);
59 
60  // by default, hide widgets
61  m_messageWidget->hide();
62  hide();
63 
64  // create animation controller, and connect widgetHidden() to showNextMessage()
65  m_animation = new KateAnimation(m_messageWidget, applyFadeEffect ? KateAnimation::FadeEffect : KateAnimation::GrowEffect);
66  connect(m_animation, SIGNAL(widgetHidden()), this, SLOT(showNextMessage()));
67 
68  // setup autoHide timer details
69  m_autoHideTimer->setSingleShot(true);
70 
71 #if KDE_IS_VERSION(4,10,60) // KMessageWidget::linkHovered() is new in KDE 4.11
72  connect(m_messageWidget, SIGNAL(linkHovered(const QString&)), SLOT(linkHovered(const QString&))); // FIXME: TODO: this?
73 #endif
74 }
75 
76 void KateMessageWidget::showNextMessage()
77 {
78  // at this point, we should not have a currently shown message
79  Q_ASSERT(m_currentMessage == 0);
80 
81  // if not message to show, just stop
82  if (m_messageQueue.size() == 0) {
83  hide();
84  return;
85  }
86 
87  // track current message
88  m_currentMessage = m_messageQueue[0];
89 
90  // set text etc.
91  m_messageWidget->setText(m_currentMessage->text());
92 #if KDE_VERSION >= KDE_MAKE_VERSION(4,10,60) // KMessageWidget::setIcon() requires KDE >= 4.11
93  m_messageWidget->setIcon(m_currentMessage->icon());
94 #endif
95 
96  // connect textChanged() and iconChanged(), so it's possible to change this on the fly
97  connect(m_currentMessage, SIGNAL(textChanged(const QString&)),
98  m_messageWidget, SLOT(setText(const QString&)), Qt::UniqueConnection);
99  connect(m_currentMessage, SIGNAL(iconChanged(const QIcon&)),
100  m_messageWidget, SLOT(setIcon(const QIcon&)), Qt::UniqueConnection);
101 
102  // the enums values do not necessarily match, hence translate with switch
103  switch (m_currentMessage->messageType()) {
104  case KTextEditor::Message::Positive:
105  m_messageWidget->setMessageType(KMessageWidget::Positive);
106  break;
107  case KTextEditor::Message::Information:
108  m_messageWidget->setMessageType(KMessageWidget::Information);
109  break;
110  case KTextEditor::Message::Warning:
111  m_messageWidget->setMessageType(KMessageWidget::Warning);
112  break;
113  case KTextEditor::Message::Error:
114  m_messageWidget->setMessageType(KMessageWidget::Error);
115  break;
116  default:
117  m_messageWidget->setMessageType(KMessageWidget::Information);
118  break;
119  }
120 
121  // remove all actions from the message widget
122  foreach (QAction* a, m_messageWidget->actions())
123  m_messageWidget->removeAction(a);
124 
125  // add new actions to the message widget
126  foreach (QAction* a, m_currentMessage->actions())
127  m_messageWidget->addAction(a);
128 
129  // set word wrap of the message
130  setWordWrap(m_currentMessage);
131 
132  // setup auto-hide timer, and start if requested
133  m_autoHideTime = m_currentMessage->autoHide();
134  m_autoHideTimer->stop();
135  if (m_autoHideTime >= 0) {
136  connect(m_autoHideTimer, SIGNAL(timeout()), m_currentMessage, SLOT(deleteLater()), Qt::UniqueConnection);
137  if (m_currentMessage->autoHideMode() == KTextEditor::Message::Immediate) {
138  m_autoHideTimer->start(m_autoHideTime == 0 ? s_defaultAutoHideTime : m_autoHideTime);
139  }
140  }
141 
142  // finally show
143  show();
144  m_animation->show();
145 }
146 
147 void KateMessageWidget::setWordWrap(KTextEditor::Message* message)
148 {
149  // want word wrap anyway? -> ok
150  if (message->wordWrap()) {
151  m_messageWidget->setWordWrap(message->wordWrap());
152  return;
153  }
154 
155  // word wrap not wanted, that's ok if a parent widget does not exist
156  if (!parentWidget()) {
157  m_messageWidget->setWordWrap(false);
158  return;
159  }
160 
161  // word wrap not wanted -> enable word wrap if it breaks the layout otherwise
162  int margin = 0;
163  if (parentWidget()->layout()) {
164  // get left/right margin of the layout, since we need to subtract these
165  int leftMargin = 0, rightMargin = 0;
166  parentWidget()->layout()->getContentsMargins(&leftMargin, 0, &rightMargin, 0);
167  margin = leftMargin + rightMargin;
168  }
169 
170  // if word wrap enabled, first disable it
171  if (m_messageWidget->wordWrap())
172  m_messageWidget->setWordWrap(false);
173 
174  // make sure the widget's size is up-to-date in its hidden state
175  m_messageWidget->ensurePolished();
176  m_messageWidget->adjustSize();
177 
178  // finally enable word wrap, if there is not enough free horizontal space
179  const int freeSpace = (parentWidget()->width() - margin) - m_messageWidget->width();
180  if (freeSpace < 0) {
181 // kDebug() << "force word wrap to avoid breaking the layout" << freeSpace;
182  m_messageWidget->setWordWrap(true);
183  }
184 }
185 
186 void KateMessageWidget::postMessage(KTextEditor::Message* message,
187  QList<QSharedPointer<QAction> > actions)
188 {
189  Q_ASSERT(!m_messageHash.contains(message));
190  m_messageHash[message] = actions;
191 
192  // insert message sorted after priority
193  int i = 0;
194  for (; i < m_messageQueue.count(); ++i) {
195  if (message->priority() > m_messageQueue[i]->priority())
196  break;
197  }
198 
199  // queue message
200  m_messageQueue.insert(i, message);
201 
202  // catch if the message gets deleted
203  connect(message, SIGNAL(closed(KTextEditor::Message*)), SLOT(messageDestroyed(KTextEditor::Message*)));
204 
205  if (i == 0 && !m_animation->hideAnimationActive()) {
206  // if message has higher priority than the one currently shown,
207  // then hide the current one and then show the new one.
208  if (m_currentMessage) {
209 
210  // autoHide timer may be running for currently shown message, therefore
211  // simply disconnect autoHide timer to all timeout() receivers
212  disconnect(m_autoHideTimer, SIGNAL(timeout()), 0, 0);
213  m_autoHideTimer->stop();
214 
215  // if there is a current message, the message queue must contain 2 messages
216  Q_ASSERT(m_messageQueue.size() > 1);
217  Q_ASSERT(m_currentMessage == m_messageQueue[1]);
218 
219  // a bit unnice: disconnect textChanged() and iconChanged() signals of previously visible message
220  disconnect(m_currentMessage, SIGNAL(textChanged(const QString&)),
221  m_messageWidget, SLOT(setText(const QString&)));
222  disconnect(m_currentMessage, SIGNAL(iconChanged(const QIcon&)),
223  m_messageWidget, SLOT(setIcon(const QIcon&)));
224 
225  m_currentMessage = 0;
226  m_animation->hide();
227  } else {
228  showNextMessage();
229  }
230  }
231 }
232 
233 void KateMessageWidget::messageDestroyed(KTextEditor::Message* message)
234 {
235  // last moment when message is valid, since KTE::Message is already in
236  // destructor we have to do the following:
237  // 1. remove message from m_messageQueue, so we don't care about it anymore
238  // 2. activate hide animation or show a new message()
239 
240  // remove widget from m_messageQueue
241  int i = 0;
242  for (; i < m_messageQueue.count(); ++i) {
243  if (m_messageQueue[i] == message) {
244  break;
245  }
246  }
247 
248  // the message must be in the list
249  Q_ASSERT(i < m_messageQueue.count());
250 
251  // remove message
252  m_messageQueue.removeAt(i);
253 
254  // remove message from hash -> release QActions
255  Q_ASSERT(m_messageHash.contains(message));
256  m_messageHash.remove(message);
257 
258  // if deleted message is the current message, launch hide animation
259  if (message == m_currentMessage) {
260  m_currentMessage = 0;
261  m_animation->hide();
262  }
263 }
264 
265 void KateMessageWidget::startAutoHideTimer()
266 {
267  // message does not want autohide, or timer already running
268  if ( !m_currentMessage // no message, nothing to do
269  || m_autoHideTime < 0 // message does not want auto-hide
270  || m_autoHideTimer->isActive() // auto-hide timer is already active
271  || m_animation->hideAnimationActive() // widget is in hide animation phase
272  || m_animation->showAnimationActive() // widget is in show animation phase
273  ) {
274  return;
275  }
276 
277  // safety checks: the message must still still be valid
278  Q_ASSERT(m_messageQueue.size());
279  Q_ASSERT(m_currentMessage->autoHide() == m_autoHideTime);
280 
281  // start autoHide timer as requrested
282  m_autoHideTimer->start(m_autoHideTime == 0 ? s_defaultAutoHideTime : m_autoHideTime);
283 }
284 
285 void KateMessageWidget::linkHovered(const QString& link)
286 {
287  QToolTip::showText(QCursor::pos(), link, m_messageWidget);
288 }
289 
290 QString KateMessageWidget::text() const
291 {
292  return m_messageWidget->text();
293 }
294 // kate: space-indent on; indent-width 2; replace-tabs on;
QWidget::layout
QLayout * layout() const
QWidget
KateAnimation::hideAnimationActive
bool hideAnimationActive() const
Returns true, if the hide animation is running, otherwise false.
Definition: kateanimation.cpp:54
KateAnimation::GrowEffect
grow / shrink
Definition: kateanimation.h:51
QWidget::setIcon
void setIcon(const QPixmap &i)
KateMessageWidget::linkHovered
void linkHovered(const QString &link)
User hovers on a link in the message widget.
Definition: katemessagewidget.cpp:285
KateMessageWidget::KateMessageWidget
KateMessageWidget(QWidget *parent, bool applyFadeEffect=false)
Constructor.
Definition: katemessagewidget.cpp:39
KateAnimation::showAnimationActive
bool showAnimationActive() const
Returns true, if the how animation is running, otherwise false.
Definition: kateanimation.cpp:59
QList::removeAt
void removeAt(int i)
QObject::disconnect
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
QToolTip::showText
void showText(const QPoint &pos, const QString &text, QWidget *w)
QList::size
int size() const
QWidget::width
width
KateAnimation::FadeEffect
fade in/out
Definition: kateanimation.h:50
KateAnimation::show
void show()
Call to show and fade in the widget.
Definition: kateanimation.cpp:64
QLayout::getContentsMargins
void getContentsMargins(int *left, int *top, int *right, int *bottom) const
KateMessageWidget::showNextMessage
void showNextMessage()
Show the next message in the queue.
Definition: katemessagewidget.cpp:76
QBoxLayout::addWidget
void addWidget(QWidget *widget, int stretch, QFlags< Qt::AlignmentFlag > alignment)
QList::count
int count(const T &value) const
kateanimation.h
QWidget::setLayout
void setLayout(QLayout *layout)
QTimer
QSharedPointer
KateAnimation
This class provides a fade in/out effect for KMessageWidgets.
Definition: kateanimation.h:41
KateMessageWidget::text
QString text() const
Definition: katemessagewidget.cpp:290
QVBoxLayout
QObject::deleteLater
void deleteLater()
QString
QList
QWidget::hide
void hide()
QHash::remove
int remove(const Key &key)
QLayout::setMargin
void setMargin(int margin)
QWidget::setSizePolicy
void setSizePolicy(QSizePolicy)
QTimer::stop
void stop()
KateMessageWidget::setWordWrap
void setWordWrap(KTextEditor::Message *message)
Helper that enables word wrap to avoid breaking the layout.
Definition: katemessagewidget.cpp:147
KateMessageWidget::postMessage
void postMessage(KTextEditor::Message *message, QList< QSharedPointer< QAction > > actions)
Post a new incoming message.
Definition: katemessagewidget.cpp:186
KateMessageWidget::messageDestroyed
void messageDestroyed(KTextEditor::Message *message)
catch when a message is deleted, then show next one, if applicable.
Definition: katemessagewidget.cpp:233
QCursor::pos
QPoint pos()
s_defaultAutoHideTime
static const int s_defaultAutoHideTime
Definition: katemessagewidget.cpp:37
QList::insert
void insert(int i, const T &value)
QWidget::parentWidget
QWidget * parentWidget() const
QAction
QTimer::start
void start(int msec)
QHash::contains
bool contains(const Key &key) const
KateAnimation::hide
void hide()
Call to hide the widget.
Definition: kateanimation.cpp:92
QWidget::show
void show()
KateMessageWidget::startAutoHideTimer
void startAutoHideTimer()
Start autoHide timer if requested.
Definition: katemessagewidget.cpp:265
QTimer::isActive
bool isActive() const
Kate::Error
Definition: katedefaultcolors.h:62
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QWidget::actions
QList< QAction * > actions() const
katemessagewidget.h
Kate::Warning
Definition: katedefaultcolors.h:61
QIcon
QTimer::setSingleShot
void setSingleShot(bool singleShot)
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Sat May 9 2020 03:56:58 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

Kate

Skip menu "Kate"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

applications API Reference

Skip menu "applications API Reference"
  •   kate
  •       kate
  •   KTextEditor
  •   Kate
  • Konsole

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