[Workman-svn] SF.net SVN: workman:[46] trunk/src
An unobtrusive time-tracking program for self-employed people
Status: Pre-Alpha
Brought to you by:
jmsilva
|
From: <jm...@us...> - 2011-10-21 00:59:20
|
Revision: 46
http://workman.svn.sourceforge.net/workman/?rev=46&view=rev
Author: jmsilva
Date: 2011-10-21 00:59:14 +0000 (Fri, 21 Oct 2011)
Log Message:
-----------
- Initial values on combo boxes from the create project and delete project dialog boxes now reflect the selected project in the main window
- Removed option to add employers/projects from informational dialog boxes
- Little bug fixes
Modified Paths:
--------------
trunk/src/gui/dialogs.py
trunk/src/gui/main_window.py
trunk/src/workman.py
Modified: trunk/src/gui/dialogs.py
===================================================================
--- trunk/src/gui/dialogs.py 2011-10-21 00:59:02 UTC (rev 45)
+++ trunk/src/gui/dialogs.py 2011-10-21 00:59:14 UTC (rev 46)
@@ -16,9 +16,8 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-from PyQt4.QtGui import QDialog, QDialogButtonBox, QWidget
+from PyQt4.QtGui import QDialog, QDialogButtonBox
from gui import compiled_ui
-from workman import DataStore
from gui.compiled_ui import Ui_startSessionDialog, Ui_endSessionDialog, Ui_viewSessionsDialog
'''
Created on 2009/12/18
@@ -26,6 +25,9 @@
@author: jms
'''
+'''TODO: There's a lot of repeated code on employer/project choice boxes.
+ Those should be generalized.'''
+
class NewEmployerDialog(QDialog, compiled_ui.Ui_newEmployerDialog):
'''
The dialog used to create employers.
@@ -40,12 +42,16 @@
def employerNameChanged(self, text):
trimmed = text.trimmed()
- if trimmed in self.dataStore.employers.keys():
+ if(trimmed == self.dataStore.NO_EMPLOYER or
+ trimmed == self.dataStore.NO_EMPLOYER_TRANSLATED):
self.okButton.setEnabled(False)
- #TODO: Show a tooltip explaining what happened
+ #TODO: Show a tooltip explaining those names are reserved
+ elif trimmed in self.dataStore.employers.keys():
+ self.okButton.setEnabled(False)
+ #TODO: Show a tooltip explaining that employer already exists
elif trimmed == '':
self.okButton.setEnabled(False)
- #TODO: Show a tooltip explaining what happened
+ #TODO: Show a tooltip explaining the user needs to write something
else:
self.okButton.setEnabled(True)
@@ -53,11 +59,14 @@
name = self.employerNameBox.text().trimmed()
desc = self.descriptionBox.toPlainText().trimmed()
rate = self.hourlyRateSpinner.value()
- self.dataStore.addEmployer(name, desc, rate)
+ self.dataStore.addEmployer(name, desc, rate)
+ """Set the boxes' text to the trimmed version, so calling classes can get
+ the correct new data"""
+ self.employerNameBox.setText(name)
+ self.descriptionBox.setText(desc)
+
QDialog.accept(self)
-
-
class NewProjectDialog(QDialog, compiled_ui.Ui_newProjectDialog):
'''
@@ -100,16 +109,20 @@
def __checkOkButtonState(self):
text = self.projectNameBox.text().trimmed()
if self.employerIndex == 0:
- currentEmployer = DataStore.NO_EMPLOYER
+ currentEmployer = self.dataStore.NO_EMPLOYER
else:
currentEmployer = self.employerChoice.currentText()
-
+
+ if(text == self.dataStore.NO_PROJECT or
+ text == self.dataStore.NO_PROJECT_TRANSLATED):
+ self.okButton.setEnabled(False)
+ #TODO: Show a tooltip explaining those names are reserved
if text in self.dataStore.employers[currentEmployer].projects.keys():
self.okButton.setEnabled(False)
- #TODO: Show a tooltip explaining what happened
+ #TODO: Show a tooltip explaining the project name already exists for this employer
elif text == '':
self.okButton.setEnabled(False)
- #TODO: Show a tooltip explaining what happened
+ #TODO: Show a tooltip explaining that the user needs to write something
else:
self.okButton.setEnabled(True)
@@ -119,7 +132,7 @@
def accept(self):
if self.employerChoice.currentIndex() == 0:
- employerName = DataStore.NO_EMPLOYER
+ employerName = self.dataStore.NO_EMPLOYER
else:
employerName = self.employerChoice.currentText()
@@ -136,10 +149,10 @@
def __populateEmployerBox(self, defaultItem = None):
self.ignoreComboBoxChanges = True
self.employerChoice.clear()
- self.employerChoice.addItem(self.tr("None (personal project)"))
+ self.employerChoice.addItem(self.dataStore.NO_EMPLOYER_TRANSLATED)
items = 1
for i in self.dataStore.employers.values():
- if i.name == DataStore.NO_EMPLOYER:
+ if i.name == self.dataStore.NO_EMPLOYER:
continue
self.employerChoice.addItem(i.name)
if i.name == defaultItem:
@@ -160,25 +173,23 @@
The work session start dialog
'''
- def __init__(self, dataStore, project = None, employer = None):
+ def __init__(self, dataStore, employer = None, project = None):
QDialog.__init__(self)
self.setupUi(self)
self.dataStore = dataStore
self.currentEmployer = employer
self.employerIndex = 0
self.projectIndex = 0
- self.__populateEmployerBox(employer)
- self.__populateProjectBox(project)
-
+ self.__populateEmployerBox(employer, project)
def __populateEmployerBox(
self, defaultEmployer = None, defaultProject = None):
self.ignoreComboBoxChanges = True
self.employerChoice.clear()
- self.employerChoice.addItem(self.tr("None (personal project)"))
+ self.employerChoice.addItem(self.dataStore.NO_EMPLOYER_TRANSLATED)
items = 1
for i in self.dataStore.employers.values():
- if i.name == DataStore.NO_EMPLOYER:
+ if i.name == self.dataStore.NO_EMPLOYER:
continue
self.employerChoice.addItem(i.name)
if i.name == defaultEmployer:
@@ -191,22 +202,22 @@
self.employerChoice.insertSeparator(items + 1)
self.employerChoice.addItem(self.tr("New..."))
self.projectIndex = 0
- self.__populateProjectBox(defaultProject)
+ self.__populateProjectBox(defaultProject)
self.ignoreComboBoxChanges = False
def __populateProjectBox(self, defaultItem = None):
self.ignoreComboBoxChanges = True
self.projectChoice.clear()
- self.projectChoice.addItem(self.tr("Unsorted"))
+ self.projectChoice.addItem(self.dataStore.NO_PROJECT_TRANSLATED)
items = 1
if self.employerIndex == 0:
- employerName = DataStore.NO_EMPLOYER
+ employerName = self.dataStore.NO_EMPLOYER
else:
employerName = self.employerChoice.currentText()
for i in self.dataStore.employers[employerName].projects.values():
- if i.name == DataStore.NO_PROJECT:
+ if i.name == self.dataStore.NO_PROJECT:
continue
self.projectChoice.addItem(i.name)
if i.name == defaultItem:
@@ -255,12 +266,12 @@
def accept(self):
if self.employerIndex == 0:
- employer = DataStore.NO_EMPLOYER
+ employer = self.dataStore.NO_EMPLOYER
else:
employer = self.employerChoice.currentText()
if self.projectIndex == 0:
- project = DataStore.NO_PROJECT
+ project = self.dataStore.NO_PROJECT
else:
project = self.projectChoice.currentText()
@@ -299,38 +310,38 @@
def employerBoxChanged(self, index):
if self.ignoreComboBoxChanges:
return
- if index == self.employerChoice.count() - 1:
+ """I don't think there's a use for creating new projects/employers
+ on a merely informational dialog"""
+ """if index == self.employerChoice.count() - 1:
self.ignoreComboBoxChanges = True
self.employerChoice.setCurrentIndex(self.employerIndex)
employerDialog = NewEmployerDialog(self.dataStore)
if employerDialog.exec_() == QDialog.Accepted:
self.__populateEmployerBox(employerDialog.employerNameBox.text())
- self.ignoreComboBoxChanges = False
- else:
- self.employerIndex = index
- self.__populateProjectBox()
- self.__reloadItemModel()
+ self.ignoreComboBoxChanges = False"""
+ self.employerIndex = index
+ self.__populateProjectBox()
+ self.__reloadItemModel()
def projectBoxChanged(self, index):
if self.ignoreComboBoxChanges:
return
- if index == self.projectChoice.count() - 1:
+ """I don't think there's a use for creating new projects/employers
+ on a merely informational dialog"""
+ """if index == self.projectChoice.count() - 1:
self.ignoreComboBoxChanges = True
self.projectChoice.setCurrentIndex(self.projectIndex)
projectDialog = NewProjectDialog(self.dataStore)
result = projectDialog.exec_()
- '''TODO: Reflect the other dialog's
- selections in the combo boxes'''
if projectDialog.createdEmployer:
self.__populateEmployerBox()
else:
self.__populateProjectBox()
- self.ignoreComboBoxChanges = False
- else:
- self.projectIndex = index
- self.__reloadItemModel()
+ self.ignoreComboBoxChanges = False"""
+ self.projectIndex = index
+ self.__reloadItemModel()
@@ -338,10 +349,10 @@
self, defaultEmployer = None, defaultProject = None):
self.ignoreComboBoxChanges = True
self.employerChoice.clear()
- self.employerChoice.addItem(self.tr("None (personal project)"))
+ self.employerChoice.addItem(self.dataStore.NO_EMPLOYER_TRANSLATED)
items = 1
for i in self.dataStore.employers.values():
- if i.name == DataStore.NO_EMPLOYER:
+ if i.name == self.dataStore.NO_EMPLOYER:
continue
self.employerChoice.addItem(i.name)
if i.name == defaultEmployer:
@@ -349,10 +360,12 @@
self.employerChoice.setCurrentIndex(items)
items += 1
- if(items > 1):
+ """I don't think there's a use for creating new projects/employers
+ on a merely informational dialog"""
+ """if(items > 1):
self.employerChoice.insertSeparator(1)
self.employerChoice.insertSeparator(items + 1)
- self.employerChoice.addItem(self.tr("New..."))
+ self.employerChoice.addItem(self.tr("New..."))"""
self.projectIndex = 0
self.__populateProjectBox(defaultProject)
self.ignoreComboBoxChanges = False
@@ -360,15 +373,15 @@
def __populateProjectBox(self, defaultItem = None):
self.ignoreComboBoxChanges = True
self.projectChoice.clear()
- self.projectChoice.addItem(self.tr("Unsorted"))
+ self.projectChoice.addItem(self.dataStore.NO_PROJECT_TRANSLATED)
items = 1
if self.employerIndex == 0:
- employerName = DataStore.NO_EMPLOYER
+ employerName = self.dataStore.NO_EMPLOYER
else:
employerName = self.employerChoice.currentText()
for i in self.dataStore.employers[employerName].projects.values():
- if i.name == DataStore.NO_PROJECT:
+ if i.name == self.dataStore.NO_PROJECT:
continue
self.projectChoice.addItem(i.name)
if i.name == defaultItem:
@@ -376,21 +389,23 @@
self.projectChoice.setCurrentIndex(items)
items += 1
- if(items > 1):
+ """I don't think there's a use for creating new projects/employers
+ on a merely informational dialog"""
+ """if(items > 1):
self.projectChoice.insertSeparator(1)
self.projectChoice.insertSeparator(items + 1)
- self.projectChoice.addItem(self.tr("New..."))
+ self.projectChoice.addItem(self.tr("New..."))"""
self.__reloadItemModel()
self.ignoreComboBoxChanges = False
def __reloadItemModel(self):
if self.employerChoice.currentIndex() == 0:
- employer = DataStore.NO_EMPLOYER
+ employer = self.dataStore.NO_EMPLOYER
else:
employer = self.employerChoice.currentText()
if self.projectChoice.currentIndex() == 0:
- project = DataStore.NO_PROJECT
+ project = self.dataStore.NO_PROJECT
else:
project = self.projectChoice.currentText()
Modified: trunk/src/gui/main_window.py
===================================================================
--- trunk/src/gui/main_window.py 2011-10-21 00:59:02 UTC (rev 45)
+++ trunk/src/gui/main_window.py 2011-10-21 00:59:14 UTC (rev 46)
@@ -24,6 +24,7 @@
'''
from compiled_ui import Ui_mainWindow
+from workman import DataStore
from PyQt4 import QtGui, QtCore
@@ -31,6 +32,9 @@
'''
The application's main window
'''
+
+ PROJECT_COLUMN = 0 # Indices for the project and employer columns
+ EMPLOYER_COLUMN = 1
def __init__(self, dataStore):
@@ -83,8 +87,8 @@
'''Opens the start session dialog'''
"""TODO: Get the selected project by default on the
dialog's combo box"""
-
- dialog = dialogs.StartSessionDialog(self.dataStore)
+ employer, project = self.__getSelectedProject()
+ dialog = dialogs.StartSessionDialog(self.dataStore, employer, project)
if dialog.exec_() == QtGui.QDialog.Accepted:
self.hide()
self.__setStartButton(False)
@@ -170,15 +174,44 @@
QtGui.qApp.quit()
def iconActivated(self, reason):
- if reason != QtGui.QSystemTrayIcon.Context:
+ if reason != QtGui.QSystemTrayIcon.Context:
self.showOrHide()
def showWindow(self):
- self.show()
+ self.show()
+
+ def __getSelectedProject(self):
+ '''Returns an (employer, project) tuple of the currently selected
+ row on the table'''
+
+ # Note: these indexes refer to cells, not rows.
+ selected = self.projectList.selectedIndexes()
+ if(len(selected) == 0):
+ selectedEmployer = self.dataStore.NO_EMPLOYER
+ selectedProject = self.dataStore.NO_PROJECT
+ else:
+ row = selected[0].row()
+ employerName = str(selected[0].sibling(
+ row, self.EMPLOYER_COLUMN).data().toString())
+ if(employerName == self.dataStore.NO_EMPLOYER or
+ employerName == self.dataStore.NO_EMPLOYER_TRANSLATED):
+ selectedEmployer = self.dataStore.NO_EMPLOYER
+ else:
+ selectedEmployer = employerName
+ projectName = str(selected[0].sibling(
+ row, self.PROJECT_COLUMN).data().toString())
+ if(projectName == self.dataStore.NO_PROJECT or
+ projectName == self.dataStore.NO_PROJECT_TRANSLATED):
+ selectedProject = self.dataStore.NO_PROJECT
+ else:
+ selectedProject = projectName
+
+ return (selectedEmployer, selectedProject)
def createProject(self):
'''Opens the new project dialog'''
- dialog = dialogs.NewProjectDialog(self.dataStore)
+ selectedEmployer = self.__getSelectedProject()[0]
+ dialog = dialogs.NewProjectDialog(self.dataStore, selectedEmployer)
if(dialog.exec_() == QtGui.QDialog.Accepted or
dialog.createdEmployer):
self.__reloadItemModel()
Modified: trunk/src/workman.py
===================================================================
--- trunk/src/workman.py 2011-10-21 00:59:02 UTC (rev 45)
+++ trunk/src/workman.py 2011-10-21 00:59:14 UTC (rev 46)
@@ -31,15 +31,22 @@
'''Where the program data is stored in memory'''
NO_EMPLOYER = 'None' # Not to be translated (here)
+ NO_EMPLOYER_TRANSLATED = ''
NO_EMPLOYER_DESCRIPTION = ''
NO_PROJECT = 'None' # Not to be translated (here)
- NO_PROJECT_DESCRIPTION = ''
+ NO_PROJECT_TRANSLATED = ''
+ NO_PROJECT_DESCRIPTION = ''
def __init__(self, db):
+ #: Meaning this project is for no employer
+ DataStore.NO_EMPLOYER_TRANSLATED = QtGui.qApp.tr("None (personal project)")
DataStore.NO_EMPLOYER_DESCRIPTION = QtGui.qApp.tr(
- "For personal projects")
+ "For personal projects")
+ #: Refers to the fact that this isn't any particular project
+ DataStore.NO_PROJECT_TRANSLATED = QtGui.qApp.tr("Unsorted")
DataStore.NO_PROJECT_DESCRIPTION = QtGui.qApp.tr("General work")
+
self.db = db
self.projectItemModel = None
if db is None:
@@ -79,7 +86,8 @@
def startBreak(self, reason):
assert(self.activeSession is not None and
- self.activeBreak is None)
+ self.activeBreak is None)
+ #TODO: write data to a file for disaster recovery
self.activeBreak = workman_types.Break(
self.activeSession, reason)
@@ -94,7 +102,7 @@
self.activeBreak = None
def addEmployer(self, name, description, rate):
- assert(name not in self.employers.keys() and
+ assert(name not in self.employers.keys() and
name is not None and name != '' and rate >= 0)
employer = workman_types.Employer(name, rate, description)
@@ -120,15 +128,12 @@
def __newItemModelRow(self, employerName, projectName, projDesc, hoursWorked):
if employerName == DataStore.NO_EMPLOYER:
- modelEmployerName = self.projectItemModel.tr(
- "None (personal project)")
+ modelEmployerName = DataStore.NO_EMPLOYER_TRANSLATED
else:
modelEmployerName = employerName
if projectName == DataStore.NO_PROJECT:
- modelProjectName = self.projectItemModel.tr(
- "Unsorted")
- modelDescription = self.projectItemModel.tr(
- "General work")
+ modelProjectName = DataStore.NO_PROJECT_TRANSLATED
+ modelDescription = DataStore.NO_PROJECT_DESCRIPTION
else:
modelProjectName = projectName
modelDescription = projDesc
@@ -154,7 +159,9 @@
self.projectItemModel.appendRow(
self.__newItemModelRow(
i.name, j.name, j.description, self.__getHoursWorked(j)))
-
+
+ # TODO: Make sorting case-insensitive
+
return self.projectItemModel
else:
return self.projectItemModel
@@ -253,19 +260,15 @@
return result
-
-
-
-
if __name__ == '__main__':
from gui.main_window import MainWindow
from gui.wizard import Wizard
app = QtGui.QApplication(sys.argv)
app.setQuitOnLastWindowClosed(False)
data = DataStore(None)
+ #TODO: Read a config file, create a database and show wizard if not found
y = Wizard()
y.exec_()
x = MainWindow(data)
x.show()
sys.exit(app.exec_())
-
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|