[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-devel
Subject:    Patch for KTeaTime
From:       Stefan =?iso-8859-1?q?B=F6hmann?= <ebrief () hilefoks ! org>
Date:       2007-08-21 3:32:01
Message-ID: 200708210532.01582.ebrief () hilefoks ! org
[Download RAW message or body]

I worked the last few days on KTeaTime to learn C++ and KDE4 development. Here 
are my results. 

Practical the diff contains a complete rewrite of KTeaTime. I'm now sure I can 
finish my work and so I want to ask if this patch can be applied.


["kteatime.diff" (text/x-diff)]

Index: toplevel.h
===================================================================
--- toplevel.h	(revision 702652)
+++ toplevel.h	(working copy)
@@ -1,123 +1,105 @@
 /*
- *   This file is part of the KTeaTime application.
- *
- *   Copyright (C) 1998-1999  Matthias Hoelzer-Kluepfel (hoelzer@kde.org)
- *   Copyright (C) 2002-2003  Martin Willers (willers@xm-arts.de)
- *
- *   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.
- *
- */
+   Copyright (c) 2007 Stefan Böhmann <ebrief@hilefoks.org>
 
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.
+*/
+
 #ifndef TOPLEVEL_H
 #define TOPLEVEL_H
 
-#include <QMenu>
-#include <qtimer.h>
-#include <qlineedit.h>
-#include <q3listview.h>
-#include <qpushbutton.h>
-#include <q3groupbox.h>
-//Added by qt3to4:
-#include <QMouseEvent>
-#include <QTimerEvent>
-#include <QPaintEvent>
-#include <knuminput.h>
-#include <ksystemtrayicon.h>
-#include <qpixmap.h>
+#include "tea.h"
 
-class KDialog;
-class QCheckBox;
-class TimeEdit;
+#include <QIcon>
 
+#include <KSystemTrayIcon>
+
+
+class QAction;
+class KHelpMenu;
+class KPassivePopup;
+class KAboutData;
+
+/**
+ * @short the main class for KTeatime
+ *
+ * @author Stefan Böhmann <ebrief@hilefoks.org>
+ */
 class TopLevel : public KSystemTrayIcon
 {
-	Q_OBJECT
+    Q_OBJECT
 
-public:
+    public:
+        explicit TopLevel(const KAboutData *aboutData, const QString \
&icon="kteatime", QWidget *parent=0); +        ~TopLevel();
 
-	TopLevel();
-	~TopLevel();
+        inline void setTeaList(QList<Tea> tealist) {
+            teas=tealist;
+            loadConfig();
+            rebuildMenus();
+        }
 
-protected:
-	void timerEvent(QTimerEvent *);
+    public slots:
+        void runTea(Tea tea);
 
-private slots:
+    private:
+        void rebuildMenus();
+        void loadConfig();
+        QPoint calculatePopupPoint();
 
-        void repaint();
-	void teaSelected(int index);
-	void teaStartSelected(int index);
-	void start();
-	void stop();
-	void config();
-	void help();
-	void anonymous();
-	void rebuildTeaMenus();
-	void slotActivated(QSystemTrayIcon::ActivationReason);
+        QList<Tea> teas;
+        QAction *stopAct, *confAct, *anonAct, *exitAct;
+        KHelpMenu *helpMenu;
+        QTimer *timer;
+        KPassivePopup *popup;
 
-	void listBoxItemSelected();
-	void nameEditTextChanged(const QString& newText);
-	void spinBoxValueChanged(int v);
-	void newButtonClicked();
-	void delButtonClicked();
-	void upButtonClicked();
-	void downButtonClicked();
-	void confButtonClicked();
-	void enable_menuEntries();
-	void disable_properties();
-	void enable_properties();
-	void enable_controls();
-	void actionEnableToggled(bool on);
+        int runningTeaTime;
+        Tea runningTea;
 
-private:
+        /** should we use notifications defined by KNotification */
+        bool usenotification;
 
-	static const int DEFAULT_TEA_TIME;
+        /** should we show a popup for events */
+        bool usepopup;
 
-	struct tea_struct {
-		QString name;
-		int time;
-	};
-	QVector<tea_struct> teas;      // list of tea-names and times
+        /** auto hide the popup? */
+        bool autohide;
 
-	bool running, ready, firstFrame, listempty;
-	int seconds;                        // variable for counting down seconds
-	int startSeconds;                   // steeping time for current tea
-	int percentDone;                    // ok, this isn't really "per 100", but "per \
360" +        /** time after the shoult be hide. */
+        int autohidetime;
 
-	int current_selected;          // index of currently +selected+ tea in menu
-	Q3ListViewItem *current_item;        // ptr to currently +selected+ tea in ListView
-	QString current_name;               // name of currently +running+ tea (if any)
-	bool shooting;                      // anonymous tea currently steeping?
+        /** remind us about a ready tea? */
+        bool usereminder;
 
-	bool useNotify, usePopup, useAction;
-	QString action;
-	bool useTrayVis;                    // visualize progress in tray icon
+        /** the time bedween remind events */
+        int remindertime;
 
-	QPixmap mugPixmap, teaNotReadyPixmap, teaAnim1Pixmap, teaAnim2Pixmap;
+        /** use a visual effect in the system tray icon. */
+        bool usevisualize;
 
-	QAction *startAct, *stopAct, *confAct, *anonAct;
-	QMenu *menu, *steeping_menu, *start_menu;
-	Q3ListView *listbox;
-	QLineEdit *nameEdit, *actionEdit;
-	TimeEdit *timeEdit;
-	Q3GroupBox *editgroup;
-	QPushButton *btn_new, *btn_del, *btn_up, *btn_down, *btn_conf;
+        const QIcon _icon;
 
-	QString lastTip;
-	KDialog *anondlg, *confdlg;
-	TimeEdit *anon_time;
-	QCheckBox *eventEnable, *popupEnable, *actionEnable, *visEnable;
+    private slots:
+        void runTea(QAction *a);
+        void showSettingsDialog();
+        void showTimeEditDialog();
+        void timerEvent();
+        void cancelTea();
+        void showPopup(QSystemTrayIcon::ActivationReason reason);
+        void repaintTrayIcon();
 };
 
+
 #endif
Index: timeedit.ui
===================================================================
--- timeedit.ui	(revision 0)
+++ timeedit.ui	(revision 0)
@@ -0,0 +1,289 @@
+<ui version="4.0" >
+ <author>Stefan Böhmann</author>
+ <class>TimeEditWidget</class>
+ <widget class="QWidget" name="TimeEditWidget" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>420</width>
+    <height>157</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string>Anonymous Tea</string>
+  </property>
+  <layout class="QVBoxLayout" >
+   <property name="leftMargin" >
+    <number>0</number>
+   </property>
+   <property name="topMargin" >
+    <number>0</number>
+   </property>
+   <property name="rightMargin" >
+    <number>0</number>
+   </property>
+   <property name="bottomMargin" >
+    <number>0</number>
+   </property>
+   <item>
+    <widget class="KButtonGroup" name="kbuttongroup" >
+     <property name="title" >
+      <string>Tea time</string>
+     </property>
+     <layout class="QGridLayout" >
+      <item row="0" column="0" >
+       <widget class="QSpinBox" name="hours" >
+        <property name="maximum" >
+         <number>48</number>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="1" >
+       <widget class="QLabel" name="hoursLabel" >
+        <property name="text" >
+         <string>hours</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="2" >
+       <widget class="QSlider" name="hoursSlider" >
+        <property name="focusPolicy" >
+         <enum>Qt::WheelFocus</enum>
+        </property>
+        <property name="maximum" >
+         <number>48</number>
+        </property>
+        <property name="tracking" >
+         <bool>true</bool>
+        </property>
+        <property name="orientation" >
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="invertedAppearance" >
+         <bool>false</bool>
+        </property>
+        <property name="invertedControls" >
+         <bool>false</bool>
+        </property>
+        <property name="tickPosition" >
+         <enum>QSlider::TicksBelow</enum>
+        </property>
+        <property name="tickInterval" >
+         <number>10</number>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="0" >
+       <widget class="QSpinBox" name="minutes" >
+        <property name="focusPolicy" >
+         <enum>Qt::WheelFocus</enum>
+        </property>
+        <property name="maximum" >
+         <number>59</number>
+        </property>
+        <property name="value" >
+         <number>3</number>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="1" >
+       <widget class="QLabel" name="minutesLabel" >
+        <property name="text" >
+         <string>minutes</string>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="2" >
+       <widget class="QSlider" name="minutesSlider" >
+        <property name="focusPolicy" >
+         <enum>Qt::WheelFocus</enum>
+        </property>
+        <property name="maximum" >
+         <number>59</number>
+        </property>
+        <property name="value" >
+         <number>3</number>
+        </property>
+        <property name="orientation" >
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="invertedAppearance" >
+         <bool>false</bool>
+        </property>
+        <property name="invertedControls" >
+         <bool>false</bool>
+        </property>
+        <property name="tickPosition" >
+         <enum>QSlider::TicksBelow</enum>
+        </property>
+        <property name="tickInterval" >
+         <number>10</number>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="0" >
+       <widget class="QSpinBox" name="seconds" >
+        <property name="maximum" >
+         <number>59</number>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="1" >
+       <widget class="QLabel" name="secondsLabel" >
+        <property name="text" >
+         <string>seconds</string>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="2" >
+       <widget class="QSlider" name="secondsSlider" >
+        <property name="focusPolicy" >
+         <enum>Qt::WheelFocus</enum>
+        </property>
+        <property name="maximum" >
+         <number>59</number>
+        </property>
+        <property name="orientation" >
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="invertedAppearance" >
+         <bool>false</bool>
+        </property>
+        <property name="invertedControls" >
+         <bool>false</bool>
+        </property>
+        <property name="tickPosition" >
+         <enum>QSlider::TicksBelow</enum>
+        </property>
+        <property name="tickInterval" >
+         <number>10</number>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <spacer>
+     <property name="orientation" >
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeHint" >
+      <size>
+       <width>40</width>
+       <height>10</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>KButtonGroup</class>
+   <extends>QGroupBox</extends>
+   <header>kbuttongroup.h</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>hours</sender>
+   <signal>valueChanged(int)</signal>
+   <receiver>hoursSlider</receiver>
+   <slot>setValue(int)</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>44</x>
+     <y>50</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>164</x>
+     <y>51</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>hoursSlider</sender>
+   <signal>valueChanged(int)</signal>
+   <receiver>hours</receiver>
+   <slot>setValue(int)</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>160</x>
+     <y>44</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>45</x>
+     <y>53</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>minutes</sender>
+   <signal>valueChanged(int)</signal>
+   <receiver>minutesSlider</receiver>
+   <slot>setValue(int)</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>42</x>
+     <y>80</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>167</x>
+     <y>77</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>minutesSlider</sender>
+   <signal>valueChanged(int)</signal>
+   <receiver>minutes</receiver>
+   <slot>setValue(int)</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>197</x>
+     <y>87</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>43</x>
+     <y>84</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>seconds</sender>
+   <signal>valueChanged(int)</signal>
+   <receiver>secondsSlider</receiver>
+   <slot>setValue(int)</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>53</x>
+     <y>111</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>173</x>
+     <y>117</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>secondsSlider</sender>
+   <signal>valueChanged(int)</signal>
+   <receiver>seconds</receiver>
+   <slot>setValue(int)</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>226</x>
+     <y>119</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>48</x>
+     <y>115</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
Index: settings.cpp
===================================================================
--- settings.cpp	(revision 0)
+++ settings.cpp	(revision 0)
@@ -0,0 +1,312 @@
+/*
+   Copyright (c) 2007 Stefan Böhmann <ebrief@hilefoks.org>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.
+*/
+
+#include "settings.h"
+#include "toplevel.h"
+#include "tealistmodel.h"
+
+#include <QCloseEvent>
+#include <QHashIterator>
+#include <QString>
+#include <QDesktopWidget>
+
+#include <knotifyconfigwidget.h>
+
+#include <iostream>
+
+SettingsUI::SettingsUI(QWidget *parent): QFrame(parent)
+{
+    setupUi(this);
+}
+
+
+
+SettingsDialog::SettingsDialog(TopLevel *toplevel, QList<Tea> &teas): KDialog()
+{
+    this->toplevel=toplevel;
+
+    setCaption(i18n("Configure Tea Cooker"));
+    setButtonWhatsThis(KDialog::Ok, i18n("Save changes and close dialog."));
+    setButtonWhatsThis(KDialog::Cancel, i18n("Close dialog without saving \
changes.")); +
+    ui = new SettingsUI(this);
+    setMainWidget(ui);
+
+    KSharedConfigPtr config = KSharedConfig::openConfig();
+    KConfigGroup group(config, "General");
+
+    restoreDialogSize(group);
+    int x=group.readEntry("SettingsDialogXPos", -500);
+    int y=group.readEntry("SettingsDialogYPos", -500);
+    if(x!=-500 && y!=-500) {
+        QDesktopWidget desktop;
+
+        if(x<0) x=0;
+        else if(x>desktop.screenGeometry().width()-width())
+            x=desktop.screenGeometry().width()-width();
+
+        if(y<0) y=0;
+        else if(y>desktop.screenGeometry().height()-height())
+            y=desktop.screenGeometry().height()-height();
+
+        move(QPoint(x,y));
+    }
+
+
+    bool noti=group.readEntry("UseNotification", true);
+    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->notificationCheckBox->setCheckState(noti?Qt::Checked:Qt::Unchecked);
+    ui->popupCheckBox->setCheckState(popup?Qt::Checked:Qt::Unchecked);
+    ui->autohideCheckBox->setCheckState(autohide?Qt::Checked:Qt::Unchecked);
+    ui->reminderCheckBox->setCheckState(reminder?Qt::Checked:Qt::Unchecked);
+    ui->visualizeCheckBox->setCheckState(vis?Qt::Checked:Qt::Unchecked);
+
+    ui->autohideSpinBox->setValue(autohidetime);
+    ui->reminderSpinBox->setValue(remindertime);
+
+    ui->notificationButton->setEnabled(noti);
+    ui->autohideCheckBox->setEnabled(popup);
+    ui->autohideSpinBox->setEnabled(autohide);
+    ui->reminderSpinBox->setEnabled(reminder);
+
+    model=new TeaListModel(teas, this);
+    ui->tealistTreeView->setModel(model);
+    connect(ui->tealistTreeView->selectionModel(), SIGNAL(selectionChanged(const \
QItemSelection&, const QItemSelection&)), this, SLOT(updateSelection(const \
QItemSelection&, const QItemSelection&))); +
+    ui->removeButton->setEnabled(false);
+    ui->upButton->setEnabled(false);
+    ui->downButton->setEnabled(false);
+
+    ui->newButton->setIcon(KIcon("document-new"));
+    ui->removeButton->setIcon(KIcon("mail-delete"));
+    ui->upButton->setIcon(KIcon("arrow-up"));
+    ui->downButton->setIcon(KIcon("arrow-down"));
+
+    connect(ui->popupCheckBox, SIGNAL(toggled(bool)), this, \
SLOT(checkPopupButtonState(bool)) ); +    connect(ui->notificationButton, \
SIGNAL(clicked()), this, SLOT(confButtonClicked()) ); +
+    connect(ui->newButton, SIGNAL(clicked()), this, SLOT(newButtonClicked()) );
+    connect(ui->removeButton, SIGNAL(clicked()), this, SLOT(removeButtonClicked()) \
); +    connect(ui->upButton, SIGNAL(clicked()), this, SLOT(upButtonClicked()) );
+    connect(ui->downButton, SIGNAL(clicked()), this, SLOT(downButtonClicked()) );
+
+
+    connect(ui->teaNameEdit, SIGNAL(textChanged(const QString&)), this, \
SLOT(nameValueChanged(const QString&)) ); +    connect(ui->hoursSpin, \
SIGNAL(valueChanged(int)), this, SLOT(timeValueChanged()) ); +    \
connect(ui->minutesSpin, SIGNAL(valueChanged(int)), this, SLOT(timeValueChanged()) ); \
+    connect(ui->secondsSpin, SIGNAL(valueChanged(int)), this, \
SLOT(timeValueChanged()) ); +    connect(ui->hoursSlider, SIGNAL(valueChanged(int)), \
this, SLOT(timeValueChanged()) ); +    connect(ui->minutesSlider, \
SIGNAL(valueChanged(int)), this, SLOT(timeValueChanged()) ); +    \
connect(ui->secondsSlider, SIGNAL(valueChanged(int)), this, SLOT(timeValueChanged()) \
); +}
+
+
+SettingsDialog::~SettingsDialog()
+{
+    delete model;
+    delete ui;
+}
+
+
+void SettingsDialog::closeEvent(QCloseEvent *event)
+{
+    hide();
+    delayedDestruct();
+    event->ignore();
+}
+
+
+void SettingsDialog::reject()
+{
+    hide();
+    delayedDestruct();
+}
+
+
+void SettingsDialog::accept()
+{
+    KSharedConfigPtr config = KSharedConfig::openConfig();
+    KConfigGroup group(config, "General");
+    group.writeEntry("SettingsDialogXPos", x());
+    group.writeEntry("SettingsDialogYPos", y());
+
+    hide();
+
+    saveDialogSize(group);
+
+    group.writeEntry("UseNotification",  \
(ui->notificationCheckBox->checkState()==Qt::Checked)?true:false); +    \
group.writeEntry("UsePopup",         \
(ui->popupCheckBox->checkState()==Qt::Checked)?true:false); +    \
group.writeEntry("PopupAutoHide",    \
(ui->autohideCheckBox->checkState()==Qt::Checked)?true:false); +    \
group.writeEntry("PopupAutoHideTime", ui->autohideSpinBox->value()); +    \
group.writeEntry("UseReminder",      \
(ui->reminderCheckBox->checkState()==Qt::Checked)?true:false); +    \
group.writeEntry("ReminderTime",      ui->reminderSpinBox->value()); +    \
group.writeEntry("UseVisualize",     \
(ui->visualizeCheckBox->checkState()==Qt::Checked)?true:false); +
+    toplevel->setTeaList(model->getTeaList());
+    delayedDestruct();
+}
+
+
+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::confButtonClicked()
+{
+    KNotifyConfigWidget::configure(this);
+}
+
+
+void SettingsDialog::newButtonClicked()
+{
+    int count=model->rowCount();
+    model->insertRows(count, 1);
+    QItemSelectionModel *sm=ui->tealistTreeView->selectionModel();
+    QItemSelection selection(model->index(count, 0), model->index(count, 1));
+    sm->select(selection, QItemSelectionModel::Clear|QItemSelectionModel::Select);
+}
+
+
+void SettingsDialog::removeButtonClicked()
+{
+    QModelIndexList \
indexes=ui->tealistTreeView->selectionModel()->selectedIndexes(); +    QModelIndex \
index; +    foreach(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) +            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 item = sm->selection().indexes();
+    if(!item.isEmpty()) {
+        QString name=model->data(model->index(item.at(0).row(), 0), \
Qt::EditRole).toString(); +        unsigned \
time=model->data(model->index(item.at(0).row(), 1), Qt::EditRole).toUInt(); +        \
int pos=item.at(0).row(); +
+        moveup?--pos:++pos;
+
+        removeButtonClicked();
+        model->insertRows(pos, 1);
+        model->setData(model->index(pos, 0), name, Qt::EditRole);
+        model->setData(model->index(pos, 1), time, Qt::EditRole);
+
+        QItemSelection selection(model->index(pos, 0), model->index(pos, 1));
+        sm->select(selection, \
QItemSelectionModel::Clear|QItemSelectionModel::Select); +    }
+}
+
+
+void SettingsDialog::updateSelection(const QItemSelection &selected, const \
QItemSelection &deselected) +{
+    Q_UNUSED(deselected);
+    QModelIndexList item = selected.indexes();
+
+    QString name;
+    unsigned time=0;
+
+    bool state=!item.isEmpty();
+
+    ui->teaPropertiesGroup->setEnabled(state);
+    ui->teaNameEdit->setEnabled(state);
+    ui->hoursSpin->setEnabled(state);
+    ui->minutesSpin->setEnabled(state);
+    ui->secondsSpin->setEnabled(state);
+    ui->hoursSlider->setEnabled(state);
+    ui->minutesSlider->setEnabled(state);
+    ui->secondsSlider->setEnabled(state);
+    ui->removeButton->setEnabled(state);
+
+    if(state) {
+        name=model->data(model->index(item.at(0).row(), 0), \
Qt::EditRole).toString(); +        time=model->data(model->index(item.at(0).row(), \
1), Qt::EditRole).toUInt(); +
+        ui->upButton->setEnabled( (item.at(0).row()>0) ? true : false );
+        ui->downButton->setEnabled( (item.at(0).row()<model->rowCount()-1) ? true : \
false ); +    }
+    else {
+        ui->upButton->setEnabled(false);
+        ui->downButton->setEnabled(false);
+    }
+
+    ui->teaNameEdit->setText(name);
+    ui->hoursSpin->setValue(time/(60*60));
+    ui->minutesSpin->setValue((time%(60*60))/60);
+    ui->secondsSpin->setValue(time%60);
+    ui->hoursSlider->setValue(ui->hoursSpin->value());
+    ui->minutesSlider->setValue(ui->minutesSpin->value());
+    ui->secondsSlider->setValue(ui->secondsSpin->value());
+}
+
+
+void SettingsDialog::timeValueChanged()
+{
+    QModelIndexList item = \
ui->tealistTreeView->selectionModel()->selection().indexes(); +    \
if(!item.isEmpty()) { +        int time=ui->secondsSpin->value();
+        time+=ui->minutesSpin->value()*60;
+        time+=ui->hoursSpin->value()*60*60;
+
+        if(time<=0) {
+            time=1;
+            ui->secondsSpin->setValue(time);
+            ui->secondsSlider->setValue(ui->secondsSpin->value());
+        }
+
+        model->setData(model->index(item.at(0).row(), 1), time, Qt::EditRole);
+    }
+}
+
+
+void SettingsDialog::nameValueChanged(const QString &text)
+{
+    QModelIndexList item = \
ui->tealistTreeView->selectionModel()->selection().indexes(); +    \
if(!item.isEmpty()) { +        model->setData(model->index(item.at(0).row(), 0), \
text, Qt::EditRole); +    }
+}
+
+
Index: timeedit.cpp
===================================================================
--- timeedit.cpp	(revision 702652)
+++ timeedit.cpp	(working copy)
@@ -1,168 +1,129 @@
 /*
- *   KTeaTime - A tea timer.
- *
- *   Copyright (C) 1998-1999  Matthias Hoelzer-Kluepfel (hoelzer@kde.org)
- *   Copyright (C) 2002-2003  Martin Willers (willers@xm-arts.de)
- *   Copyright (C) 2003       Daniel Teske (teske@bigfoot.com)
- *
- *   With contributions from Daniel Teske <teske@bigfoot.com>, and
- *   Jackson Dunstan <jdunstan@digipen.edu>
- *   (and possibly others, as well)
- *
- *   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.
- *
- */
+   Copyright (c) 2007 Stefan Böhmann <ebrief@hilefoks.org>
 
-#include "timeedit.h"
-#include "timeedit.moc"
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
 
-#include <klocale.h>
-#include <qlabel.h>
-#include <qlayout.h>
-#include <QHBoxLayout>
+   This library 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
+   Library General Public License for more details.
 
-WrappingSpinBox::WrappingSpinBox(int minimum, int maximum, int step, QWidget \
                *parent, const char *name)
-	: QSpinBox(minimum, maximum, step, parent, name)
-{
-}
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.
+*/
 
-WrappingSpinBox::~WrappingSpinBox()
-{
-}
+#include "timeedit.h"
+#include "toplevel.h"
+#include "tea.h"
 
+#include <QCloseEvent>
+#include <QDesktopWidget>
 
-/** Overloaded QSpinBox method */
-void WrappingSpinBox::stepUp()
-{
-	bool wrap = false;
-	if (value() == 59)
-		wrap = true;
-	if (wrap)
-		emit wrapUp();              // must wrap first (to avoid double-step-up)
-	QSpinBox::stepUp();
-}
+#include <iostream>
 
-/** Overloaded QSpinBox method */
-void WrappingSpinBox::stepDown()
+TimeEditUI::TimeEditUI(QWidget *parent): QFrame(parent)
 {
-	bool wrap = false;
-	if (value() == 0)
-		wrap = true;
-	QSpinBox::stepDown();
-	if (wrap)
-		emit wrapDown();
+    setupUi(this);
 }
 
 
-// -------------------------------------------------------------------------
+TimeEditDialog::TimeEditDialog(TopLevel *toplevel): KDialog()
+{
+    this->toplevel=toplevel;
+    setCaption(i18n("Anonymous Tea"));
 
+    setButtonWhatsThis(KDialog::Ok, i18n("Start a new anonymous tea with the in this \
dialog configured time.")); +    setButtonWhatsThis(KDialog::Cancel, i18n("Close this \
dialog without starting a new tea."));  
-TimeEdit::TimeEdit(QWidget* parent)
-    : QWidget(parent)
-{
-	layout = new QHBoxLayout(this);
-    layout->setSpacing( 5 );
-    layout->setMargin( 0 );
-	minuteBox = new QSpinBox(0, 300, 1, this);
-//	minuteBox->setFixedSize(minuteBox->sizeHint());
+    ui = new TimeEditUI(this);
+    setMainWidget(ui);
 
-	QLabel* min = new QLabel(i18n("min"), this);
-	min->setFixedSize(min->sizeHint());
-	secondBox = new WrappingSpinBox(0, 59, 1, this);
-	secondBox->setWrapping(true);
-//	secondBox->setFixedSize(secondBox->sizeHint());
+    KSharedConfigPtr config = KSharedConfig::openConfig();
+    KConfigGroup group(config, "AnonymousTeaDialog");
 
-	QLabel* sec = new QLabel(i18n("sec"),this);
-	sec->setFixedSize(sec->sizeHint());
+    int time=group.readEntry("AnonymousTeaTime", 180);
 
-	layout->addWidget(minuteBox);
-	layout->addWidget(min);
+    ui->hours->setValue(time/(60*60));
+    ui->minutes->setValue((time%(60*60))/60);
+    ui->seconds->setValue(time%60);
 
-	layout->addWidget(secondBox);
-	layout->addWidget(sec);
+    ui->hoursSlider->setValue(ui->hours->value());
+    ui->minutesSlider->setValue(ui->minutes->value());
+    ui->secondsSlider->setValue(ui->seconds->value());
 
-	connect(minuteBox, SIGNAL(valueChanged(int)), SLOT(spinBoxValueChanged(int)) );
-	connect(secondBox, SIGNAL(valueChanged(int)), SLOT(spinBoxValueChanged(int)) );
-	connect(secondBox, SIGNAL(wrapUp()), SLOT(wrappedUp()));
-	connect(secondBox, SIGNAL(wrapDown()), SLOT(wrappedDown()));
-}
+    restoreDialogSize(group);
+    int x=group.readEntry("AnonymousTeaDialogXPos", -500);
+    int y=group.readEntry("AnonymousTeaDialogYPos", -500);
 
-TimeEdit::~TimeEdit()
-{
-}
+    if(x!=-500 && y!=-500) {
+        QDesktopWidget desktop;
 
-/** Set to specified number of seconds. */
-void TimeEdit::setValue(int val)
-{
-	if (val < 0)
-		return;
+        if(x<0) x=0;
+        else if(x>desktop.screenGeometry().width()-width())
+            x=desktop.screenGeometry().width()-width();
 
-	// block signals to avoid receiption of valueChanged()
-	// between changing of minutes and seconds
-	secondBox->blockSignals(true);
-	minuteBox->blockSignals(true);
+        if(y<0) y=0;
+        else if(y>desktop.screenGeometry().height()-height())
+            y=desktop.screenGeometry().height()-height();
 
-	secondBox->setValue(val % 60);
-	minuteBox->setValue(val / 60);
+        move(QPoint(x,y));
+    }
 
-	secondBox->blockSignals(false);
-	minuteBox->blockSignals(false);
 
-	emit valueChanged(value());
+    connect( ui->hours, 	SIGNAL(valueChanged(int)), this, SLOT(checkOkButtonState()) \
); +    connect( ui->minutes, 	SIGNAL(valueChanged(int)), this, \
SLOT(checkOkButtonState()) ); +    connect( ui->seconds, 	SIGNAL(valueChanged(int)), \
this, SLOT(checkOkButtonState()) );  }
 
-/** Return current value in seconds. */
-int TimeEdit::value()
+
+TimeEditDialog::~TimeEditDialog()
 {
-	return minuteBox->value()*60 + secondBox->value();
+    delete ui;
 }
 
-/** SLOT: Handle wrap-up of seconds-box */
-void TimeEdit::wrappedUp()
+
+void TimeEditDialog::checkOkButtonState()
 {
-	if (minuteBox->value() != minuteBox->maximum()) {
-		minuteBox->stepUp();
-	} else {
-		secondBox->setValue(58);    // ugly: must cater for wrapping-first
-	}
+    enableButtonOk( ui->minutes->value() || ui->seconds->value() || \
ui->hours->value() );  }
 
-/** SLOT: Handle wrap-down of seconds-box */
-void TimeEdit::wrappedDown()
+
+void TimeEditDialog::closeEvent(QCloseEvent *event)
 {
-	// well, the "if" should always be true
-	if (minuteBox->value() != minuteBox->minimum()) {
-		minuteBox->stepDown();
-	} else {
-		secondBox->setValue(0);
-	}
+    hide();
+    delayedDestruct();
+    event->ignore();
 }
 
-/** SLOT: Handle any change in minutes of seconds */
-void TimeEdit::spinBoxValueChanged(int)
-{
-	if (value() == 0) {
-		secondBox->stepUp();        // this will give another spinBoxValueChanged() \
                invocation
-		return;
-	}
 
-	emit valueChanged(value());
+void TimeEditDialog::reject()
+{
+    hide();
+    delayedDestruct();
 }
 
-/** SLOT (overloading QSpinBox): set focus */
-void TimeEdit::setFocus()
+
+void TimeEditDialog::accept()
 {
-	minuteBox->setFocus();
+    hide();
+    int time=ui->seconds->value();
+    time+=ui->minutes->value()*60;
+    time+=ui->hours->value()*60*60;
+
+    KSharedConfigPtr config = KSharedConfig::openConfig();
+    KConfigGroup group(config, "AnonymousTeaDialog");
+    group.writeEntry("AnonymousTeaTime", time);
+    saveDialogSize(group);
+
+    group.writeEntry("AnonymousTeaDialogXPos", x());
+    group.writeEntry("AnonymousTeaDialogYPos", y());
+
+    emit toplevel->runTea(Tea(i18n("Anonymous Tea"), ui->hours->value()*60*60 + \
ui->minutes->value()*60 + ui->seconds->value()) ); +    delayedDestruct();
 }
+
Index: tealist.cpp
===================================================================
--- tealist.cpp	(revision 702652)
+++ tealist.cpp	(working copy)
@@ -1,83 +0,0 @@
-/*
- *   KTeaTime - A tea timer.
- *
- *   Copyright (C) 1998-1999  Matthias Hoelzer-Kluepfel (hoelzer@kde.org)
- *   Copyright (C) 2002-2003  Martin Willers (willers@xm-arts.de)
- *   Copyright (C) 2003       Daniel Teske (teske@bigfoot.com)
- *
- *   With contributions from Daniel Teske <teske@bigfoot.com>, and
- *   Jackson Dunstan <jdunstan@digipen.edu>
- *   (and possibly others, as well)
- *
- *   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 "tealist.h"
-
-#include <klocale.h>
-#include <q3listview.h>
-
-QString int2time(int time)
-{
-	QString str;
-	if (time / 60)
-		str.append(i18n("%1 min", time / 60));
-	if (time % 60)
-          if (str.isEmpty())
-            str.append(i18n("%1 s", time % 60));
-          else
-            str.append(i18n(" %1 s", time % 60));
-	return str;
-}
-
-
-TeaListItem::TeaListItem(Q3ListView * parent)
-    :Q3ListViewItem(parent)
-{
-
-}
-
-TeaListItem::TeaListItem(Q3ListView * parent, Q3ListViewItem *after)
-    :Q3ListViewItem(parent, after)
-{
-
-}
-
-TeaListItem::~TeaListItem()
-{
-}
-
-void TeaListItem::setTime(int t)
-{
-	Q3ListViewItem::setText(1, int2time(t));
-	tim = t;
-}
-
-void TeaListItem::setName(const QString &n)
-{
-	nam = n;
-	Q3ListViewItem::setText(0, n);
-}
-
-QString TeaListItem::name() const
-{
-	return nam;
-}
-
-int TeaListItem::time() const
-{
-	return tim;
-}
Index: settings.h
===================================================================
--- settings.h	(revision 0)
+++ settings.h	(revision 0)
@@ -0,0 +1,82 @@
+/*
+   Copyright (c) 2007 Stefan Böhmann <ebrief@hilefoks.org>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.
+*/
+
+#ifndef SETTINGS_H
+#define SETTINGS_H
+
+#include "ui_settings.h"
+
+#include <QObject>
+
+class QCloseEvent;
+class TopLevel;
+class TeaListModel;
+class Tea;
+
+/**
+ * @short Class for wrapping the ui file for the settings dialog.
+ *
+ * @author Stefan Böhmann <ebrief@hilefoks.org>
+ */
+class SettingsUI : public QFrame, public Ui::SettingsWidget
+{
+    Q_OBJECT
+    public:
+        SettingsUI(QWidget *parent=0);
+};
+
+
+/**
+ * @short the settings dialog
+ *
+ * @author Stefan Böhmann <ebrief@hilefoks.org>
+ */
+class SettingsDialog : public KDialog
+{
+    Q_OBJECT
+    public:
+        SettingsDialog(TopLevel *toplevel, QList<Tea> &teas);
+        ~SettingsDialog();
+
+
+    private:
+        SettingsUI *ui;
+        TopLevel *toplevel;
+        TeaListModel *model;
+        void moveSelectedItem(bool moveup);
+
+
+    private slots:
+        void closeEvent(QCloseEvent *event);
+        void updateSelection(const QItemSelection &selected, const QItemSelection \
&deselected); +        void reject();
+        void accept();
+        void checkPopupButtonState(bool b);
+        void confButtonClicked();
+
+        void newButtonClicked();
+        void removeButtonClicked();
+        void upButtonClicked();
+        void downButtonClicked();
+
+        void nameValueChanged(const QString &text);
+        void timeValueChanged();
+};
+
+#endif
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 702652)
+++ ChangeLog	(working copy)
@@ -1,3 +1,10 @@
+2007-08-20  Stefan Böhmann <ebrief@hilefoks.org>
+	- ported to KDE4
+	- noew using .ui files
+	- Implement command-line argument requested in #144708
+	- bumped version number to 1.2.0
+
+
 2003-11-02  Martin Willers <willers@xm-arts.de>
 	- bugfix: opening the configuration dialog was leaking memory
 	- workaround for Qt bug(?): deleting teas didn't update QListView properly (fixes \
                #63840)
Index: tea.cpp
===================================================================
--- tea.cpp	(revision 0)
+++ tea.cpp	(revision 0)
@@ -0,0 +1,64 @@
+/*
+   Copyright (c) 2007 Stefan Böhmann <ebrief@hilefoks.org>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.
+*/
+
+#include "tea.h"
+
+#include <QString>
+
+
+QString Tea::int2time(const int time, const bool longdesc)
+{
+    QString str;
+    const unsigned min=60;
+    const unsigned hour=60*min;
+    const unsigned day=24*hour;
+    const unsigned year=365*day;
+
+    if(time/year) {
+        if(longdesc) str.append(i18np("%1 year", "%1 years", time/year ));
+        else str.append(i18np("%1 a", "%1 a", time/year ));
+    }
+
+    if((time%year)/day) {
+        if(!str.isEmpty()) str.append(' ');
+        if(longdesc) str.append(i18np("%1 day", "%1 days", (time%year)/day ));
+        else str.append(i18np("%1 d", "%1 d", (time%year)/day ));
+    }
+
+    if((time%day)/hour) {
+        if(!str.isEmpty()) str.append(' ');
+        if(longdesc) str.append(i18np("%1 hour", "%1 hours", ((time%day)/hour) ));
+        else str.append(i18np("%1 h", "%1 h", ((time%day)/hour)  ));
+    }
+
+    if((time%hour)/min) {
+        if(!str.isEmpty()) str.append(' ');
+        if(longdesc) str.append(i18np("%1 minute", "%1 minutes", ((time%hour)/min) \
)); +        else str.append(i18np("%1 min", "%1 min", ((time%hour)/min) ));
+    }
+
+    if(time%min) {
+        if(!str.isEmpty()) str.append(' ');
+        if(longdesc) str.append(i18np("%1 second", "%1 seconds", time%min));
+        else str.append(i18np("%1 s", "%1 s", time%min));
+    }
+
+    return str;
+}
+
Index: timeedit.h
===================================================================
--- timeedit.h	(revision 702652)
+++ timeedit.h	(working copy)
@@ -1,93 +1,68 @@
 /*
- *   KTeaTime - A tea timer.
- *
- *   Copyright (C) 1998-1999  Matthias Hoelzer-Kluepfel (hoelzer@kde.org)
- *   Copyright (C) 2002-2003  Martin Willers (willers@xm-arts.de)
- *   Copyright (C) 2003       Daniel Teske (teske@bigfoot.com)
- *
- *   With contributions from Daniel Teske <teske@bigfoot.com>, and
- *   Jackson Dunstan <jdunstan@digipen.edu>
- *   (and possibly others, as well)
- *
- *   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.
- *
- */
+   Copyright (c) 2007 Stefan Böhmann <ebrief@hilefoks.org>
 
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.
+*/
+
 #ifndef TIMEEDIT_H
 #define TIMEEDIT_H
 
-#include <qspinbox.h>
-#include <qwidget.h>
-#include <QBoxLayout>
+#include "ui_timeedit.h"
 
-class QBoxLayout;
+class QCloseEvent;
+class TopLevel;
 
 
 /**
- * @short   A spinbox that wraps around after reaching minimum resp. maximum.
- * @author  Daniel Teske
+ * @short Class for wrapping the ui file for the timeedit dialog.
+ *
+ * @author Stefan Böhmann <ebrief@hilefoks.org>
  */
-class WrappingSpinBox : public QSpinBox
+class TimeEditUI : public QFrame, public Ui::TimeEditWidget
 {
-	Q_OBJECT
-
-public:
-	WrappingSpinBox(int minimum, int maximum, int step = 1, QWidget *parent=0, const \
                char *name=0);
-	~WrappingSpinBox();
-
-	void stepUp();
-	void stepDown();
-
-signals:
-	void wrapUp();
-	void wrapDown();
+    Q_OBJECT
+    public:
+        TimeEditUI(QWidget *parent=0);
 };
 
 
 /**
- * @short   A widget for entering a timeout in minutes and seconds.
- * @author  Daniel Teske
+ * @short the timeedit dialog.
+ *
+ * @author Stefan Böhmann <ebrief@hilefoks.org>
  */
-class TimeEdit : public QWidget
+class TimeEditDialog : public KDialog
 {
-	Q_OBJECT
+    Q_OBJECT
 
-public:
-	explicit TimeEdit(QWidget* parent = 0);
-	~TimeEdit();
+    public:
+        TimeEditDialog(TopLevel *toplevel);
+        ~TimeEditDialog();
 
-	void setValue(int value);
-	int value();
+    private:
+        TimeEditUI *ui;
+        TopLevel *toplevel;
 
-public slots:
-	void setFocus();
+    protected:
+        void closeEvent(QCloseEvent *event);
 
-private slots:
-	void spinBoxValueChanged(int);
-	void wrappedUp();
-	void wrappedDown();
-
-signals:
-	void valueChanged(int);
-
-
-protected:
-	QSpinBox *minuteBox;
-	WrappingSpinBox *secondBox;
-	QBoxLayout* layout;
+    private slots:
+        void checkOkButtonState();
+        void reject();
+        void accept();
 };
 
 #endif
-
Index: tealist.h
===================================================================
--- tealist.h	(revision 702652)
+++ tealist.h	(working copy)
@@ -1,56 +0,0 @@
-/*
- *   KTeaTime - A tea timer.
- *
- *   Copyright (C) 1998-1999  Matthias Hoelzer-Kluepfel (hoelzer@kde.org)
- *   Copyright (C) 2002-2003  Martin Willers (willers@xm-arts.de)
- *   Copyright (C) 2003       Daniel Teske (teske@bigfoot.com)
- *
- *   With contributions from Daniel Teske <teske@bigfoot.com>, and
- *   Jackson Dunstan <jdunstan@digipen.edu>
- *   (and possibly others, as well)
- *
- *   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.
- *
- */
-
-#ifndef TEALIST_H
-#define TEALIST_H
-
-#include <qstring.h>
-#include <Q3ListViewItem>
-class Q3ListView;
-
-
-class TeaListItem : public Q3ListViewItem
-{
-
-public:
-	explicit TeaListItem(Q3ListView *parent);
-	TeaListItem(Q3ListView *parent, Q3ListViewItem *after);
-	~TeaListItem();
-
-	int time() const;
-	QString name() const;
-	void setTime(int v);
-	void setName(const QString &n);
-
-private:
-	int tim;
-	QString nam;
-};
-
-
-QString int2time(int t);
-#endif
Index: kteatime.notifyrc
===================================================================
--- kteatime.notifyrc	(revision 702652)
+++ kteatime.notifyrc	(working copy)
@@ -1,16 +1,11 @@
 [Global]
 IconName=kteatime
 Comment=The KDE Tea Cooker
-Comment[fr]=Le préparateur de thé de KDE
 Comment[x-test]=xxThe KDE Tea Cookerxx
 
-[Event/tea]
+[Event/ready]
 Name=Tea is ready
-Name[fr]=Le thé est prêt
 Name[x-test]=xxTea is readyxx
 Comment=Tea is ready
-Comment[fr]=Le thé est prêt
-Comment[x-test]=xxTea is readyxx
 Sound=KDE_Notify.wav
 Action=Sound
-
Index: tea.h
===================================================================
--- tea.h	(revision 0)
+++ tea.h	(revision 0)
@@ -0,0 +1,102 @@
+/*
+   Copyright (c) 2007 Stefan Böhmann <ebrief@hilefoks.org>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.
+*/
+
+#ifndef TEA_H
+#define TEA_H
+
+#include <QString>
+
+#include <klocalizedstring.h>
+
+/**
+ * @short this class represent a tea.
+ *
+ * @author Stefan Böhmann <ebrief@hilefoks.org>
+ */
+class Tea {
+    public:
+         /**
+          * Constructs an tea.
+          * @param name the name of this tea.
+          * @param time the tea time in seconds.
+          */
+        inline Tea(const QString name=i18n("Anonymous Tea"), const unsigned \
time=180) : _name(name), _time(time) +        {
+        }
+
+        /**
+         * Returns the name of this tea.
+         *
+         * @return the name of this tea.
+         */
+        inline QString name() const {
+            return _name;
+        }
+
+        /**
+         * Returns the time for this tea in seconds.
+         *
+         * @return the time for this tea in seconds.
+         */
+        inline unsigned time() const {
+            return _time;
+        }
+
+        /**
+         * Returns the time for this tea as a @ref QString.
+         * @param longdesc if true return long names like  "5 minutes 30 seconds", \
else returns a short form like "5 min 30 s". +         *
+         * @return the time for this tea as a @ref QString.
+         */
+        inline QString timeToString(const bool longdesc=false) const {
+            return int2time(_time, longdesc);
+        }
+
+        /**
+         * Set the name of this the.
+         * @param name the new name for this tea.
+         */
+        inline void setName(const QString name) {
+            _name=name;
+        }
+
+        /**
+         * Set the time of this tea.
+         * @param time the new time for this tea in seconds.
+         */
+        inline void setTime(const unsigned time)	{
+            _time=time;
+        }
+
+        /**
+         * Returns a formatted @ref QString for the given time.
+         * @param time the time in seconds.
+         * @param longdesc if true return long names like  "5 minutes 30 seconds", \
else returns a short form like "5 min 30 s". +         *
+         * @return the formatted @ref QString.
+         */
+        static QString int2time(const int time, const bool longdesc=false);
+
+    private:
+        QString _name;
+        unsigned _time;
+};
+
+#endif
+
Index: main.cpp
===================================================================
--- main.cpp	(revision 702652)
+++ main.cpp	(working copy)
@@ -1,60 +1,63 @@
 /*
- *   KTeaTime - A tea timer.
- *
- *   Copyright (C) 1998-1999  Matthias Hoelzer-Kluepfel (hoelzer@kde.org)
- *   Copyright (C) 2002-2003  Martin Willers (willers@xm-arts.de)
- *
- *   With contributions from Daniel Teske <teske@bigfoot.com>, and
- *   Jackson Dunstan <jdunstan@digipen.edu>
- *   (and possibly others, as well)
- *
- *   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.
- *
- */
+   Copyright (c) 2007 Stefan Böhmann <ebrief@hilefoks.org>
 
-#include <kwindowsystem.h>
-#include <kstartupinfo.h>
-#include <kcmdlineargs.h>
-#include <kaboutdata.h>
-#include <klocale.h>
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.
+*/
+
 #include "toplevel.h"
-#include <kapplication.h>
 
-static const char description[] =
-    I18N_NOOP("KDE utility for making a fine cup of tea");
+#include <KApplication>
+#include <KAboutData>
+#include <KCmdLineArgs>
 
-static const char version[] = "v1.1.0";
+#include <iostream>
 
-int main(int argc, char *argv[])
+static const char description[] = I18N_NOOP("KDE utility for making a fine cup of \
tea."); +
+static const char version[] = "v1.2.0";
+
+
+int main (int argc, char *argv[])
 {
-  KAboutData aboutData( "kteatime", 0, ki18n("KTeaTime"),
-    version, ki18n(description), KAboutData::License_GPL,
-    ki18n("(c) 1998-1999, Matthias Hoelzer-Kluepfel\n(c) 2002-2003, Martin \
                Willers"));
-  aboutData.addAuthor(ki18n("Matthias Hoelzer-Kluepfel"),KLocalizedString(), \
                "hoelzer@kde.org");
-  aboutData.addAuthor(ki18n("Martin Willers"), KLocalizedString(), \
                "willers@xm-arts.de");
-  aboutData.addCredit(ki18n("Daniel Teske"), ki18n("Many patches"), \
                "teske@bigfoot.com");
-  KCmdLineArgs::init( argc, argv, &aboutData );
+    KAboutData aboutData( "kteatime", 0, ki18n("KTeaTime"), version, \
ki18n(description), KAboutData::License_GPL, +        ki18n("(c) 1998-1999, Matthias \
Hoelzer-Kluepfel\n(c) 2002-2003, Martin Willers\n(c) 2007, Stefan Böhmann")); +    \
aboutData.addAuthor(ki18n("Matthias Hoelzer-Kluepfel"), KLocalizedString(), \
"hoelzer@kde.org"); +    aboutData.addAuthor(ki18n("Martin Willers"), \
KLocalizedString(), "willers@xm-arts.de"); +    aboutData.addAuthor(ki18n("Stefan \
Böhmann"), KLocalizedString(), "ebrief@hilefoks.org"); +    \
aboutData.addCredit(ki18n("Daniel Teske"), ki18n("Many patches"), \
"teske@bigfoot.com");  
-  KApplication app;
+    KCmdLineArgs::init( argc, argv, &aboutData );
 
-  TopLevel toplevel;
-  // KWindowSystem::setSystemTrayWindowFor(toplevel.winId(), 0);
-  toplevel.show();
+    KCmdLineOptions options;
+    options.add("a <seconds>", ki18n("Start a new anonymous tea"));
+    KCmdLineArgs::addCmdLineOptions(options);
 
-  //app.setTopWidget(&toplevel);
-  KStartupInfo::appStarted();
+    KApplication app;
 
-  return app.exec();
+    KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+
+    TopLevel *toplevel=new TopLevel(&aboutData);
+    if(args->isSet("a")) {
+        int time=args->getOption("a").toInt();
+        if(time>0)
+            toplevel->runTea(Tea(i18n("Anonymous Tea"), time));
+    }
+    args->clear();
+
+    toplevel->show();
+
+    return app.exec();
 }
Index: TODO
===================================================================
--- TODO	(revision 702652)
+++ TODO	(working copy)
@@ -1,58 +1,5 @@
-- create SVG icon(s) (or at least a 32x32 version for "About KTeaTime")
-- Rename "shooting"
-- Rename "Event" to "Notification"
-- nicer placement of "Configure events" button:
-  "Configure Events..." --> move to same line as "Event" and rename to \
                "Configure..."?
-  (and/or have a look at KStdAction::configureNotifications()!)
-  (common is "Configure &Notifications..." btw.)
-   [which gets translated in kdelibs.ps to "&Benachrichtigungen festlegen..."]
-   [[more often, "einrichten" is used for "configure"]]
-- use "readPathEntry()" instead of "readEntry()" (expands/replaces $HOME)
-
-- have a look at memory consumption; seems too high for me..
-- adapt kteatime.docbook to new century...
-- save default time for "anonymous" to config
-- in configure-window: add "Execute: "-label in front of "action"-text edit
-- KNotifyClient: "Execute" not capable of %t substitution?
-  (--> hence no replacement for my own "Execute: " action)
-- KNotifyClient: passive popup cannot(?) have no timeout
-  (--> hence no replacement for my own "Popup" action)
-- when steeping, display "stop <teaname>" on left-click, not just "stop"
-  (not easy when using KAction in a simple way?)
-- use QMovie for tea-is-finished-icon instead of two alternating pixmaps?
-
-
-internals:
-- 'int2time()' somewhere into class-namespace? (ie. not as global function)
-- do kapp->closeAllWindows() on slotFileQuit() ?
-- when in "ready"-state, left-click -> auto-go to initial state
-  before opening left-click menu(?)
-- remember geometry of config-dialog (and its QListView!)
-  (or at least: x-maximize QListView's titles)
-- somehow make double-click with left button start 'current' tea
-  without displaying start_menu?
-- figure out how to use KAction for "quit"-entry of menu
-  (somehow doesn't work as expected..)
-- some more tidying of configure-dialog
-  (eg. initial position!, initial size)
-- DCOP interface?
-- have a closer look at i18n-dos and -donts
-- use XML-UI
+- find and fix bugs
+- figure out how to use KAction for "quit" ant "Help" entry of menu
 - check for memory leaks
-- make config-reading bullet-proof
+- category support (wish #92158) and different icons for it (wish #89600)
 
-
----- new approach:
-
-- make it a generalized timer-application (with better UI than KTimer)
-  (think: cooking spaghetti, watch TV-show, etc.)
-
-  - This needs another approach to entering timeouts, since they'll often be
-    needed just once -> eg. popup "Enter timeout:"-window on leftclick?
-  - Must be able to run arbitrary amounts of parallel timers!
-    (difficult to use 'useTrayVis' then..)
-  - Should be able to enter timeouts not just as seconds, but in any unit.
-  - option for "popup reminder every X minutes"
-  - Allow periodical timouts (eg. "Take this medication every 2 hours")
-    (if not clicked away, add count to window)
---> better start new application and let people migrate to it from KTeaTime
Index: tealistmodel.cpp
===================================================================
--- tealistmodel.cpp	(revision 0)
+++ tealistmodel.cpp	(revision 0)
@@ -0,0 +1,135 @@
+/*
+   Copyright (c) 2007 Stefan Böhmann <ebrief@hilefoks.org>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.
+*/
+
+#include "tealistmodel.h"
+#include "tea.h"
+
+#include <klocalizedstring.h>
+
+
+TeaListModel::TeaListModel(QList<Tea> &teas, QObject *parent) : \
QAbstractTableModel(parent), tealist(teas) +{
+}
+
+
+QModelIndex TeaListModel::index(int row, int column, const QModelIndex &parent) \
const +{
+    Q_UNUSED(parent);
+    return createIndex(row, column);
+}
+
+
+int TeaListModel::rowCount(const QModelIndex &parent) const
+{
+    Q_UNUSED(parent);
+    return tealist.size();
+}
+
+
+int TeaListModel::columnCount(const QModelIndex &parent) const
+{
+    Q_UNUSED(parent);
+    return 2;
+}
+
+
+QVariant TeaListModel::data(const QModelIndex &index, int role) const
+{
+    if(!index.isValid())
+        return QVariant();
+
+    if(role==Qt::DisplayRole) {
+        if(index.column()==0)
+            return QVariant(tealist.at(index.row()).name());
+        return QVariant(tealist.at(index.row()).timeToString());
+    }
+
+    if(role==Qt::EditRole) {
+        if(index.column()==0)
+            return QVariant(tealist.at(index.row()).name());
+        return QVariant(tealist.at(index.row()).time());
+    }
+
+    if(role==Qt::ToolTipRole) {
+        QString s(tealist.at(index.row()).name());
+        s.append(i18n(" ("));
+        s.append(tealist.at(index.row()).timeToString(true));
+        s.append(i18n(")"));
+        return QVariant(s);
+    }
+
+    if(role==Qt::WhatsThisRole)
+        return QVariant(i18n("This is the list of teas."));
+
+    return QVariant();
+}
+
+
+bool TeaListModel::setData(const QModelIndex &index, const QVariant &value, int \
role) +{
+    if(index.isValid() && (role==Qt::EditRole || role==Qt::DisplayRole)) {
+        if(index.column()==0) {
+            tealist[index.row()].setName(value.toString());
+        } else if(index.column()==1) {
+            tealist[index.row()].setTime(value.toUInt());
+        }
+        emit dataChanged(index, index);
+        return true;
+    }
+    return false;
+}
+
+
+QVariant TeaListModel::headerData(int section, Qt::Orientation orientation, int \
role) const +{
+    if(orientation==Qt::Horizontal) {
+        if(role==Qt::DisplayRole)
+            return QVariant(section==0?i18n("Name"):i18n("Time"));
+    }
+    return QAbstractTableModel::headerData(section, orientation, role);
+}
+
+
+bool TeaListModel::insertRows(int row, int count, const QModelIndex &parent)
+{
+    Q_UNUSED(parent);
+    beginInsertRows(QModelIndex(), row, row+count-1);
+    for(int i=0; i<count; ++i)
+        tealist.insert(row, Tea(i18n("Unnamed Tea"), 180));
+
+    endInsertRows();
+    return true;
+}
+
+
+bool TeaListModel::removeRows(int row, int count, const QModelIndex &parent)
+{
+    Q_UNUSED(parent);
+    if(row-count>tealist.size())
+        return false;
+
+    beginRemoveRows(QModelIndex(), row, row+count-1);
+    for(int i=0; i<count; ++i)
+        tealist.removeAt(row);
+
+    endRemoveRows();
+
+    return true;
+}
+
Index: toplevel.cpp
===================================================================
--- toplevel.cpp	(revision 702652)
+++ toplevel.cpp	(working copy)
@@ -1,865 +1,306 @@
 /*
- *   This file is part of the KTeaTime application.
- *
- *   Copyright (C) 1998-1999  Matthias Hoelzer-Kluepfel (hoelzer@kde.org)
- *   Copyright (C) 2002-2003  Martin Willers (willers@xm-arts.de)
- *
- *   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.
- *
- */
+   Copyright (c) 2007 Stefan Böhmann <ebrief@hilefoks.org>
 
-#include "toplevel.h"
-#include "tealist.h"
-#include "timeedit.h"
-#include "toplevel.moc"
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
 
-#include <stdlib.h>
-#include <assert.h>
+   This library 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
+   Library General Public License for more details.
 
-#include <qcheckbox.h>
-#include <qlayout.h>
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.
+*/
 
-#include <qlineedit.h>
-#include <qpainter.h>
+#include "toplevel.h"
+#include "timeedit.h"
+#include "settings.h"
+#include "tea.h"
 
-#include <qfile.h>
-#include <qcursor.h>
-#include <qpushbutton.h>
-#include <q3groupbox.h>
-#include <q3header.h>
-#include <qpixmap.h>
-#include <qbitmap.h>
-#include <knotifyconfigwidget.h>
-#include <kapplication.h>
-#include <QGridLayout>
-//Added by qt3to4:
-#include <QPaintEvent>
-#include <QBoxLayout>
-#include <QHBoxLayout>
-#include <QLabel>
-#include <QTimerEvent>
-#include <QVBoxLayout>
-#include <QMouseEvent>
-#include <QAbstractEventDispatcher>
-#include <kconfig.h>
-#include <khelpmenu.h>
-#include <kiconloader.h>
-#include <klocale.h>
-#include <kmessagebox.h>
-#include <kpassivepopup.h>
-#include <knuminput.h>
-#include <kseparator.h>
-#include <kmenu.h>
-#include <kdialog.h>
-#include <kaction.h>
-#include <kactioncollection.h>
-#include <ktoolinvocation.h>
-#include <kglobal.h>
-#include <kicon.h>
-#include <Q3ListViewItem>
+#include <QString>
+#include <QAction>
+#include <QTimer>
+#include <QPainter>
+#include <QBrush>
 
-const int TopLevel::DEFAULT_TEA_TIME = 3*60;
+#include <KMenu>
+#include <KActionCollection>
+#include <KHelpMenu>
+#include <KPassivePopup>
+#include <KGlobalSettings>
+#include <KNotification>
+#include <KAboutData>
+#include <iostream>
 
 
-TopLevel::TopLevel() : KSystemTrayIcon()
+TopLevel::TopLevel(const KAboutData *aboutData, const QString &icon, QWidget \
*parent) : +     KSystemTrayIcon(loadIcon(icon),parent), runningTeaTime(0), \
_icon(loadIcon(icon))  {
-        QString n, key;
-	unsigned int num;
+    timer = new QTimer(this);
+    connect(timer, SIGNAL(timeout()), this, SLOT(timerEvent()));
 
-	teas.clear();
+    popup = new KPassivePopup();
+    popup->setAutoDelete(false);
 
-	KConfigGroup config(KGlobal::config(), "Teas");
+    stopAct = new QAction("stop", this);
+    stopAct->setIcon(KIcon("arrow-right"));
+    stopAct->setText(i18n("&Stop"));
+    stopAct->setEnabled(false);
 
-	if (config.hasKey("Number")) {
-		// assuming this is a new-style config
-		num = config.readEntry("Number", 0);
-		teas.resize(num);
-		QString tempstr;
-		for (unsigned int index=1; index<=num; ++index) {
-			key.sprintf("Tea%d Time", index);
-			tempstr = config.readEntry(key, QString());
-			teas[index-1].time = tempstr.toInt();
-  			key.sprintf("Tea%d Name", index);
-			teas[index-1].name = config.readEntry(key, QString());
-			// FIXME: check for non-existence!
-  		}
-		config.changeGroup("General");
-	} else {
-		// either old-style config or first start, so provide some sensible defaults
-		// (which are the same as in old-style kteatime)
-		tea_struct temp;
-		temp.name = i18n("Black Tea");
-		temp.time = 180;
-		teas.append(temp);
-		temp.name = i18n("Earl Grey");
-		temp.time = 300;
-		teas.append(temp);
-		temp.name = i18n("Fruit Tea");
-		temp.time = 480;
-		teas.append(temp);
+    confAct = new QAction("configure", this);
+    confAct->setIcon(KIcon("configure"));
+    confAct->setText(i18n("&Configure..."));
 
-		// switch back to old-style default group
-		config.changeGroup(QString());
-		// look for old-style "UserTea"-entry and add that one also
-		if (config.hasKey("UserTea")) {
-			num = config.readEntry("UserTea", 150);
-			temp.name = i18n("Other Tea");
-			temp.time = num;
-			teas.append(temp);
-		}
-	}
-	current_selected = config.readEntry("Tea", 0);
-	if (current_selected >= teas.count())
-		current_selected = 0;
+    anonAct = new QAction("anonymous", this);
+    anonAct->setText(i18n("&Anonymous..."));
 
-	listempty = (teas.count() == 0);
+    exitAct = actionCollection()->action(KStandardAction::name(KStandardAction::Quit));
  
-	startAct = actionCollection()->addAction("start");
-	startAct->setIcon(KIcon("arrow-right"));
-	startAct->setText(i18n("&Start"));
-	connect(startAct, SIGNAL(triggered(bool)), SLOT(start()));
-	stopAct = actionCollection()->addAction("stop");
-	stopAct->setIcon(KIcon("cancel"));
-	stopAct->setText(i18n("Sto&p"));
-	connect(stopAct, SIGNAL(triggered(bool)), SLOT(stop()));
-	confAct = actionCollection()->addAction("configure");
-	confAct->setIcon(KIcon("configure"));
-	confAct->setText(i18n("&Configure..."));
-	connect(confAct, SIGNAL(triggered(bool)), SLOT(config()));
-	anonAct = actionCollection()->addAction("anonymous");
-	anonAct->setText(i18n("&Anonymous..."));
-	connect(anonAct, SIGNAL(triggered(bool)), SLOT(anonymous()));
-//	KAction *quitAct = actionCollection()->action("file_quit");
 
-        connect( this, SIGNAL( activated( QSystemTrayIcon::ActivationReason ) ),
-                 SLOT( slotActivated( QSystemTrayIcon::ActivationReason ) ) );
+    helpMenu = new KHelpMenu(0, aboutData, false);
+    //FIXME KSystemTrayIcon isn't a QWidget so the dialogs from KHelpMenu terminate \
KTeaTime.  
-	// create app menu (displayed on right-click)
-	menu = new QMenu();
-	connect(menu, SIGNAL(activated(int)), this, SLOT(teaSelected(int)));
 
-	// this menu will be displayed when no tea is steeping, and left mouse button is \
                clicked
-	start_menu = new QMenu();
-	connect(start_menu, SIGNAL(activated(int)), this, SLOT(teaStartSelected(int)));
+    KSharedConfigPtr config = KSharedConfig::openConfig();
+    KConfigGroup tealistGroup(config, "Tealist");
 
-	rebuildTeaMenus();      // populate tops of menus with tea-entries from config
+    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()) +                \
teas.append(Tea(tealistGroup.readEntry(key, i18n("Unknown Tea")), temp)); +        }
+    }
+    // If the list of teas is empty insert a set of default teas.
+    if(teas.isEmpty()) {
+        teas.append(Tea(i18n("Black Tea"), 180));
+        teas.append(Tea(i18n("Earl Grey"), 300));
+        teas.append(Tea(i18n("Fruit Tea"), 480));
+    }
 
-	KHelpMenu* help = new KHelpMenu(0, KGlobal::mainComponent().aboutData(), false);
-	KMenu* helpMnu = help->menu();
+    loadConfig();
+    rebuildMenus();
 
-	start_menu->addSeparator();
-	start_menu->addAction( anonAct );
-
-	menu->addSeparator();
-	menu->addAction( anonAct );
-	menu->addAction( startAct );
-	menu->addAction( stopAct );
-	menu->addSeparator();
-	menu->addAction( confAct );
-        helpMnu->setIcon( SmallIcon("help-contents") );
-        helpMnu->setTitle( i18n("&Help") );
-	menu->addMenu(helpMnu);
-	menu->insertItem(SmallIcon("application-exit"), i18n("Quit"), kapp, SLOT(quit()));
-//	quitAct->plug(menu);    // FIXME: this doesn't seem to work with above definition \
                of quitAct?
-	                        //        (need special 'quit'-method?)
-
-	// this menu will be displayed when a tea is steeping, and left mouse button is \
                clicked
-	steeping_menu = new QMenu();
-//	steeping_menu->insertItem(SmallIcon("cancel"), i18n("Just &Cancel Current"), \
                this, SLOT(stop()));
-	steeping_menu->addAction( stopAct );   // FIXME: can provide different text for \
                this incarnation?
-
-//	start_menu->insertSeparator();
-//	startAct->plug(start_menu);     // FIXME: include "start" entry here for quick \
                access to current tea?
-
-	// read remaining entries from config-file
-	useNotify = config.readEntry("Beep", true);    // "Beep" should really be named \
                "Notify"
-	usePopup = config.readEntry("Popup", false );
-	useAction = config.readEntry("UseAction", false);
-	action = config.readEntry("Action");
-	useTrayVis = config.readEntry("UseTrayVis", true);
-
-	mugPixmap = loadIcon("mug").pixmap();
-	teaNotReadyPixmap = loadIcon("tea_not_ready").pixmap();
-	teaAnim1Pixmap = loadIcon("tea_anim1").pixmap();
-	teaAnim2Pixmap = loadIcon("tea_anim2").pixmap();
-
-	confdlg = 0L;
-	anondlg = 0L;
-
-	stop();                         // reset timer, disable some menu entries, etc.
+    connect(stopAct, SIGNAL(triggered(bool)), this, SLOT(cancelTea()));
+    connect(confAct, SIGNAL(triggered(bool)), this, SLOT(showSettingsDialog()));
+    connect(anonAct, SIGNAL(triggered(bool)), this, SLOT(showTimeEditDialog()));
+    connect(contextMenu(), SIGNAL(triggered(QAction*)), this, \
SLOT(runTea(QAction*))); +    connect(this, \
SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, \
SLOT(showPopup(QSystemTrayIcon::ActivationReason)));  }
 
-/* slot: signal shutDown() from KApplication */
-/* (not currently needed)
-void TopLevel::queryExit()
-{
-	KSharedConfig::Ptr config = KGlobal::config();
-//	config.sync();
-}
-*/
 
-
-/** Destructor */
 TopLevel::~TopLevel()
 {
-	delete menu;
-	delete steeping_menu;
-	delete start_menu;
-	// FIXME: must delete more (like all the QWidgets in config-window)?
+    delete helpMenu;
+    delete timer;
+    delete popup;
 }
 
 
-/** Handle mousePressEvent */
-void TopLevel::slotActivated(QSystemTrayIcon::ActivationReason reason)
+void TopLevel::rebuildMenus()
 {
-	if (reason == Trigger )
-        {
-		if (ready) {
-			stop();                         // reset tooltip and stop animation
-		} else {
-			if (running)
-				steeping_menu->popup(QCursor::pos());
-			else
-				start_menu->popup(QCursor::pos());
-		}
-	}
-}
+    contextMenu()->clear();
 
-void TopLevel::repaint()
-{
-	QPixmap *pm = &mugPixmap;
+    (static_cast<KMenu*>(contextMenu()))->addTitle( qApp->windowIcon(), \
KGlobal::caption() );  
-	if (running) {
-		if (useTrayVis)
-			pm = &teaAnim1Pixmap;                            // this is 'mugPixmap' plus \
                brown content
-		else
-			pm = &teaNotReadyPixmap;                         // generic "steeping" icon
-	} else {
-		// use simple two-frame "animation"
-		// FIXME: how about using a QMovie instead? (eg. MNG)
-		if (ready) {
-			if (firstFrame)
-				pm = &teaAnim1Pixmap;
-			else
-				pm = &teaAnim2Pixmap;
-		}
-	}
+    bool state=runningTeaTime!=0;
 
-	// overlay pie chart onto tray icon
-	QPixmap base(*pm);                                      // make copy of base pixmap
-	if (useTrayVis && running) {
-		// extend mask
-		QBitmap mask = (base.mask());
-		QPainter pm(&mask);
-		pm.setBrush(Qt::color1);                            // fill with \
                "foreground-colour"
-		pm.setPen(Qt::NoPen);                               // no border needed/wanted
-		pm.drawPie(0+1, 9+1, 11, 11, 90*16, -360*16);       // full circle of small size
-		pm.drawPie(0, 9, 13, 13, 90*16, percentDone*16);    // pie part of big size
-		pm.end();
-		base.setMask(mask);
+    foreach(Tea t, teas) {
+        QString s;
+        s.append(t.name());
+        s.append(i18n(" ("));
+        s.append(t.timeToString());
+        s.append(i18n(")"));
+        QAction *a=contextMenu()->addAction(s);
+        a->setData(t.name());
 
-		// draw pie chart
-		QPainter px(&base);
-		px.setPen(QPen(Qt::black, 0));                      // black border
-		px.setBrush(QColor(192, 0, 0));                     // red fill colour for small \
                circle
-		px.drawPie(0+1, 9+1, 11, 11, 90*16, -360*16);
+        if(state) a->setEnabled(false);
+    }
 
-		px.setBrush(QColor(0, 192, 0));                     // green fill colour for pie \
                part
-		px.drawPie(0, 9, 13, 13, 90*16, percentDone*16);
-		px.end();
-	}
-	// FIXME: over-emphasize first and last few percent? (for better visibility)
-	// FIXME: some optimizations (eg. store pre-drawn QPixmap with small circle)
-	//        (and use drawEllipse() instead of drawPie() for small circle!)
+    contextMenu()->addSeparator();
+    contextMenu()->addAction(stopAct);
+    contextMenu()->addAction(anonAct);
+    contextMenu()->addSeparator();
+    contextMenu()->addAction(confAct);
+    contextMenu()->addMenu(helpMenu->menu());
+    contextMenu()->addAction(exitAct);
 
-        setIcon( *pm );
-}
+    stopAct->setEnabled(state);
+    confAct->setEnabled(!state);
+    anonAct->setEnabled(!state);
 
-/** Check timer and initiate appropriate action if finished */
-void TopLevel::timerEvent(QTimerEvent *)
-{
-	if (running) {
-		// a tea is steeping; must count down
-		seconds--;
-
-		if (seconds <= 0) {
-			// timer has run out; notify user
-			running = false;
-			ready = true;
-			enable_menuEntries();
-			if (shooting) {
-				// re-check current tea
-				shooting = false;
-				if (!listempty)
-					menu->setItemChecked(current_selected, true);
-			}
-
-			QString teaMessage = i18n("The %1 is now ready!", current_name);
-			// invoke action
-			if (useNotify) {
-#ifdef __GNUC__
-#warning KSystemTrayIcon is no widget, consider using showMessage
-#endif
-                            //KNotifyClient::event(0, "tea", teaMessage);
-                            showMessage( i18n( "The Tea Cooker" ), teaMessage );
-			}
-			if (useAction && (!action.isEmpty())) {
-				QString cmd = action;
-				cmd.replace("%t", current_name);
-				system(QFile::encodeName(cmd));
-			}
-			if (usePopup)
-				KPassivePopup::message(i18n("The Tea Cooker"),
-				                       teaMessage, teaAnim1Pixmap, ( QWidget* )0, 0);
-				// FIXME: does auto-deletion work without timeout?
-			setToolTip(teaMessage);
-			repaint();
-		} else {
-			// timer not yet run out; just update tray-icon (if configured)...
-			if (useTrayVis) {
-				int pDone = (360 * (startSeconds - seconds)) / startSeconds;
-				if (pDone - percentDone > 8) {
-					// update icon not every second, but only if somewhat noticeable
-					percentDone = pDone;
-					repaint();
-				}
-			}
-			// ...and Tooltip
-			QString min = int2time(seconds);
-			setToolTip(i18n("%1 left for %2", min, current_name));
-		}
-	} else {
-		// no tea is steeping; just animate icon
-		if (ready) {
-			firstFrame = !firstFrame;
-			repaint();
-		}
-	}
+    if(!state) {
+        popup->setView(i18n("The Tea Cooler"), i18n("No running tea."));
+        setToolTip(i18n("The Tea Cooker"));
+    }
 }
 
-/** add all configured teas to both menus */
-void TopLevel::rebuildTeaMenus() {
-	// first remove all current tea-entries from menus; these can be identified by \
                their positive id
-	while (menu->idAt(0) >= 0)
-		menu->removeItemAt(0);          // remove from right-click menu
-	while (start_menu->idAt(0) >= 0)
-		start_menu->removeItemAt(0);    // remove from left-click menu
 
-	// now add new tea-entries to top of menus
-	int id = 0;
-	int index = 0;
-	for (QVector<tea_struct>::ConstIterator it=teas.begin(); it != teas.end(); ++it) {
-		// construct string with name and steeping time
-		QString str = it->name;
-		str.append(" (");
-		str.append(int2time(it->time));
-		str.append(")");
-
-		start_menu->insertItem(str, id, index);     // add to left-click menu
-		menu->insertItem(str, id++, index++);       // add to right-click menu
-	}
-
-	// now select 'current' tea
-	if (!listempty)
-		menu->setItemChecked(current_selected, true);   // all others aren't checked,
-		                                                // because we just added them
-
-        setContextMenu( menu );
-}
-
-/* enable/disable menu-entries according to current running-state */
-void TopLevel::enable_menuEntries()
+void TopLevel::showSettingsDialog()
 {
-	for (int index=0; menu->idAt(index) >= 0; ++index) {
-		// [en|dis]able all tea-entries (all have positive menu-ids)
-		menu->setItemEnabled(menu->idAt(index), !running);
-	}
-
-	startAct->setEnabled(!running);     // "start" entry
-	stopAct->setEnabled(running);       // "stop" entry
-	confAct->setEnabled(!running);      // "configuration" entry
-	anonAct->setEnabled(!running);      // "anonymous" entry
+    (new SettingsDialog(this, teas))->exec();
 }
 
-/* menu-slot: tea selected in tea-menu */
-void TopLevel::teaSelected(int index)
-{
-	if (index >=0 && index < teas.count()) {
-		// tick new active item in menu
-		menu->setItemChecked(current_selected, false);
-		menu->setItemChecked(index, true);
 
-		current_selected = index;
-		KConfigGroup config( KGlobal::config(), "General");
-		config.writeEntry("Tea", current_selected);
-	}
-	// all other entries of this menu have custom handlers
-}
-
-/* start_menu-slot: tea selected (and activated!) in tea-menu */
-void TopLevel::teaStartSelected(int index)
+void TopLevel::showTimeEditDialog()
 {
-	if (index >=0 && index < teas.count()) {
-		teaSelected(index);
-
-		start();
-	}
+    (new TimeEditDialog(this))->exec();
 }
 
-/* menu-slot: "start" selected in menu */
-void TopLevel::start()
-{
-	if (listempty && !shooting) {
-		KMessageBox::error(0, i18n("There is no tea to begin steeping."), i18n("No Tea"));
-	} else {
-		if (!shooting) {
-			current_name = teas[current_selected].name;     // remember name of current tea
-			startSeconds = teas[current_selected].time;     // initialize time for current \
                tea
-			seconds = startSeconds;
-			percentDone = 0;
-		}
-		// else both are already defined by dialog handler
 
-		QAbstractEventDispatcher::instance()->unregisterTimers(this);
-		startTimer(1000);                               // 1000ms = 1s (sufficient \
                resolution)
-
-		running = true;
-		ready = false;
-		enable_menuEntries();                           // disable "start", enable "stop"
-
-		repaint();
-	}
-}
-
-/* menu-slot: "stop" selected in menu */
-void TopLevel::stop()
+void TopLevel::runTea(QAction *a)
 {
-	QAbstractEventDispatcher::instance()->unregisterTimers(this);
+    QString currname=a->data().toString();
 
-	running = false;
-	ready = false;
-	enable_menuEntries();                               // disable "top", enable \
                "start"
-	if (shooting) {
-		// re-check current tea
-		shooting = false;
-		if (!listempty)
-			menu->setItemChecked(current_selected, true);
-	}
+    if(currname.isEmpty())
+        return;
 
-	setToolTip(i18n("The Tea Cooker"));
-	repaint();
+    foreach(Tea t, teas) {
+        if(t.name()==currname) {
+            runTea(t);
+            return;
+        }
+    }
 }
 
