VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/objects/UIRichTextString.cpp@ 82781

Last change on this file since 82781 was 76606, checked in by vboxsync, 5 years ago

FE/Qt: Cleaning out old precompiled header experiment.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
  • Property svn:mergeinfo set to (toggle deleted branches)
    /branches/VBox-3.0/src/VBox/Frontends/VirtualBox/src/selector/graphics/chooser/UIGChooserItemMachine.cpp58652,​70973
    /branches/VBox-3.2/src/VBox/Frontends/VirtualBox/src/selector/graphics/chooser/UIGChooserItemMachine.cpp66309,​66318
    /branches/VBox-4.0/src/VBox/Frontends/VirtualBox/src/selector/graphics/chooser/UIGChooserItemMachine.cpp70873
    /branches/VBox-4.1/src/VBox/Frontends/VirtualBox/src/selector/graphics/chooser/UIGChooserItemMachine.cpp74233
    /branches/VBox-4.2/src/VBox/Frontends/VirtualBox/src/selector/graphics/details/UIGDetailsElement.cpp91503-91504,​91506-91508,​91510,​91514-91515,​91521
    /branches/VBox-4.3/src/VBox/Frontends/VirtualBox/src/selector/graphics/details/UIGDetailsElement.cpp91223
    /branches/VBox-4.3/trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/details/UIGDetailsElement.cpp91223
    /branches/dsen/gui/src/VBox/Frontends/VirtualBox/src/selector/graphics/chooser/UIGChooserItemMachine.cpp79076-79078,​79089,​79109-79110,​79112-79113,​79127-79130,​79134,​79141,​79151,​79155,​79157-79159,​79193,​79197
    /branches/dsen/gui2/src/VBox/Frontends/VirtualBox/src/selector/graphics/details/UIGDetailsElement.cpp79562-79569,​79572-79573,​79578,​79581-79582,​79590-79591,​79598-79599,​79602-79603,​79605-79606,​79632,​79635,​79637,​79644
    /branches/dsen/gui3/src/VBox/Frontends/VirtualBox/src/selector/graphics/details/UIGDetailsElement.cpp79645-79692
    /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/chooser/UIGChooserItemMachine.cpp79225,​79271
