Pulling in changes from skeleton
[multilist] / src / libliststorehandler.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 """
5 This file is part of Multilist.
6
7 Multilist is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 Multilist is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Multilist.  If not, see <http://www.gnu.org/licenses/>.
19
20 Copyright (C) 2008 Christoph Würstle
21 """
22
23 from __future__ import with_statement
24
25 import ConfigParser
26 import csv
27 import uuid
28 import logging
29
30 import gtk
31
32 import gtk_toolbox
33
34 try:
35         _
36 except NameError:
37         _ = lambda x: x
38
39
40 _moduleLogger = logging.getLogger(__name__)
41
42
43 class Liststorehandler(object):
44
45         SHOW_ALL = "all"
46         SHOW_NEW = "-1"
47         SHOW_ACTIVE = "0"
48         SHOW_COMPLETE = "1"
49         ALL_FILTERS = (SHOW_ALL, SHOW_NEW, SHOW_ACTIVE, SHOW_COMPLETE)
50
51         def __init__(self, db, selection):
52                 self.db = db
53                 self.__filter = self.SHOW_ALL
54                 self.liststore = None
55                 self.unitsstore = None
56                 self.selection = selection
57                 self.collist = ("uid", "status", "title", "quantity", "unit", "price", "priority", "date", "private", "stores", "note", "custom1", "custom2")
58
59                 sql = "CREATE TABLE items (uid TEXT, list TEXT, category TEXT, status TEXT, title TEXT, quantity TEXT, unit TEXT, price TEXT, priority TEXT, date TEXT, pcdate TEXT, private TEXT, stores TEXT, note TEXT, custom1 TEXT, custom2 TEXT)"
60                 self.db.speichereSQL(sql)
61
62                 self.selection.load()
63                 self.selection.connect("changed", self.update_list)
64                 #self.selection.connect("changedCategory", self.update_category)
65
66         def save_settings(self, config, sectionName):
67                 config.set(sectionName, "filter", self.__filter)
68
69         def load_settings(self, config, sectionName):
70                 try:
71                         selectedFilter = config.get(sectionName, "filter")
72                         self.set_filter(selectedFilter)
73                 except ConfigParser.NoSectionError:
74                         pass
75                 except ConfigParser.NoOptionError:
76                         pass
77
78         def export_data(self, filename):
79                 sql = "SELECT list, category, uid, status, title, quantity, unit, price, priority, date, private, stores, note, custom1, custom2 FROM items ORDER BY list, title ASC"
80                 rows = self.db.ladeSQL(sql)
81                 with open(filename, "w") as f:
82                         csvWriter = csv.writer(f)
83                         headerRow = ["list", "category"]
84                         headerRow.extend(self.collist)
85                         csvWriter.writerow(headerRow)
86                         csvWriter.writerows(rows)
87
88         def append_data(self, filename):
89                 with open(filename, "r") as f:
90                         csvReader = csv.reader(f)
91                         for row in csvReader:
92                                 uid = str(uuid.uuid4())
93                                 row[2] = uid
94                                 sql = "INSERT INTO items (list, category, uid, status, title, quantity, unit, price, priority, date, private, stores, note, custom1, custom2) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
95                                 self.db.speichereSQL(sql, row, rowid = uid)
96                 self.db.commitSQL()
97                 self.update_list()
98
99         def set_filter(self, filter):
100                 assert filter in self.ALL_FILTERS
101                 self.__filter = filter
102                 self.update_list()
103
104         def get_filter(self):
105                 return self.__filter
106
107         def get_unitsstore(self):
108                 if self.unitsstore is None:
109                         self.unitsstore = gtk.ListStore(str, str, str, str, str, str, str, str, str, str, str, str, str)
110                 self.unitsstore.clear()
111                 #row(3) quantities
112                 #row 4 units
113                 #row 6 priority
114                 self.unitsstore.append(["-1", "-1", "", "", "", "", "", "", "", "", "", "", ""])
115                 self.unitsstore.append(["-1", "-1", "", "1", "g", "", "0", "", "", "", "", "", ""])
116                 self.unitsstore.append(["-1", "-1", "", "2", "kg", "", "1", "", "", "", "", "", ""])
117                 self.unitsstore.append(["-1", "-1", "", "3", "liter", "", "2", "", "", "", "", "", ""])
118                 self.unitsstore.append(["-1", "-1", "", "4", "packs", "", "3", "", "", "", "", "", ""])
119                 self.unitsstore.append(["-1", "-1", "", "5", "", "", "4", "", "", "", "", "", ""])
120                 self.unitsstore.append(["-1", "-1", "", "6", "", "", "5", "", "", "", "", "", ""])
121                 self.unitsstore.append(["-1", "-1", "", "7", "", "", "6", "", "", "", "", "", ""])
122                 self.unitsstore.append(["-1", "-1", "", "8", "", "", "7", "", "", "", "", "", ""])
123                 self.unitsstore.append(["-1", "-1", "", "9", "", "", "8", "", "", "", "", "", ""])
124                 self.unitsstore.append(["-1", "-1", "", "", "", "", "9", "", "", "", "", "", ""])
125
126                 return self.unitsstore
127
128         def __calculate_status(self):
129                 if self.__filter == self.SHOW_ALL:
130                         status = self.SHOW_NEW
131                 else:
132                         status = self.__filter
133                 return status
134
135         def get_liststore(self, titlesearch = ""):
136                 if self.liststore is None:
137                         self.liststore = gtk.ListStore(str, str, str, str, str, str, str, str, str, str, str, str, str)
138                 self.liststore.clear()
139
140                 titlesearch = "%"+titlesearch+"%"
141
142                 if self.__filter != self.SHOW_ALL:
143                         status = self.__calculate_status()
144                         sql = "SELECT uid, status, title, quantity, unit, price, priority, date, private, stores, note, custom1, custom2 FROM items WHERE list = ? AND category LIKE ? AND status = ? AND title like ? ORDER BY category, status, title"
145                         rows = self.db.ladeSQL(sql, (self.selection.get_list(), self.selection.get_category(True), status, titlesearch))
146                 else:
147                         sql = "SELECT uid, status, title, quantity, unit, price, priority, date, private, stores, note, custom1, custom2 FROM items WHERE list = ? AND category LIKE ? AND title LIKE ? ORDER BY category, title ASC"
148                         rows = self.db.ladeSQL(sql, (self.selection.get_list(), self.selection.get_category(True), titlesearch))
149
150                 if rows is not None:
151                         for row in rows:
152                                 uid, status, title, quantity, unit, price, priority, date, private, stores, note, custom1, custom2 = row
153                                 if unit is None:
154                                         unit = ""
155                                 self.liststore.append([uid, status, title, quantity, unit, price, priority, date, private, stores, note, custom1, custom2])
156
157                 return self.liststore
158
159         def emptyValueExists(self):
160                 for child in self.liststore:
161                         if child[2] == "":
162                                 return True
163                 return False
164
165         def update_row(self, irow, icol, new_text):
166                 if -1 < irow and self.liststore[irow][0] != "-1" and self.liststore[irow][0] is not None:
167                         sql = "UPDATE items SET "+self.collist[icol]+" = ? WHERE uid = ?"
168                         self.db.speichereSQL(sql, (new_text, self.liststore[irow][0]), rowid = self.liststore[irow][0])
169
170                         _moduleLogger.info("Updated row: "+self.collist[icol]+" new text "+new_text+" Titel: "+str(self.liststore[irow][2])+" with uid "+str(self.liststore[irow][0]))
171
172                         self.liststore[irow][icol] = new_text
173                 else:
174                         _moduleLogger.warning("update_row: row does not exist")
175                         return
176
177         def checkout_rows(self):
178                 sql = "UPDATE items SET status = ? WHERE list = ? AND category LIKE ? AND status = ?"
179                 self.db.speichereSQL(sql, (self.SHOW_NEW, self.selection.get_list(), self.selection.get_category(True), self.SHOW_COMPLETE))
180                 for i in range(len(self.liststore)):
181                         if self.liststore[i][1] == self.SHOW_COMPLETE:
182                                 self.liststore[i][1] = self.SHOW_NEW
183
184         def add_row(self, title = ""):
185                 status = self.__calculate_status()
186                 uid = str(uuid.uuid4())
187                 sql = "INSERT INTO items (uid, list, category, status, title) VALUES (?, ?, ?, ?, ?)"
188                 self.db.speichereSQL(sql, (uid, self.selection.get_list(), self.selection.get_category(), status, title), rowid = uid)
189                 _moduleLogger.info("Insertet row: status = "+status+" with uid "+str(uid))
190
191                 self.liststore.append([uid, status, title, " ", "", "", "", "", "", "", "", "", ""])
192                 self.selection.comboLists_check_for_update()
193
194         def del_row(self, irow, row_iter):
195                 uid = self.liststore[irow][0]
196                 self.liststore.remove(row_iter)
197                 sql = "DELETE FROM items WHERE uid = ?"
198                 self.db.speichereSQL(sql, (uid, ))
199
200         def get_colname(self, i):
201                 if i < len(self.collist):
202                         return self.collist[i]
203                 else:
204                         return None
205
206         def get_colcount(self):
207                 return len(self.collist)
208
209         def rename_category(self, new_name):
210                 sql = "UPDATE items SET category = ? WHERE list = ? AND category = ?"
211                 self.db.speichereSQL(sql, (new_name, self.selection.get_list(), self.selection.get_category()))
212                 self.selection.update_categories()
213                 self.selection.set_category(new_name)
214
215         def rename_list(self, new_name):
216                 sql = "UPDATE items SET list = ? WHERE list = ?"
217                 self.db.speichereSQL(sql, (new_name, self.selection.get_list(), ))
218                 self.selection.load()
219                 self.selection.set_list(new_name)
220
221         #@gtk_toolbox.log_exception(_moduleLogger)
222         #def update_category(self, widget = None, data = None, data2 = None, data3 = None):
223         #       self.get_liststore()
224
225         @gtk_toolbox.log_exception(_moduleLogger)
226         def update_list(self, widget = None, data = None, data2 = None, data3 = None):
227                 self.get_liststore()