kde-workspace/plasma/applets/digital-clock/clock.cpp
Ivailo Monev 7819796c55 plasma: replace the seconds option with time format
this essentially extends the digital clock options to 3 formats which are
also configurable instead of using a hardcoded format (the old
implementation), that ofcourse means an update has to be done every
second (or even milisecond) because the format is unknown to the digital
clock applet

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
2023-07-28 00:11:11 +03:00

757 lines
28 KiB
C++

/***************************************************************************
* Copyright (C) 2007-2008 by Riccardo Iaconelli <riccardo@kde.org> *
* Copyright (C) 2007-2010 by Sebastian Kügler <sebas@kde.org> *
* Copyright (C) 2011 by Teo Mrnjavac <teo@kde.org> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
#include "clock.h"
#include <math.h>
#include <QtGui/QPainter>
#include <QtGui/qstyleoption.h>
#include <QtGui/QSpinBox>
#include <QtCore/QTimeLine>
#include <QtGui/QGraphicsView>
#include <QtGui/qgraphicssceneevent.h>
#include <QtCore/qdatetime.h>
#include <KDebug>
#include <KLocale>
#include <KSharedConfig>
#include <KColorScheme>
#include <KGlobalSettings>
#include <KConfigDialog>
#include <KServiceTypeTrader>
#include <KRun>
#include <Plasma/Theme>
#include <Plasma/Dialog>
#include <Plasma/Svg>
#include <Plasma/PaintUtils>
#include <Plasma/ToolTipManager>
Clock::Clock(QObject *parent, const QVariantList &args)
: ClockApplet(parent, args),
m_plainClockFont(KGlobalSettings::generalFont()),
m_useCustomColor(false),
m_useCustomShadowColor(false),
m_drawShadow(true),
m_dateStyle(0),
m_timeFormat(QLocale::ShortFormat),
m_showTimezone(false),
m_dateTimezoneBesides(false),
m_svg(0)
{
KGlobal::locale()->insertCatalog("libplasmaclock");
// this catalog is only used once on the first start of the clock to translate the timezone in the configuration file
KGlobal::locale()->insertCatalog("timezones4");
setHasConfigurationInterface(true);
resize(150, 75);
}
Clock::~Clock()
{
}
void Clock::init()
{
ClockApplet::init();
dataEngine("time")->connectSource(currentTimezone(), this, updateInterval(), intervalAlignment());
connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), this, SLOT(updateColors()));
connect(KGlobalSettings::self(), SIGNAL(appearanceChanged()), SLOT(resetSize()));
connect(KGlobalSettings::self(), SIGNAL(settingsChanged(int)), SLOT(updateClock(int)));
}
void Clock::constraintsEvent(Plasma::Constraints constraints)
{
ClockApplet::constraintsEvent(constraints);
if (constraints & Plasma::SizeConstraint || constraints & Plasma::FormFactorConstraint) {
updateSize();
}
}
// In case time format has changed, e.g. from 24h to 12h format.
void Clock::updateClock(int category)
{
if (category != KGlobalSettings::SETTINGS_LOCALE) {
return;
}
generatePixmap();
update();
}
void Clock::resetSize()
{
// Called when the size of the applet may change externally, such as on
// font size changes
constraintsEvent(Plasma::SizeConstraint);
}
void Clock::updateSize()
{
Plasma::FormFactor f = formFactor();
if (f != Plasma::Vertical && f != Plasma::Horizontal) {
const QFontMetricsF metrics(KGlobalSettings::smallestReadableFont());
// calculates based on size of "23:59"!
const QString timeString = KGlobal::locale()->formatTime(QTime(23, 59), m_timeFormat);
setMinimumSize(metrics.size(Qt::TextSingleLine, timeString));
}
// more magic numbers
int aspect = 2;
if (m_timeFormat == QLocale::LongFormat) {
aspect = 3;
}
int w, h;
if (m_dateStyle || showTimezone()) {
const QFont f(KGlobalSettings::smallestReadableFont());
const QFontMetrics metrics(f);
// if there's enough vertical space, wrap the words
if (contentsRect().height() < f.pointSize() * 6) {
QSize s = metrics.size(Qt::TextSingleLine, m_dateString);
w = s.width() + metrics.width(" ");
h = f.pointSize();
//kDebug() << "uS: singleline" << w;
} else {
QSize s = metrics.size(Qt::TextWordWrap, m_dateString);
w = s.width();
h = f.pointSize();
//kDebug() << "uS: wordwrap" << w;
}
if (!m_dateTimezoneBesides) {
w = qMax(w, (int)(contentsRect().height() * aspect));
h = h+(int)(contentsRect().width() / aspect);
} else {
w = w+(int)(contentsRect().height() * aspect);
h = qMax(h, (int)(contentsRect().width() / aspect));
}
} else {
w = (int)(contentsRect().height() * aspect);
h = (int)(contentsRect().width() / aspect);
}
if (f == Plasma::Horizontal) {
// We have a fixed height, set some sensible width
setMinimumSize(QSize(w, 0));
//kDebug() << "DR" << m_dateRect.width() << "CR" << contentsRect().height() * aspect;
// kDebug() << contentsRect();
} else {
// We have a fixed width, set some sensible height
setMinimumSize(QSize(0, h));
}
setPreferredSize(QSize(w, h));
emit sizeHintChanged(Qt::PreferredSize);
//kDebug() << "minZize: " << minimumSize() << preferredSize();
if (m_isDefaultFont) {
const QString fakeTimeString = KGlobal::locale()->formatTime(QTime(23,59,59), m_timeFormat);
expandFontToMax(m_plainClockFont, fakeTimeString);
}
generatePixmap();
update();
}
void Clock::clockConfigChanged()
{
KConfigGroup cg = config();
m_showTimezone = cg.readEntry("showTimezone", !isLocalTimezone());
kDebug() << "showTimezone:" << m_showTimezone;
if (cg.hasKey("showDate")) { //legacy config entry as of 2011-1-4
m_dateStyle = cg.readEntry("showDate", false) ? 2 : 0; //short date : no date
cg.deleteEntry("showDate");
}
else {
m_dateStyle = cg.readEntry("dateStyle", 0);
}
if (cg.hasKey("showYear")) { //legacy config entry as of 2011-1-4
if( m_dateStyle ) {
m_dateStyle = cg.readEntry("showYear", false) ? 2 : 1; //short date : compact date
}
cg.deleteEntry("showYear");
}
m_timeFormat = static_cast<QLocale::FormatType>(cg.readEntry("timeFormat", int(QLocale::ShortFormat)));
//We don't need to cache the applet if it update every seconds
setCacheMode(QGraphicsItem::NoCache);
QFont f = cg.readEntry("plainClockFont", m_plainClockFont);
m_isDefaultFont = f == m_plainClockFont;
m_plainClockFont = f;
m_useCustomColor = cg.readEntry("useCustomColor", m_useCustomColor);
m_plainClockColor = cg.readEntry("plainClockColor", m_plainClockColor);
m_useCustomShadowColor = cg.readEntry("useCustomShadowColor", m_useCustomShadowColor);
m_plainClockShadowColor = cg.readEntry("plainClockShadowColor", m_plainClockShadowColor);
m_drawShadow = cg.readEntry("plainClockDrawShadow", m_drawShadow);
updateColors();
if (m_useCustomColor) {
m_pixmap = QPixmap();
delete m_svg;
m_svg = 0;
}
const QFontMetricsF metrics(KGlobalSettings::smallestReadableFont());
const QString timeString = KGlobal::locale()->formatTime(QTime(23, 59), m_timeFormat);
setMinimumSize(metrics.size(Qt::TextSingleLine, timeString));
if (isUserConfiguring()) {
updateSize();
}
}
bool Clock::showTimezone() const
{
return m_showTimezone || shouldDisplayTimezone();
}
void Clock::dataUpdated(const QString &source, const Plasma::DataEngine::Data &data)
{
Q_UNUSED(source);
m_time = data["Time"].toTime();
m_date = data["Date"].toDate();
if (Plasma::ToolTipManager::self()->isVisible(this)) {
updateTipContent();
}
updateClockApplet(data);
generatePixmap();
update();
}
void Clock::createClockConfigurationInterface(KConfigDialog *parent)
{
//TODO: Make the size settable
QWidget *widget = new QWidget();
ui.setupUi(widget);
parent->addPage(widget, i18n("Appearance"), "view-media-visualization");
ui.timeFormatBox->addItem(i18nc("A kind of time representation", "Compact time"), QVariant(int(QLocale::NarrowFormat)));
ui.timeFormatBox->addItem(i18nc("A kind of time representation", "Short time"), QVariant(int(QLocale::ShortFormat)));
ui.timeFormatBox->addItem(i18nc("A kind of time representation", "Long time"), QVariant(int(QLocale::LongFormat)));
ui.timeFormatBox->setCurrentIndex(ui.timeFormatBox->findData(int(m_timeFormat)));
ui.showTimeZone->setChecked(m_showTimezone);
ui.plainClockFontBold->setChecked(m_plainClockFont.bold());
ui.plainClockFontItalic->setChecked(m_plainClockFont.italic());
ui.plainClockFont->setCurrentFont(m_plainClockFont);
ui.useCustomColor->setChecked(m_useCustomColor);
ui.plainClockColor->setColor(m_plainClockColor);
ui.drawShadow->setChecked(m_drawShadow);
ui.useCustomShadowColor->setChecked(m_useCustomShadowColor);
ui.plainClockShadowColor->setColor(m_plainClockShadowColor);
ui.configureDateFormats->setIcon( KIcon( "configure" ) );
QStringList dateStyles;
dateStyles << i18nc("A kind of date representation", "No date")
<< i18nc("A kind of date representation", "Compact date")
<< i18nc("A kind of date representation", "Short date")
<< i18nc("A kind of date representation", "Long date");
ui.dateStyle->addItems(dateStyles);
ui.dateStyle->setCurrentIndex(m_dateStyle);
connect(ui.drawShadow, SIGNAL(toggled(bool)),
this, SLOT(configDrawShadowToggled(bool)));
connect(ui.configureDateFormats, SIGNAL(clicked()),
this, SLOT(launchDateKcm()));
configDrawShadowToggled(m_drawShadow);
connect(ui.plainClockFont, SIGNAL(currentFontChanged(QFont)),
parent, SLOT(settingsModified()));
connect(ui.plainClockFontBold, SIGNAL(stateChanged(int)),
parent, SLOT(settingsModified()));
connect(ui.plainClockFontItalic, SIGNAL(stateChanged(int)),
parent, SLOT(settingsModified()));
connect(ui.useCustomColor, SIGNAL(stateChanged(int)),
parent, SLOT(settingsModified()));
connect(ui.plainClockColor, SIGNAL(changed(QColor)),
parent, SLOT(settingsModified()));
connect(ui.drawShadow, SIGNAL(stateChanged(int)),
parent, SLOT(settingsModified()));
connect(ui.useCustomShadowColor, SIGNAL(stateChanged(int)),
parent, SLOT(settingsModified()));
connect(ui.plainClockShadowColor, SIGNAL(changed(QColor)),
parent, SLOT(settingsModified()));
connect(ui.showTimeZone, SIGNAL(stateChanged(int)),
parent, SLOT(settingsModified()));
connect(ui.timeFormatBox, SIGNAL(currentIndexChanged(int)),
parent, SLOT(settingsModified()));
connect(ui.dateStyle, SIGNAL(currentIndexChanged(int)),
parent, SLOT(settingsModified()));
}
void Clock::configDrawShadowToggled(bool value)
{
ui.useCustomShadowColor->setEnabled(value);
ui.customShadowColorLabel->setEnabled(value);
ui.plainClockShadowColor->setEnabled(value && ui.useCustomShadowColor->isChecked());
}
void Clock::clockConfigAccepted()
{
KConfigGroup cg = config();
m_showTimezone = ui.showTimeZone->isChecked();
cg.writeEntry("showTimezone", m_showTimezone);
if (m_isDefaultFont && ui.plainClockFont->currentFont() != m_plainClockFont) {
m_isDefaultFont = false;
}
m_plainClockFont = ui.plainClockFont->currentFont();
m_dateStyle = ui.dateStyle->currentIndex();
cg.writeEntry("dateStyle", m_dateStyle);
m_timeFormat = static_cast<QLocale::FormatType>(ui.timeFormatBox->itemData(ui.timeFormatBox->currentIndex()).toInt());
cg.writeEntry("timeFormat", int(m_timeFormat));
m_useCustomColor = ui.useCustomColor->isChecked();
cg.writeEntry("useCustomColor", m_useCustomColor);
if (m_useCustomColor) {
m_plainClockColor = ui.plainClockColor->color();
cg.writeEntry("plainClockColor", m_plainClockColor);
m_pixmap = QPixmap();
delete m_svg;
m_svg = 0;
} else {
m_plainClockColor = Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor);
}
m_useCustomShadowColor = ui.useCustomShadowColor->isChecked();
cg.writeEntry("useCustomShadowColor", m_useCustomShadowColor);
if (m_useCustomShadowColor) {
m_plainClockShadowColor = ui.plainClockShadowColor->color();
cg.writeEntry("plainClockShadowColor", m_plainClockShadowColor);
} else {
m_plainClockShadowColor = Plasma::Theme::defaultTheme()->color(Plasma::Theme::BackgroundColor);
}
m_drawShadow = ui.drawShadow->isChecked();
cg.writeEntry("plainClockDrawShadow", m_drawShadow);
m_plainClockFont.setBold(ui.plainClockFontBold->checkState() == Qt::Checked);
m_plainClockFont.setItalic(ui.plainClockFontItalic->checkState() == Qt::Checked);
cg.writeEntry("plainClockFont", m_plainClockFont);
constraintsEvent(Plasma::SizeConstraint);
generatePixmap();
update();
emit sizeHintChanged(Qt::PreferredSize);
emit configNeedsSaving();
}
void Clock::changeEngineTimezone(const QString &oldTimezone, const QString &newTimezone)
{
resetLastTimeSeen();
dataEngine("time")->disconnectSource(oldTimezone, this);
dataEngine("time")->connectSource(newTimezone, this, updateInterval(), intervalAlignment());
}
QRectF Clock::normalLayout(int subtitleWidth, int subtitleHeight, const QRect &contentsRect)
{
Q_UNUSED(subtitleWidth);
QRectF myRect = QRectF(contentsRect.left(),
contentsRect.bottom() - subtitleHeight,
contentsRect.width(),
contentsRect.bottom());
//p->fillRect(myRect, QBrush(QColor("green")));
// Now find out how much space is left for painting the time
m_timeRect = QRect(contentsRect.left(),
contentsRect.top(),
contentsRect.width(),
contentsRect.height() - subtitleHeight);
return myRect;
}
QRectF Clock::sideBySideLayout(int subtitleWidth, int subtitleHeight, const QRect &contentsRect)
{
QRectF myRect = QRectF(contentsRect.right()-subtitleWidth,
contentsRect.top() + (contentsRect.height()-subtitleHeight)/2,
subtitleWidth,
subtitleHeight);
// kDebug() << "myRect: " << myRect;
// p->fillRect(myRect, QBrush(QColor("grey")));
// Now find out how much space is left for painting the time
m_timeRect = QRect(contentsRect.left(),
contentsRect.top(),
contentsRect.right() - subtitleWidth,
contentsRect.bottom());
return myRect;
}
void Clock::paintInterface(QPainter *p, const QStyleOptionGraphicsItem *option, const QRect &contentsRect)
{
Q_UNUSED(option);
if (!m_time.isValid() || !m_date.isValid()) {
return;
}
p->setPen(QPen(m_plainClockColor));
p->setRenderHint(QPainter::SmoothPixmapTransform);
p->setRenderHint(QPainter::Antialiasing);
/* ... helps debugging contentsRect and sizing ...
QColor c = QColor(Qt::blue);
c.setAlphaF(.5);
p->setBrush(c);
p->drawRect(contentsRect);
*/
// Paint the date, conditionally, and let us know afterwards how much
// space is left for painting the time on top of it.
QRectF dateRect;
const QString timeString = KGlobal::locale()->formatTime(m_time, m_timeFormat);
const QString fakeTimeString = KGlobal::locale()->formatTime(QTime(23,59,59), m_timeFormat);
QFont smallFont = KGlobalSettings::smallestReadableFont();
//create the string for the date and/or the timezone
if (m_dateStyle || showTimezone()) {
QString dateString;
//Create the localized date string if needed
if (m_dateStyle) {
if (m_dateStyle == 1) { //compact date
dateString = KGlobal::locale()->formatDate(m_date, QLocale::NarrowFormat);
} else if (m_dateStyle == 2) { //short date
dateString = KGlobal::locale()->formatDate(m_date, QLocale::ShortFormat);
} else if (m_dateStyle == 3) { //long date
dateString = KGlobal::locale()->formatDate(m_date, QLocale::LongFormat);
} else { //shouldn't happen
dateString = KGlobal::locale()->formatDate(m_date, QLocale::ShortFormat);
}
if (showTimezone()) {
QString currentTimezone = prettyTimezone();
dateString = i18nc("@label Date with currentTimezone: "
"%1 day of the week with date, %2 currentTimezone",
"%1 %2", dateString, currentTimezone);
}
} else if (showTimezone()) {
dateString = prettyTimezone();
}
dateString = dateString.trimmed();
if (m_dateString != dateString) {
// If this string has changed (for example due to changes in the config
// we have to reset the sizing of the applet
m_dateString = dateString;
updateSize();
}
// Check sizes
// magic 10 is for very big spaces,
// where there's enough space to grow without harming time space
QFontMetrics fm(smallFont);
if (contentsRect.height() > contentsRect.width() * 2) {
//kDebug() << Plasma::Vertical << contentsRect.height() <<contentsRect.width() * 2;
QRect dateRect = contentsRect;
dateRect.setHeight(dateRect.width());
smallFont.setPixelSize(qMax(dateRect.height() / 2, fm.ascent()));
m_dateRect = preparePainter(p, dateRect, smallFont, dateString);
} else {
// Find a suitable size for the date font
if (formFactor() == Plasma::Vertical) {
smallFont.setPixelSize(qMax(contentsRect.height()/6, fm.ascent()));
} else if (formFactor() == Plasma::Horizontal) {
smallFont.setPixelSize(qMax(qMin(contentsRect.height(), contentsRect.width())*2/7, fm.ascent()));
//we want to write the date always on one line
fm = QFontMetrics(smallFont);
const int tempWidth = fm.width(dateString);
if(tempWidth > contentsRect.width()){
smallFont.setPixelSize((contentsRect.width() * smallFont.pixelSize())/tempWidth);
}
} else {
smallFont.setPixelSize(qMax(qMin(contentsRect.height(), contentsRect.width())/8, KGlobalSettings::smallestReadableFont().pointSize()));
}
m_dateRect = preparePainter(p, contentsRect, smallFont, dateString);
}
// kDebug() << "m_dateRect: " << m_dateRect;
const int subtitleHeight = m_dateRect.height();
const int subtitleWidth = m_dateRect.width();
// kDebug() << "subtitleWitdh: " << subtitleWitdh;
// kDebug() << "subtitleHeight: " << subtitleHeight;
if (m_dateTimezoneBesides) {
//kDebug() << contentsRect.height() << subtitleHeight << smallFont.pixelSize();
if (contentsRect.height() - subtitleHeight >= smallFont.pixelSize() || formFactor() != Plasma::Horizontal) {
// to small to display the time on top of the date/timezone
// put them side by side
// kDebug() << "switching to normal";
m_dateTimezoneBesides = false;
dateRect = normalLayout(subtitleWidth, subtitleHeight, contentsRect);
} else {
dateRect = sideBySideLayout(subtitleWidth, subtitleHeight, contentsRect);
}
} else {
/* kDebug() << "checking timezone placement"
<< contentsRect.height() << dateRect.height() << subtitleHeight
<< smallFont.pixelSize() << smallFont.pointSize();*/
if (contentsRect.height() - subtitleHeight < smallFont.pixelSize() && formFactor() == Plasma::Horizontal) {
// to small to display the time on top of the date/timezone
// put them side by side
// kDebug() << "switching to s-b-s";
m_dateTimezoneBesides = true;
dateRect = sideBySideLayout(subtitleWidth, subtitleHeight, contentsRect);
} else {
dateRect = normalLayout(subtitleWidth, subtitleHeight, contentsRect);
}
}
} else {
m_timeRect = contentsRect;
}
// kDebug() << "timeRect: " << m_timeRect;
// p->fillRect(timeRect, QBrush(QColor("red")));
// kDebug() << m_time;
// Choose a relatively big font size to start with
m_plainClockFont.setPointSizeF(qMax(m_timeRect.height(), KGlobalSettings::smallestReadableFont().pointSize()));
preparePainter(p, m_timeRect, m_plainClockFont, fakeTimeString, true);
if (!m_dateString.isEmpty()) {
if (m_dateTimezoneBesides) {
QFontMetrics fm(m_plainClockFont);
//kDebug() << dateRect << m_timeRect << fm.boundingRect(m_timeRect, Qt::AlignCenter, timeString);
QRect br = fm.boundingRect(m_timeRect, Qt::AlignCenter, timeString);
QFontMetrics smallfm(smallFont);
dateRect.moveLeft(br.right() + qMin(0, br.left()) + smallfm.width(" "));
}
// When we're relatively low, force everything into a single line
QFont f = p->font();
p->setFont(smallFont);
QPen datePen = p->pen();
QColor dateColor = m_plainClockColor;
dateColor.setAlphaF(0.7);
datePen.setColor(dateColor);
p->setPen(datePen);
if (formFactor() == Plasma::Horizontal && (contentsRect.height() < smallFont.pointSize()*6)) {
p->drawText(dateRect, Qt::TextSingleLine | Qt::AlignHCenter, m_dateString);
} else {
p->drawText(dateRect, Qt::TextWordWrap | Qt::AlignHCenter, m_dateString);
}
p->setFont(f);
}
if (m_useCustomColor || !m_svgExistsInTheme) {
QFontMetrics fm(p->font());
QPointF timeTextOrigin(QPointF(qMax(0, (m_timeRect.center().x() - fm.width(fakeTimeString) / 2)),
(m_timeRect.center().y() + fm.height() / 3)));
p->translate(-0.5, -0.5);
if (m_drawShadow) {
QPen tmpPen = p->pen();
// Paint a backdrop behind the time's text
qreal shadowOffset = 1.0;
QPen shadowPen;
QColor shadowColor = m_plainClockShadowColor;
shadowColor.setAlphaF(.4);
shadowPen.setColor(shadowColor);
p->setPen(shadowPen);
QPointF shadowTimeTextOrigin = QPointF(timeTextOrigin.x() + shadowOffset,
timeTextOrigin.y() + shadowOffset);
p->drawText(shadowTimeTextOrigin, timeString);
p->setPen(tmpPen);
// Paint the time itself with a linear translucency gradient
QLinearGradient gradient = QLinearGradient(QPointF(0, 0), QPointF(0, fm.height()));
QColor startColor = m_plainClockColor;
startColor.setAlphaF(.95);
QColor stopColor = m_plainClockColor;
stopColor.setAlphaF(.7);
gradient.setColorAt(0.0, startColor);
gradient.setColorAt(0.5, stopColor);
gradient.setColorAt(1.0, startColor);
QBrush gradientBrush(gradient);
QPen gradientPen(gradientBrush, tmpPen.width());
p->setPen(gradientPen);
}
p->drawText(timeTextOrigin, timeString);
//when use the custom theme colors, draw the time textured
} else {
QRect adjustedTimeRect = m_pixmap.rect();
adjustedTimeRect.moveCenter(m_timeRect.center());
p->drawPixmap(adjustedTimeRect, m_pixmap);
}
}
void Clock::generatePixmap()
{
if (m_useCustomColor || !m_svgExistsInTheme) {
return;
}
if (!m_svg) {
m_svg = new Plasma::Svg(this);
m_svg->setImagePath("widgets/labeltexture");
m_svg->setContainsMultipleImages(true);
}
const QString fakeTimeString = KGlobal::locale()->formatTime(QTime(23,59,59), m_timeFormat);
const QString timeString = KGlobal::locale()->formatTime(m_time, m_timeFormat);
QRect rect(contentsRect().toRect());
QFont font(m_plainClockFont);
prepareFont(font, rect, fakeTimeString, true);
m_pixmap = Plasma::PaintUtils::texturedText(timeString, font, m_svg);
}
void Clock::expandFontToMax(QFont &font, const QString &text)
{
bool first = true;
const QRect rect = contentsRect().toRect();
int oldWidth = 0;
int oldHeight = 0;
// Starting with the given font, increase its size until it'll fill the rect
do {
if (first) {
first = false;
} else {
font.setPointSize(font.pointSize() + 1);
}
const QFontMetrics fm(font);
QRect fr = fm.boundingRect(rect, Qt::TextSingleLine, text);
if (oldWidth == fr.width() && oldHeight == fr.height()) {
// Largest font size reached.
break;
}
oldWidth = fr.width();
oldHeight = fr.height();
if (fr.width() >= rect.width() || fr.height() >= rect.height()) {
break;
}
} while (true);
}
void Clock::prepareFont(QFont &font, QRect &rect, const QString &text, bool singleline)
{
QRect tmpRect;
bool first = true;
const int smallest = KGlobalSettings::smallestReadableFont().pointSize();
// Starting with the given font, decrease its size until it'll fit in the
// given rect allowing wrapping where possible
do {
if (first) {
first = false;
} else {
font.setPointSize(qMax(smallest, font.pointSize() - 1));
}
const QFontMetrics fm(font);
int flags = (singleline || ((formFactor() == Plasma::Horizontal) && (contentsRect().height() < font.pointSize()*6))) ?
Qt::TextSingleLine : Qt::TextWordWrap;
tmpRect = fm.boundingRect(rect, flags, text);
} while (font.pointSize() > smallest &&
(tmpRect.width() > rect.width() || tmpRect.height() > rect.height()));
rect = tmpRect;
}
QRect Clock::preparePainter(QPainter *p, const QRect &rect, const QFont &font, const QString &text, bool singleline)
{
QRect tmpRect = rect;
QFont tmpFont = font;
prepareFont(tmpFont, tmpRect, text, singleline);
p->setFont(tmpFont);
return tmpRect;
}
int Clock::updateInterval() const
{
// even the short format can include seconds
return 1000;
}
Plasma::IntervalAlignment Clock::intervalAlignment() const
{
return Plasma::NoAlignment;
}
void Clock::updateColors()
{
m_svgExistsInTheme = Plasma::Theme::defaultTheme()->currentThemeHasImage("widgets/labeltexture");
if (!m_useCustomColor) {
m_plainClockColor = Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor);
}
if (!m_useCustomShadowColor) {
m_plainClockShadowColor = Plasma::Theme::defaultTheme()->color(Plasma::Theme::BackgroundColor);
}
if (!m_useCustomColor || !m_useCustomShadowColor) {
update();
}
}
void Clock::launchDateKcm() //SLOT
{
KService::List offers = KServiceTypeTrader::self()->query("KCModule", "Library == 'kcm_locale'");
if (!offers.isEmpty()) {
KService::Ptr service = offers.first();
KRun::run(*service, KUrl::List(), 0);
}
update();
}
#include "moc_clock.cpp"