File size: 7.7 KB
Line 
1/* $Id: UIRichTextString.cpp 76606 2019-01-02 05:40:39Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIRichTextString class implementation.
4 */
5
6/*
7 * Copyright (C) 2015-2019 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18/* Qt includes: */
19#include <QApplication>
20#include <QPalette>
21
22/* GUI includes: */
23#include "UIRichTextString.h"
24
25/* Other VBox includes: */
26#include "iprt/assert.h"
27
28
29const QString UIRichTextString::s_strAny = QString("[\\s\\S]*");
30const QMap<UIRichTextString::Type, QString> UIRichTextString::s_patterns = populatePatterns();
31const QMap<UIRichTextString::Type, bool> UIRichTextString::s_doPatternHasMeta = populatePatternHasMeta();
32
33UIRichTextString::UIRichTextString(Type enmType /* = Type_None */)
34 : m_enmType(enmType)
35 , m_strString(QString())
36 , m_strStringMeta(QString())
37{
38}
39
40UIRichTextString::UIRichTextString(const QString &strString, Type enmType /* = Type_None */, const QString &strStringMeta /* = QString() */)
41 : m_enmType(enmType)
42 , m_strString(strString)
43 , m_strStringMeta(strStringMeta)
44{
45 //printf("Creating new UIRichTextString with string=\"%s\" and string-meta=\"%s\"\n",
46 // m_strString.toUtf8().constData(), m_strStringMeta.toUtf8().constData());
47 parse();
48}
49
50UIRichTextString::~UIRichTextString()
51{
52 /* Erase the map: */
53 qDeleteAll(m_strings.begin(), m_strings.end());
54 m_strings.clear();
55}
56
57QString UIRichTextString::toString() const
58{
59 /* Add own string first: */
60 QString strString = m_strString;
61
62 /* Add all the strings of children finally: */
63 foreach (const int &iPosition, m_strings.keys())
64 strString.insert(iPosition, m_strings.value(iPosition)->toString());
65
66 /* Return result: */
67 return strString;
68}
69
70QList<QTextLayout::FormatRange> UIRichTextString::formatRanges(int iShift /* = 0 */) const
71{
72 /* Prepare format range list: */
73 QList<QTextLayout::FormatRange> ranges;
74
75 /* Add own format range first: */
76 QTextLayout::FormatRange range;
77 range.start = iShift;
78 range.length = toString().size();
79 range.format = textCharFormat(m_enmType);
80 /* Enable anchor if present: */
81 if (!m_strAnchor.isNull())
82 {
83 range.format.setAnchorHref(m_strAnchor);
84 /* Highlight anchor if hovered: */
85 if (range.format.anchorHref() == m_strHoveredAnchor)
86 range.format.setForeground(qApp->palette().color(QPalette::Link));
87 }
88 ranges.append(range);
89
90 /* Add all the format ranges of children finally: */
91 foreach (const int &iPosition, m_strings.keys())
92 ranges.append(m_strings.value(iPosition)->formatRanges(iShift + iPosition));
93
94 /* Return result: */
95 return ranges;
96}
97
98void UIRichTextString::setHoveredAnchor(const QString &strHoveredAnchor)
99{
100 /* Define own hovered anchor first: */
101 m_strHoveredAnchor = strHoveredAnchor;
102
103 /* Propagate hovered anchor to children finally: */
104 foreach (const int &iPosition, m_strings.keys())
105 m_strings.value(iPosition)->setHoveredAnchor(m_strHoveredAnchor);
106}
107
108void UIRichTextString::parse()
109{
110 /* Assign the meta to anchor directly for now,
111 * will do a separate parsing when there will
112 * be more than one type of meta: */
113 if (!m_strStringMeta.isNull())
114 m_strAnchor = m_strStringMeta;
115
116 /* Parse the passed QString with all the known patterns: */
117 foreach (const Type &enmPattern, s_patterns.keys())
118 {
119 /* Get the current pattern: */
120 const QString strPattern = s_patterns.value(enmPattern);
121
122 /* Recursively parse the string: */
123 int iMaxLevel = 0;
124 do
125 {
126 /* Search for the maximum level of the current pattern: */
127 iMaxLevel = searchForMaxLevel(m_strString, strPattern, strPattern);
128 //printf(" Maximum level for the pattern \"%s\" is %d.\n",
129 // strPattern.toUtf8().constData(), iMaxLevel);
130 /* If current pattern of at least level 1 is found: */
131 if (iMaxLevel > 0)
132 {
133 /* Compose full pattern of the corresponding level: */
134 const QString strFullPattern = composeFullPattern(strPattern, strPattern, iMaxLevel);
135 //printf(" Full pattern: %s\n", strFullPattern.toUtf8().constData());
136 QRegExp regExp(strFullPattern);
137 regExp.setMinimal(true);
138 const int iPosition = regExp.indexIn(m_strString);
139 AssertReturnVoid(iPosition != -1);
140 if (iPosition != -1)
141 {
142 /* Cut the found string: */
143 m_strString.remove(iPosition, regExp.cap(0).size());
144 /* And paste that string as our child: */
145 const bool fPatterHasMeta = s_doPatternHasMeta.value(enmPattern);
146 const QString strSubString = !fPatterHasMeta ? regExp.cap(1) : regExp.cap(2);
147 const QString strSubMeta = !fPatterHasMeta ? QString() : regExp.cap(1);
148 m_strings.insert(iPosition, new UIRichTextString(strSubString, enmPattern, strSubMeta));
149 }
150 }
151 }
152 while (iMaxLevel > 0);
153 }
154}
155
156/* static */
157QMap<UIRichTextString::Type, QString> UIRichTextString::populatePatterns()
158{
159 QMap<Type, QString> patterns;
160 patterns.insert(Type_Anchor, QString("<a href=([^>]+)>(%1)</a>"));
161 patterns.insert(Type_Bold, QString("<b>(%1)</b>"));
162 patterns.insert(Type_Italic, QString("<i>(%1)</i>"));
163 return patterns;
164}
165
166/* static */
167QMap<UIRichTextString::Type, bool> UIRichTextString::populatePatternHasMeta()
168{
169 QMap<Type, bool> patternHasMeta;
170 patternHasMeta.insert(Type_Anchor, true);
171 patternHasMeta.insert(Type_Bold, false);
172 patternHasMeta.insert(Type_Italic, false);
173 return patternHasMeta;
174}
175
176/* static */
177int UIRichTextString::searchForMaxLevel(const QString &strString, const QString &strPattern,
178 const QString &strCurrentPattern, int iCurrentLevel /* = 0 */)
179{
180 QRegExp regExp(strCurrentPattern.arg(s_strAny));
181 regExp.setMinimal(true);
182 if (regExp.indexIn(strString) != -1)
183 return searchForMaxLevel(strString, strPattern,
184 strCurrentPattern.arg(s_strAny + strPattern + s_strAny),
185 iCurrentLevel + 1);
186 return iCurrentLevel;
187}
188
189/* static */
190QString UIRichTextString::composeFullPattern(const QString &strPattern,
191 const QString &strCurrentPattern, int iCurrentLevel)
192{
193 if (iCurrentLevel > 1)
194 return composeFullPattern(strPattern,
195 strCurrentPattern.arg(s_strAny + strPattern + s_strAny),
196 iCurrentLevel - 1);
197 return strCurrentPattern.arg(s_strAny);
198}
199
200/* static */
201QTextCharFormat UIRichTextString::textCharFormat(Type enmType)
202{
203 QTextCharFormat format;
204 switch (enmType)
205 {
206 case Type_Anchor:
207 {
208 format.setAnchor(true);
209 break;
210 }
211 case Type_Bold:
212 {
213 QFont font = format.font();
214 font.setBold(true);
215 format.setFont(font);
216 break;
217 }
218 case Type_Italic:
219 {
220 QFont font = format.font();
221 font.setItalic(true);
222 format.setFont(font);
223 break;
224 }
225
226 case Type_None: break; /* Shut up MSC */
227 }
228 return format;
229}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use