root/trunk/qt4-gui/src/config/skin.cpp

Revision 6007, 16.2 kB (checked in by eugene, 11 months ago)

Made group back image be optionally tiled.

  • Property svn:eol-style set to native
Line 
1// -*- c-basic-offset: 2 -*-
2/*
3 * This file is part of Licq, an instant messaging client for UNIX.
4 * Copyright (C) 1999-2006 Licq developers
5 *
6 * Licq is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * Licq is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with Licq; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19 */
20
21#include "skin.h"
22
23#include "config.h"
24
25#include "core/gui-defines.h"
26
27#include <QPainter>
28#include <QWidget>
29
30#include <licq_constants.h>
31#include <licq_file.h>
32#include <licq_log.h>
33
34using namespace LicqQtGui;
35/* TRANSLATOR LicqQtGui::Config::Skin */
36
37Config::Skin* Config::Skin::myInstance = NULL;
38
39void Config::Skin::createInstance(QString skinName, QObject* parent)
40{
41  myInstance = new Skin(skinName, parent);
42}
43
44Config::Skin::Skin(QString skinName, QObject* parent)
45  : QObject(parent)
46{
47  loadSkin(skinName);
48}
49
50void Config::Skin::loadSkin(QString skinName)
51{
52  gLog.Info("%sApplying %s skin.\n", L_INITxSTR, skinName.toLocal8Bit().data());
53
54  // Set default values even if skin is valid as skin may not include all settings
55  SetDefaultValues();
56
57  if (skinName.isEmpty())
58  {
59    emit changed();
60    emit frameChanged();
61    return;
62  }
63
64  CIniFile skinFile/*(INI_FxFATAL | INI_FxERROR | INI_FxWARN)*/;
65
66  QString skinFileName = skinName + ".skin";
67  QString subdir = QString(QTGUI_DIR) + SKINS_DIR + skinName + "/";
68  QString baseSkinDir = QString::fromLocal8Bit(BASE_DIR) + subdir;
69  if (!skinFile.LoadFile((baseSkinDir + skinFileName).toLocal8Bit()))
70  {
71    baseSkinDir = QString::fromLocal8Bit(SHARE_DIR) + subdir;
72    if (!skinFile.LoadFile((baseSkinDir + skinFileName).toLocal8Bit()))
73    {
74      emit changed();
75      emit frameChanged();
76      return;
77    }
78  }
79
80  mySkinName = skinName;
81
82  skinFile.SetFlag(INI_FxWARN);
83  skinFile.SetSection("skin");
84
85  // Frame
86  frame.loadSkin(skinFile, "frame", baseSkinDir);
87
88  // System Button
89  btnSys.loadSkin(skinFile, "btnSys", baseSkinDir);
90
91  // Status Label
92  lblStatus.loadSkin(skinFile, "lblStatus", baseSkinDir);
93
94  // Message Label
95  lblMsg.loadSkin(skinFile, "lblMsg", baseSkinDir);
96
97  // Group Combo Box
98  cmbGroups.loadSkin(skinFile, "cmbGroups");
99
100  // Read in the colors
101  char temp[MAX_FILENAME_LEN];
102  skinFile.ReadStr("colors.background", temp, "default");
103  if (strncmp(temp, "default", 7) != 0)
104    backgroundColor.setNamedColor(temp);
105
106  skinFile.ReadStr("colors.gridlines", temp, "default");
107  if (strncmp(temp, "default", 7) != 0)
108    gridlineColor.setNamedColor(temp);
109
110  skinFile.ReadStr("colors.scrollbar", temp, "default");
111  if (strncmp(temp, "default", 7) != 0)
112    scrollbarColor.setNamedColor(temp);
113
114  skinFile.ReadStr("colors.btnTxt", temp, "default");
115  if (strncmp(temp, "default", 7) != 0)
116    buttonTextColor.setNamedColor(temp);
117
118  skinFile.ReadStr("colors.online", temp, "default");
119  if (strncmp(temp, "default", 7) != 0)
120    onlineColor.setNamedColor(temp);
121
122  skinFile.ReadStr("colors.offline", temp, "default");
123  if (strncmp(temp, "default", 7) != 0)
124    offlineColor.setNamedColor(temp);
125
126  skinFile.ReadStr("colors.away", temp, "default");
127  if (strncmp(temp, "default", 7) != 0)
128    awayColor.setNamedColor(temp);
129
130  skinFile.ReadStr("colors.newuser", temp, "default");
131  if (strncmp(temp, "default", 7) != 0)
132    newUserColor.setNamedColor(temp);
133
134  skinFile.ReadStr("colors.authwait", temp, "default");
135  if (strncmp(temp, "default", 7) != 0)
136    awaitingAuthColor.setNamedColor(temp);
137
138  skinFile.ReadStr("colors.highlight.bg", temp, "default");
139  if (strncmp(temp, "default", 7) != 0)
140    highBackColor.setNamedColor(temp);
141
142  skinFile.ReadStr("colors.highlight.fg", temp, "default");
143  if (strncmp(temp, "default", 7) != 0)
144    highTextColor.setNamedColor(temp);
145
146  skinFile.ReadStr("colors.group.bg", temp, "default");
147  if (strncmp(temp, "default", 7) != 0)
148    groupBackColor.setNamedColor(temp);
149
150  skinFile.ReadStr("colors.group.fg", temp, "default");
151  if (strncmp(temp, "default", 7) != 0)
152    groupTextColor.setNamedColor(temp);
153
154  skinFile.ReadStr("colors.group.highlight.bg", temp, "default");
155  if (strncmp(temp, "default", 7) != 0)
156    groupHighBackColor.setNamedColor(temp);
157
158  skinFile.ReadStr("colors.group.highlight.fg", temp, "default");
159  if (strncmp(temp, "default", 7) != 0)
160    groupHighTextColor.setNamedColor(temp);
161
162  // And images
163  skinFile.ReadStr("images.groupBack", temp, "none");
164  if (strncmp(temp, "none", 4) != 0)
165    groupBackImage.load(baseSkinDir + temp);
166
167  skinFile.ReadBool("images.groupBack.tile", tileGroupBackImage, false);
168
169  emit changed();
170  emit frameChanged();
171}
172
173void Config::Skin::setFrameTransparent(bool transparent)
174{
175  if (transparent == frame.transparent)
176    return;
177
178  frame.transparent = transparent;
179  emit frameChanged();
180}
181
182void Config::Skin::setFrameStyle(unsigned short frameStyle)
183{
184  if (frameStyle == frame.frameStyle)
185    return;
186
187  frame.frameStyle = frameStyle;
188  emit frameChanged();
189}
190
191void Config::Skin::SetDefaultValues()
192{
193  mySkinName = "";
194  myMenuBarHeight = 0;
195
196  frame.pixmap = QPixmap();
197  frame.mask = QPixmap();
198  frame.border.top = 0;
199  frame.border.bottom = 80;
200  frame.border.left = 0;
201  frame.border.right = 0;
202  frame.hasMenuBar = true;
203  frame.frameStyle = 33;
204  frame.transparent = false;
205
206  lblStatus.rect.setCoords(5, -25, -5, -5);
207  lblStatus.foreground = QColor();
208  lblStatus.background = QColor();
209  lblStatus.frameStyle = 51;
210  lblStatus.pixmap = QPixmap();
211  lblStatus.margin = 5;
212
213  btnSys.rect.setCoords(20, -65, 70, -45);
214  btnSys.pixmapUpFocus = QPixmap();
215  btnSys.pixmapUpNoFocus = QPixmap();
216  btnSys.pixmapDown = QPixmap();
217  btnSys.foreground = QColor();
218  btnSys.background = QColor();
219  btnSys.caption = QString();
220
221  lblMsg.rect.setCoords(5, -50, -5, -30);
222  lblMsg.foreground = QColor();
223  lblMsg.background = QColor();
224  lblMsg.frameStyle = 51;
225  lblMsg.pixmap = QPixmap();
226  lblMsg.margin = 5;
227
228  cmbGroups.rect.setCoords(5, -75, -5, -55);
229  cmbGroups.foreground = QColor();
230  cmbGroups.background = QColor();
231
232  backgroundColor = QColor();
233  gridlineColor.setNamedColor("black");
234  scrollbarColor = QColor();
235  buttonTextColor = QColor();
236
237  onlineColor.setNamedColor("blue");
238  offlineColor.setNamedColor("firebrick");
239  awayColor.setNamedColor("darkgreen");
240  newUserColor.setNamedColor("yellow");
241  awaitingAuthColor.setNamedColor("darkcyan");
242
243  highBackColor = QColor();
244  highTextColor = QColor();
245
246  groupBackColor = QColor();
247  groupTextColor = QColor();
248  groupHighBackColor = QColor();
249  groupHighTextColor = QColor();
250
251  groupBackImage = QImage();
252  tileGroupBackImage = false;
253}
254
255
256void Config::Skin::AdjustForMenuBar(unsigned short h)
257{
258  frame.border.AdjustForMenuBar(myMenuBarHeight, h);
259  lblStatus.AdjustForMenuBar(myMenuBarHeight, h);
260  btnSys.AdjustForMenuBar(myMenuBarHeight, h);
261  lblMsg.AdjustForMenuBar(myMenuBarHeight, h);
262  cmbGroups.AdjustForMenuBar(myMenuBarHeight, h);
263
264  myMenuBarHeight = h;
265}
266
267void Config::FrameSkin::loadSkin(CIniFile& skinFile, QString name, QString baseSkinDir)
268{
269  char temp[255];
270  skinFile.SetFlags(0);
271  skinFile.ReadStr((name + ".pixmap").toLatin1().data(), temp, "none");
272  if (strncmp(temp, "none", 4) != 0)
273    if (!pixmap.load(baseSkinDir + temp))
274      gLog.Error("%sError loading background pixmap (%s).\n", L_ERRORxSTR, temp);
275
276  skinFile.ReadStr((name + ".mask").toLatin1().data(), temp, "none");
277  if (strncmp(temp, "none", 4) != 0)
278    if (!mask.load(baseSkinDir + temp))
279      gLog.Error("%sError loading background mask (%s).\n", L_ERRORxSTR, temp);
280
281  skinFile.SetFlags(INI_FxFATAL | INI_FxERROR);
282  skinFile.ReadNum((name + ".border.top").toLatin1().data(), border.top);
283  skinFile.ReadNum((name + ".border.bottom").toLatin1().data(), border.bottom);
284  skinFile.ReadNum((name + ".border.left").toLatin1().data(), border.left);
285  skinFile.ReadNum((name + ".border.right").toLatin1().data(), border.right);
286  skinFile.SetFlags(0);
287  skinFile.ReadBool((name + ".hasMenuBar").toLatin1().data(), hasMenuBar, hasMenuBar);
288  skinFile.ReadNum((name + ".frameStyle").toLatin1().data(), frameStyle, frameStyle);
289  skinFile.ReadBool((name + ".transparent").toLatin1().data(), transparent, transparent);
290}
291
292void Config::ShapeSkin::loadSkin(CIniFile& skinFile, QString name)
293{
294  signed short x1, y1, x2, y2;
295  skinFile.SetFlags(INI_FxFATAL | INI_FxERROR);
296  skinFile.ReadNum((name + ".rect.x1").toLatin1().data(), x1);
297  skinFile.ReadNum((name + ".rect.y1").toLatin1().data(), y1);
298  skinFile.ReadNum((name + ".rect.x2").toLatin1().data(), x2);
299  skinFile.ReadNum((name + ".rect.y2").toLatin1().data(), y2);
300  skinFile.SetFlags(0);
301  rect.setCoords(x1, y1, x2, y2);
302
303  char temp[255];
304  skinFile.ReadStr((name + ".color.fg").toLatin1().data(), temp, "default");
305  foreground = (strncmp(temp, "default", 7) == 0 ? QColor() : QColor(temp));
306  if (strncmp(temp, "transparent", 11) == 0)
307    foreground.setAlpha(0);
308  skinFile.ReadStr((name + ".color.bg").toLatin1().data(), temp, "default");
309  background = (strncmp(temp, "default", 7) == 0 ? QColor() : QColor(temp));
310  if (strncmp(temp, "transparent", 11) == 0)
311    background.setAlpha(0);
312}
313
314void Config::ButtonSkin::loadSkin(CIniFile& skinFile, QString name, QString baseSkinDir)
315{
316  Config::ShapeSkin::loadSkin(skinFile, name);
317
318  char temp[255];
319  skinFile.ReadStr((name + ".caption").toLatin1().data(), temp, "default");
320  caption = (strncmp(temp, "default", 7) == 0 ? QString() : QString::fromLocal8Bit(temp));
321
322  skinFile.ReadStr((name + ".pixmapUpFocus").toLatin1().data(), temp, "none");
323  if (strncmp(temp, "none", 4) != 0)
324    pixmapUpFocus.load(baseSkinDir + temp);
325
326  skinFile.ReadStr((name + ".pixmapUpNoFocus").toLatin1().data(), temp, "none");
327  if (strncmp(temp, "none", 4) != 0)
328    pixmapUpNoFocus.load(baseSkinDir + temp);
329
330  skinFile.ReadStr((name + ".pixmapDown").toLatin1().data(), temp, "none");
331  if (strncmp(temp, "none", 4) != 0)
332    pixmapDown.load(baseSkinDir + temp);
333}
334
335void Config::LabelSkin::loadSkin(CIniFile& skinFile, QString name, QString baseSkinDir)
336{
337  Config::ShapeSkin::loadSkin(skinFile, name);
338  transparent = (background.alpha() == 0);
339
340  char temp[255];
341  skinFile.ReadStr((name + ".pixmap").toLatin1().data(), temp, "none");
342  if (strncmp(temp, "none", 4) != 0)
343    pixmap.load(baseSkinDir + temp);
344
345  skinFile.ReadNum((name + ".margin").toLatin1().data(), margin, margin);
346  skinFile.SetFlags(INI_FxFATAL | INI_FxERROR);
347  skinFile.ReadNum((name + ".frameStyle").toLatin1().data(), frameStyle, frameStyle);
348  skinFile.SetFlags(0);
349}
350
351void Config::ShapeSkin::AdjustForMenuBar(unsigned short h_old, unsigned short h_new)
352{
353  if (rect.top() >= 0)
354    rect.setTop(rect.top() + h_new - h_old);
355  if (rect.bottom() >= 0)
356    rect.setBottom(rect.bottom() + h_new - h_old);
357}
358
359void Config::Border::AdjustForMenuBar(unsigned short h_old, unsigned short h_new)
360{
361  top += (h_new - h_old);
362}
363
364
365int Config::Skin::frameWidth(void)
366{
367   return (frame.border.right + frame.border.left);
368}
369
370int Config::Skin::frameHeight(void)
371{
372   return (frame.border.top + frame.border.bottom);
373}
374
375QRect Config::ShapeSkin::borderToRect(const QWidget* w) const
376{
377   QRect ret;
378
379   // X1
380   if (rect.left() >= 0)
381      ret.setX(rect.left());
382   else
383      ret.setX(w->width() + rect.left());
384
385   // Y1
386   if (rect.top() >= 0)
387      ret.setY(rect.top());
388   else
389      ret.setY(w->height() + rect.top());
390
391   // X2
392   if (rect.right() >= 0)
393      ret.setWidth(rect.right() - ret.x());
394   else
395      ret.setWidth((w->width() + rect.right()) - ret.x());
396
397   // Y2
398   if (rect.bottom() >= 0)
399      ret.setHeight(rect.bottom() - ret.y());
400   else
401      ret.setHeight((w->height() + rect.bottom()) - ret.y());
402
403   return ret;
404}
405
406QPixmap Config::Skin::scaleWithBorder(const QPixmap& pm, int width, int height) const
407{
408  if (pm.isNull())
409    return QPixmap();
410
411  QPainter p;
412  const Border& border(frame.border);
413
414  // top left corner
415  QPixmap pmTL(border.left, border.top);
416  p.begin(&pmTL);
417  p.drawPixmap(0, 0, pm, 0, 0, pmTL.width(), pmTL.height());
418  p.end();
419
420  // top border
421  QPixmap pmT(pm.width() - border.left - border.right, border.top);
422  p.begin(&pmT);
423  p.drawPixmap(0, 0, pm, border.left, 0, pmT.width(), pmT.height());
424  p.end();
425  QImage imT( (pmT.toImage()).scaled(width - border.left - border.right, pmT.height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation) );
426
427  // top right corner
428  QPixmap pmTR(border.right, border.top);
429  p.begin(&pmTR);
430  p.drawPixmap(0, 0, pm, pm.width() - border.right, 0, pmTR.width(), pmTR.height());
431  p.end();
432
433  // left border
434  QPixmap pmL(border.left, pm.height() - border.top - border.bottom);
435  p.begin(&pmL);
436  p.drawPixmap(0, 0, pm, 0, border.top, pmL.width(), pmL.height());
437  p.end();
438  QImage imL( (pmL.toImage()).scaled(pmL.width(), height - border.top - border.bottom, Qt::IgnoreAspectRatio, Qt::SmoothTransformation) );
439
440  // center
441  QPixmap pmC(pmT.width(), pmL.height());
442  p.begin(&pmC);
443  p.drawPixmap(0, 0, pm, border.left, border.top, pmC.width(), pmC.height());
444  p.end();
445  QImage imC( (pmC.toImage()).scaled(imT.width(), imL.height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation) );
446
447  // right border
448  QPixmap pmR(border.right, pm.height() - border.top - border.bottom);
449  p.begin(&pmR);
450  p.drawPixmap(0, 0, pm, pm.width() - border.right, border.top, pmR.width(), pmR.height());
451  p.end();
452  QImage imR ( (pmR.toImage()).scaled(pmR.width(), height - border.top - border.bottom, Qt::IgnoreAspectRatio, Qt::SmoothTransformation) );
453
454  // bottom left border
455  QPixmap pmBL(border.left, border.bottom);
456  p.begin(&pmBL);
457  p.drawPixmap(0, 0, pm, 0, pm.height() - border.bottom, pmBL.width(), pmBL.height());
458  p.end();
459
460  // bottom border
461  QPixmap pmB(pm.width() - border.left - border.right, border.bottom);
462  p.begin(&pmB);
463  p.drawPixmap(0, 0, pm, border.left, pm.height() - border.bottom, pmB.width(), pmB.height());
464  p.end();
465  QImage imB( (pmB.toImage()).scaled(width - border.left - border.right, pmB.height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation) );
466
467  // bottom right border
468  QPixmap pmBR(border.right, border.bottom);
469  p.begin(&pmBR);
470  p.drawPixmap(0, 0, pm, pm.width() - border.right, pm.height() - border.bottom, pmBR.width(), pmBR.height());
471  p.end();
472
473  // put the image together
474  QPixmap pmFinal(width, height);
475  p.begin(&pmFinal);
476  p.drawPixmap(0, 0, pmTL, 0, 0, -1, -1);
477  p.drawImage(border.left, 0, imT, 0, 0, -1, -1);
478  p.drawPixmap(pmFinal.width() - border.right, 0, pmTR, 0, 0, -1, -1);
479  p.drawImage(0, border.top, imL, 0, 0, -1, -1);
480  p.drawImage(pmFinal.width() - border.right, border.top, imR, 0, 0, -1, -1);
481  p.drawPixmap(0, pmFinal.height() - border.bottom, pmBL, 0, 0, -1, -1);
482  p.drawImage(border.left, pmFinal.height() - border.bottom, imB, 0, 0, -1, -1);
483  p.drawPixmap(pmFinal.width() - border.right, pmFinal.height() - border.bottom, pmBR, 0, 0, -1, -1);
484  p.drawImage(border.left, border.top, imC, 0, 0, -1, -1);
485  p.end();
486
487  return pmFinal;
488}
489
490QPixmap Config::Skin::mainwinPixmap(int width, int height) const
491{
492  return scaleWithBorder(frame.pixmap, width, height);
493}
494
495QPixmap Config::Skin::mainwinMask(int width, int height) const
496{
497  return scaleWithBorder(frame.mask, width, height);
498}
499
500/*! \brief Returns a palette with colored scrollbars
501 *
502 *  This method creates a palette with skin specific scrollbar colors.
503 *  Parent should be a widget that holds a "default" active palette, which will
504 *  be used as base for the resulting palette.
505 *  The returned QPalette is a copy of the parent palette but with modified
506 *  scrollbar colors: QColorGroup::Highlight, QColorGroup::Button,
507 *  QColorGroup::Foreground, QColorGroup::Background and QColorGroup::ButtonText.
508 */
509QPalette Config::Skin::palette(QWidget* parent)
510{
511  QPalette pal = parent->palette();
512  // ButtonText +  arrow of scrollbar
513  if (buttonTextColor.isValid())
514  {
515    pal.setColor(QPalette::ButtonText, buttonTextColor);
516    pal.setColor(QPalette::Foreground, buttonTextColor);
517  }
518  // Scrollbar
519  if (scrollbarColor.isValid())
520  {
521    pal.setColor(QPalette::Highlight, scrollbarColor);
522    pal.setColor(QPalette::Button, scrollbarColor);
523    pal.setColor(QPalette::Background, scrollbarColor);
524  }
525  return pal;
526}
Note: See TracBrowser for help on using the browser.