1 /***************************************************************************
2 * Copyright (C) 2005-07 by The Quassel Team *
3 * devel@quassel-irc.org *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
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. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
24 // Colors (mIRC standard)
25 colors["00"] = QColor("white");
26 colors["01"] = QColor("black");
27 colors["02"] = QColor("navy");
28 colors["03"] = QColor("green");
29 colors["04"] = QColor("red");
30 colors["05"] = QColor("maroon");
31 colors["06"] = QColor("purple");
32 colors["07"] = QColor("orange");
33 colors["08"] = QColor("yellow");
34 colors["09"] = QColor("lime");
35 colors["10"] = QColor("teal");
36 colors["11"] = QColor("aqua");
37 colors["12"] = QColor("royalblue");
38 colors["13"] = QColor("fuchsia");
39 colors["14"] = QColor("grey");
40 colors["15"] = QColor("silver");
43 def.setForeground(QBrush("black"));
44 def.setFont(QFont("Verdana",9));
45 formats["default"] = def;
49 bold.setFontWeight(QFont::Bold);
55 // %R - 0x12 - reverse
56 // -- - 0x16 - reverse
60 QTextCharFormat italic;
61 italic.setFontItalic(true);
62 formats["%S"] = italic;
64 // %U - 0x1f - underline
65 QTextCharFormat underline;
66 underline.setFontUnderline(true);
67 formats["%U"] = underline;
69 // %C - 0x03 - mIRC colors
70 for(uint i = 0; i < 16; i++) {
71 QString idx = QString("%1").arg(i, (int)2, (int)10, (QChar)'0');
72 QTextCharFormat fgf; fgf.setForeground(QBrush(colors[idx])); formats[QString("cf%1").arg(idx)] = fgf;
73 QTextCharFormat bgf; bgf.setBackground(QBrush(colors[idx])); formats[QString("cb%1").arg(idx)] = bgf;
76 // Internal formats - %D<char>
78 QTextCharFormat plainMsg;
79 plainMsg.setForeground(QBrush("black"));
80 formats["%D0"] = plainMsg;
82 QTextCharFormat notice;
83 notice.setForeground(QBrush("navy"));
84 formats["%Dn"] = notice;
86 QTextCharFormat server;
87 server.setForeground(QBrush("navy"));
88 formats["%Ds"] = server;
90 QTextCharFormat error;
91 error.setForeground(QBrush("red"));
92 formats["%De"] = error;
95 join.setForeground(QBrush("green"));
96 formats["%Dj"] = join;
99 part.setForeground(QBrush("indianred"));
100 formats["%Dp"] = part;
102 QTextCharFormat quit;
103 quit.setForeground(QBrush("indianred"));
104 formats["%Dq"] = quit;
106 QTextCharFormat kick;
107 kick.setForeground(QBrush("indianred"));
108 formats["%Dk"] = kick;
110 QTextCharFormat nren;
111 nren.setForeground(QBrush("magenta"));
112 formats["%Dr"] = nren;
114 QTextCharFormat mode;
115 mode.setForeground(QBrush("steelblue"));
116 formats["%Dm"] = mode;
118 QTextCharFormat action;
119 action.setFontItalic(true);
120 action.setForeground(QBrush("darkmagenta"));
121 formats["%Da"] = action;
125 ts.setForeground(QBrush("grey"));
128 QTextCharFormat sender;
129 sender.setAnchor(true);
130 sender.setForeground(QBrush("navy"));
131 formats["%DS"] = sender;
133 QTextCharFormat nick;
134 nick.setAnchor(true);
135 nick.setFontWeight(QFont::Bold);
136 formats["%DN"] = nick;
138 QTextCharFormat hostmask;
139 hostmask.setFontItalic(true);
140 formats["%DH"] = hostmask;
142 QTextCharFormat channel;
143 channel.setAnchor(true);
144 channel.setFontWeight(QFont::Bold);
145 formats["%DC"] = channel;
147 QTextCharFormat flags;
148 flags.setFontWeight(QFont::Bold);
149 formats["%DM"] = flags;
150 // %DU - clickable URL
152 url.setFontUnderline(true);
154 formats["%DU"] = url;
157 /** Returns a string stripped of format codes, and a list of FormatRange objects
158 * describing the formats of the string.
159 * \param s string in internal format (% style format codes)
161 Style::StyledString Style::formattedToStyled(QString s) {
162 QHash<QString, int> toggles;
165 QTextLayout::FormatRange rng;
166 rng.format = formats["default"]; rng.start = 0; rng.length = -1; sf.formats.append(rng);
167 toggles["default"] = sf.formats.count() - 1;
169 for(i = 0, j = 0; i < s.length(); i++) {
170 if(s[i] != '%') { p += s[i]; j++; continue; }
171 if(s[++i] == '%') { p += '%'; j++; continue; }
172 else if(s[i] == 'D' && s[i+1] == 'c') { // color code
173 if(s[i+2] == '-') { // color off
174 if(toggles.contains("fg")) {
175 sf.formats[toggles["fg"]].length = j - sf.formats[toggles["fg"]].start;
176 toggles.remove("fg");
178 if(toggles.contains("bg")) {
179 sf.formats[toggles["bg"]].length = j - sf.formats[toggles["bg"]].start;
180 toggles.remove("bg");
183 } else if(s[i+2] == 'f') { // foreground
184 if(toggles.contains("fg")) {
185 sf.formats[toggles["fg"]].length = j - sf.formats[toggles["fg"]].start;
186 toggles.remove("fg");
188 QTextLayout::FormatRange range;
189 range.format = formats[s.mid(i+1, 4)]; range.start = j; range.length = -1; sf.formats.append(range);
190 toggles["fg"] = sf.formats.count() - 1;
192 } else { // background
193 Q_ASSERT(s[i+2] == 'b');
194 if(toggles.contains("bg")) {
195 sf.formats[toggles["bg"]].length = j - sf.formats[toggles["bg"]].start;
196 toggles.remove("bg");
198 QTextLayout::FormatRange range;
199 range.format = formats[s.mid(i+1, 4)]; range.start = j; range.length = -1; sf.formats.append(range);
200 toggles["bg"] = sf.formats.count() - 1;
203 } else if(s[i] == 'O') {
204 foreach(QString key, toggles.keys()) {
205 if(key == "default") continue;
206 sf.formats[toggles[key]].length = j - sf.formats[toggles[key]].start;
210 } else if(s[i] == 'R') {
211 // TODO implement reverse formatting
214 // all others are toggles
215 QString key = "%"; key += s[i];
216 if(s[i] == 'D') key += s[i+1];
217 if(formats.contains(key)) {
219 if(toggles.contains(key)) {
220 sf.formats[toggles[key]].length = j - sf.formats[toggles[key]].start;
223 // FIXME check for and handle format codes within URLs
224 QString u = s.mid(i - sf.formats[toggles[key]].length - 2, sf.formats[toggles[key]].length);
226 url.start = sf.formats[toggles[key]].start;
233 QTextLayout::FormatRange range;
234 range.format = formats[key]; range.start = j; range.length = -1;
235 sf.formats.append(range);
236 toggles[key] = sf.formats.count() -1;
240 p += '%'; p += s[i]; j+=2;
244 foreach(int idx, toggles.values()) {
245 sf.formats[idx].length = j - sf.formats[idx].start;
251 QHash<QString, QTextCharFormat> Style::formats;
252 QHash<QString, QColor> Style::colors;