/*************************************************************************** * Copyright (c) 1996-2002 the kicker authors. (fuzzy logic) * * Copyright (C) 2007 by Riccardo Iaconelli * * Copyright (C) 2007 by Sven Burmeister * * * * 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 "fuzzyClock.h" #include #include #include #include #include #include #include Clock::Clock(QObject *parent, const QVariantList &args) : ClockApplet(parent, args), m_oldContentSize(QSizeF (0,0)), m_configUpdated(false), m_adjustToHeight(1), m_useCustomFontColor(false), m_fontColor(Qt::white), m_fontTimeBold(false), m_fontTimeItalic(false), m_fontTime(KGlobalSettings::smallestReadableFont()), m_showTimezone(false), m_showDate(false), m_showYear(false), m_showDay(false), m_layout(0) { KGlobal::locale()->insertCatalog("libplasmaclock"); KGlobal::locale()->insertCatalog("timezones4"); setHasConfigurationInterface(true); setBackgroundHints(Plasma::Applet::DefaultBackground); //If we do not set this, the user has to press CTRL when shrinking the plasmoid on the desktop beyond a certain size. setAspectRatioMode(Plasma::IgnoreAspectRatio); } Clock::~Clock() { } void Clock::init() { ClockApplet::init(); initFuzzyTimeStrings(); m_contentSize = geometry().size(); kDebug() << "The first content's size [geometry().size()] we get, init() called: " << geometry().size(); m_locale = KGlobal::locale(); clockConfigChanged(); //By default we use the smallest readable font. m_fontDate = QFont ( KGlobalSettings::smallestReadableFont() ); m_margin = 2; m_verticalSpacing = 2; Plasma::DataEngine* timeEngine = dataEngine("time"); timeEngine->connectSource(currentTimezone(), this, 6000, Plasma::AlignToMinute); connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), this, SLOT(updateColors())); } void Clock::clockConfigChanged() { KConfigGroup cg = config(); m_showTimezone = cg.readEntry("showTimezone", false); m_showDate = cg.readEntry("showDate", true); m_showYear = cg.readEntry("showYear",false); m_showDay = cg.readEntry("showDay",true); m_fuzzyness = cg.readEntry("fuzzyness", 1); m_fontTime = cg.readEntry("fontTime", KGlobalSettings::smallestReadableFont()); m_useCustomFontColor = cg.readEntry("useCustomFontColor", false); if (m_useCustomFontColor){ m_fontColor = cg.readEntry("fontColor", m_fontColor); }else{ m_fontColor = KColorScheme(QPalette::Active, KColorScheme::View, Plasma::Theme::defaultTheme()->colorScheme()).foreground().color(); } m_fontTimeBold = cg.readEntry("fontTimeBold", true); m_fontTimeItalic = cg.readEntry("fontTimeItalic", false); m_fontTime.setBold(m_fontTimeBold); m_fontTime.setItalic(m_fontTimeItalic); m_adjustToHeight = cg.readEntry("adjustToHeight", 1); } Qt::Orientations Clock::expandingDirections() const { //This tells the layout whether it's ok to be stretched, even if we do not need that space. Since we would become far too wide on a panel we do not want that. return 0; } // QSizeF Clock::contentSizeHint() const // { // return contentSize(); // } void Clock::constraintsEvent(Plasma::Constraints constraints) { kDebug() << "constraintsEvent() called"; if (constraints & Plasma::SizeConstraint || constraints & Plasma::FormFactorConstraint) { if ( (m_oldContentSize.toSize() != geometry().size() && m_oldContentSize.toSize() != QSize (0,0)) || m_configUpdated == true ) { //The size changed or config was updated kDebug() << "The content's size [geometry().size()] changed! old: " << m_oldContentSize << "new: " << geometry().size(); if ( m_configUpdated ) { calculateDateString(); calculateTimeString(); } kDebug() << "Constraints changed: " << constraints; if (formFactor() == Plasma::Planar || formFactor() == Plasma::MediaCenter) { kDebug() << "######## Other FormFactor"; calculateSize(); } else { kDebug() << "######## Small FormFactor"; calculateSize(); } kDebug() << "The new size has been calculated and set.\nneeded m_contenSize (if not in panel): " << m_contentSize << "\nactual content's size [geometry().size()] is: " << geometry().size() << "\nminimumSize() needed (in panel): " << minimumSize(); m_oldContentSize = geometry().size(); m_configUpdated = false; update(); } } } void Clock::dataUpdated(const QString& source, const Plasma::DataEngine::Data &data) { Q_UNUSED(source); m_time = data["Time"].toTime(); m_date = data["Date"].toDate(); kDebug() << "dataUpdated() was called."; if (m_time.minute() == m_lastTimeSeen.minute()) { // avoid unnecessary repaints // kDebug() << "avoided unnecessary update!"; return; } if (Plasma::ToolTipManager::self()->isVisible(this)) { updateTipContent(); } updateClockApplet(data); m_lastTimeSeen = m_time; calculateDateString(); calculateTimeString(); //The timestring changed. if (m_timeString != m_lastTimeStringSeen || m_dateString != m_lastDateStringSeen) { //The size might have changed calculateSize(); m_lastTimeStringSeen = m_timeString; m_lastDateStringSeen = m_dateString; updateGeometry(); //request to get painted. update(); } } void Clock::createClockConfigurationInterface(KConfigDialog *parent) { QWidget *widget = new QWidget(); ui.setupUi(widget); parent->addPage(widget, i18n("General"), icon()); ui.fuzzynessSlider->setSliderPosition( m_fuzzyness ); ui.showTimezone->setChecked( m_showTimezone ); ui.showDate->setChecked( m_showDate ); ui.showYear->setChecked( m_showYear ); ui.showDay->setChecked( m_showDay ); ui.adjustToHeight->setSliderPosition( m_adjustToHeight ); ui.fontTimeBold->setChecked(m_fontTimeBold); ui.fontTimeItalic->setChecked(m_fontTimeItalic); ui.fontTime->setCurrentFont(m_fontTime); ui.fontColor->setColor(m_fontColor); ui.useCustomFontColor->setChecked(m_useCustomFontColor); connect(ui.fontTime, SIGNAL(editTextChanged(QString)), parent, SLOT(settingsModified())); connect(ui.fontTimeBold, SIGNAL(stateChanged(int)), parent, SLOT(settingsModified())); connect(ui.fontTimeItalic, SIGNAL(stateChanged(int)), parent, SLOT(settingsModified())); connect(ui.useThemeColor, SIGNAL(toggled(bool)), parent, SLOT(settingsModified())); connect(ui.adjustToHeight, SIGNAL(valueChanged(int)), parent, SLOT(settingsModified())); connect(ui.showDate, SIGNAL(stateChanged(int)), parent, SLOT(settingsModified())); connect(ui.showDay, SIGNAL(stateChanged(int)), parent, SLOT(settingsModified())); connect(ui.showYear, SIGNAL(stateChanged(int)), parent, SLOT(settingsModified())); connect(ui.showTimezone, SIGNAL(stateChanged(int)), parent, SLOT(settingsModified())); connect(ui.fuzzynessSlider, SIGNAL(valueChanged(int)), parent, SLOT(settingsModified())); } void Clock::clockConfigAccepted() { KConfigGroup cg = config(); QGraphicsItem::update(); m_fontTime = ui.fontTime->currentFont(); cg.writeEntry("fontTime", m_fontTime); //In case adjustToHeight was disabled we have to reset the point-size of fontTime m_fontTime.setPointSize ( m_fontDate.pointSize() ); m_useCustomFontColor = ui.useCustomFontColor->isChecked(); cg.writeEntry("useCustomFontColor", m_useCustomFontColor); if (m_useCustomFontColor) { m_fontColor = ui.fontColor->color(); } else { m_fontColor = KColorScheme(QPalette::Active, KColorScheme::View, Plasma::Theme::defaultTheme()->colorScheme()).foreground().color(); } cg.writeEntry("fontColor", ui.fontColor->color()); m_fontTimeBold = ui.fontTimeBold->isChecked(); cg.writeEntry("fontTimeBold", m_fontTimeBold); m_fontTimeItalic = ui.fontTimeItalic->isChecked(); cg.writeEntry("fontTimeItalic", m_fontTimeItalic); m_fontTime.setBold(m_fontTimeBold); m_fontTime.setItalic(m_fontTimeItalic); m_fuzzyness = ui.fuzzynessSlider->value(); cg.writeEntry("fuzzyness", m_fuzzyness); m_showDate = ui.showDate->isChecked(); cg.writeEntry("showDate", m_showDate); m_showYear = ui.showYear->isChecked(); cg.writeEntry("showYear", m_showYear); m_showDay = ui.showDay->isChecked(); cg.writeEntry("showDay", m_showDay); m_adjustToHeight = ui.adjustToHeight->value(); kDebug() << "adjustToHeight" << m_adjustToHeight; cg.writeEntry("adjustToHeight", m_adjustToHeight); m_showTimezone = ui.showTimezone->isChecked(); cg.writeEntry("showTimezone", m_showTimezone); dataEngine("time")->connectSource(currentTimezone(), this, 6000, Plasma::AlignToMinute); m_configUpdated = true; updateConstraints(); emit configNeedsSaving(); } void Clock::changeEngineTimezone(const QString &oldTimezone, const QString &newTimezone) { dataEngine("time")->disconnectSource(oldTimezone, this); dataEngine("time")->connectSource(newTimezone, this, 6000, Plasma::AlignToMinute); } void Clock::calculateDateString() { if (!m_date.isValid() || ( m_showTimezone == false && m_showDate == false) ) { return; } const QLocale locale = KGlobal::locale()->toLocale(); QString day = QString::number(m_date.day()); QString month = locale.monthName(m_date.month(), QLocale::ShortFormat); QString year = QString::number(m_date.year()); //Copied from the digital-clock if (m_showDate) { if (m_showYear) { m_dateString = i18nc("@label Short date: " "%1 day in the month, %2 short month name, %3 year", "%1 %2 %3", day, month, year); } else { m_dateString = i18nc("@label Short date: " "%1 day in the month, %2 short month name", "%1 %2", day, month); } if (m_showDay) { QString weekday = locale.dayName(m_date.dayOfWeek(), QLocale::ShortFormat); m_dateString = i18nc("@label Day of the week with date: " "%1 short day name, %2 short date", "%1, %2", weekday, m_dateString); } } // QString newDateString = m_locale->formatDate ( m_date , m_locale->ShortDate ); // if( m_showDate == true ) { // m_dateString = newDateString; // } if( m_showTimezone == true ) { QString timezonetranslated = i18n( currentTimezone().toUtf8().data()); timezonetranslated = timezonetranslated.replace('_', ' '); m_timezoneString = '(' + timezonetranslated + ')'; } } void Clock::initFuzzyTimeStrings() { m_hourNames << i18nc("hour in the messages below","one") << i18nc("hour in the messages below","two") << i18nc("hour in the messages below","three") << i18nc("hour in the messages below","four") << i18nc("hour in the messages below","five") << i18nc("hour in the messages below","six") << i18nc("hour in the messages below","seven") << i18nc("hour in the messages below","eight") << i18nc("hour in the messages below","nine") << i18nc("hour in the messages below","ten") << i18nc("hour in the messages below","eleven") << i18nc("hour in the messages below","twelve"); m_normalFuzzy << ki18nc("%1 the hour translated above","%1 o'clock") << ki18nc("%1 the hour translated above","five past %1") << ki18nc("%1 the hour translated above","ten past %1") << ki18nc("%1 the hour translated above","quarter past %1") << ki18nc("%1 the hour translated above","twenty past %1") << ki18nc("%1 the hour translated above","twenty five past %1") << ki18nc("%1 the hour translated above","half past %1") << ki18nc("%1 the hour translated above","twenty five to %1") << ki18nc("%1 the hour translated above","twenty to %1") << ki18nc("%1 the hour translated above","quarter to %1") << ki18nc("%1 the hour translated above","ten to %1") << ki18nc("%1 the hour translated above","five to %1") << ki18nc("%1 the hour translated above","%1 o'clock"); m_dayTime << i18n("Night") << i18n("Early morning") << i18n("Morning") << i18n("Almost noon") << i18n("Noon") << i18n("Afternoon") << i18n("Evening") << i18n("Late evening"); m_weekTime << i18n("Start of week") << i18n("Middle of week") << i18n("End of week") << i18n("Weekend!"); } void Clock::calculateTimeString() { if (!m_time.isValid()) { return; } const int hours = m_time.hour(); // int hours = 1; const int minutes = m_time.minute(); // int minutes = 0; bool upcaseFirst = i18nc("Whether to uppercase the first letter of " "completed fuzzy time strings above: " "translate as 1 if yes, 0 if no.", "1") != QString('0'); //Create time-string QString newTimeString; if (m_fuzzyness == 1 || m_fuzzyness == 2) { // NOTE: Time strings are deliberately assembled here with English // only in mind: translators are able to script the translation to // their liking, and this code provides the least surprise for that. // Those inquiring should be directed to kde-i18n-doc mailing list // for instructions on how to make it right for their language. int sector = 0; int realHour = 0; if (m_fuzzyness == 1) { if (minutes > 2) { sector = (minutes - 3) / 5 + 1; } } else { if (minutes > 6) { sector = ((minutes - 7) / 15 + 1) * 3; } } int deltaHour = (sector <= 6 ? 0 : 1); if ((hours + deltaHour) % 12 > 0) { //there is a modulo realHour = (hours + deltaHour) % 12 - 1; } else { realHour = 12 - ((hours + deltaHour) % 12 + 1); } newTimeString = m_normalFuzzy[sector].subs(m_hourNames[realHour]).toString(); if (upcaseFirst) { newTimeString.replace(0, 1, QString(newTimeString.at(0).toUpper())); } } else if (m_fuzzyness == 3) { newTimeString = m_dayTime[hours / 3]; } else { //Timezones not yet implemented: int dow = QDateTime::currentDateTime().addSecs(TZoffset).date().dayOfWeek(); int dow = QDateTime::currentDateTime().date().dayOfWeek(); int weekStrIdx; if (dow == 1) { weekStrIdx = 0; } else if (dow >= 2 && dow <= 4) { weekStrIdx = 1; } else if (dow == 5) { weekStrIdx = 2; } else { weekStrIdx = 3; } newTimeString = m_weekTime[weekStrIdx]; } m_timeString = newTimeString; } void Clock::calculateSize() { //Minimal sizes. // QFont minimalFontTime = m_fontTime; // minimalFontTime.setPointsize ( m_fontDate.pointsize() ); // QFontMetrics fmMinimalTime ( minimalFontTime ); // // minimalTimeStringSize = QSizeF( minimalFontTime.width( m_timeString ) + m_margin*2,minimalFontTime.height() ); //In case adjustToHeight was disabled we have to reset the point-size of fontTime m_fontTime.setPointSize ( m_fontDate.pointSize() ); //Actual size, set in config or init QFontMetrics m_fmTime ( m_fontTime ); m_timeStringSize = QSizeF( m_fmTime.width( m_timeString ) + m_margin*2,m_fmTime.height() ); QFontMetrics m_fmDate ( m_fontDate ); //The date+timezone are currently hardcoded to the smallestReadableFont m_dateStringSize = QSizeF ( m_fmDate.width( m_dateString ), m_fmDate.height() ); m_timezoneStringSize = QSizeF( m_fmDate.width( m_timezoneString ), m_fmDate.height() ); int minimumWantedSize = KGlobalSettings::smallestReadableFont().pointSize(); if (formFactor() == Plasma::Horizontal) { QFont font(m_fontTime); font.setPixelSize(size().height()/2); minimumWantedSize = m_fontDatabase.font(font.family(), font.styleName(), font.pointSize()).pointSize(); } if ( contentsRect().size().width() > m_timeStringSize.width() && (formFactor() == Plasma::Planar || formFactor() == Plasma::MediaCenter)) { //plasmoid wider than timestring kDebug() << "Plasmoid wider than the timestring"; if( m_showDate == true && m_showTimezone == true ) { //date + timezone enabled kDebug() << "Date + Timezone enabled"; if ( contentsRect().size().width() > m_dateStringSize.width() + m_timezoneStringSize.width() ) { //date + timezone fit -> 2 rows within the plasmoid kDebug() << "plasmoid wider than date + timezone in 1 row"; m_subtitleString = m_dateString + ' ' + m_timezoneString; //Set subtitleString //set subtitleSize m_subtitleStringSize = QSizeF ( m_fmDate.width ( m_dateString + ' ' + m_timezoneString ) , m_dateStringSize.height()*1 ); } else { //date + timezone are split into two lines to fit the plasmoid -> 3 rows within the plasmoid kDebug() << "Plasmoid not wide enough for date + timezone in 1 row -> 2 rows"; m_subtitleString = m_dateString + '\n' + m_timezoneString; //Set subtitleString //set subtitleSize m_subtitleStringSize = QSizeF ( qMax( m_dateStringSize.width(),m_timezoneStringSize.width() ) , m_dateStringSize.height()*2 ); } } else if ( m_showDate == true ) { kDebug() << "Only Date enabled"; m_subtitleString = m_dateString; //Set subtitleString //set subtitleSize m_subtitleStringSize = QSizeF ( m_dateStringSize.width() , m_dateStringSize.height() ); } else if ( m_showTimezone == true ) { kDebug() << "Only timezone enabled"; m_subtitleString = m_timezoneString; //Set subtitleString //set subtitleSize m_subtitleStringSize = QSizeF ( m_timezoneStringSize.width() , m_timezoneStringSize.height() ); } else { //no subtitle kDebug() << "Neither date nor timezone enabled"; m_subtitleStringSize = QSizeF ( 0,0 ); } // //If the date/timezone was re-enabled we might have a wide enough, but not high enough plasmoid whose minimumContentSize only fits the timestring. -> increase minimumContentSize if ( m_timeStringSize.height() + m_verticalSpacing + m_subtitleStringSize.height() > minimumSize().height() ) { kDebug() << "Although the plasmoid is wider than necessary the height is too small -> set new minimum height: " << m_timeStringSize.height() + m_verticalSpacing + m_subtitleStringSize.height(); setMinimumSize ( QSizeF ( minimumSize().width(),m_timeStringSize.height() + m_verticalSpacing + m_subtitleStringSize.height() ) ); kDebug() << "New minimumContentSize(): " << minimumSize(); } //Make the timestring fit the plasmoid since it is bigger than minimumWantedSize m_fontTime.setPointSize(qMax((int)( geometry().size().height()/1.5), minimumWantedSize) ); m_fmTime = QFontMetrics( m_fontTime ); while ( ( m_fmTime.width( m_timeString ) > contentsRect().size().width() - 2*m_margin || m_fmTime.height() > contentsRect().size().height() - m_subtitleStringSize.height() - m_verticalSpacing ) && m_fontTime.pointSize() > minimumWantedSize) { //decrease pointSize m_fontTime.setPointSize(m_fontTime.pointSize() - 1); m_fmTime = QFontMetrics( m_fontTime ); m_timeStringSize = QSizeF ( m_fmTime.width( m_timeString ), m_fmTime.height() ); } //Adjust the height to the new horizontal size m_contentSize = QSizeF ( contentsRect().width(),m_timeStringSize.height() + m_verticalSpacing + m_subtitleStringSize.height() ); if ( formFactor() == Plasma::Horizontal ) { //if we are on the panel we are forced to accept the given height. kDebug() << "needed height: " << m_contentSize.height() << "fixed height forced on us: " << geometry().size().height(); //FIXME: it was resizing to size() itself //resize ( QSizeF ( m_contentSize.width(),geometry().size().height() ) ); } else { //add margins resize(m_contentSize + QSizeF(size()-contentsRect().size())); setPreferredSize(m_contentSize + QSizeF(size()-contentsRect().size())); resize(preferredSize()); emit sizeHintChanged(Qt::PreferredSize); emit appletTransformedItself(); } } else { //in a panel or timestring wider than plasmoid -> change size to the minimal needed space, i.e. the timestring will not increase in point-size OR plasmoid in Panel. kDebug() << "Plasmoid is in a panel or too small for the timestring, we are using minimumWantedSize as pointSize"; if ( m_showDate == true && m_showTimezone == true ) { //Date + timezone enabled kDebug() << "Date + timezone enabled"; //If the user has set adjustToHeight to true the timezone and date are put into one line. This is a design decision and not based on anything else but the opinion that a slightly increased point-size is not what adjustToHeight is meant for. The latter is meant to replace the need to be able to set a font-size in the settings. Bigger fonts than this and only slightly bigger ones don't make sense on the panel. The desktop-plasmoid is not imfluenced by this. if( m_timeStringSize.width() > m_dateStringSize.width() + m_timezoneStringSize.width() || m_adjustToHeight != 0 ) { //Time wider than date + timezone -> 2 rows in plasmoid kDebug() << "timestring is wider than date + timezone in one row -> 1 row."; m_subtitleString = m_dateString + ' ' + m_timezoneString; //Set subtitleString //set subtitleSize m_subtitleStringSize = QSizeF ( m_fmDate.width ( m_dateString + ' ' + m_timezoneString ) , m_dateStringSize.height()*1 ); //set new minimal width to fit the strings m_minimumContentSize = QSizeF ( m_timeStringSize.width(),m_subtitleStringSize.height() + m_verticalSpacing + m_subtitleStringSize.height() ); } else { //date and timezone have to be split. kDebug() << "Date + timezone do not fit into one row -> 2 rows."; m_subtitleString = m_dateString + '\n' + m_timezoneString; //Set subtitleString //set subtitleSize m_subtitleStringSize = QSizeF ( qMax ( m_dateStringSize.width(),m_timezoneStringSize.width() ), m_dateStringSize.height()*2 ); kDebug() << "max: " << qMax ( m_timeStringSize.width(),qMax ( m_dateStringSize.width(),m_timezoneStringSize.width() ) ) << " timestring: " << m_timeStringSize.width() << "date: " << m_dateStringSize.width() << "timezone: " << m_timezoneStringSize.width(); //set new minimal width to fit widest string and adjust the height m_minimumContentSize = QSizeF ( qMax ( m_timeStringSize.width(),qMax ( m_dateStringSize.width(),m_timezoneStringSize.width() ) ),m_timeStringSize.height() + m_verticalSpacing + m_subtitleStringSize.height() ); } } else if ( m_showDate == true ) { kDebug() << "Only date is enabled"; m_subtitleString = m_dateString; //Set subtitleString //set subtitleSize m_subtitleStringSize = QSizeF ( m_dateStringSize.width(), m_dateStringSize.height() ); //set new minimal width to fit the widest string m_minimumContentSize = QSizeF ( qMax ( m_dateStringSize.width(),m_timeStringSize.width() ),m_timeStringSize.height() + m_verticalSpacing + m_subtitleStringSize.height() ); } else if ( m_showTimezone == true ) { kDebug() << "Only timezone is enabled"; m_subtitleString = m_timezoneString; //Set subtitleString //set subtitleSize m_subtitleStringSize = QSizeF ( m_timezoneStringSize.width(), m_timezoneStringSize.height() ); //set new size to fit the strings m_minimumContentSize = QSizeF ( qMax ( m_timezoneStringSize.width(),m_timeStringSize.width() ),m_timeStringSize.height() + m_verticalSpacing + m_subtitleStringSize.height() ); } else { //no subtitle kDebug() << "Neither timezone nor date are enabled"; //set subtitleSize m_subtitleStringSize = QSizeF ( 0,0 ); m_minimumContentSize = QSizeF ( m_timeStringSize.width(),m_timeStringSize.height() );//set new minimal width } float heightToUse = 0; //Use x of the available height for the timstring if ( m_adjustToHeight == 1 ) { heightToUse = (float)2/3; kDebug() << "We will use 2/3 of the panel's height for the time: " << heightToUse; } else if ( m_adjustToHeight == 2 ) { kDebug() << "We will use all of the panel's height for the time."; heightToUse = 1; } //If the user enabled adjustToHeight we increase the point-size until the height is fully used. 40 as limit to avoid an endless loop. if ( m_adjustToHeight != 0 ) { kDebug() << "We try to find a larger font that fits the size:"; //FIXME: if the clock is the only applet on a vertical panel and returns 0 via expandingDirections(), it still gets the full height of the panel as recommended height, i.e. on a vertical panel width a height of 800, geometry().size().height() does not return 48 but some huge value. Unless this is fixed in plasma, the while-loop will take a while. //Make the timestring fit the plasmoid since it is bigger than minimumWantedSize m_fontTime.setPointSize(qMax((int)( geometry().size().height()/1.5), minimumWantedSize) ); m_fmTime = QFontMetrics( m_fontTime ); kDebug() << "Starting with a point size of: " << m_fontTime.pointSize(); kDebug() << "We want to have: \nwidth: < " << geometry().size().width() - 2*m_margin << "\nheight < " << (geometry().size().height() - m_subtitleStringSize.height() - m_verticalSpacing)*heightToUse; while ( ( ( m_fmTime.width( m_timeString ) > geometry().size().width() - 2*m_margin && formFactor() != Plasma::Horizontal ) || m_fmTime.height() > (geometry().size().height() - m_subtitleStringSize.height() - m_verticalSpacing)*heightToUse ) && m_fontTime.pointSize() > minimumWantedSize) { //decrease pointSize m_fontTime.setPointSize(m_fontTime.pointSize() - 1); kDebug() << "new point size: " << m_fontTime.pointSize(); m_fmTime = QFontMetrics( m_fontTime ); m_timeStringSize = QSizeF ( m_fmTime.width( m_timeString ), m_fmTime.height() ); } } //Adjust the width to the new size, including margins, will be reverted, if the panel is vertical m_minimumContentSize = QSizeF ( m_timeStringSize.width() + m_margin*2,m_minimumContentSize.height() ); kDebug() << "Set new minimumSize: geometry().size() " << geometry().size() << "\nm_minimumContentSize: " << m_minimumContentSize; //if the width given by the panel is too wide, e.g. when switching from panel at the right to panel at the bottom we get some 600 as width //However: If we are in a vertical panel, we should use the width given. if( m_timeStringSize.width() + m_margin*2 < geometry().size().width() && formFactor() != Plasma::Vertical ) { kDebug() << "The width we got was too big, we need less, so lets resize."; setMinimumSize ( m_minimumContentSize + (size() - contentsRect().size()) ); } if ( formFactor() == Plasma::Horizontal ) { //if we are on the panel we are forced to accept the given height. kDebug() << "needed height: " << m_minimumContentSize.height() << "[horizontal panel] fixed height forced on us: " << geometry().size().height() << " adding margin-left/-right of: " << m_margin << "width is going to be set resize( " << m_minimumContentSize.width() << "," << geometry().size().height() << ")"; setMinimumSize(QSizeF(m_minimumContentSize.width(), 0)); //Expand the panel as necessary setPreferredSize(minimumSize()); emit sizeHintChanged(Qt::PreferredSize); } else if ( formFactor() == Plasma::Vertical ) { kDebug() << "needed width: " << m_minimumContentSize.width() << "[vertical panel] fixed width forced on us: " << geometry().size().width() << " adding margin left/right of: " << m_margin; setMinimumSize ( QSizeF(0, m_minimumContentSize.height()) ); //Expand the panel as necessary setPreferredSize(minimumSize()); emit sizeHintChanged(Qt::PreferredSize); }else { //FIXME: In case this height does not fit the content -> disable timezone (and date) //if the minimal width is larger than the actual size -> force minimal needed width if( m_fontTime.pointSize() <= m_fontDate.pointSize() ) { setMinimumSize ( m_minimumContentSize + (size() - contentsRect().size()) ); } //we use the minimal height here, since the user has given us too much height we cannot use for anything useful. minimal width because we are in a panel. kDebug() << "we set the minimum size needed as the size we want"; setPreferredSize ( QSizeF ( m_minimumContentSize.width() + m_margin*2,m_minimumContentSize.height() ) + (size() - contentsRect().size()) ); resize(preferredSize()); emit sizeHintChanged(Qt::PreferredSize); emit appletTransformedItself(); } } } void Clock::paintInterface(QPainter *p, const QStyleOptionGraphicsItem *option, const QRect &contentsRect) { Q_UNUSED( option ); kDebug() << "We get painted!"; if( m_showDate == true || m_showTimezone == true ) { m_fontDate = QFont( KGlobalSettings::smallestReadableFont() ); QFontMetrics m_fmDate( m_fontDate ); p->setPen(QPen(m_fontColor)); p->setFont( m_fontDate ); kDebug() << "date + timezone [" << m_subtitleString << "] gets painted. y: " << -m_subtitleStringSize.height() + contentsRect.size().height() << "width: " << contentsRect.size().width() << "[needed: " << m_fmDate.width( m_subtitleString ) << "] " << "height:" << m_subtitleStringSize.height(); if( m_showDate == true || m_showTimezone == true ) { //Draw the subtitle p->drawText( QRectF(contentsRect.x(), contentsRect.y() - m_subtitleStringSize.height() + contentsRect.size().height(), contentsRect.size().width(), m_subtitleStringSize.height()) , m_subtitleString, QTextOption(Qt::AlignHCenter) ); } } QFontMetrics m_fmTime ( m_fontTime ); kDebug() << "timestrings [" << m_timeString << "] gets painted. width: " << contentsRect.size().width() << "[needed: " << m_fmTime.width( m_timeString ) << "] " << "height: " << m_timeStringSize.height(); p->setFont( m_fontTime ); p->setPen(QPen(m_fontColor)); p->setRenderHint(QPainter::SmoothPixmapTransform); p->setRenderHint(QPainter::Antialiasing); p->drawText( QRectF(contentsRect.x(), contentsRect.y(), contentsRect.size().width(), m_timeStringSize.height()) , m_timeString, QTextOption(Qt::AlignHCenter) ); } void Clock::updateColors() { if (!m_useCustomFontColor) { m_fontColor = KColorScheme(QPalette::Active, KColorScheme::View, Plasma::Theme::defaultTheme()->colorScheme()).foreground().color(); update(); } } #include "moc_fuzzyClock.cpp"