File indexing completed on 2024-04-21 05:54:05
0001 /* 0002 SPDX-FileCopyrightText: 2005-2006, 2009-2010 Tom Albers <toma@kde.org> 0003 SPDX-FileCopyrightText: 2006 Bram Schoenmakers <bramschoenmakers@kde.nl> 0004 SPDX-FileCopyrightText: 2010 Juan Luis Baptiste <juan.baptiste@gmail.com> 0005 0006 SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #include "rsiwidget.h" 0010 #include "grayeffect.h" 0011 #include "plasmaeffect.h" 0012 #include "popupeffect.h" 0013 #include "rsidock.h" 0014 #include "rsiglobals.h" 0015 #include "rsirelaxpopup.h" 0016 #include "rsitimer.h" 0017 #include "rsiwidgetadaptor.h" 0018 #include "slideshoweffect.h" 0019 0020 #include <QDebug> 0021 #include <QDesktopWidget> 0022 #include <QPainter> 0023 #include <QTimer> 0024 0025 #include <KConfigGroup> 0026 #include <KLocalizedString> 0027 #include <KMessageBox> 0028 #include <KNotification> 0029 #include <KSharedConfig> 0030 #include <QDBusInterface> 0031 #include <QTemporaryFile> 0032 0033 #include <KFormat> 0034 #include <math.h> 0035 #include <time.h> 0036 0037 RSIObject::RSIObject(QWidget *parent) 0038 : QObject(parent) 0039 , m_timer(nullptr) 0040 , m_effect(nullptr) 0041 , m_useImages(false) 0042 , m_usePlasma(false) 0043 , m_usePlasmaRO(false) 0044 { 0045 // Keep these 2 lines _above_ the messagebox, so the text actually is right. 0046 m_tray = new RSIDock(this); 0047 m_tray->setIconByName("rsibreak0"); 0048 0049 new RsiwidgetAdaptor(this); 0050 QDBusConnection dbus = QDBusConnection::sessionBus(); 0051 dbus.registerObject("/rsibreak", this); 0052 0053 m_relaxpopup = new RSIRelaxPopup(nullptr); 0054 connect(m_relaxpopup, &RSIRelaxPopup::lock, this, &RSIObject::slotLock); 0055 0056 connect(m_tray, &RSIDock::configChanged, RSIGlobals::instance(), &RSIGlobals::slotReadConfig); 0057 connect(m_tray, &RSIDock::configChanged, this, &RSIObject::readConfig); 0058 connect(m_tray, &RSIDock::configChanged, m_relaxpopup, &RSIRelaxPopup::slotReadConfig); 0059 connect(m_tray, &RSIDock::suspend, m_relaxpopup, &RSIRelaxPopup::setSuspended); 0060 0061 readConfig(); 0062 0063 setIcon(0); 0064 0065 QTimer::singleShot(2000, this, &RSIObject::slotWelcome); 0066 } 0067 0068 RSIObject::~RSIObject() 0069 { 0070 delete m_effect; 0071 delete RSIGlobals::instance(); 0072 delete m_timer; 0073 } 0074 0075 void RSIObject::slotWelcome() 0076 { 0077 if (KMessageBox::shouldBeShownContinue("dont_show_welcome_again_for_001")) { 0078 KMessageBox::information(nullptr, 0079 i18n("<p>Welcome to RSIBreak</p>\n<p>" 0080 "In your tray you can now see RSIBreak.</p>\n") 0081 + i18n("<p>When you right-click on that you will see a menu, from which " 0082 "you can go to the configuration for example.</p>\n<p>When you want to " 0083 "know when the next break is, hover over the icon.</p>\n<p>Use RSIBreak " 0084 "wisely.</p>"), 0085 i18n("Welcome"), 0086 "dont_show_welcome_again_for_001"); 0087 } 0088 } 0089 0090 void RSIObject::minimize() 0091 { 0092 m_effect->deactivate(); 0093 } 0094 0095 void RSIObject::maximize() 0096 { 0097 m_effect->activate(); 0098 } 0099 0100 void RSIObject::slotLock() 0101 { 0102 m_effect->deactivate(); 0103 m_timer->slotLock(); 0104 0105 QDBusInterface lock("org.freedesktop.ScreenSaver", "/ScreenSaver", "org.freedesktop.ScreenSaver"); 0106 lock.call("Lock"); 0107 } 0108 0109 void RSIObject::setCounters(int timeleft) 0110 { 0111 if (timeleft > 0) { 0112 m_effect->setLabel(KFormat().formatSpelloutDuration(timeleft * 1000)); 0113 } else if (m_timer->isSuspended()) { 0114 m_effect->setLabel(i18n("Suspended")); 0115 } else { 0116 m_effect->setLabel(QString()); 0117 } 0118 } 0119 0120 void RSIObject::updateIdleAvg(double idleAvg) 0121 { 0122 if (idleAvg == 0.0) 0123 setIcon(0); 0124 else if (idleAvg > 0 && idleAvg < 30) 0125 setIcon(1); 0126 else if (idleAvg >= 30 && idleAvg < 60) 0127 setIcon(2); 0128 else if (idleAvg >= 60 && idleAvg < 90) 0129 setIcon(3); 0130 else 0131 setIcon(4); 0132 } 0133 0134 void RSIObject::setIcon(int level) 0135 { 0136 QString newIcon = "rsibreak" + (m_timer->isSuspended() ? QString("x") : QString::number(level)); 0137 0138 if (newIcon != m_currentIcon) { 0139 m_tray->setIconByName(newIcon); 0140 m_tray->setToolTipIconByName(newIcon); 0141 m_currentIcon = newIcon; 0142 } 0143 } 0144 0145 // ------------------- Popup for skipping break ------------- // 0146 0147 void RSIObject::tinyBreakSkipped() 0148 { 0149 m_notificator.onShortTimerReset(); 0150 } 0151 0152 void RSIObject::bigBreakSkipped() 0153 { 0154 m_notificator.onTimersReset(); 0155 } 0156 0157 //--------------------------- CONFIG ----------------------------// 0158 0159 void RSIObject::configureTimer() 0160 { 0161 if (m_timer != nullptr) { 0162 m_timer->updateConfig(); 0163 return; 0164 } 0165 m_timer = new RSITimer(this); 0166 0167 connect(m_timer, &RSITimer::breakNow, this, &RSIObject::maximize, Qt::QueuedConnection); 0168 connect(m_timer, &RSITimer::updateWidget, this, &RSIObject::setCounters, Qt::QueuedConnection); 0169 connect(m_timer, &RSITimer::updateToolTip, m_tray, &RSIDock::setCounters, Qt::QueuedConnection); 0170 connect(m_timer, &RSITimer::updateIdleAvg, this, &RSIObject::updateIdleAvg, Qt::QueuedConnection); 0171 connect(m_timer, &RSITimer::minimize, this, &RSIObject::minimize, Qt::QueuedConnection); 0172 connect(m_timer, &RSITimer::relax, m_relaxpopup, &RSIRelaxPopup::relax, Qt::QueuedConnection); 0173 connect(m_timer, &RSITimer::tinyBreakSkipped, this, &RSIObject::tinyBreakSkipped, Qt::QueuedConnection); 0174 connect(m_timer, &RSITimer::bigBreakSkipped, this, &RSIObject::bigBreakSkipped, Qt::QueuedConnection); 0175 connect(m_timer, &RSITimer::startLongBreak, &m_notificator, &Notificator::onStartLongBreak); 0176 connect(m_timer, &RSITimer::endLongBreak, &m_notificator, &Notificator::onEndLongBreak); 0177 connect(m_timer, &RSITimer::startShortBreak, &m_notificator, &Notificator::onStartShortBreak); 0178 connect(m_timer, &RSITimer::endShortBreak, &m_notificator, &Notificator::onEndShortBreak); 0179 0180 connect(m_tray, &RSIDock::dialogEntered, m_timer, &RSITimer::slotStop); 0181 connect(m_tray, &RSIDock::dialogLeft, m_timer, &RSITimer::slotStart); 0182 connect(m_tray, &RSIDock::suspend, m_timer, &RSITimer::slotSuspended); 0183 0184 connect(m_relaxpopup, &RSIRelaxPopup::skip, m_timer, &RSITimer::skipBreak); 0185 connect(m_relaxpopup, &RSIRelaxPopup::postpone, m_timer, &RSITimer::postponeBreak); 0186 } 0187 0188 void RSIObject::readConfig() 0189 { 0190 KConfigGroup config = KSharedConfig::openConfig()->group("General Settings"); 0191 0192 m_relaxpopup->setSkipButtonHidden(config.readEntry("HideMinimizeButton", false)); 0193 m_relaxpopup->setLockButtonHidden(config.readEntry("HideLockButton", false)); 0194 m_relaxpopup->setPostponeButtonHidden(config.readEntry("HidePostponeButton", false)); 0195 0196 m_usePlasma = config.readEntry("UsePlasma", false); 0197 m_usePlasmaRO = config.readEntry("UsePlasmaReadOnly", false); 0198 0199 m_useImages = config.readEntry("ShowImages", false); 0200 int slideInterval = config.readEntry("SlideInterval", 10); 0201 bool recursive = config.readEntry("SearchRecursiveCheck", false); 0202 bool showSmallImages = config.readEntry("ShowSmallImagesCheck", true); 0203 const bool expandImageToFullScreen = config.readEntry("ExpandImageToFullScreen", true); 0204 QString path = config.readEntry("ImageFolder"); 0205 0206 configureTimer(); 0207 0208 int effect = config.readEntry("Effect", 0); 0209 0210 delete m_effect; 0211 switch (effect) { 0212 case Plasma: { 0213 m_effect = new PlasmaEffect(nullptr); 0214 m_effect->setReadOnly(m_usePlasmaRO); 0215 break; 0216 } 0217 case SlideShow: { 0218 SlideEffect *slide = new SlideEffect(nullptr); 0219 slide->reset(path, recursive, showSmallImages, expandImageToFullScreen, slideInterval); 0220 if (slide->hasImages()) 0221 m_effect = slide; 0222 else { 0223 delete slide; 0224 m_effect = new GrayEffect(nullptr); 0225 } 0226 break; 0227 } 0228 case Popup: { 0229 PopupEffect *effect = new PopupEffect(nullptr); 0230 m_effect = effect; 0231 break; 0232 } 0233 case SimpleGray: 0234 default: { 0235 GrayEffect *effect = new GrayEffect(nullptr); 0236 effect->setLevel(config.readEntry("Graylevel", 80)); 0237 m_effect = effect; 0238 break; 0239 } 0240 } 0241 connect(m_effect, &BreakBase::skip, m_timer, &RSITimer::skipBreak); 0242 connect(m_effect, &BreakBase::lock, this, &RSIObject::slotLock); 0243 connect(m_effect, &BreakBase::postpone, m_timer, &RSITimer::postponeBreak); 0244 0245 m_effect->showMinimize(!config.readEntry("HideMinimizeButton", false)); 0246 m_effect->showLock(!config.readEntry("HideLockButton", false)); 0247 m_effect->showPostpone(!config.readEntry("HidePostponeButton", false)); 0248 m_effect->disableShortcut(config.readEntry("DisableAccel", false)); 0249 } 0250 0251 void RSIObject::resume() 0252 { 0253 m_tray->doResume(); 0254 } 0255 0256 void RSIObject::suspend() 0257 { 0258 m_tray->doSuspend(); 0259 }