-/* open dialog to start an 'anonymous' tea */
-void TopLevel::anonymous()
-{
-	if (!anondlg) {
-		// FIXME: dialog appears centered on screen, but should be near systray icon!
-		anondlg = new KDialog(0);
-                anondlg->setCaption( i18n("Anonymous Tea") );
-                anondlg->setButtons( KDialog::Ok | KDialog::Cancel );
-                anondlg->setDefaultButton( KDialog::Ok );
-                anondlg->setModal( true );
 
-                KHBox *page = new KHBox( anondlg );
-                anondlg->setMainWidget( page );
-
-                new QLabel(anon_time, i18n("Tea time:"), page);
-		anon_time = new TimeEdit(page);
-		anon_time->setFixedHeight(anon_time->sizeHint().height());
-		anon_time->setValue(DEFAULT_TEA_TIME);
-
-		anon_time->setFocus();
-	} else {
-		// FIXME: do what here?
-		// reset time to DEFAULT_TEA_TIME?
-		// (why? - better use LRU, and save that to config)
-	}
-
-	if (anondlg->exec() == QDialog::Accepted) {
-		shooting = true;
-		if (!listempty)
-			menu->setItemChecked(current_selected, false);  // no item is to be checked
-		current_name = i18n("tea");                         // some generic tea name
-		startSeconds = anon_time->value();
-		seconds = startSeconds;
-		percentDone = 0;
-		start();
-	}
+void TopLevel::runTea(Tea tea)
+{
+    runningTea=tea;
+    runningTeaTime=runningTea.time();
+    rebuildMenus();
+    timer->start(1000);
 }
 
 
+void TopLevel::repaintTrayIcon()
+{
+    if(runningTeaTime==0) {
+        setIcon(_icon);
+    } else {
+        QPixmap ico=_icon.pixmap(QSize(22, 22));
 
+        QPainter p(&ico);
 
-//
-// Configure-window handling
-//
-
-
-/* enable/disable buttons for editing listbox */
-void TopLevel::enable_controls() {
-	bool haveSelection = (listbox->currentItem() != 0);
-	bool amFirst = (listbox->currentItem() == listbox->firstChild());
-	bool amLast = true;
-	if (haveSelection)
-		amLast = (!listbox->currentItem()->itemBelow());   // itemBelow() returns returns \
                NULL if last
-
-	btn_del->setEnabled(haveSelection);
-	btn_up->setEnabled(haveSelection && !amFirst);
-	btn_down->setEnabled(haveSelection && !amLast);
-	if (haveSelection)
-		listbox->ensureItemVisible(listbox->currentItem());
+        if(runningTeaTime>0) {
+            double height=(geometry().height()/100.0)*(100.0/runningTea.time()*runningTeaTime);
 +            QRectF rectangle(geometry().width()-6, (int)height, 4, \
geometry().height()); +            p.drawRect(rectangle);
+            p.fillRect(rectangle, QBrush(Qt::red));
+        }
+        else {
+            p.setFont(QFont("Times", 20, QFont::Bold));
+            p.drawText((geometry().width()/2)-3, geometry().height(), "!");
+        }
+        setIcon(ico);
+    }
 }
 
-/* disable right side of configure-window */
-void TopLevel::disable_properties() {
-	editgroup->setEnabled(false);
-}
 
-/* enable right side of configure-window */
-void TopLevel::enable_properties() {
-	editgroup->setEnabled(true);
-}
+void TopLevel::timerEvent()
+{
+    if(runningTeaTime==0) {
+        timer->stop();
 
-/* config-slot: item in tea-list selected */
-void TopLevel::listBoxItemSelected() {
-	if (listbox->currentItem()) {
-		// item selected, display its properties on right side
-		nameEdit->setText(static_cast<TeaListItem *>(listbox->currentItem())->name());
-		timeEdit->setValue(static_cast<TeaListItem *>(listbox->currentItem())->time());
-		enable_controls();
-	}
-}
+        //NOTICE Timeout is set to ~24 days when no auto hide is request. Ok - \
nearly the same... +        if(usepopup)
+            showMessage(i18n("The Tea Cooker"), i18n("%1 is now ready!", \
runningTea.name()), QSystemTrayIcon::Information, autohide?autohidetime:2100000000);  \
                
-/* config-slot: name of a tea edited */
-void TopLevel::nameEditTextChanged(const QString& newText) {
-	/* this method also gets called when the last TeaListItem has been deleted
-	 * (to clear the name edit widget), so check for empty listbox */
-	if (listbox->currentItem() != NULL) {
-		listbox->blockSignals(true);
-		static_cast<TeaListItem *>(listbox->currentItem())->setName(newText);
-		listbox->blockSignals(false);
-	}
-}
+        if(usenotification) {
+            KNotification::event("tea", i18n("%1 is now ready!", \
runningTea.name())); +        }
 
-/* config-slot: time for a tea changed */
-void TopLevel::spinBoxValueChanged(int v) {
-	/* this method also gets called when the last TeaListItem has been deleted
-	 * (to clear the time edit widget), so check for empty listbox */
-	if (listbox->currentItem() != NULL)
-		static_cast<TeaListItem *>(listbox->currentItem())->setTime(v);
-}
+        if(usereminder && remindertime>0) {
+            popup->setView(i18n("The Tea Cooker"),  i18n("%1 is now ready!", \
runningTea.name())); +            setToolTip(i18n("%1 is now ready!", \
runningTea.name())); +            timer->start(remindertime*1000);
+            runningTeaTime-=remindertime;
+        }
+        rebuildMenus();
+    }
+    else if(runningTeaTime<0) {
+        QString s=i18n("%1 is ready since %2!", runningTea.name(), \
Tea::int2time(runningTeaTime*-1, true)); +        setToolTip(s);
+        popup->setView(i18n("The Tea Cooker"), s);
+        showMessage(i18n("The Tea Cooker"), s, QSystemTrayIcon::Information, \
autohide?autohidetime:2100000000); +        runningTeaTime-=remindertime;
+    }
+    else {
+        --runningTeaTime;
+        setToolTip(i18n("%1 left for %2.", Tea::int2time(runningTeaTime, true), \
runningTea.name())); +        popup->setView(i18n("The Tea Cooker"), i18n("%1 left \
for %2.", Tea::int2time(runningTeaTime, true), runningTea.name())); +    }
 
-/* config-slot: "new" button clicked */
-void TopLevel::newButtonClicked() {
-	TeaListItem* item = new TeaListItem(listbox, listbox->currentItem());
-	listbox->setCurrentItem(item);
-
-	nameEdit->setText(i18n("New Tea"));
-	timeEdit->setValue(DEFAULT_TEA_TIME);
-
-	nameEdit->setFocus();
-
-	if (listbox->childCount() == 1) {
-		enable_properties();
-		current_item = item;
-	}
-	enable_controls();
+    if(usevisualize)
+        emit repaintTrayIcon();
 }
 
-/* config-slot: "delete" button clicked */
-void TopLevel::delButtonClicked() {
-	if (listbox->currentItem()) {
-		TeaListItem *curritem = static_cast<TeaListItem *>(listbox->currentItem());
 
-		if (listbox->childCount() == 1) {
-			// no children left after we've deleted this item
-			listbox->setSelected(listbox->currentItem(), false);
-			nameEdit->setText("");
-			timeEdit->setValue(0);
-			disable_properties();
-		} else {
-			// select new current item
-			if (listbox->firstChild() != curritem)
-				listbox->setSelected(listbox->firstChild(), true);
-			else
-				listbox->setSelected(listbox->firstChild()->nextSibling(), true);
-		}
-
-		delete curritem;
-		enable_controls();
-	}
+void TopLevel::cancelTea()
+{
+    timer->stop();
+    runningTeaTime=0;
+    rebuildMenus();
+    if(usevisualize)
+        emit repaintTrayIcon();
 }
 
-/* config-slot: "up" button clicked */
-void TopLevel::upButtonClicked() {
-	Q3ListViewItem* item = listbox->currentItem();
 
-	if (item && item->itemAbove())
-		item->itemAbove()->moveItem(item);
+void TopLevel::loadConfig()
+{
+    KSharedConfigPtr config = KSharedConfig::openConfig();
+    KConfigGroup generalGroup(config, "General");
 
-	enable_controls();
+    usenotification=generalGroup.readEntry("UseNotification", true);
+    usepopup=generalGroup.readEntry("UsePopup", true);
+    autohide=generalGroup.readEntry("PopupAutoHide", false);
+    autohidetime=generalGroup.readEntry("PopupAutoHideTime", 30);
+    usereminder=generalGroup.readEntry("UseReminder", false);
+    remindertime=generalGroup.readEntry("ReminderTime", 60);
+    usevisualize=generalGroup.readEntry("UseVisualize", true);
 }
 
-/* config-slot: "down" button clicked */
-void TopLevel::downButtonClicked() {
-	Q3ListViewItem* item = listbox->currentItem();
 
-	if (item && item->itemBelow())
-		item->moveItem(item->itemBelow());
-
-	enable_controls();
+void TopLevel::showPopup(QSystemTrayIcon::ActivationReason reason) {
+    if(QSystemTrayIcon::Trigger==reason)
+        if(popup->isVisible())
+            popup->setVisible(false);
+        else
+            popup->show(calculatePopupPoint());
 }
 
-/* config-slot: checkbox next to "action" field toggled*/
-void TopLevel::actionEnableToggled(bool on)
-{
-	actionEdit->setEnabled(on);
-}
 
-/* config-slot: "help" button clicked */
-void TopLevel::help()
-{
-    KToolInvocation::invokeHelp();
-}
+QPoint TopLevel::calculatePopupPoint() {
+    QPoint pos=geometry().topLeft();
 
-/* config-slot: "Configure Events..." button clicked */
-void TopLevel::confButtonClicked()
-{
-	KNotifyConfigWidget::configure(btn_conf);
-}
+    int x=pos.x();
+    int y=pos.y();
+    int w=popup->minimumSizeHint().width();
+    int h=popup->minimumSizeHint().height();
 
+    QRect r=KGlobalSettings::desktopGeometry(QPoint(x+w/2,y+h/2));
 
-void TopLevel::config()
-{
-  if (!confdlg) {
-    confdlg = new KDialog(0);
-    confdlg->setCaption( i18n("Configure Tea Cooker") );
-    confdlg->setButtons( KDialog::Ok|KDialog::Cancel|KDialog::Help );
-    confdlg->setDefaultButton( KDialog::Ok );
+    if(x<r.center().x())
+        x+=geometry().width();
+    else
+        x-=w;
 
-    QWidget *page = new QWidget( 0 );
-    confdlg->setMainWidget( page );
-    // FIXME: enforce sensible initial/default size of dialog
-    // FIXME: modal is ok, but can avoid always-on-top?
+    if((y+h)>r.bottom())
+        y=r.bottom()-h;
 
-    QBoxLayout *top_box = new QVBoxLayout(page);    // whole config-stuff
-    top_box->setSpacing( 8 );
-    top_box->setMargin(0);
-    QBoxLayout *box = new QHBoxLayout();           // list + properties
-    box->setSpacing(8);
-    box->setMargin(0);
-    top_box->addItem( box );
+    if((x+w)>r.right())
+        x=r.right()-w;
 
-    /* left side - tea list and list-modifying buttons */
-    QBoxLayout *leftside = new QVBoxLayout();
-    leftside->setMargin(0);
-    box->addItem( leftside );
-    Q3GroupBox *listgroup = new Q3GroupBox(2, Qt::Vertical, i18n("Tea List"), page);
-    leftside->addWidget(listgroup, 0, 0);
+    if(y<r.top())
+        y=r.top();
 
-    listbox = new Q3ListView(listgroup, "listBox");
-    listbox->addColumn(i18n("Name"));
-    listbox->header()->setClickEnabled(false, listbox->header()->count()-1);
-    listbox->addColumn(i18n("Time"));
-    listbox->header()->setClickEnabled(false, listbox->header()->count()-1);
-    listbox->setSorting(-1);
-    connect(listbox, SIGNAL(selectionChanged()), SLOT(listBoxItemSelected()));
+    if(x<r.left())
+        x=r.left();
 
-    // now buttons for editing the tea-list
-    QWidget *listgroup_widget = new QWidget(listgroup);
-    QBoxLayout *hbox = new QHBoxLayout(listgroup_widget);
-    hbox->setMargin(0);
-    hbox->setSpacing(4);
-    btn_new = new QPushButton(listgroup_widget);
-    btn_new->setToolTip( i18n("New"));
-    btn_new->setPixmap(SmallIcon("document-new"));
-    connect(btn_new, SIGNAL(clicked()), SLOT(newButtonClicked()));
-    hbox->addWidget(btn_new);
-
-    btn_del = new QPushButton(listgroup_widget);
-    btn_del->setToolTip( i18n("Delete"));
-    btn_del->setIcon(KIcon("edit-delete"));
-    connect(btn_del, SIGNAL(clicked()), SLOT(delButtonClicked()));
-    hbox->addWidget(btn_del);
-
-    btn_up = new QPushButton(listgroup_widget);
-    btn_up->setToolTip( i18n("Up"));
-    btn_up->setIcon(KIcon("go-up"));
-    connect(btn_up, SIGNAL(clicked()), SLOT(upButtonClicked()));
-    hbox->addWidget(btn_up);
-
-    btn_down = new QPushButton(listgroup_widget);
-    btn_down->setToolTip( i18n("Down"));
-    btn_down->setIcon(KIcon("go-down"));
-    connect(btn_down, SIGNAL(clicked()), SLOT(downButtonClicked()));
-    hbox->addWidget(btn_down);
-
-    hbox->addStretch(10);
-
-    /* right side - tea properties */
-    QBoxLayout *rightside = new QVBoxLayout();
-    rightside->setMargin(0);
-    box->addItem( rightside );
-    editgroup = new Q3GroupBox(2, Qt::Vertical, i18n("Tea Properties"), page);
-    rightside->addWidget(editgroup);
-    QWidget *propbox = new QWidget(editgroup);
-    QGridLayout *gridLayout1 = new QGridLayout();
-    propbox->setLayout(gridLayout1);
-    QLabel *l = new QLabel(nameEdit, i18n("Name:"));
-    l->setFixedSize(l->sizeHint());
-    gridLayout1->addWidget(l, 0, 0);
-    nameEdit = new QLineEdit;
-    nameEdit->setFixedHeight(nameEdit->sizeHint().height());
-    gridLayout1->addWidget(nameEdit, 0, 1, Qt::AlignLeft);
-    connect(nameEdit, SIGNAL(textChanged(const QString&)), \
                SLOT(nameEditTextChanged(const QString&)) );
-
-    l = new QLabel(timeEdit, i18n("Tea time:"));
-    l->setFixedSize(l->sizeHint());
-    gridLayout1->addWidget(l, 1, 0);
-    timeEdit = new TimeEdit;
-    timeEdit->setFixedHeight(timeEdit->sizeHint().height());
-    gridLayout1->addWidget(timeEdit, 1, 1);
-    connect(timeEdit, SIGNAL(valueChanged(int)), SLOT(spinBoxValueChanged(int)));
-
-    /* bottom - timeout actions */
-    Q3GroupBox *actiongroup = new Q3GroupBox(4, Qt::Vertical, i18n("Action"), page);
-    top_box->addWidget(actiongroup);
-
-    QWidget *actionconf_widget = new QWidget(actiongroup);
-    QBoxLayout *actionconf_hbox = new QHBoxLayout(actionconf_widget);
-    actionconf_hbox->setMargin(0);
-    btn_conf = new QPushButton(i18n("Configure Events..."), actionconf_widget);
-    actionconf_hbox->addWidget(btn_conf);
-    connect(btn_conf, SIGNAL(clicked()), SLOT(confButtonClicked()));
-    actionconf_hbox->addStretch(10);
-
-    eventEnable = new QCheckBox(i18n("Event"), actiongroup);
-    popupEnable = new QCheckBox(i18n("Popup"), actiongroup);
-    eventEnable->setFixedHeight(eventEnable->sizeHint().height());
-    popupEnable->setFixedHeight(popupEnable->sizeHint().height());
-
-    QWidget *actionbox = new QWidget(actiongroup);
-    QHBoxLayout *hboxLayout6 = new QHBoxLayout;
-    hboxLayout6->setMargin(0);
-    actionbox->setLayout(hboxLayout6);
-    actionEnable = new QCheckBox( i18n( "Execute:" ), actionbox );
-    hboxLayout6->addWidget( actionEnable );
-    actionEdit = new QLineEdit;
-    hboxLayout6->addWidget( actionEdit );
-    actionbox->setLayout( hboxLayout6 );
-    actionEdit->setFixedHeight(actionEdit->sizeHint().height());
-    actionEdit->setToolTip( i18n("Enter command here; '%t' will be replaced with \
                name of steeping tea"));
-    connect(actionEnable, SIGNAL(toggled(bool)), SLOT(actionEnableToggled(bool)));
-    rightside->addStretch();
-
-    // single checkbox
-    visEnable = new QCheckBox(i18n("Visualize progress in icon tray"), page);
-    top_box->addWidget(visEnable, 0, 0);
-
-
-    // let listbox claim all remaining vertical space
-    top_box->setStretchFactor(box, 10);
-
-    connect(confdlg, SIGNAL(helpClicked()), SLOT(help()));
-  }
-
-  // now add all defined teas (and their times) to the listview
-  // this is done backwards because QListViewItems are inserted at the top
-  listbox->clear();
-  for (int i=teas.count()-1; i>=0; i--) {
-    TeaListItem *item = new TeaListItem(listbox);
-    item->setName(teas[i].name);
-    item->setTime(teas[i].time);
-    if (i == current_selected)
-      current_item = item;
-  }
-
-  // select first entry in listbox; if no entries present then disable right side
-  if (listempty) {
-    enable_controls();
-    disable_properties();
-    nameEdit->setText("");
-    timeEdit->setValue(1);
-  } else {
-    listbox->setSelected(listbox->firstChild(), true);
-  }
-
-  // -------------------------
-
-  eventEnable->setChecked(useNotify);
-  popupEnable->setChecked(usePopup);
-  actionEnable->setChecked(useAction);
-  actionEdit->setText(action);
-  actionEdit->setEnabled(useAction);
-  visEnable->setChecked(useTrayVis);
-
-  if (confdlg->exec() == QDialog::Accepted)
-  {
-    // activate new settings
-    useNotify = eventEnable->isChecked();
-    usePopup = popupEnable->isChecked();
-    useAction = actionEnable->isChecked();
-    action = actionEdit->text();
-    useTrayVis = visEnable->isChecked();
-
-    teas.clear();
-
-    // Copy over teas and times from the QListView
-    int i = 0;
-    teas.clear();
-    teas.resize(listbox->childCount());
-    for (Q3ListViewItemIterator it(listbox); it.current() != 0; ++it) {
-      teas[i].name = static_cast<TeaListItem *>(it.current())->name();
-      teas[i].time = static_cast<TeaListItem *>(it.current())->time();
-      if (it.current() == current_item)
-        current_selected = i;
-      i++;
-    }
-
-    listempty = (teas.count() == 0);
-
-    rebuildTeaMenus();
-
-    // and store to config
-    KConfigGroup config( KGlobal::config(), QString() );
-    // remove old-style entries from default-group (if present)
-    if (config.hasKey("UserTea"))
-      config.deleteEntry("UserTea");
-
-    config.changeGroup("General");
-    config.writeEntry("Beep", useNotify);
-    config.writeEntry("Popup", usePopup);
-    config.writeEntry("UseAction", useAction);
-    config.writeEntry("Action", action);
-    config.writeEntry("Tea", current_selected);
-    config.writeEntry("UseTrayVis", useTrayVis);
-    // first get rid of all previous tea-entries from config, then write anew
-    config.changeGroup( "Teas" );
-    config.deleteGroup();          // deep remove of whole group
-    config.writeEntry("Number", teas.count());
-    QString key;
-    int index = 1;
-    for (QVector<tea_struct>::ConstIterator it = teas.begin(); it != teas.end(); \
                ++it) {
-      key.sprintf("Tea%d Name", index);
-      config.writeEntry(key, it->name);
-      key.sprintf("Tea%d Time", index);
-      config.writeEntry(key, it->time);
-      index++;
-    }
-
-    config.sync();
-  }
+    return QPoint(x,y);
 }
Index: tealistmodel.h
===================================================================
--- tealistmodel.h	(revision 0)
+++ tealistmodel.h	(revision 0)
@@ -0,0 +1,132 @@
+/*
+   Copyright (c) 2007 Stefan Böhmann <ebrief@hilefoks.org>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.
+*/
+
+#ifndef TEALISTMODEL_H
+#define TEALISTMODEL_H
+
+#include <QAbstractTableModel>
+
+class Tea;
+
+/**
+ * @short provides an model used by SettingsDialog
+ *
+ * @author Stefan Böhmann <ebrief@hilefoks.org>
+ */
+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(QList<Tea> &teas, QObject *parent=0);
+
+        /**
+         * 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.
+         */
+        inline QList<Tea> getTeaList() const {
+            return tealist;
+        }
+
+    private:
+        QList<Tea> tealist;
+};
+
+#endif
Index: settings.ui
===================================================================
--- settings.ui	(revision 0)
+++ settings.ui	(revision 0)
@@ -0,0 +1,656 @@
+<ui version="4.0" >
+ <class>SettingsWidget</class>
+ <widget class="QWidget" name="SettingsWidget" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>536</width>
+    <height>514</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" >
+   <item>
+    <layout class="QHBoxLayout" >
+     <item>
+      <widget class="KButtonGroup" name="kbuttongroup1" >
+       <property name="title" >
+        <string>Tea List</string>
+       </property>
+       <layout class="QVBoxLayout" >
+        <property name="topMargin" >
+         <number>0</number>
+        </property>
+        <item>
+         <widget class="QTreeView" name="tealistTreeView" >
+          <property name="rootIsDecorated" >
+           <bool>false</bool>
+          </property>
+          <property name="itemsExpandable" >
+           <bool>false</bool>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <layout class="QHBoxLayout" >
+          <item>
+           <widget class="QToolButton" name="newButton" >
+            <property name="text" >
+             <string>N</string>
+            </property>
+            <property name="icon" >
+             <iconset/>
+            </property>
+            <property name="autoRaise" >
+             <bool>true</bool>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QToolButton" name="removeButton" >
+            <property name="enabled" >
+             <bool>true</bool>
+            </property>
+            <property name="text" >
+             <string>D</string>
+            </property>
+            <property name="autoRaise" >
+             <bool>true</bool>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QToolButton" name="upButton" >
+            <property name="enabled" >
+             <bool>true</bool>
+            </property>
+            <property name="text" >
+             <string>U</string>
+            </property>
+            <property name="autoRaise" >
+             <bool>true</bool>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QToolButton" name="downButton" >
+            <property name="enabled" >
+             <bool>true</bool>
+            </property>
+            <property name="autoFillBackground" >
+             <bool>false</bool>
+            </property>
+            <property name="text" >
+             <string>D</string>
+            </property>
+            <property name="icon" >
+             <iconset/>
+            </property>
+            <property name="autoRaise" >
+             <bool>true</bool>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <spacer>
+            <property name="orientation" >
+             <enum>Qt::Horizontal</enum>
+            </property>
+            <property name="sizeHint" >
+             <size>
+              <width>1</width>
+              <height>20</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+         </layout>
+        </item>
+       </layout>
+      </widget>
+     </item>
+     <item>
+      <layout class="QVBoxLayout" >
+       <item>
+        <widget class="QGroupBox" name="teaPropertiesGroup" >
+         <property name="enabled" >
+          <bool>false</bool>
+         </property>
+         <property name="title" >
+          <string>Tea Properties</string>
+         </property>
+         <layout class="QVBoxLayout" >
+          <item>
+           <layout class="QHBoxLayout" >
+            <item>
+             <widget class="QLabel" name="label" >
+              <property name="text" >
+               <string>Name</string>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QLineEdit" name="teaNameEdit" >
+              <property name="enabled" >
+               <bool>false</bool>
+              </property>
+             </widget>
+            </item>
+           </layout>
+          </item>
+          <item>
+           <widget class="QGroupBox" name="groupBox_2" >
+            <property name="title" >
+             <string>Tea time</string>
+            </property>
+            <property name="flat" >
+             <bool>true</bool>
+            </property>
+            <property name="checkable" >
+             <bool>false</bool>
+            </property>
+            <layout class="QVBoxLayout" >
+             <property name="leftMargin" >
+              <number>5</number>
+             </property>
+             <property name="topMargin" >
+              <number>5</number>
+             </property>
+             <property name="rightMargin" >
+              <number>5</number>
+             </property>
+             <property name="bottomMargin" >
+              <number>5</number>
+             </property>
+             <item>
+              <layout class="QGridLayout" >
+               <item row="0" column="0" >
+                <widget class="QSpinBox" name="hoursSpin" >
+                 <property name="enabled" >
+                  <bool>false</bool>
+                 </property>
+                 <property name="maximum" >
+                  <number>48</number>
+                 </property>
+                </widget>
+               </item>
+               <item row="0" column="1" >
+                <widget class="QLabel" name="label_5" >
+                 <property name="text" >
+                  <string>hours</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="0" column="2" >
+                <widget class="QSlider" name="hoursSlider" >
+                 <property name="enabled" >
+                  <bool>false</bool>
+                 </property>
+                 <property name="minimumSize" >
+                  <size>
+                   <width>100</width>
+                   <height>0</height>
+                  </size>
+                 </property>
+                 <property name="maximum" >
+                  <number>48</number>
+                 </property>
+                 <property name="orientation" >
+                  <enum>Qt::Horizontal</enum>
+                 </property>
+                </widget>
+               </item>
+               <item row="1" column="0" >
+                <widget class="QSpinBox" name="minutesSpin" >
+                 <property name="enabled" >
+                  <bool>false</bool>
+                 </property>
+                 <property name="maximum" >
+                  <number>59</number>
+                 </property>
+                </widget>
+               </item>
+               <item row="1" column="1" >
+                <widget class="QLabel" name="label_3" >
+                 <property name="text" >
+                  <string>minutes</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="1" column="2" >
+                <widget class="QSlider" name="minutesSlider" >
+                 <property name="enabled" >
+                  <bool>false</bool>
+                 </property>
+                 <property name="minimumSize" >
+                  <size>
+                   <width>100</width>
+                   <height>0</height>
+                  </size>
+                 </property>
+                 <property name="maximum" >
+                  <number>59</number>
+                 </property>
+                 <property name="orientation" >
+                  <enum>Qt::Horizontal</enum>
+                 </property>
+                </widget>
+               </item>
+               <item row="2" column="0" >
+                <widget class="QSpinBox" name="secondsSpin" >
+                 <property name="enabled" >
+                  <bool>false</bool>
+                 </property>
+                 <property name="maximum" >
+                  <number>59</number>
+                 </property>
+                </widget>
+               </item>
+               <item row="2" column="1" >
+                <widget class="QLabel" name="label_4" >
+                 <property name="text" >
+                  <string>seconds</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="2" column="2" >
+                <widget class="QSlider" name="secondsSlider" >
+                 <property name="enabled" >
+                  <bool>false</bool>
+                 </property>
+                 <property name="minimumSize" >
+                  <size>
+                   <width>100</width>
+                   <height>0</height>
+                  </size>
+                 </property>
+                 <property name="maximum" >
+                  <number>59</number>
+                 </property>
+                 <property name="orientation" >
+                  <enum>Qt::Horizontal</enum>
+                 </property>
+                </widget>
+               </item>
+              </layout>
+             </item>
+            </layout>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+       </item>
+       <item>
+        <spacer>
+         <property name="orientation" >
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" >
+          <size>
+           <width>20</width>
+           <height>40</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="KButtonGroup" name="kbuttongroup2" >
+     <property name="title" >
+      <string>Action</string>
+     </property>
+     <layout class="QVBoxLayout" >
+      <item>
+       <layout class="QHBoxLayout" >
+        <item>
+         <widget class="QCheckBox" name="notificationCheckBox" >
+          <property name="text" >
+           <string>Notification</string>
+          </property>
+          <property name="checked" >
+           <bool>true</bool>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="KPushButton" name="notificationButton" >
+          <property name="enabled" >
+           <bool>true</bool>
+          </property>
+          <property name="text" >
+           <string>Configure &amp;Notifications...</string>
+          </property>
+          <property name="default" >
+           <bool>false</bool>
+          </property>
+          <property name="flat" >
+           <bool>false</bool>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer>
+          <property name="orientation" >
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" >
+           <size>
+            <width>1</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
+      </item>
+      <item>
+       <widget class="QCheckBox" name="popupCheckBox" >
+        <property name="text" >
+         <string>Popup</string>
+        </property>
+        <property name="checked" >
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <layout class="QHBoxLayout" >
+        <item>
+         <spacer>
+          <property name="orientation" >
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeType" >
+           <enum>QSizePolicy::Fixed</enum>
+          </property>
+          <property name="sizeHint" >
+           <size>
+            <width>16</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="autohideCheckBox" >
+          <property name="enabled" >
+           <bool>true</bool>
+          </property>
+          <property name="text" >
+           <string>Auto hide popup after</string>
+          </property>
+          <property name="checked" >
+           <bool>false</bool>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QSpinBox" name="autohideSpinBox" >
+          <property name="enabled" >
+           <bool>false</bool>
+          </property>
+          <property name="minimum" >
+           <number>1</number>
+          </property>
+          <property name="maximum" >
+           <number>300</number>
+          </property>
+          <property name="value" >
+           <number>30</number>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QLabel" name="label_6" >
+          <property name="text" >
+           <string>seconds.</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer>
+          <property name="orientation" >
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" >
+           <size>
+            <width>151</width>
+            <height>24</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
+      </item>
+      <item>
+       <layout class="QHBoxLayout" >
+        <item>
+         <widget class="QCheckBox" name="reminderCheckBox" >
+          <property name="text" >
+           <string>Reminder every</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QSpinBox" name="reminderSpinBox" >
+          <property name="enabled" >
+           <bool>false</bool>
+          </property>
+          <property name="minimum" >
+           <number>1</number>
+          </property>
+          <property name="maximum" >
+           <number>300</number>
+          </property>
+          <property name="value" >
+           <number>60</number>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QLabel" name="label_9" >
+          <property name="text" >
+           <string>seconds.</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer>
+          <property name="orientation" >
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" >
+           <size>
+            <width>181</width>
+            <height>25</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
+      </item>
+      <item>
+       <layout class="QHBoxLayout" />
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QCheckBox" name="visualizeCheckBox" >
+     <property name="text" >
+      <string>Visualize progress in icon tray</string>
+     </property>
+     <property name="checked" >
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>KButtonGroup</class>
+   <extends>QGroupBox</extends>
+   <header>kbuttongroup.h</header>
+   <container>1</container>
+  </customwidget>
+  <customwidget>
+   <class>KPushButton</class>
+   <extends>QPushButton</extends>
+   <header>kpushbutton.h</header>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>notificationCheckBox</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>notificationButton</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>88</x>
+     <y>303</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>314</x>
+     <y>300</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>hoursSpin</sender>
+   <signal>valueChanged(int)</signal>
+   <receiver>hoursSlider</receiver>
+   <slot>setValue(int)</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>337</x>
+     <y>124</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>507</x>
+     <y>119</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>hoursSlider</sender>
+   <signal>valueChanged(int)</signal>
+   <receiver>hoursSpin</receiver>
+   <slot>setValue(int)</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>488</x>
+     <y>118</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>337</x>
+     <y>124</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>minutesSpin</sender>
+   <signal>valueChanged(int)</signal>
+   <receiver>minutesSlider</receiver>
+   <slot>setValue(int)</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>337</x>
+     <y>156</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>507</x>
+     <y>151</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>minutesSlider</sender>
+   <signal>valueChanged(int)</signal>
+   <receiver>minutesSpin</receiver>
+   <slot>setValue(int)</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>507</x>
+     <y>151</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>337</x>
+     <y>156</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>secondsSpin</sender>
+   <signal>valueChanged(int)</signal>
+   <receiver>secondsSlider</receiver>
+   <slot>setValue(int)</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>337</x>
+     <y>188</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>507</x>
+     <y>183</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>secondsSlider</sender>
+   <signal>valueChanged(int)</signal>
+   <receiver>secondsSpin</receiver>
+   <slot>setValue(int)</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>507</x>
+     <y>183</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>337</x>
+     <y>188</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>autohideCheckBox</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>autohideSpinBox</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>222</x>
+     <y>368</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>283</x>
+     <y>367</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>reminderCheckBox</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>reminderSpinBox</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>108</x>
+     <y>401</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>217</x>
+     <y>400</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
Index: CMakeLists.txt
===================================================================
--- CMakeLists.txt	(revision 702652)
+++ CMakeLists.txt	(working copy)
@@ -1,19 +1,21 @@
 project(kteatime)
 
-add_definitions (-DQT3_SUPPORT)
-
 ########### next target ###############
 
 set(kteatime_SRCS 
-   main.cpp 
-   toplevel.cpp 
-   tealist.cpp 
-   timeedit.cpp )
+    settings.cpp
+    timeedit.cpp
+    toplevel.cpp
+    tealistmodel.cpp
+    tea.cpp
+    main.cpp
+  )
 
+kde4_add_ui_files(kteatime_SRCS settings.ui timeedit.ui)
 
 kde4_add_executable(kteatime ${kteatime_SRCS})
 
-target_link_libraries(kteatime  ${KDE4_KIO_LIBS} ${KDE4_KNOTIFYCONFIG_LIBS} \
${QT_QT3SUPPORT_LIBRARY}) +target_link_libraries(kteatime  ${KDE4_KIO_LIBS} \
${KDE4_KNOTIFYCONFIG_LIBS})  
 install(TARGETS kteatime  DESTINATION ${BIN_INSTALL_DIR} )
 



>> Visit http://mail.kde.org/mailman/listinfo/kde-devel#unsub to unsubscribe <<


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic