diff --git a/CMakeLists.txt b/CMakeLists.txt index e6bca81..c179368 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,41 +1,44 @@ cmake_minimum_required(VERSION 2.8.12) project(kteatime) find_package(ECM 1.3.0 REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) include(ECMInstallIcons) # Search KDE installation find_package(Qt5 5.2.0 CONFIG REQUIRED Core Widgets ) find_package(KF5 5.23.0 REQUIRED Config Crash DocTools I18n IconThemes NotifyConfig Notifications TextWidgets XmlGui ) include(KDEInstallDirs) include(KDECMakeSettings) include(KDECompilerSettings NO_POLICY_SCOPE) include(FeatureSummary) add_definitions( -DQT_NO_CAST_FROM_ASCII ) add_definitions( -DQT_NO_CAST_TO_ASCII ) add_definitions(-DQT_USE_FAST_OPERATOR_PLUS) +add_definitions(-DQT_NO_NARROWING_CONVERSIONS_IN_CONNECT) +add_definitions(-DQT_NO_URL_CAST_FROM_STRING) +add_definitions(-DQT_USE_QSTRINGBUILDER) ADD_SUBDIRECTORY(doc) ADD_SUBDIRECTORY(data) ADD_SUBDIRECTORY(src) install(FILES org.kde.kteatime.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR}) feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/src/settings.cpp b/src/settings.cpp index 50f316b..89fabaa 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1,295 +1,295 @@ /* * Copyright 2007-2009 by Stefan Böhmann * * 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, see . */ #include "settings.h" #include "toplevel.h" #include "tealistmodel.h" #include #include #include #include #include #include #include #include #include #include #include class SettingsUI : public QWidget, public Ui::SettingsWidget { public: - SettingsUI(QWidget *parent = 0) + explicit SettingsUI(QWidget *parent = nullptr) : QWidget( parent ) { setupUi( this ); } }; SettingsDialog::SettingsDialog(TopLevel *toplevel, const QList &teas) : QDialog(), m_toplevel(toplevel) { setWindowTitle( i18n( "Configure Tea Cooker" ) ); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel|QDialogButtonBox::Help); QVBoxLayout *mainLayout = new QVBoxLayout; setLayout(mainLayout); ui = new SettingsUI( this ); mainLayout->addWidget(ui); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox, &QDialogButtonBox::accepted, this, &SettingsDialog::accept); connect(buttonBox, &QDialogButtonBox::rejected, this, &SettingsDialog::reject); mainLayout->addWidget(buttonBox); connect(buttonBox, &QDialogButtonBox::helpRequested, this, &SettingsDialog::showHelp); buttonBox->button(QDialogButtonBox::Ok)->setWhatsThis(i18n( "Save changes and close dialog." )); buttonBox->button(QDialogButtonBox::Cancel)->setWhatsThis(i18n( "Close dialog without saving changes." )); buttonBox->button(QDialogButtonBox::Help)->setWhatsThis(i18n( "Show help page for this dialog." )); KSharedConfigPtr config = KSharedConfig::openConfig(); KConfigGroup group( config, "General" ); restoreGeometry(group.readEntry("Geometry", QByteArray())); QDesktopWidget desktop; int x=group.readEntry( "SettingsDialogXPos", desktop.screenGeometry().width()/2 - width()/2 ); int y=group.readEntry( "SettingsDialogYPos", desktop.screenGeometry().height()/2 - height()/2 ); x = qMin( qMax( 0, x ), desktop.screenGeometry().width() - width() ); x = qMin( qMax( 0, y ), desktop.screenGeometry().height() - height() ); move( QPoint( x, y ) ); bool popup=group.readEntry( "UsePopup", true ); bool autohide=group.readEntry( "PopupAutoHide", false ); int autohidetime=group.readEntry( "PopupAutoHideTime", 30 ); bool reminder=group.readEntry( "UseReminder", false ); int remindertime=group.readEntry( "ReminderTime", 60 ); bool vis=group.readEntry( "UseVisualize", true ); ui->popupCheckBox->setChecked( popup ); ui->autohideCheckBox->setChecked( autohide ); ui->reminderCheckBox->setChecked( reminder ); ui->visualizeCheckBox->setChecked( vis ); ui->autohideSpinBox->setValue( autohidetime ); ui->reminderSpinBox->setValue( remindertime ); ui->autohideSpinBox->setSuffix( ki18ncp( "Auto hide popup after", " second", " seconds") ); ui->reminderSpinBox->setSuffix( ki18ncp( "Reminder every", " second", " seconds") ); ui->autohideCheckBox->setEnabled( popup ); ui->autohideSpinBox->setEnabled( autohide ); ui->reminderSpinBox->setEnabled( reminder ); m_model=new TeaListModel( teas, this ); ui->tealistTreeView->setModel( m_model ); connect(ui->tealistTreeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &SettingsDialog::updateSelection); ui->removeButton->setEnabled( false ); ui->upButton->setEnabled( false ); ui->downButton->setEnabled( false ); ui->newButton->setIcon( QIcon::fromTheme( QLatin1String( "list-add" ) ) ); ui->removeButton->setIcon( QIcon::fromTheme( QLatin1String( "edit-delete" ) ) ); ui->upButton->setIcon( QIcon::fromTheme( QLatin1String( "arrow-up" ) ) ); ui->downButton->setIcon( QIcon::fromTheme( QLatin1String( "arrow-down" ) ) ); connect(ui->popupCheckBox, &QCheckBox::toggled, this, &SettingsDialog::checkPopupButtonState); connect(ui->newButton, &QToolButton::clicked, this, &SettingsDialog::newButtonClicked); connect(ui->removeButton, &QToolButton::clicked, this, &SettingsDialog::removeButtonClicked); connect(ui->upButton, &QToolButton::clicked, this, &SettingsDialog::upButtonClicked); connect(ui->downButton, &QToolButton::clicked, this, &SettingsDialog::downButtonClicked); connect(ui->teaNameEdit, &QLineEdit::textChanged, this, &SettingsDialog::nameValueChanged); connect(ui->minutesSpin, static_cast(&QSpinBox::valueChanged), this, &SettingsDialog::timeValueChanged); connect(ui->secondsSpin, static_cast(&QSpinBox::valueChanged), this, &SettingsDialog::timeValueChanged); } SettingsDialog::~SettingsDialog() { delete m_model; delete ui; } void SettingsDialog::showHelp() { KHelpClient::invokeHelp(); } void SettingsDialog::accept() { KSharedConfigPtr config = KSharedConfig::openConfig(); KConfigGroup group( config, "General" ); group.writeEntry( "SettingsDialogXPos", x() ); group.writeEntry( "SettingsDialogYPos", y() ); hide(); group.writeEntry("Geometry", saveGeometry()); group.writeEntry( "UsePopup", ui->popupCheckBox->checkState() == Qt::Checked ); group.writeEntry( "PopupAutoHide", ui->autohideCheckBox->checkState() == Qt::Checked ); group.writeEntry( "PopupAutoHideTime", ui->autohideSpinBox->value() ); group.writeEntry( "UseReminder", ui->reminderCheckBox->checkState() == Qt::Checked ); group.writeEntry( "ReminderTime", ui->reminderSpinBox->value() ); group.writeEntry( "UseVisualize", ui->visualizeCheckBox->checkState() == Qt::Checked ); config->sync(); m_toplevel->setTeaList( m_model->getTeaList() ); } void SettingsDialog::checkPopupButtonState(bool b) { ui->autohideCheckBox->setEnabled( b ); if( !b ) { ui->autohideSpinBox->setEnabled( b ); } else if( ui->autohideCheckBox->checkState() == 2 ) { ui->autohideSpinBox->setEnabled( b ); } } void SettingsDialog::newButtonClicked() { int count = m_model->rowCount(); m_model->insertRows( count, 1 ); QItemSelectionModel *sm = ui->tealistTreeView->selectionModel(); QItemSelection selection( m_model->index( count, 0 ), m_model->index( count, 1 ) ); sm->select( selection, QItemSelectionModel::Clear | QItemSelectionModel::Select ); } void SettingsDialog::removeButtonClicked() { const QModelIndexList indexes = ui->tealistTreeView->selectionModel()->selectedIndexes(); for (const QModelIndex &index : indexes) { // Only delete a row when column==0, otherwise the row will be delete // multiple times (the loop iterate over every cell, not over rows). if( index.column() == 0 ) { m_model->removeRows( index.row(), 1 ); } } } void SettingsDialog::upButtonClicked() { moveSelectedItem( true ); } void SettingsDialog::downButtonClicked() { moveSelectedItem( false ); } void SettingsDialog::moveSelectedItem(bool moveup) { QItemSelectionModel *sm = ui->tealistTreeView->selectionModel(); QModelIndexList items = sm->selection().indexes(); if( !items.isEmpty() ) { QString name = m_model->data( m_model->index( items.at(0).row(), 0 ), Qt::EditRole).toString(); unsigned time = m_model->data( m_model->index( items.at(0).row(), 1 ), Qt::EditRole).toUInt(); int pos = items.at(0).row(); moveup ? --pos : ++pos; removeButtonClicked(); m_model->insertRows( pos, 1 ); m_model->setData( m_model->index( pos, 0 ), name, Qt::EditRole ); m_model->setData( m_model->index( pos, 1 ), time, Qt::EditRole ); QItemSelection selection( m_model->index( pos, 0 ), m_model->index( pos, 1 ) ); sm->select( selection, QItemSelectionModel::Clear | QItemSelectionModel::Select ); } } void SettingsDialog::updateSelection(const QItemSelection &selected, const QItemSelection &deselected) { Q_UNUSED(deselected); QModelIndexList items = selected.indexes(); QString name; unsigned time=0; bool state = !items.isEmpty(); ui->teaPropertiesGroup->setEnabled( state ); ui->teaNameEdit->setEnabled( state ); ui->minutesSpin->setEnabled( state ); ui->secondsSpin->setEnabled( state ); ui->removeButton->setEnabled( state ); if( state ) { name = m_model->data( m_model->index( items.at(0).row(), 0 ), Qt::EditRole ).toString(); time = m_model->data( m_model->index( items.at(0).row(), 1 ), Qt::EditRole ).toUInt(); ui->upButton->setEnabled( items.at(0).row() > 0 ); ui->downButton->setEnabled( items.at(0).row() < ( m_model->rowCount() - 1 ) ); } else { ui->upButton->setEnabled( false ); ui->downButton->setEnabled( false ); } ui->teaNameEdit->setText( name ); ui->minutesSpin->setValue( time / 60 ); ui->secondsSpin->setValue( time % 60 ); } void SettingsDialog::timeValueChanged() { QModelIndexList items = ui->tealistTreeView->selectionModel()->selection().indexes(); if( !items.isEmpty() ) { int time = ui->secondsSpin->value(); time += ui->minutesSpin->value() * 60; if( time <= 0 ) { time = 1; ui->secondsSpin->setValue( time ); } m_model->setData( m_model->index( items.at(0).row(), 1 ), time, Qt::EditRole ); } } void SettingsDialog::nameValueChanged(const QString &text) { QModelIndexList items = ui->tealistTreeView->selectionModel()->selection().indexes(); if( !items.isEmpty() ) { m_model->setData( m_model->index( items.at(0).row(), 0 ), text, Qt::EditRole ); } } // kate: word-wrap off; encoding utf-8; indent-width 4; tab-width 4; line-numbers on; mixed-indent off; remove-trailing-space-save on; replace-tabs-save on; replace-tabs on; space-indent on; // vim:set spell et sw=4 ts=4 nowrap cino=l1,cs,U1: diff --git a/src/tealistmodel.h b/src/tealistmodel.h index 5a7bb81..ecb6132 100644 --- a/src/tealistmodel.h +++ b/src/tealistmodel.h @@ -1,131 +1,131 @@ /* * Copyright 2007-2009 by Stefan Böhmann * * 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, see . */ #ifndef TEALISTMODEL_H #define TEALISTMODEL_H #include class Tea; /** * @short provides an model used by SettingsDialog * * @author Stefan Böhmann */ class TeaListModel : public QAbstractTableModel { public: /** * Constructs an TeaListModel with the given list of Teas and for the given parent. * @param teas the initial list of teas to manage. * @param parent the parent object. */ - explicit TeaListModel(const QList &teas, QObject *parent = 0); + explicit TeaListModel(const QList &teas, QObject *parent = nullptr); /** * Returns the index of the item in the model specified by the given row, column and parent index. * @param row the row. * @param column the column. * @param parent will be ignored by this model. * * @return @ref QModelIndex with the index of the item. */ QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const; /** * Returns the number of rows. * @param parent will be ignored by this model. * * @return the number of rows. */ int rowCount(const QModelIndex &parent = QModelIndex()) const; /** * Returns the number of columns. * @param parent will be ignored by this model. * * @return the number of columns. */ int columnCount(const QModelIndex &parent = QModelIndex()) const; /** * Returns the data stored under the given role for the item referred to by the index. * @param index the index of the item. * @param role the role * * @return the specified data. */ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; /** * Sets the role data for the item at index to value. * @param index the index of the item. * @param value the new value for the item. * @param role the role. * * @return if successful true, otherwise false. */ bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); /** * Returns the data for the given role and section in the header with the specified orientation. * @param section the section. * @param orientation the orientation. * @param role the role. * * @return the specified data. */ QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; /** * inserts rows into the model before the given one. * * @param row the row - if 0 the new rows will be insert before any exists rows. * @param count number of rows to add. * @param parent will be ignored by this model. * * @return true if the rows were successfully inserted, otherwise false. */ bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()); /** * removes rows from the model, starting with the given row. * @param row the first row to remove. * @param count number of rows to remove. * @param parent will be ignored by this model. * * @return true if the rows were successfully removed, otherwise false. */ bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); /** * Returns the whole list of teas. * * @return list of teas. */ const QList getTeaList() const; private: QList m_tealist; }; #endif // kate: word-wrap off; encoding utf-8; indent-width 4; tab-width 4; line-numbers on; mixed-indent off; remove-trailing-space-save on; replace-tabs-save on; replace-tabs on; space-indent on; // vim:set spell et sw=4 ts=4 nowrap cino=l1,cs,U1: diff --git a/src/timeedit.cpp b/src/timeedit.cpp index cf355d2..4f92e27 100644 --- a/src/timeedit.cpp +++ b/src/timeedit.cpp @@ -1,124 +1,124 @@ /* * Copyright 1998-1999 by Matthias Hoelzer-Kluepfel * Copyright 2002-2003 by Martin Willers * Copyright 2003 by Daniel Teske * Copyright 2007-2009 by Stefan Böhmann * * 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, see . */ #include "timeedit.h" #include "toplevel.h" #include "tea.h" #include #include #include #include #include class TimeEditUI : public QWidget, public Ui::TimeEditWidget { public: - TimeEditUI(QWidget *parent = 0) + explicit TimeEditUI(QWidget *parent = nullptr) : QWidget( parent ) { setupUi( this ); } }; TimeEditDialog::TimeEditDialog(TopLevel *toplevel) : QDialog(), m_toplevel( toplevel ) { setWindowTitle( i18n( "Anonymous Tea" ) ); buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel); buttonBox->button(QDialogButtonBox::Ok)->setWhatsThis(i18n( "Start a new anonymous tea with the time configured in this dialog." )); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); buttonBox->button(QDialogButtonBox::Cancel)->setWhatsThis(i18n( "Close this dialog without starting a new tea." )); QVBoxLayout *mainLayout = new QVBoxLayout; setLayout(mainLayout); ui = new TimeEditUI( this ); mainLayout->addWidget(ui); mainLayout->addWidget(buttonBox); KSharedConfigPtr config = KSharedConfig::openConfig(); KConfigGroup group( config, "AnonymousTeaDialog" ); int time=group.readEntry( "AnonymousTeaTime", 180 ); ui->minutes->setSuffix( ki18np( " minute", " minutes") ); ui->seconds->setSuffix( ki18np( " second", " seconds") ); ui->minutes->setValue( time / 60 ); ui->seconds->setValue( time % 60 ); ui->minutes->setFocus( Qt::ShortcutFocusReason ); restoreGeometry(group.readEntry("Geometry", QByteArray())); QDesktopWidget desktop; int x = group.readEntry( "AnonymousTeaDialogXPos", desktop.screenGeometry().width()/2 - width()/2 ); int y = group.readEntry( "AnonymousTeaDialogYPos", desktop.screenGeometry().height()/2 - height()/2 ); x = qMin( qMax( 0, x ), desktop.screenGeometry().width() - width() ); x = qMin( qMax( 0, y ), desktop.screenGeometry().height() - height() ); move( QPoint( x, y ) ); connect(ui->minutes, static_cast(&KPluralHandlingSpinBox::valueChanged), this, &TimeEditDialog::checkOkButtonState); connect(ui->seconds, static_cast(&KPluralHandlingSpinBox::valueChanged), this, &TimeEditDialog::checkOkButtonState); connect(buttonBox, &QDialogButtonBox::accepted, this, &TimeEditDialog::accept); connect(buttonBox, &QDialogButtonBox::rejected, this, &TimeEditDialog::reject); } TimeEditDialog::~TimeEditDialog() { delete ui; } void TimeEditDialog::checkOkButtonState() { buttonBox->button(QDialogButtonBox::Ok)->setEnabled( ui->minutes->value() || ui->seconds->value() ); } void TimeEditDialog::accept() { hide(); int time = ui->seconds->value(); time += ui->minutes->value() * 60; KSharedConfigPtr config = KSharedConfig::openConfig(); KConfigGroup group( config, "AnonymousTeaDialog" ); group.writeEntry( "AnonymousTeaTime", time ); group.writeEntry("Geometry", saveGeometry()); group.writeEntry( "AnonymousTeaDialogXPos", x() ); group.writeEntry( "AnonymousTeaDialogYPos", y() ); m_toplevel->runTea( Tea( i18n( "Anonymous Tea" ), time ) ); } // kate: word-wrap off; encoding utf-8; indent-width 4; tab-width 4; line-numbers on; mixed-indent off; remove-trailing-space-save on; replace-tabs-save on; replace-tabs on; space-indent on; // vim:set spell et sw=4 ts=4 nowrap cino=l1,cs,U1: diff --git a/src/timeedit.h b/src/timeedit.h index cda9744..dcee9dc 100644 --- a/src/timeedit.h +++ b/src/timeedit.h @@ -1,55 +1,55 @@ /* * Copyright 1998-1999 by Matthias Hoelzer-Kluepfel * Copyright 2002-2003 by Martin Willers * Copyright 2003 by Daniel Teske * Copyright 2007-2009 by Stefan Böhmann * * 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, see . */ #ifndef TIMEEDIT_H #define TIMEEDIT_H #include "ui_timeedit.h" #include class QDialogButtonBox; class TopLevel; class TimeEditUI; /** * @short the timeedit dialog. * * @author Stefan Böhmann */ class TimeEditDialog : public QDialog { public: explicit TimeEditDialog(TopLevel *toplevel); - ~TimeEditDialog(); + ~TimeEditDialog() override; private: void checkOkButtonState(); - void accept(); + void accept() override; TimeEditUI *ui; TopLevel *m_toplevel; QDialogButtonBox *buttonBox; }; #endif // kate: word-wrap off; encoding utf-8; indent-width 4; tab-width 4; line-numbers on; mixed-indent off; remove-trailing-space-save on; replace-tabs-save on; replace-tabs on; space-indent on; // vim:set spell et sw=4 ts=4 nowrap cino=l1,cs,U1: diff --git a/src/toplevel.cpp b/src/toplevel.cpp index a3c1cac..37066b2 100644 --- a/src/toplevel.cpp +++ b/src/toplevel.cpp @@ -1,386 +1,386 @@ /* * Copyright 1998-1999 by Matthias Hoelzer-Kluepfel * Copyright 2002-2003 by Martin Willers * Copyright 2007-2009 by Stefan Böhmann * * 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, see . */ #include "toplevel.h" #include "timeedit.h" #include "settings.h" #include "tea.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include TopLevel::TopLevel(const KAboutData *aboutData, const QString &icon, QWidget *parent) : QSystemTrayIcon( parent ), m_popup( new KPassivePopup ), m_iconName(icon), m_runningTeaTime( 0 ), m_nextNotificationTime( 0 ) { repaintTrayIcon(); // Set initial icon KSharedConfigPtr config = KSharedConfig::openConfig(); KConfigGroup tealistGroup( config, "Tealist" ); if( tealistGroup.exists() ) { QString key, time; for(unsigned index=0; tealistGroup.hasKey(time.sprintf("Tea%d Time", index)) && tealistGroup.hasKey(key.sprintf("Tea%d Name", index)); ++index) { if( int temp = ( tealistGroup.readEntry( time, QString() ) ).toUInt() ) { m_tealist.append( Tea( tealistGroup.readEntry( key, i18n( "Unknown Tea" ) ), temp ) ); } } } // If the list of teas is empty insert a set of default teas. if( m_tealist.isEmpty() ) { m_tealist.append( Tea(i18n( "Black Tea" ), 180 ) ); m_tealist.append( Tea(i18n( "Earl Grey" ), 300 ) ); m_tealist.append( Tea(i18n( "Fruit Tea" ), 480 ) ); m_tealist.append( Tea(i18n( "Green Tea" ), 120 ) ); } m_teaActionGroup=new QActionGroup( this ); m_actionCollection = new KActionCollection(this); // build the context menu action = m_actionCollection->addAction( QStringLiteral( "stop" )); action->setIcon(QIcon::fromTheme( QStringLiteral( "edit-delete" ) ) ); action->setText( i18n( "&Stop" ) ); action->setEnabled( false ); connect(action, &QAction::triggered, this, &TopLevel::cancelTea); action = m_actionCollection->addAction( QStringLiteral( "configure" )); action->setIcon(QIcon::fromTheme( QStringLiteral( "configure" ) ) ); action->setText(i18n( "&Configure..." ) ); connect(action, &QAction::triggered, this, &TopLevel::showSettingsDialog); action = KStandardAction::configureNotifications(this, &TopLevel::configureNotifications, m_actionCollection); action = KStandardAction::quit(qApp, &QCoreApplication::quit, m_actionCollection); action->setShortcut(0); action = m_actionCollection->addAction( QStringLiteral( "anonymous" )); action->setText(i18n( "&Anonymous..." ) ); connect(action, &QAction::triggered, this, &TopLevel::showTimeEditDialog); - m_helpMenu = new KHelpMenu( 0, *aboutData, false ); + m_helpMenu = new KHelpMenu( nullptr, *aboutData, false ); loadTeaMenuItems(); contextMenu()->addSeparator(); contextMenu()->addAction( m_actionCollection->action(QStringLiteral("stop")) ); contextMenu()->addAction( m_actionCollection->action(QStringLiteral("anonymous")) ); contextMenu()->addSeparator(); contextMenu()->addAction( m_actionCollection->action(QStringLiteral("configure")) ); contextMenu()->addAction( m_actionCollection->action(QLatin1String(KStandardAction::name(KStandardAction::ConfigureNotifications))) ); contextMenu()->addMenu( m_helpMenu->menu() ); contextMenu()->addSeparator(); contextMenu()->addAction( m_actionCollection->action(QLatin1String(KStandardAction::name(KStandardAction::Quit))) ); m_timer = new QTimer( this ); connect(m_timer, &QTimer::timeout, this, &TopLevel::teaTimeEvent); connect(contextMenu(), static_cast(&QMenu::triggered), this, static_cast(&TopLevel::runTea)); connect(this, &TopLevel::activated, this, &TopLevel::showPopup); loadConfig(); checkState(); show(); } TopLevel::~TopLevel() { delete m_helpMenu; delete m_timer; delete m_popup; delete m_teaActionGroup; } void TopLevel::checkState() { const bool state = m_runningTeaTime != 0; m_teaActionGroup->setEnabled( !state ); m_actionCollection->action(QStringLiteral("stop"))->setEnabled( state ); m_actionCollection->action(QStringLiteral("anonymous"))->setEnabled( !state ); if( !state ) { setTooltipText( i18n( "No steeping tea." ) ); } } void TopLevel::setTeaList(const QList &tealist) { m_tealist=tealist; // Save list... KSharedConfigPtr config = KSharedConfig::openConfig(); KConfigGroup tealistGroup( config, "Tealist" ); tealistGroup.deleteGroup(); for(int i=0; isync(); const auto actions = m_teaActionGroup->actions(); for ( QAction* a : actions ) { m_teaActionGroup->removeAction( a ); } contextMenu()->clear(); loadTeaMenuItems(); contextMenu()->addSeparator(); contextMenu()->addAction( m_actionCollection->action(QStringLiteral("stop")) ); contextMenu()->addAction( m_actionCollection->action(QStringLiteral("anonymous")) ); contextMenu()->addSeparator(); contextMenu()->addAction( m_actionCollection->action(QStringLiteral("configure")) ); contextMenu()->addAction( m_actionCollection->action(QLatin1String(KStandardAction::name(KStandardAction::ConfigureNotifications))) ); contextMenu()->addMenu(m_helpMenu->menu() ); contextMenu()->addSeparator(); contextMenu()->addAction( m_actionCollection->action(QLatin1String(KStandardAction::name(KStandardAction::Quit))) ); connect(contextMenu(), static_cast(&QMenu::triggered), this, static_cast(&TopLevel::runTea)); loadConfig(); } void TopLevel::loadTeaMenuItems() { int i=0; setContextMenu(new QMenu); foreach(const Tea &t, m_tealist) { QAction *a = contextMenu()->addAction( i18nc( "%1 - name of the tea, %2 - the predefined time for " "the tea", "%1 (%2)", t.name(), t.timeToString() ) ); a->setData( ++i ); m_teaActionGroup->addAction( a ); } } void TopLevel::showSettingsDialog() { SettingsDialog( this, m_tealist ).exec(); } void TopLevel::showTimeEditDialog() { TimeEditDialog( this ).exec(); } void TopLevel::runTea(QAction *a) { int index = a->data().toInt(); if( index <= 0 ) { return; } --index; if( index > m_tealist.size() ) { return; } runTea( m_tealist.at( index ) ); } void TopLevel::runTea(const Tea &tea) { m_runningTea = tea; m_runningTeaTime = m_runningTea.time(); checkState(); repaintTrayIcon(); m_timer->start( 1000 ); } void TopLevel::repaintTrayIcon() { QPixmap icon( KIconLoader::global()->loadIcon( m_iconName, KIconLoader::Panel ) ); if ( m_runningTeaTime <= 0) { setIcon(icon); return; } if (m_usevisualize) { QPainter painter( &icon ); painter.setRenderHint( QPainter::Antialiasing ); const QRectF rectangle( 1, icon.height() / 3 + 1, icon.width() / 1.5 - 2, icon.height() / 1.5 - 2 ); const int startAngle = 90 * 16; const int angleSpan = -( 360*16.0 / m_runningTea.time() * m_runningTeaTime ); painter.setBrush( QColor( 0, 255, 0, 90 ) ); painter.drawPie( rectangle, startAngle, 360*16 + angleSpan ); painter.setBrush( QColor( 255, 0, 0, 90 ) ); painter.drawPie( rectangle, startAngle, angleSpan ); } else { KIconLoader::global()->drawOverlays(QStringList() << QStringLiteral( "alarm-symbolic" ), icon, KIconLoader::Panel); } setIcon(icon); } void TopLevel::teaTimeEvent() { QString title = i18n( "The Tea Cooker" ); if( m_runningTeaTime == 0 ) { m_timer->stop(); QString content = i18n( "%1 is now ready!", m_runningTea.name() ); //NOTICE Timeout is set t ~o24 days when no auto hide is request. Ok - nearly the same... if( m_usepopup ) { showMessage( title, content, QSystemTrayIcon::Information, m_autohide ? m_autohidetime*1000 : 2100000000 ); } KNotification::event( QStringLiteral( "ready" ), content ); if( m_usereminder && m_remindertime > 0 ) { setTooltipText( content ); m_timer->start( 1000 ); m_nextNotificationTime -= m_remindertime; --m_runningTeaTime; } checkState(); repaintTrayIcon(); } else if(m_runningTeaTime<0) { QString content = i18n( "%1 is ready since %2!", m_runningTea.name(), Tea::int2time( m_runningTeaTime*-1, true ) ); setTooltipText( content ); if( m_runningTeaTime == m_nextNotificationTime ) { if( m_usepopup ) { showMessage( title, content, QSystemTrayIcon::Information, m_autohide ? m_autohidetime*1000 : 2100000000 ); } KNotification::event( QLatin1String( "reminder" ), content ); m_nextNotificationTime -= m_remindertime; } --m_runningTeaTime; } else { --m_runningTeaTime; setTooltipText( i18nc( "%1 is the time, %2 is the name of the tea", "%1 left for %2.", Tea::int2time( m_runningTeaTime, true ), m_runningTea.name() ) ); } if( m_usevisualize ) { repaintTrayIcon(); } } void TopLevel::cancelTea() { m_timer->stop(); m_runningTeaTime = 0; checkState(); repaintTrayIcon(); } void TopLevel::configureNotifications() { KNotifyConfigWidget::configure(); } void TopLevel::loadConfig() { KSharedConfigPtr config = KSharedConfig::openConfig(); KConfigGroup generalGroup( config, "General" ); m_usepopup=generalGroup.readEntry( "UsePopup", true ); m_autohide=generalGroup.readEntry( "PopupAutoHide", false ); m_autohidetime=generalGroup.readEntry( "PopupAutoHideTime", 30 ); m_usereminder=generalGroup.readEntry( "UseReminder", false ); m_remindertime=generalGroup.readEntry( "ReminderTime", 60 ); m_usevisualize=generalGroup.readEntry( "UseVisualize", true ); } void TopLevel::showPopup(QSystemTrayIcon::ActivationReason reason) { if ( reason != QSystemTrayIcon::Trigger ) { return; } if ( m_popup->isVisible() ) { m_popup->hide(); } else { QPoint p = geometry().topLeft(); QRect r = QApplication::desktop()->screenGeometry( p ); QSize popupSize = m_popup->minimumSizeHint(); if ( p.x() + popupSize.width() > r.right() ) { p.rx() -= popupSize.width(); } if ( p.y() + popupSize.height() > r.bottom() ) { p.ry() -= popupSize.height(); } m_popup->show( p ); } } void TopLevel::setTooltipText(const QString& content) { const QString title = i18n( "The Tea Cooker" ); setToolTip( content ); m_popup->setView( title, content, KIconLoader::global()->loadIcon( m_iconName, KIconLoader::MainToolbar ) ); } // kate: word-wrap off; encoding utf-8; indent-width 4; tab-width 4; line-numbers on; mixed-indent off; remove-trailing-space-save on; replace-tabs-save on; replace-tabs on; space-indent on; // vim:set spell et sw=4 ts=4 nowrap cino=l1,cs,U1: diff --git a/src/toplevel.h b/src/toplevel.h index 83917fe..bd76b75 100644 --- a/src/toplevel.h +++ b/src/toplevel.h @@ -1,98 +1,98 @@ /* * Copyright 1998-1999 by Matthias Hoelzer-Kluepfel * Copyright 2002-2003 by Martin Willers * Copyright 2007-2009 by Stefan Böhmann * * 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, see . */ #ifndef TOPLEVEL_H #define TOPLEVEL_H #include "tea.h" #include class QAction; class QActionGroup; class QTimer; class KAboutData; class KActionCollection; class KHelpMenu; class KPassivePopup; /** * @short the main class for KTeatime * * @author Stefan Böhmann */ class TopLevel : public QSystemTrayIcon { public: - explicit TopLevel(const KAboutData *aboutData, const QString &icon = QLatin1String("kteatime"), QWidget *parent = 0); + explicit TopLevel(const KAboutData *aboutData, const QString &icon = QLatin1String("kteatime"), QWidget *parent = nullptr); ~TopLevel(); void setTeaList(const QList &tealist); void runTea(const Tea &tea); private: void runTea(QAction *a); void showSettingsDialog(); void showTimeEditDialog(); void teaTimeEvent(); void cancelTea(); void showPopup(QSystemTrayIcon::ActivationReason reason); void checkState(); void loadConfig(); void loadTeaMenuItems(); void repaintTrayIcon(); void setTooltipText(const QString& content); void configureNotifications(); QList m_tealist; QAction *action; QActionGroup *m_teaActionGroup; KActionCollection *m_actionCollection; KHelpMenu *m_helpMenu; QTimer *m_timer; KPassivePopup *m_popup; QString m_iconName; int m_runningTeaTime; int m_nextNotificationTime; Tea m_runningTea; /** should we show a popup for events */ bool m_usepopup; /** auto hide the popup? */ bool m_autohide; /** time after the popup should be hide. */ int m_autohidetime; /** remind us about a ready tea? */ bool m_usereminder; /** the time bedween remind events */ int m_remindertime; /** use a visual effect in the system tray icon. */ bool m_usevisualize; }; #endif // kate: word-wrap off; encoding utf-8; indent-width 4; tab-width 4; line-numbers on; mixed-indent off; remove-trailing-space-save on; replace-tabs-save on; replace-tabs on; space-indent on; // vim:set spell et sw=4 ts=4 nowrap cino=l1,cs,U1: