• Skip to content
  • Skip to link menu
KDE 4.1 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

Applets

clock.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2007-2008 by Riccardo Iaconelli <riccardo@kde.org>      *
00003  *   Copyright (C) 2007-2008 by Sebastian Kuegler <sebas@kde.org>          *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA .        *
00019  ***************************************************************************/
00020 
00021 
00022 #include "clock.h"
00023 
00024 #include <math.h>
00025 
00026 #include <QtGui/QPainter>
00027 #include <QtGui/QStyleOptionGraphicsItem>
00028 #include <QtGui/QSpinBox>
00029 #include <QtCore/QTimeLine>
00030 #include <QtGui/QGraphicsView>
00031 #include <QtGui/QGraphicsSceneMouseEvent>
00032 #include <QtCore/QDate>
00033 
00034 #include <KDebug>
00035 #include <KLocale>
00036 #include <KIcon>
00037 #include <KSharedConfig>
00038 #include <KTimeZoneWidget>
00039 #include <KDialog>
00040 #include <KColorScheme>
00041 #include <KGlobalSettings>
00042 #include <KConfigDialog>
00043 #include <KDatePicker>
00044 #include <plasma/theme.h>
00045 #include <plasma/dialog.h>
00046 
00047 
00048 Clock::Clock(QObject *parent, const QVariantList &args)
00049     : ClockApplet(parent, args),
00050       m_plainClockFont(KGlobalSettings::generalFont()),
00051       m_useCustomColor(false),
00052       m_plainClockColor(),
00053       m_showDate(false),
00054       m_showYear(false),
00055       m_showDay(false),
00056       m_showSeconds(false),
00057       m_showTimezone(false),
00058       m_timeZones(),
00059       m_layout(0)
00060 {
00061     KGlobal::locale()->insertCatalog("libplasmaclock");
00062     setHasConfigurationInterface(true);
00063     resize(150, 75);
00064 }
00065 
00066 void Clock::init()
00067 {
00068     KConfigGroup cg = config();
00069     setCurrentTimezone(cg.readEntry("currentTimezone", localTimezone()));
00070     m_timeZones = cg.readEntry("timeZones", QStringList());
00071 
00072     m_showTimezone = cg.readEntry("showTimezone", !isLocalTimezone());
00073 
00074     kDebug() << "showTimezone:" << m_showTimezone;
00075 
00076     m_showDate = cg.readEntry("showDate", false);
00077     m_showYear = cg.readEntry("showYear", false);
00078     m_showDay = cg.readEntry("showDay", true);
00079 
00080     m_showSeconds = cg.readEntry("showSeconds", false);
00081     m_plainClockFont = cg.readEntry("plainClockFont", m_plainClockFont);
00082     m_useCustomColor = cg.readEntry("useCustomColor", false);
00083     if (m_useCustomColor) {
00084         m_plainClockColor = cg.readEntry("plainClockColor", m_plainClockColor);
00085     } else {
00086         m_plainClockColor = KColorScheme(QPalette::Active, KColorScheme::View, Plasma::Theme::defaultTheme()->colorScheme()).foreground().color();
00087     }
00088 
00089     QFontMetricsF metrics(KGlobalSettings::smallestReadableFont());
00090     QString timeString = KGlobal::locale()->formatTime(QTime(23, 59), m_showSeconds);
00091     setMinimumSize(metrics.size(Qt::TextSingleLine, timeString));
00092 
00093     m_toolTipIcon = KIcon("chronometer").pixmap(IconSize(KIconLoader::Desktop));
00094 
00095     dataEngine("time")->connectSource(currentTimezone(), this, updateInterval(), intervalAlignment());
00096     connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), this, SLOT(updateColors()));
00097 }
00098 
00099 void Clock::constraintsEvent(Plasma::Constraints constraints)
00100 {
00101     if (constraints & Plasma::SizeConstraint) {
00102         updateSize();
00103     }
00104 }
00105 
00106 void Clock::updateSize() {
00107     int aspect = 2;
00108     if (m_showSeconds) {
00109         aspect = 3;
00110     }
00111     if (formFactor() == Plasma::Horizontal) {
00112         // We have a fixed height, set some sensible width
00113         if (m_showDate || m_showTimezone) {
00114             setMinimumWidth(qMax(m_dateRect.width(), (int)(contentsRect().height() * aspect)));
00115         } else {
00116             setMinimumWidth((int)(contentsRect().height() * aspect));
00117         }
00118         setMinimumHeight(0);
00119         //kDebug() << "DR" << m_dateRect.width() << "CR" << contentsRect().height() * aspect;
00120     } else if (formFactor() == Plasma::Vertical) {
00121         // We have a fixed width, set some sensible height
00122         setMinimumHeight((int)contentsRect().width() / aspect);
00123         setMinimumWidth(0);
00124     }
00125 }
00126 
00127 void Clock::updateToolTipContent() {
00128     //FIXME Port to future tooltip manager
00129     /*Plasma::ToolTipData tipData;
00130 
00131     tipData.mainText = KGlobal::locale()->formatTime(m_time, m_showSeconds);
00132     tipData.subText = m_date.toString();
00133     tipData.image = m_toolTipIcon;
00134 
00135     setToolTip(tipData);*/
00136 }
00137 
00138 void Clock::dataUpdated(const QString &source, const Plasma::DataEngine::Data &data)
00139 {
00140     Q_UNUSED(source);
00141     m_time = data["Time"].toTime();
00142     m_date = data["Date"].toDate();
00143     m_prettyTimezone = data["Timezone City"].toString();
00144     m_prettyTimezone.replace("_", " ");
00145 
00146     updateToolTipContent();
00147 
00148     // avoid unnecessary repaints
00149     if (m_showSeconds || m_time.minute() != m_lastTimeSeen.minute()) {
00150         m_lastTimeSeen = m_time;
00151         update();
00152     }
00153 }
00154 
00155 void Clock::createConfigurationInterface(KConfigDialog *parent)
00156 {
00157     //TODO: Make the size settable
00158     QWidget *widget = new QWidget();
00159     ui.setupUi(widget);
00160     parent->setButtons( KDialog::Ok | KDialog::Cancel | KDialog::Apply );
00161     parent->addPage(widget, parent->windowTitle(), icon());
00162     connect(parent, SIGNAL(applyClicked()), this, SLOT(configAccepted()));
00163     connect(parent, SIGNAL(okClicked()), this, SLOT(configAccepted()));
00164 
00165     ui.showDate->setChecked(m_showDate);
00166     ui.showYear->setChecked(m_showYear);
00167     ui.showDay->setChecked(m_showDay);
00168     ui.secondsCheckbox->setChecked(m_showSeconds);
00169     ui.showTimezone->setChecked(m_showTimezone);
00170     ui.plainClockFontBold->setChecked(m_plainClockFont.bold());
00171     ui.plainClockFontItalic->setChecked(m_plainClockFont.italic());
00172     ui.plainClockFont->setCurrentFont(m_plainClockFont);
00173     ui.useCustomColor->setChecked(m_useCustomColor);
00174     ui.plainClockColor->setColor(m_plainClockColor);
00175     ui.localTimeZone->setChecked(isLocalTimezone());
00176     ui.timeZones->setEnabled(!isLocalTimezone());
00177     foreach (const QString &str, m_timeZones) {
00178         ui.timeZones->setSelected(str, true);
00179     }
00180 }
00181 
00182 void Clock::configAccepted()
00183 {
00184     KConfigGroup cg = config();
00185 
00186     m_showTimezone = ui.showTimezone->isChecked();
00187     cg.writeEntry("showTimezone", m_showTimezone);
00188 
00189     m_plainClockFont = ui.plainClockFont->currentFont();
00190     //We need this to happen before we disconnect/reconnect sources to ensure
00191     //that the update interval is set properly.
00192     if (m_showSeconds != ui.secondsCheckbox->isChecked()) {
00193         m_showSeconds = !m_showSeconds;
00194         cg.writeEntry("showSeconds", m_showSeconds);
00195     }
00196 
00197     m_timeZones = ui.timeZones->selection();
00198     cg.writeEntry("timeZones", m_timeZones);
00199 
00200     dataEngine("time")->disconnectSource(currentTimezone(), this);
00201     QString newTimezone = localTimezone();
00202 
00203     if (!ui.localTimeZone->isChecked() && !m_timeZones.isEmpty()) {
00204         newTimezone = m_timeZones.at(0);
00205     }
00206 
00207     setCurrentTimezone(newTimezone);
00208     dataEngine("time")->connectSource(newTimezone, this, updateInterval(), intervalAlignment());
00209     cg.writeEntry("currentTimezone", newTimezone);
00210 
00211     m_showDate = ui.showDate->checkState() == Qt::Checked;
00212     cg.writeEntry("showDate", m_showDate);
00213     m_showYear = ui.showYear->checkState() == Qt::Checked;
00214     cg.writeEntry("showYear", m_showYear);
00215     m_showDay = ui.showDay->checkState() == Qt::Checked;
00216     cg.writeEntry("showDay", m_showDay);
00217     m_showSeconds = ui.secondsCheckbox->checkState() == Qt::Checked;
00218     cg.writeEntry("showSeconds", m_showSeconds);
00219 
00220     m_useCustomColor = ui.useCustomColor->checkState() == Qt::Checked;
00221     if (m_useCustomColor) {
00222         m_plainClockColor = ui.plainClockColor->color();
00223     } else {
00224         m_plainClockColor = KColorScheme(QPalette::Active, KColorScheme::View, Plasma::Theme::defaultTheme()->colorScheme()).foreground().color();
00225     }
00226 
00227     m_plainClockFont.setBold(ui.plainClockFontBold->checkState() == Qt::Checked);
00228     m_plainClockFont.setItalic(ui.plainClockFontItalic->checkState() == Qt::Checked);
00229 
00230     cg.writeEntry("plainClockFont", m_plainClockFont);
00231     cg.writeEntry("useCustomColor", m_useCustomColor);
00232     cg.writeEntry("plainClockColor", m_plainClockColor);
00233 
00234     constraintsEvent(Plasma::SizeConstraint);
00235     update();
00236     emit configNeedsSaving();
00237 }
00238 
00239 Clock::~Clock()
00240 {
00241 }
00242 
00243 void Clock::paintInterface(QPainter *p, const QStyleOptionGraphicsItem *option, const QRect &contentsRect)
00244 {
00245     Q_UNUSED(option);
00246 
00247     if (m_time.isValid() && m_date.isValid()) {
00248         p->setPen(QPen(m_plainClockColor));
00249         p->setRenderHint(QPainter::SmoothPixmapTransform);
00250         p->setRenderHint(QPainter::Antialiasing);
00251 
00252         /* ... helps debugging contentsRect and sizing ...
00253         QColor c = QColor(Qt::green);
00254         c.setAlphaF(.5);
00255         p->setBrush(c);
00256         p->drawRect(contentsRect);
00257         */
00258         QRect timeRect;
00259 
00260         // Paint the date, conditionally, and let us know afterwards how much
00261         // space is left for painting the time on top of it.
00262         if (m_showDate || m_showTimezone) {
00263             QString dateString;
00264             if (m_showDate) {
00265                 KLocale tmpLocale(*KGlobal::locale());
00266                 tmpLocale.setDateFormat("%e"); // day number of the month
00267                 QString day = tmpLocale.formatDate(m_date);
00268                 tmpLocale.setDateFormat("%b"); // short form of the month
00269                 QString month = tmpLocale.formatDate(m_date);
00270 
00271                 if (m_showYear) {
00272                     tmpLocale.setDateFormat("%Y"); // whole year
00273                     QString year = tmpLocale.formatDate(m_date);
00274                     dateString = i18nc("@label Short date: "
00275                                        "%1 day in the month, %2 short month name, %3 year",
00276                                        "%1 %2 %3", day, month, year);
00277                 } else {
00278                     dateString = i18nc("@label Short date: "
00279                                        "%1 day in the month, %2 short month name",
00280                                        "%1 %2", day, month);
00281                 }
00282 
00283                 if (m_showDay) {
00284                     tmpLocale.setDateFormat("%a"); // short weekday
00285                     QString weekday = tmpLocale.formatDate(m_date);
00286                     dateString = i18nc("@label Day of the week with date: "
00287                                        "%1 short day name, %2 short date",
00288                                        "%1, %2", weekday, dateString);
00289                 }
00290 
00291                 if (m_showTimezone) {
00292                     QString currentTimezone = m_prettyTimezone;
00293                     dateString = i18nc("@label Date with currentTimezone: "
00294                                        "%1 day of the week with date, %2 currentTimezone",
00295                                        "%1 %2", dateString, currentTimezone);
00296                 }
00297             } else if (m_showTimezone) {
00298                 dateString = m_prettyTimezone;
00299             }
00300 
00301             // Check sizes
00302             m_dateRect = preparePainter(p, contentsRect, KGlobalSettings::smallestReadableFont(), dateString);
00303             int subtitleHeight = m_dateRect.height();
00304 
00305             QRectF myRect = QRectF(0,
00306                                 contentsRect.bottom()-subtitleHeight,
00307                                 contentsRect.right(),
00308                                 contentsRect.bottom());
00309             p->drawText(myRect,
00310                         Qt::AlignHCenter | Qt::TextDontClip,
00311                         dateString
00312                     );
00313 
00314             // Now find out how much space is left for painting the time
00315             timeRect = QRect(   contentsRect.left(),
00316                                 contentsRect.top(),
00317                                 contentsRect.width(),
00318                                 (contentsRect.height()-subtitleHeight+4));
00319         } else {
00320             timeRect = contentsRect;
00321         }
00322 
00323         QString timeString = KGlobal::locale()->formatTime(m_time, m_showSeconds);
00324         // Choose a relatively big font size to start with
00325         m_plainClockFont.setPointSizeF(qMax(timeRect.height(), KGlobalSettings::smallestReadableFont().pointSize()));
00326         preparePainter(p, timeRect, m_plainClockFont, timeString);
00327 
00328         p->drawText(timeRect,
00329                     timeString,
00330                     QTextOption(Qt::AlignCenter)
00331                 );
00332     }
00333 }
00334 
00335 QRect Clock::preparePainter(QPainter *p, const QRect &rect, const QFont &font, const QString &text)
00336 {
00337     QRect tmpRect;
00338     QFont tmpFont = font;
00339 
00340     // Starting with the given font, decrease its size until it'll fit in the
00341     // given rect allowing wrapping where possible
00342     do {
00343         p->setFont(tmpFont);
00344         tmpFont.setPointSize(qMax(KGlobalSettings::smallestReadableFont().pointSize(), tmpFont.pointSize() - 1));
00345         int flags = (formFactor() == Plasma::Horizontal) ? Qt::TextSingleLine : Qt::TextWordWrap;
00346         tmpRect = p->boundingRect(rect, flags, text);
00347     } while (tmpFont.pointSize() > KGlobalSettings::smallestReadableFont().pointSize() && (tmpRect.width() > rect.width() ||
00348             tmpRect.height() > rect.height()));
00349 
00350     return tmpRect;
00351 }
00352 
00353 int Clock::updateInterval() const
00354 {
00355     return m_showSeconds ? 1000 : 60000;
00356 }
00357 
00358 Plasma::IntervalAlignment Clock::intervalAlignment() const
00359 {
00360     return m_showSeconds ? Plasma::NoAlignment : Plasma::AlignToMinute;
00361 }
00362 
00363 void Clock::updateColors()
00364 {
00365     if (!m_useCustomColor) {
00366         m_plainClockColor = KColorScheme(QPalette::Active, KColorScheme::View, Plasma::Theme::defaultTheme()->colorScheme()).foreground().color();
00367         update();
00368     }
00369 }
00370 #include "clock.moc"

Applets

Skip menu "Applets"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members

API Reference

Skip menu "API Reference"
  • KWin
  •   KWin Libraries
  • Libraries
  •   libkworkspace
  •   libplasma
  •   libsolidcontrol
  •   libtaskmanager
  • Plasma
  •   Animators
  •   Applets
  •   Engines
  • Solid Modules
Generated for API Reference by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal