Added a few source files.

Fri, 19 Oct 2012 13:06:56 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Fri, 19 Oct 2012 13:06:56 +0200
changeset 1
a0beac325e5a
parent 0
944024997123
child 2
058c6a316ca8

Added a few source files.

PluginTimeTracker.e4p file | annotate | diff | comparison | revisions
PluginTimeTracker.py file | annotate | diff | comparison | revisions
TimeTracker/TimeTrackEntry.py file | annotate | diff | comparison | revisions
TimeTracker/TimeTracker.py file | annotate | diff | comparison | revisions
TimeTracker/TimeTrackerEntryDialog.ui file | annotate | diff | comparison | revisions
TimeTracker/TimeTrackerWidget.py file | annotate | diff | comparison | revisions
TimeTracker/TimeTrackerWidget.ui file | annotate | diff | comparison | revisions
TimeTracker/__init__.py file | annotate | diff | comparison | revisions
--- a/PluginTimeTracker.e4p	Sat Oct 13 18:07:16 2012 +0200
+++ b/PluginTimeTracker.e4p	Fri Oct 19 13:06:56 2012 +0200
@@ -15,8 +15,15 @@
   <Sources>
     <Source>__init__.py</Source>
     <Source>PluginTimeTracker.py</Source>
+    <Source>TimeTracker/__init__.py</Source>
+    <Source>TimeTracker/TimeTracker.py</Source>
+    <Source>TimeTracker/TimeTrackEntry.py</Source>
+    <Source>TimeTracker/TimeTrackerWidget.py</Source>
   </Sources>
-  <Forms/>
+  <Forms>
+    <Form>TimeTracker/TimeTrackerEntryDialog.ui</Form>
+    <Form>TimeTracker/TimeTrackerWidget.ui</Form>
+  </Forms>
   <Translations/>
   <Resources/>
   <Interfaces/>
--- a/PluginTimeTracker.py	Sat Oct 13 18:07:16 2012 +0200
+++ b/PluginTimeTracker.py	Fri Oct 19 13:06:56 2012 +0200
@@ -0,0 +1,135 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2012 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing the Time Tracker plugin.
+"""
+
+import os
+
+from PyQt4.QtCore import QObject, QTranslator
+
+from E5Gui.E5Application import e5App
+
+from TimeTracker.TimeTracker import TimeTracker
+
+# Start-Of-Header
+name = "Time Tracker Plugin"
+author = "Detlev Offenbach <detlev@die-offenbachs.de>"
+autoactivate = True
+deactivateable = True
+version = "0.1.0"
+className = "TimeTrackerPlugin"
+packageName = "TimeTracker"
+shortDescription = "Time Tracker to keep track of the project time."
+longDescription = """This plugin implements a time tracker to keep track""" \
+    """ of the time used for a project. The time can be subdivided into tasks."""
+needsRestart = False
+pyqtApi = 2
+# End-Of-Header
+
+error = ""
+    
+
+class TimeTrackerPlugin(QObject):
+    """
+    Class implementing the Eric assistant plugin.
+    """
+    def __init__(self, ui):
+        """
+        Constructor
+        
+        @param ui reference to the user interface object (UI.UserInterface)
+        """
+        QObject.__init__(self, ui)
+        self.__ui = ui
+        self.__initialize()
+        
+        self.__translator = None
+        self.__loadTranslator()
+        
+        self.__e5project = e5App().getObject("Project")
+    
+    def __initialize(self):
+        """
+        Private slot to (re)initialize the plugin.
+        """
+        self.__object = None
+    
+    def __checkVersions(self):
+        """
+        Private function to check that the eric5 version is ok.
+        
+        @return flag indicating version is ok (boolean)
+        """
+        global error
+        
+        if self.__ui.versionIsNewer('5.2.99', '20121012'):
+            error = ""
+        else:
+            error = self.trUtf8("eric5 version is too old, {0}, {1} or newer needed.")\
+                .format("5.3.0", "20121012")
+            return False
+        
+        return True
+    
+    def activate(self):
+        """
+        Public method to activate this plugin.
+        
+        @return tuple of None and activation status (boolean)
+        """
+        global error
+        error = ""     # clear previous error
+        
+        if not self.__checkVersions():
+            return None, False
+        
+        self.__object = TimeTracker(self, self.__ui)
+##        self.__object.initActions()
+        e5App().registerPluginObject("TimeTracker", self.__object)
+        
+        if self.__e5project.isOpen():
+            self.__object.projectOpened()
+        
+        self.__e5project.newProject.connect(self.__object.projectOpened)
+        self.__e5project.projectOpened.connect(self.__object.projectOpened)
+        self.__e5project.projectClosed.connect(self.__object.projectClosed)
+        
+        return None, True
+    
+    def deactivate(self):
+        """
+        Public method to deactivate this plugin.
+        """
+        e5App().unregisterPluginObject("TimeTracker")
+        
+        self.__e5project.newProject.disconnect(self.__object.projectOpened)
+        self.__e5project.projectOpened.disconnect(self.__object.projectOpened)
+        self.__e5project.projectClosed.disconnect(self.__object.projectClosed)
+        
+        self.__object.projectClosed()
+        
+        self.__initialize()
+    
+    def __loadTranslator(self):
+        """
+        Private method to load the translation file.
+        """
+        if self.__ui is not None:
+            loc = self.__ui.getLocale()
+            if loc and loc != "C":
+                locale_dir = \
+                    os.path.join(os.path.dirname(__file__), "TimeTracker", "i18n")
+                translation = "timetracker_{0}".format(loc)
+                translator = QTranslator(None)
+                loaded = translator.load(translation, locale_dir)
+                if loaded:
+                    self.__translator = translator
+                    e5App().installTranslator(self.__translator)
+                else:
+                    print("Warning: translation file '{0}' could not be loaded."\
+                        .format(translation))
+                    print("Using default.")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TimeTracker/TimeTrackEntry.py	Fri Oct 19 13:06:56 2012 +0200
@@ -0,0 +1,190 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2012 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing the time track entry class.
+"""
+
+from PyQt4.QtCore import Qt, QDateTime
+
+
+class TimeTrackEntry(object):
+    """
+    Class implementing the time track entry.
+    """
+    LineMarker = "Entry: "
+    Separator = "@@"
+    
+    def __init__(self):
+        """
+        Constructor
+        """
+        self.__entryMembersCount = 4
+        self.__startDateTime = QDateTime()      # start date and time
+        self.__duration = 0                     # duration in minutes
+        self.__task = ""                        # task specification
+        self.__comment = ""                     # comment string
+        self.__valid = False                    # flag for a valid entry
+        
+        self.__continueDateTime = QDateTime()
+        self.__paused = False
+    
+    def toString(self):
+        """
+        Public method to get a string representation of the entry.
+        
+        @return string representation of the entry (string)
+        """
+        if self.__valid:
+            dataLine = TimeTrackEntry.Separator.join([
+                self.__startDateTime.toString(Qt.ISODate),
+                str(self.__duration),
+                self.__task,
+                self.__comment,
+            ])
+            return "{0}{1}".format(TimeTrackEntry.LineMarker, dataLine)
+        else:
+            return ""
+    
+    def fromString(self, line):
+        """
+        Public method to populate the entry from the given string.
+        
+        @param line stringified entry data as generated by toString() (string)
+        @return flag indicating valid data
+        """
+        if not line.startswith(TimeTrackEntry.LineMarker):
+            return False
+        
+        line = line.replace(TimeTrackEntry.LineMarker, "")
+        dataList = line.split(TimeTrackEntry.Separator)
+        if len(dataList) != self.__entryMembersCount:
+            return False
+        
+        dt = QDateTime.fromString(dataList[0], Qt.ISODate)
+        if not dt.isValid():
+            return False
+        self.__startDateTime = dt
+        
+        try:
+            dt = int(dataList[1])
+        except ValueError:
+            return False
+        self.__duration = dt
+        
+        self.__task = dataList[2]
+        self.__comment = dataList[3]
+        
+        self.__valid = True
+        return True
+    
+    def isValid(self):
+        """
+        Public method to check the validity of the entry.
+        
+        @return validity of the entry (boolean)
+        """
+        return self.__valid
+    
+    def start(self):
+        """
+        Public method to set the start time of this entry.
+        """
+        self.__startDateTime = QDateTime.currentDateTime()
+        self.__continueDateTime = QDateTime(self.__startDateTime)
+    
+    def stop(self):
+        """
+        Public method to stop this entry.
+        """
+        if not self.__paused:
+            minutes = self.__calculateDuration(
+                self.__continueDateTime, QDateTime.currentDateTime())
+            self.__duration += minutes
+        
+        if self.__duration >= 2:
+            self.__valid = True
+        else:
+            self.__duration = 0
+            self.__valid = False
+    
+    def pause(self):
+        """
+        Public method to pause the entry.
+        """
+        if not self.__paused:
+            minutes = self.__calculateDuration(
+                self.__continueDateTime, QDateTime.currentDateTime())
+            self.__duration += minutes
+            self.__paused = True
+    
+    def continue_(self):
+        """
+        Public method to continue the entry.
+        """
+        if self.__paused:
+            self.__continueDateTime = QDateTime(self.__startDateTime)
+            self.__paused = False
+    
+    def isPaused(self):
+        """
+        Public method to check for a paused state.
+        
+        @return flag indicating a paused state (boolean)
+        """
+        return self.__paused
+    
+    def __calculateDuration(self, start, stop):
+        """
+        Private method to calculate the duration in minutes.
+        
+        @param start start date and time (QDateTime)
+        @param stop end date and time (QDateTime)
+        @return duration in minutes (int)
+        """
+        secs = start.secsTo(stop)
+        minutes = secs // 60
+        secsRemaining = secs % 60
+        if secsRemaining >= 30:
+            minutes += 1
+        
+        return minutes
+    
+    def setTask(self, description):
+        """
+        Public method to set the task description.
+        
+        @param description task description (string)
+        """
+        self.__task = description.replace("\r\n", " ")\
+                                 .replace("\n", " ")\
+                                 .replace("\r", " ")
+    
+    def setComment(self, comment):
+        """
+        Public method to set a comment.
+        
+        @param comment comment to set (string)
+        """
+        self.__comment = comment.replace("\r\n", " ")\
+                                .replace("\n", " ")\
+                                .replace("\r", " ")
+    
+    def getEntryData(self):
+        """
+        Public method to get the entry data.
+        
+        @return entry data as a tuple of start date (string), start time (string),
+            duration (integer), task (string), comment (string) and flag indicating
+            a paused state (boolean)
+        """
+        return (
+            self.__startDateTime.toString("yyyy-MM-dd"),
+            self.__startDateTime.toString("hh:mm"),
+            self.__duration,
+            self.__task,
+            self.__comment,
+            self.__paused,
+        )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TimeTracker/TimeTracker.py	Fri Oct 19 13:06:56 2012 +0200
@@ -0,0 +1,170 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2012 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing the time tracker object.
+"""
+
+import os
+
+from PyQt4.QtCore import pyqtSignal, QObject
+
+from E5Gui.E5Application import e5App
+from E5Gui import E5MessageBox
+
+from .TimeTrackEntry import TimeTrackEntry
+
+
+class TimeTracker(QObject):
+    """
+    Class implementing the time tracker object.
+    """
+    currentEntryChanged = pyqtSignal()
+    
+    FileName = "TimeTracker.txt"
+    
+    def __init__(self, plugin, parent=None):
+        """
+        Constructor
+        
+        @param plugin reference to the plugin object
+        @param parent parent (QObject)
+        """
+        QObject.__init__(self, parent)
+        
+        self.__plugin = plugin
+        self.__ui = parent
+        
+        self.__e5project = e5App().getObject("Project")
+        
+        self.__initialize()
+    
+    def __initialize(self):
+        """
+        Public slot to initialize some member variables.
+        """
+        self.__projectPath = ''
+        self.__trackerFilePath = ''
+        self.__projectOpen = False
+        
+        self.__entries = []
+        self.__currentEntry = None
+    
+    def projectOpened(self):
+        """
+        Public slot to handle the projectOpened signal.
+        """
+        if self.__projectOpen:
+            self.projectClosed()
+        
+        self.__projectOpen = True
+        self.__projectPath = self.__e5project.getProjectPath()
+        self.__trackerFilePath = os.path.join(
+            self.__e5project.getProjectManagementDir(),
+            TimeTracker.FileName)
+        
+        self.__readTrackerEntries()
+        
+        self.__currentEntry = TimeTrackEntry()
+        self.__currentEntry.start()
+        self.currentEntryChanged.emit()
+    
+    def projectClosed(self):
+        """
+        Public slot to handle the projectClosed signal.
+        """
+        if self.__currentEntry is not None:
+            self.__currentEntry.stop()
+            if self.__currentEntry.isValid():
+                self.__entries.append(self.__currentEntry)
+        
+        self.__saveTrackerEntries()
+        
+        self.__initialize()
+    
+    def __readTrackerEntries(self):
+        """
+        Private slot to read the time tracker entries from a file.
+        """
+        if os.path.exists(self.__trackerFilePath):
+            try:
+                f = open(self.__trackerFilePath, "r", encoding="utf-8")
+                data = f.read()
+                f.close()
+            except (IOError, OSError) as err:
+                E5MessageBox.critical(self.__ui,
+                    self.trUtf8("Read Time Tracker File"),
+                    self.trUtf8("""<p>The time tracker file <b>{0}</b> could not be"""
+                                """ read.</p><p>Reason: {1}</p>""").format(
+                        self.__trackerFilePath, str(err)))
+                return
+            
+            invalidCount = 0
+            for line in data.splitlines():
+                entry = TimeTrackEntry()
+                if entry.fromString(line.strip()):
+                    self.__entries.append(entry)
+                else:
+                    invalidCount += 1
+            
+            if invalidCount:
+                E5MessageBox.information(self.__ui,
+                    self.trUtf8("Read Time Tracker File"),
+                    self.trUtf8("""<p>The time tracker file <b>{0}</b> contained"""
+                                """ %n invalid entries. These have been discarded.""",
+                                "", invalidCount).format(self.__trackerFilePath))
+    
+    def __saveTrackerEntries(self):
+        """
+        Private slot to save the tracker entries to a file.
+        """
+        try:
+            f = open(self.__trackerFilePath, "w", encoding="utf-8")
+            for entry in self.__entries:
+                if entry.isValid():
+                    f.write(entry.toString() + "\n")
+            f.close()
+        except (IOError, OSError) as err:
+            E5MessageBox.critical(self.__ui,
+                self.trUtf8("Save Time Tracker File"),
+                self.trUtf8("""<p>The time tracker file <b>{0}</b> could not be"""
+                            """ saved.</p><p>Reason: {1}</p>""").format(
+                    self.__trackerFilePath, str(err)))
+    
+    def pauseTrackerEntry(self):
+        """
+        Public method to pause the current tracker entry.
+        """
+        self.__currentEntry.pause()
+    
+    def continueTrackerEntry(self):
+        """
+        Public method to continue the current tracker entry.
+        """
+        self.__currentEntry.continue_()
+    
+    def getCurrentEntry(self):
+        """
+        Public method to get a reference to the current tracker entry.
+        """
+        return self.__currentEntry
+    
+    def newEntry(self):
+        """
+        Public method to stop the current tracker entry and start a new one.
+        """
+        # stop the current time tracker entry
+        if self.__currentEntry is not None:
+            self.__currentEntry.stop()
+            if self.__currentEntry.isValid():
+                self.__entries.append(self.__currentEntry)
+        
+        # save the tracker entries
+        self.__saveTrackerEntries()
+        
+        # start a new time tracker entry
+        self.__currentEntry = TimeTrackEntry()
+        self.__currentEntry.start()
+        self.currentEntryChanged.emit()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TimeTracker/TimeTrackerEntryDialog.ui	Fri Oct 19 13:06:56 2012 +0200
@@ -0,0 +1,186 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>TimeTrackerEntryDialog</class>
+ <widget class="QDialog" name="TimeTrackerEntryDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>515</width>
+    <height>147</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Edit Timer Entry</string>
+  </property>
+  <property name="sizeGripEnabled">
+   <bool>true</bool>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <layout class="QGridLayout" name="gridLayout">
+     <item row="0" column="0">
+      <widget class="QLabel" name="label">
+       <property name="text">
+        <string>Start Date/Time:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="1" colspan="2">
+      <widget class="QDateTimeEdit" name="startDateTimeEdit">
+       <property name="toolTip">
+        <string>Edit the start date and time of the timer</string>
+       </property>
+       <property name="displayFormat">
+        <string>yyyy-MM-dd HH:mm:ss</string>
+       </property>
+       <property name="calendarPopup">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="3">
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item row="1" column="0">
+      <widget class="QLabel" name="label_2">
+       <property name="text">
+        <string>Duration:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="1">
+      <widget class="QSpinBox" name="durationSpinBox">
+       <property name="toolTip">
+        <string>Edit the duration of the timer</string>
+       </property>
+       <property name="alignment">
+        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+       </property>
+       <property name="suffix">
+        <string> min</string>
+       </property>
+       <property name="maximum">
+        <number>9999</number>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="2" colspan="2">
+      <spacer name="horizontalSpacer_2">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>108</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item row="2" column="0">
+      <widget class="QLabel" name="label_3">
+       <property name="text">
+        <string>Task:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="1" colspan="3">
+      <widget class="QComboBox" name="taskCombo">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="toolTip">
+        <string>Enter the task description for the timer</string>
+       </property>
+       <property name="editable">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item row="3" column="0">
+      <widget class="QLabel" name="label_4">
+       <property name="text">
+        <string>Comment:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="3" column="1" colspan="3">
+      <widget class="QComboBox" name="commentCombo">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="toolTip">
+        <string>Enter a comment for the timer</string>
+       </property>
+       <property name="editable">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>TimeTrackerEntryDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>TimeTrackerEntryDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TimeTracker/TimeTrackerWidget.py	Fri Oct 19 13:06:56 2012 +0200
@@ -0,0 +1,123 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2012 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing the time tracker widget.
+"""
+
+from PyQt4.QtCore import pyqtSlot, QPoint
+from PyQt4.QtGui import QWidget, QMenu
+
+from .Ui_TimeTrackerWidget import Ui_TimeTrackerWidget
+
+
+class TimeTrackerWidget(QWidget, Ui_TimeTrackerWidget):
+    """
+    Class implementing the time tracker widget.
+    """
+    def __init__(self, tracker, parent=None):
+        """
+        Constructor
+        
+        @param tracker reference to the time tracker (TimeTracker)
+        @param parent reference to the parent widget (QWidget)
+        """
+        super().__init__(parent)
+        self.setupUi(self)
+        
+        self.__tracker = tracker
+    
+    @pyqtSlot(str)
+    def on_taskCombo_editTextChanged(self, p0):
+        """
+        Slot documentation goes here.
+        """
+        # TODO: not implemented yet
+        raise NotImplementedError
+    
+    @pyqtSlot(str)
+    def on_commentCombo_editTextChanged(self, p0):
+        """
+        Slot documentation goes here.
+        """
+        # TODO: not implemented yet
+        raise NotImplementedError
+    
+    @pyqtSlot(bool)
+    def on_pauseButton_toggled(self, checked):
+        """
+        Slot documentation goes here.
+        """
+        # TODO: not implemented yet
+        raise NotImplementedError
+    
+    @pyqtSlot()
+    def on_newButton_clicked(self):
+        """
+        Slot documentation goes here.
+        """
+        # TODO: not implemented yet
+        raise NotImplementedError
+    
+    @pyqtSlot(QPoint)
+    def on_entriesList_customContextMenuRequested(self, pos):
+        """
+        Private slot to create the context menu and show it.
+        
+        @param pos position the menu should be shown at (QPoint)
+        """
+        menu = QMenu()
+        
+        menu.addAction(self.tr("Edit"), self.__editEntry).setEnabled(
+            len(self.entriesList.selectedItems()) == 1)
+        menu.addAction(self.tr("Delete"), self.__deleteSelectedEntries)
+        menu.addSeparator()
+        menu.addAction(self.tr("Save"), self.__saveEntries)
+        menu.addSeparator()
+        menu.addAction(self.tr("Import"), self.__importEntries)
+        menu.addAction(self.tr("Export Selected"), self.__exportSelectedEntries)
+        menu.addAction(self.tr("Export All"), self.__exportAllEntries)
+    
+    def __editEntry(self):
+        """
+        Private slot to edit the selected tracker entry.
+        """
+        # TODO: not implemented yet
+        raise NotImplementedError
+    
+    def __deleteSelectedEntries(self):
+        """
+        Private slot to delete the selected tracker entries.
+        """
+        # TODO: not implemented yet
+        raise NotImplementedError
+    
+    def __saveEntries(self):
+        """
+        Private slot to save the tracker entries.
+        """
+        # TODO: not implemented yet
+        raise NotImplementedError
+    
+    def __importEntries(self):
+        """
+        Private slot to import tracker entries.
+        """
+        # TODO: not implemented yet
+        raise NotImplementedError
+    
+    def __exportSelectedEntries(self):
+        """
+        Private slot to export the selected tracker entries.
+        """
+        # TODO: not implemented yet
+        raise NotImplementedError
+    
+    def __exportAllEntries(self):
+        """
+        Private slot to export all tracker entries.
+        """
+        # TODO: not implemented yet
+        raise NotImplementedError
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TimeTracker/TimeTrackerWidget.ui	Fri Oct 19 13:06:56 2012 +0200
@@ -0,0 +1,218 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>TimeTrackerWidget</class>
+ <widget class="QWidget" name="TimeTrackerWidget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>609</width>
+    <height>149</height>
+   </rect>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <property name="margin">
+    <number>0</number>
+   </property>
+   <item>
+    <layout class="QGridLayout" name="gridLayout">
+     <item row="0" column="0">
+      <widget class="QLabel" name="label">
+       <property name="text">
+        <string>Start Date/Time:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="1">
+      <widget class="QLabel" name="label_2">
+       <property name="text">
+        <string>Duration:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="2">
+      <widget class="QLabel" name="label_3">
+       <property name="text">
+        <string>Task:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="3">
+      <widget class="QLabel" name="label_4">
+       <property name="text">
+        <string>Comment:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="0">
+      <widget class="QDateTimeEdit" name="startDateTimeEdit">
+       <property name="toolTip">
+        <string>Shows the start date and time of the current timer</string>
+       </property>
+       <property name="readOnly">
+        <bool>true</bool>
+       </property>
+       <property name="displayFormat">
+        <string>yyyy-MM-dd HH:mm:ss</string>
+       </property>
+       <property name="calendarPopup">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="1">
+      <widget class="QSpinBox" name="durationSpinBox">
+       <property name="toolTip">
+        <string>Shows the duration of the current timer</string>
+       </property>
+       <property name="alignment">
+        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+       </property>
+       <property name="readOnly">
+        <bool>true</bool>
+       </property>
+       <property name="suffix">
+        <string> min</string>
+       </property>
+       <property name="maximum">
+        <number>9999</number>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="2">
+      <widget class="QComboBox" name="taskCombo">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="toolTip">
+        <string>Enter the task description for the current timer</string>
+       </property>
+       <property name="editable">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="3">
+      <widget class="QComboBox" name="commentCombo">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="toolTip">
+        <string>Enter a comment for the current timer</string>
+       </property>
+       <property name="editable">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QPushButton" name="pauseButton">
+       <property name="toolTip">
+        <string>Press to pause the current timer</string>
+       </property>
+       <property name="text">
+        <string>Pause</string>
+       </property>
+       <property name="checkable">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="newButton">
+       <property name="toolTip">
+        <string>Press to end the current timer and start a new one</string>
+       </property>
+       <property name="text">
+        <string>End Current Timer and Start a New Timer</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer_2">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="QTreeWidget" name="entriesList">
+     <property name="contextMenuPolicy">
+      <enum>Qt::CustomContextMenu</enum>
+     </property>
+     <property name="editTriggers">
+      <set>QAbstractItemView::NoEditTriggers</set>
+     </property>
+     <property name="alternatingRowColors">
+      <bool>true</bool>
+     </property>
+     <property name="selectionMode">
+      <enum>QAbstractItemView::ExtendedSelection</enum>
+     </property>
+     <property name="rootIsDecorated">
+      <bool>false</bool>
+     </property>
+     <property name="allColumnsShowFocus">
+      <bool>true</bool>
+     </property>
+     <attribute name="headerStretchLastSection">
+      <bool>false</bool>
+     </attribute>
+     <column>
+      <property name="text">
+       <string>Start Date/Time</string>
+      </property>
+     </column>
+     <column>
+      <property name="text">
+       <string>Duration</string>
+      </property>
+     </column>
+     <column>
+      <property name="text">
+       <string>Task</string>
+      </property>
+     </column>
+     <column>
+      <property name="text">
+       <string>Comment</string>
+      </property>
+     </column>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TimeTracker/__init__.py	Fri Oct 19 13:06:56 2012 +0200
@@ -0,0 +1,8 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2012 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Package implementing the time tracker.
+"""

eric ide

mercurial