893a3545bb3dcedd81d631d76b41a33645b15ac1
[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 import ConfigParser
24 import csv
25 import uuid
26 import logging
27
28 import gtk
29
30 import gtk_toolbox
31
32 try:
33         _
34 except NameError:
35         _ = lambda x: x
36
37
38 _moduleLogger = logging.getLogger(__name__)
39
40
41 class Liststorehandler(object):
42
43         SHOW_ALL = "all"
44         SHOW_NEW = "-1"
45         SHOW_ACTIVE = "0"
46         SHOW_COMPLETE = "1"
47         ALL_FILTERS = (SHOW_ALL, SHOW_NEW, SHOW_ACTIVE, SHOW_COMPLETE)
48
49         def __init__(self, db, selection):
50                 self.db = db
51                 self.__filter = self.SHOW_ALL
52                 self.liststore = None
53                 self.unitsstore = None
54                 self.selection = selection
55                 self.collist = ("uid", "status", "title", "quantity", "unit", "price", "priority", "date", "private", "stores", "note", "custom1", "custom2")
56
57                 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)"
58                 self.db.speichereSQL(sql)
59
60                 self.selection.load()
61                 self.selection.connect("changed", self.update_list)
62                 #self.selection.connect("changedCategory", self.update_category)
63
64         def save_settings(self, config, sectionName):
65                 config.set(sectionName, "filter", self.__filter)
66
67         def load_settings(self, config, sectionName):
68                 try:
69                         selectedFilter = config.get(sectionName, "filter")
70                         self.set_filter(selectedFilter)
71                 except ConfigParser.NoSectionError:
72                         pass
73                 except ConfigParser.NoOptionError:
74                         pass
75
76         def export_data(self, filename):
77                 sql = "SELECT list, category, uid, status, title, quantity, unit, price, priority, date, private, stores, note, custom1, custom2 FROM items ORDER BY list, title ASC"
78                 rows = self.db.ladeSQL(sql)
79                 with open(filename, "w") as f:
80                         csvWriter = csv.writer(f)
81                         headerRow = ["list", "category"]
82                         headerRow.extend(self.collist)
83                         csvWriter.writerow(headerRow)
84                         csvWriter.writerows(rows)
85
86         def append_data(self, filename):
87                 with open(filename, "r") as f:
88                         csvReader = csv.reader(f)
89                         for row in csvReader:
90                                 uid = str(uuid.uuid4())
91                                 row[2] = uid
92                                 sql = "INSERT INTO items (list, category, uid, status, title, quantity, unit, price, priority, date, private, stores, note, custom1, custom2) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
93                                 self.db.speichereSQL(sql, row, rowid = uid)
94                 self.db.commitSQL()
95                 self.update_list()
96
97         def set_filter(self, filter):
98                 assert filter in self.ALL_FILTERS
99                 self.__filter = filter
100                 self.update_list()
101
102         def get_filter(self):
103                 return self.__filter
104
105         def get_unitsstore(self):
106                 if self.unitsstore is None:
107                         self.unitsstore = gtk.ListStore(str, str, str, str, str, str, str, str, str, str, str, str, str)
108                 self.unitsstore.clear()
109                 #row(3) quantities
110                 #row 4 units
111                 #row 6 priority
112                 self.unitsstore.append(["-1", "-1", "", "", "", "", "", "", "", "", "", "", ""])
113                 self.unitsstore.append(["-1", "-1", "", "1", "g", "", "0", "", "", "", "", "", ""])
114                 self.unitsstore.append(["-1", "-1", "", "2", "kg", "", "1", "", "", "", "", "", ""])
115                 self.unitsstore.append(["-1", "-1", "", "3", "liter", "", "2", "", "", "", "", "", ""])
116                 self.unitsstore.append(["-1", "-1", "", "4", "packs", "", "3", "", "", "", "", "", ""])
117                 self.unitsstore.append(["-1", "-1", "", "5", "", "", "4", "", "", "", "", "", ""])
118                 self.unitsstore.append(["-1", "-1", "", "6", "", "", "5", "", "", "", "", "", ""])
119                 self.unitsstore.append(["-1", "-1", "", "7", "", "", "6", "", "", "", "", "", ""])
120                 self.unitsstore.append(["-1", "-1", "", "8", "", "", "7", "", "", "", "", "", ""])
121                 self.unitsstore.append(["-1", "-1", "", "9", "", "", "8", "", "", "", "", "", ""])
122                 self.unitsstore.append(["-1", "-1", "", "", "", "", "9", "", "", "", "", "", ""])
123
124                 return self.unitsstore
125
126         def __calculate_status(self):
127                 if self.__filter == self.SHOW_ALL:
128                         status = self.SHOW_NEW
129                 else:
130                         status = self.__filter
131                 return status
132
133         def get_liststore(self, titlesearch = ""):
134                 if self.liststore is None:
135                         self.liststore = gtk.ListStore(str, str, str, str, str, str, str, str, str, str, str, str, str)
136                 self.liststore.clear()
137
138                 titlesearch = "%"+titlesearch+"%"
139
140                 if self.__filter != self.SHOW_ALL:
141                         status = self.__calculate_status()
142                         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"
143                         rows = self.db.ladeSQL(sql, (self.selection.get_list(), self.selection.get_category(True), status, titlesearch))
144                 else:
145                         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"
146                         rows = self.db.ladeSQL(sql, (self.selection.get_list(), self.selection.get_category(True), titlesearch))
147
148                 if rows is not None:
149                         for row in rows:
150                                 uid, status, title, quantity, unit, price, priority, date, private, stores, note, custom1, custom2 = row
151                                 if unit is None:
152                                         unit = ""
153                                 self.liststore.append([uid, status, title, quantity, unit, price, priority, date, private, stores, note, custom1, custom2])
154
155                 return self.liststore
156
157         def emptyValueExists(self):
158                 for child in self.liststore:
159                         if child[2] == "":
160                                 return True
161                 return False
162
163         def update_row(self, irow, icol, new_text):
164                 if -1 < irow and self.liststore[irow][0] != "-1" and self.liststore[irow][0] is not None:
165                         sql = "UPDATE items SET "+self.collist[icol]+" = ? WHERE uid = ?"
166                         self.db.speichereSQL(sql, (new_text, self.liststore[irow][0]), rowid = self.liststore[irow][0])
167
168                         _moduleLogger.info("Updated row: "+self.collist[icol]+" new text "+new_text+" Titel: "+str(self.liststore[irow][2])+" with uid "+str(self.liststore[irow][0]))
169
170                         self.liststore[irow][icol] = new_text
171                 else:
172                         _moduleLogger.warning("update_row: row does not exist")
173                         return
174
175         def checkout_rows(self):
176                 sql = "UPDATE items SET status = ? WHERE list = ? AND category LIKE ? AND status = ?"
177                 self.db.speichereSQL(sql, (self.SHOW_NEW, self.selection.get_list(), self.selection.get_category(True), self.SHOW_COMPLETE))
178                 for i in range(len(self.liststore)):
179                         if self.liststore[i][1] == self.SHOW_COMPLETE:
180                                 self.liststore[i][1] = self.SHOW_NEW
181
182         def add_row(self, title = ""):
183                 status = self.__calculate_status()
184                 uid = str(uuid.uuid4())
185                 sql = "INSERT INTO items (uid, list, category, status, title) VALUES (?, ?, ?, ?, ?)"
186                 self.db.speichereSQL(sql, (uid, self.selection.get_list(), self.selection.get_category(), status, title), rowid = uid)
187                 _moduleLogger.info("Insertet row: status = "+status+" with uid "+str(uid))
188
189                 self.liststore.append([uid, status, title, " ", "", "", "", "", "", "", "", "", ""])
190                 self.selection.comboLists_check_for_update()
191
192         def del_row(self, irow, row_iter):
193                 uid = self.liststore[irow][0]
194                 self.liststore.remove(row_iter)
195                 sql = "DELETE FROM items WHERE uid = ?"
196                 self.db.speichereSQL(sql, (uid, ))
197
198         def get_colname(self, i):
199                 if i < len(self.collist):
200                         return self.collist[i]
201                 else:
202                         return None
203
204         def get_colcount(self):
205                 return len(self.collist)
206
207         def rename_category(self, new_name):
208                 sql = "UPDATE items SET category = ? WHERE list = ? AND category = ?"
209                 self.db.speichereSQL(sql, (new_name, self.selection.get_list(), self.selection.get_category()))
210                 self.selection.update_categories()
211                 self.selection.set_category(new_name)
212
213         def rename_list(self, new_name):
214                 sql = "UPDATE items SET list = ? WHERE list = ?"
215                 self.db.speichereSQL(sql, (new_name, self.selection.get_list(), ))
216                 self.selection.load()
217                 self.selection.set_list(new_name)
218
219         #@gtk_toolbox.log_exception(_moduleLogger)
220         #def update_category(self, widget = None, data = None, data2 = None, data3 = None):
221         #       self.get_liststore()
222
223         @gtk_toolbox.log_exception(_moduleLogger)
224         def update_list(self, widget = None, data = None, data2 = None, data3 = None):
225                 self.get_liststore()