VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/extensions/QILabel.cpp@ 35740

Last change on this file since 35740 was 33540, checked in by vboxsync, 14 years ago

*: spelling fixes, thanks Timeless!

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Revision Author Id
File size: 9.7 KB
Line 
1/* $Id: QILabel.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
2/** @file
3 *
4 * VBox frontends: Qt GUI ("VirtualBox"):
5 * VirtualBox Qt extensions: QILabel class implementation
6 */
7
8/*
9 * Copyright (C) 2006-2008 Oracle Corporation
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 */
19
20/*
21 * This class is based on the original QLabel implementation.
22 */
23
24/* Global includes */
25#include <QApplication>
26#include <QClipboard>
27#include <QContextMenuEvent>
28#include <QFocusEvent>
29#include <QMenu>
30#include <QMimeData>
31#include <QMouseEvent>
32#include <QPainter>
33#include <QStyleOptionFocusRect>
34
35/* Local includes */
36#include "QILabel.h"
37
38/* Some constant regular expressions */
39const QRegExp QILabel::mCopyRegExp = QRegExp ("<[^>]*>");
40QRegExp QILabel::mElideRegExp = QRegExp ("(<compact\\s+elipsis=\"(start|middle|end)\"?>([^<]*)</compact>)");
41
42#define HOR_PADDING 1
43
44QILabel::QILabel (QWidget *aParent /* = 0 */, Qt::WindowFlags aFlags /* = 0 */)
45 : QLabel (aParent, aFlags)
46{
47 init();
48}
49
50QILabel::QILabel (const QString &aText, QWidget *aParent /* = 0 */, Qt::WindowFlags aFlags /* = 0 */)
51 : QLabel (aParent, aFlags)
52{
53 init();
54 setFullText (aText);
55}
56
57bool QILabel::fullSizeSelection () const
58{
59 return mFullSizeSelection;
60}
61
62void QILabel::setFullSizeSelection (bool aEnabled)
63{
64 mFullSizeSelection = aEnabled;
65 if (mFullSizeSelection)
66 {
67 /* Enable mouse interaction only */
68 setTextInteractionFlags (Qt::LinksAccessibleByMouse);
69 /* The label should be able to get the focus */
70 setFocusPolicy (Qt::StrongFocus);
71 /* Change the appearance in the focus state a little bit.
72 * Note: Unfortunately QLabel, precisely the text of a QLabel isn't
73 * styleable. The trolls have forgotten the simplest case ... So this
74 * is done by changing the currently used palette in the In/Out-focus
75 * events below. Next broken feature is drawing a simple dotted line
76 * around the label. So this is done manually in the paintEvent. Not
77 * sure if the stylesheet stuff is ready for production environments. */
78 setStyleSheet (QString ("QLabel::focus {\
79 background-color: palette(highlight);\
80 }\
81 QLabel {\
82 padding: 0px %1px 0px %1px;\
83 }").arg (HOR_PADDING));
84 }
85 else
86 {
87 /* Text should be selectable/copyable */
88 setTextInteractionFlags (Qt::TextBrowserInteraction);
89 /* No Focus an the label */
90 setFocusPolicy (Qt::NoFocus);
91 /* No focus style change */
92 setStyleSheet ("");
93 }
94}
95
96void QILabel::useSizeHintForWidth (int aWidthHint) const
97{
98 mWidthHint = aWidthHint;
99 updateSizeHint();
100}
101
102QSize QILabel::sizeHint() const
103{
104 if (!mIsHintValid)
105 updateSizeHint();
106
107 /* If there is an updated sizeHint() present - using it. */
108 return mOwnSizeHint.isValid() ? mOwnSizeHint : QLabel::sizeHint();
109}
110
111QSize QILabel::minimumSizeHint() const
112{
113 if (!mIsHintValid)
114 updateSizeHint();
115
116 /* If there is an updated minimumSizeHint() present - using it. */
117 return mOwnSizeHint.isValid() ? mOwnSizeHint : QLabel::minimumSizeHint();
118}
119
120QString QILabel::text() const
121{
122 return mText;
123}
124
125void QILabel::clear()
126{
127 QLabel::clear();
128 setFullText ("");
129}
130
131void QILabel::setText (const QString &aText)
132{
133 setFullText (aText);
134
135 /* If QILabel forced to be fixed vertically */
136 if (minimumHeight() == maximumHeight())
137 {
138 /* Check if new text requires label growing */
139 QSize sh (width(), heightForWidth (width()));
140 if (sh.height() > minimumHeight())
141 setFixedHeight (sh.height());
142 }
143}
144
145void QILabel::copy()
146{
147 QString text = removeHtmlTags (mText);
148 /* Copy the current text to the global and selection clipboard. */
149 QApplication::clipboard()->setText (text, QClipboard::Clipboard);
150 QApplication::clipboard()->setText (text, QClipboard::Selection);
151}
152
153void QILabel::resizeEvent (QResizeEvent *aEvent)
154{
155 QLabel::resizeEvent (aEvent);
156 /* Recalculate the elipsis of the text after every resize. */
157 updateText();
158}
159
160void QILabel::mousePressEvent (QMouseEvent *aEvent)
161{
162 if (aEvent->button() == Qt::LeftButton && geometry().contains (aEvent->pos()) && mFullSizeSelection)
163 mStartDragging = true;
164 else
165 QLabel::mousePressEvent (aEvent);
166}
167
168void QILabel::mouseReleaseEvent (QMouseEvent *aEvent)
169{
170 mStartDragging = false;
171 QLabel::mouseReleaseEvent (aEvent);
172}
173
174void QILabel::mouseMoveEvent (QMouseEvent *aEvent)
175{
176 if (mStartDragging)
177 {
178 mStartDragging = false;
179 /* Create a drag object out of the given data. */
180 QDrag *drag = new QDrag (this);
181 QMimeData *mimeData = new QMimeData;
182 mimeData->setText (removeHtmlTags (mText));
183 drag->setMimeData (mimeData);
184 /* Start the dragging */
185#if QT_VERSION >= 0x040300
186 drag->exec();
187#else /* QT_VERSION >= 0x040300 */
188 drag->start (Qt::MoveAction);
189#endif /* QT_VERSION >= 0x040300 */
190 }
191 else
192 QLabel::mouseMoveEvent (aEvent);
193}
194
195void QILabel::contextMenuEvent (QContextMenuEvent *aEvent)
196{
197 if (mFullSizeSelection)
198 {
199 /* Create a context menu for the copy to clipboard action. */
200 QMenu menu;
201 mCopyAction->setText (tr ("&Copy"));
202 menu.addAction (mCopyAction);
203 menu.exec (aEvent->globalPos());
204 }
205 else
206 QLabel::contextMenuEvent (aEvent);
207}
208
209void QILabel::focusInEvent (QFocusEvent * /* aEvent */)
210{
211 if (mFullSizeSelection)
212 {
213 /* Set the text color to the current used highlight text color. */
214 QPalette pal = qApp->palette();
215 pal.setBrush (QPalette::WindowText, pal.brush (QPalette::HighlightedText));
216 setPalette (pal);
217 }
218}
219
220void QILabel::focusOutEvent (QFocusEvent *aEvent)
221{
222 /* Reset to the default palette */
223 if (mFullSizeSelection && aEvent->reason() != Qt::PopupFocusReason)
224 setPalette (qApp->palette());
225}
226
227void QILabel::paintEvent (QPaintEvent *aEvent)
228{
229 QLabel::paintEvent (aEvent);
230
231 if (mFullSizeSelection && hasFocus())
232 {
233 QPainter painter (this);
234 /* Paint a focus rect based on the current style. */
235 QStyleOptionFocusRect option;
236 option.initFrom (this);
237 style()->drawPrimitive (QStyle::PE_FrameFocusRect, &option, &painter, this);
238 }
239}
240
241void QILabel::showEvent(QShowEvent *pEvent)
242{
243 QLabel::showEvent(pEvent);
244 emit shown();
245}
246
247void QILabel::init()
248{
249 /* Initial setup */
250 mIsHintValid = false;
251 mWidthHint = -1;
252 mStartDragging = false;
253 setFullSizeSelection (false);
254 setOpenExternalLinks (true);
255
256 /* Create invisible copy action */
257 mCopyAction = new QAction (this);
258 addAction (mCopyAction);
259 mCopyAction->setShortcut (QKeySequence (QKeySequence::Copy));
260 mCopyAction->setShortcutContext (Qt::WidgetShortcut);
261 connect (mCopyAction, SIGNAL (triggered()), this, SLOT (copy()));
262}
263
264void QILabel::updateSizeHint() const
265{
266 mOwnSizeHint = mWidthHint == -1 ? QSize() : QSize (mWidthHint, heightForWidth (mWidthHint));
267 mIsHintValid = true;
268}
269
270void QILabel::setFullText (const QString &aText)
271{
272 QSizePolicy sp = sizePolicy();
273 sp.setHeightForWidth (wordWrap());
274 setSizePolicy (sp);
275 mIsHintValid = false;
276
277 mText = aText;
278 updateText();
279}
280
281void QILabel::updateText()
282{
283 QString comp = compressText (mText);
284
285 QLabel::setText (comp);
286 /* Only set the tooltip if the text is shortened in any way. */
287 if (removeHtmlTags (comp) != removeHtmlTags (mText))
288 setToolTip (removeHtmlTags (mText));
289 else
290 setToolTip ("");
291}
292
293QString QILabel::removeHtmlTags (QString aText) const
294{
295 /* Remove all HTML tags from the text and return it. */
296 return QString(aText).remove (mCopyRegExp);
297}
298
299Qt::TextElideMode QILabel::toTextElideMode (const QString& aStr) const
300{
301 /* Converts a string to a Qt elide mode */
302 Qt::TextElideMode mode = Qt::ElideNone;
303 if (aStr == "start")
304 mode = Qt::ElideLeft;
305 else if (aStr == "middle")
306 mode = Qt::ElideMiddle;
307 else if (aStr == "end")
308 mode = Qt::ElideRight;
309 return mode;
310}
311
312QString QILabel::compressText (const QString &aText) const
313{
314 QStringList strResult;
315 QFontMetrics fm = fontMetrics();
316 /* Split up any multi line text */
317 QStringList strList = aText.split (QRegExp ("<br */?>"));
318 foreach (QString text, strList)
319 {
320 /* Search for the compact tag */
321 if (mElideRegExp.indexIn (text) > -1)
322 {
323 QString workStr = text;
324 /* Grep out the necessary info of the regexp */
325 QString compactStr = mElideRegExp.cap (1);
326 QString elideModeStr = mElideRegExp.cap (2);
327 QString elideStr = mElideRegExp.cap (3);
328 /* Remove the whole compact tag (also the text) */
329 QString flatStr = removeHtmlTags (QString (workStr).remove (compactStr));
330 /* What size will the text have without the compact text */
331 int flatWidth = fm.width (flatStr);
332 /* Create the shortened text */
333 QString newStr = fm.elidedText (elideStr, toTextElideMode (elideModeStr), width() - (2 * HOR_PADDING) - flatWidth);
334 /* Replace the compact part with the shortened text in the initial string */
335 text = QString (workStr).replace (compactStr, newStr);
336 }
337 strResult << text;
338 }
339 return strResult.join ("<br />");
340}
341
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use