86e9b12a08be7f6aa9641767e09c4a5d6cf3b3e4
[biaweb_qt.git] / main_window.py
1 # BiaWeb Website content manager (c) 2010 V.Harishankar
2 # Main Window class
3
4 import PyQt4
5 import sys
6
7 import ui_main_window
8 import site_configuration_dialog as scd
9 import category_dialog as catd
10 import article_dialog as artd
11 import templates_dialog as tpld
12 import generate_dialog as gend
13 import biaweb_db
14
15 class MainWindow (PyQt4.QtGui.QMainWindow, ui_main_window.Ui_MainWindow):
16 def __init__ (self):
17 PyQt4.QtGui.QMainWindow.__init__ (self)
18 self.setupUi (self)
19 self.current_db = None
20
21 # refresh the category list
22 def repopulate_categories (self):
23 recs = biaweb_db.get_categories (self.current_db)
24
25 # check with False because None is returned when no records exist
26 if recs == False:
27 PyQt4.QtGui.QMessageBox.critical (self, "Error", "SQLite 3 error in getting the categories")
28 return
29
30 self.categories.clear ()
31 for (id, name, desc, stub) in recs:
32 qrow = PyQt4.QtGui.QTreeWidgetItem ([str(id), str(name)])
33 self.categories.addTopLevelItem (qrow)
34
35 # refresh the articles list
36 def repopulate_articles (self, catid=None):
37 recs = biaweb_db.get_articles (self.current_db, catid)
38
39 # check with False because None is returned when no records exist
40 if recs == False:
41 PyQt4.QtGui.QMessageBox.critical (self, "Error", "SQLite 3 error in getting the articles")
42 return
43
44 self.articles.clear ()
45 for item in recs:
46 qrow = PyQt4.QtGui.QTreeWidgetItem ([str(item[0]), str(item[1])])
47 self.articles.addTopLevelItem (qrow)
48
49 # when the view is refreshed
50 def onViewRefresh (self):
51 if self.current_db is not None:
52 self.repopulate_categories ()
53 self.repopulate_articles ()
54
55 # when add article is triggered
56 def onArticleAdd (self):
57 if self.current_db is None:
58 PyQt4.QtGui.QMessageBox.critical (self, "Error",
59 "Cannot create article. You need to create or open a website first")
60 else:
61 catid = self.get_selected_item_id (self.categories)
62 # if no category is selected
63 if catid is None:
64 PyQt4.QtGui.QMessageBox.critical (self, "Error", "No category selected for article")
65 return
66 artdlg = artd.ArticleDialog (self)
67 cats = biaweb_db.get_categories (self.current_db)
68
69 artdlg.populate_categories (cats, catid)
70
71 # if OK is pressed
72 if artdlg.exec_ () == PyQt4.QtGui.QDialog.Accepted:
73 title = str (artdlg.article_title.text ()).strip ()
74 keywords = str (artdlg.keywords.text ()).strip ()
75 summary = str (artdlg.summary.toPlainText ()).strip ()
76 content = str (artdlg.content.toPlainText ()).strip ()
77 cid, ok = artdlg.category.itemData (artdlg.category.currentIndex ()).toInt ()
78 # if catid is not an integer then abort
79 if not ok:
80 return
81 rating = artdlg.rating.value ()
82 stub = str (artdlg.stub.text ()).strip ()
83
84 ret = biaweb_db.create_article (self.current_db, title, summary, keywords, content, cid,
85 stub, rating)
86 if ret:
87 PyQt4.QtGui.QMessageBox.information (self, "Success", "Article successfully created")
88 self.repopulate_categories ()
89 self.repopulate_articles (catid)
90 else:
91 PyQt4.QtGui.QMessageBox.critical (self, "Error", "SQLite 3 error in creating article")
92
93 # when edit article is triggered
94 def onArticleEdit (self):
95 if self.current_db is None:
96 PyQt4.QtGui.QMessageBox.critical (self, "Error",
97 "Cannot edit article. You need to create or open a website first")
98 else:
99 # get the selected article
100 artid = self.get_selected_item_id (self.articles)
101 catid = self.get_selected_item_id (self.categories)
102
103 # no article is selected
104 if artid is None:
105 PyQt4.QtGui.QMessageBox.critical (self, "Error", "No article selected")
106 return
107 article = biaweb_db.get_article (self.current_db, artid)
108 # if article cannot be read
109 if not article:
110 PyQt4.QtGui.QMessageBox.critical (self, "Error", "SQLite 3 error in reading article")
111 return
112 artdlg = artd.ArticleDialog (self)
113
114 artdlg.article_title.setText (article[1])
115 artdlg.summary.setPlainText (article[2])
116 artdlg.keywords.setText (article[3])
117 artdlg.content.setPlainText (article[4])
118 # populate category combo box and set active category to the article's category
119 cats = biaweb_db.get_categories (self.current_db)
120 artdlg.populate_categories (cats, article[7])
121 artdlg.stub.setText (article[8])
122 artdlg.rating.setValue (article[9])
123
124 # ok is pressed
125 if artdlg.exec_ () == PyQt4.QtGui.QDialog.Accepted:
126 title = str (artdlg.article_title.text ()).strip ()
127 summary = str (artdlg.summary.toPlainText ()).strip ()
128 keywords = str (artdlg.keywords.text ()).strip ()
129 content = str (artdlg.content.toPlainText ()).strip ()
130 cid, ok = artdlg.category.itemData (artdlg.category.currentIndex()).toInt ()
131 # if cat id is not an integer
132 if not ok:
133 return
134 rating = artdlg.rating.value ()
135 stub = str (artdlg.stub.text ()).strip ()
136 ret = biaweb_db.update_article (self.current_db, artid, title,
137 summary, keywords, content, cid, stub, rating)
138 if ret:
139 PyQt4.QtGui.QMessageBox.information (self, "Success", "Article successfully updated")
140 self.repopulate_articles (catid)
141 else:
142 PyQt4.QtGui.QMessageBox.critical (self, "Error", "SQLite 3 error in updating article")
143
144 # when delete article is triggered
145 def onArticleDelete (self):
146 if self.current_db is None:
147 PyQt4.QtGui.QMessageBox.critical (self, "Error",
148 "Cannot delete article. You need to create or open a website first")
149 else:
150 # get the selected article
151 artid = self.get_selected_item_id (self.articles)
152 catid = self.get_selected_item_id (self.categories)
153 if artid is None:
154 PyQt4.QtGui.QMessageBox.critical (self, "Error", "No article selected")
155 return
156 # get confirmation on delete
157 flag = PyQt4.QtGui.QMessageBox.question (self, "Confirm",
158 "Are you sure you wish to delete the selected article?",
159 PyQt4.QtGui.QMessageBox.Yes, PyQt4.QtGui.QMessageBox.No)
160 # confirmed
161 if flag == PyQt4.QtGui.QMessageBox.Yes:
162 ret = biaweb_db.delete_article (self.current_db, artid)
163 if not ret:
164 PyQt4.QtGui.QMessageBox.critical (self, "Error", "SQLite 3 error in deleting article")
165 else:
166 self.repopulate_articles (catid)
167
168 # when category item is activated
169 def onCategoryItemActivated (self):
170 self.onCategoryEdit ()
171
172 # when article item is activated
173 def onArticleItemActivated (self):
174 self.onArticleEdit ()
175
176 # when item selection is changed in categories tree widget
177 def onCategorySelectionChanged (self):
178 if self.current_db is not None:
179 catid = self.get_selected_item_id (self.categories)
180 self.repopulate_articles (catid)
181
182 # when configuration menu is triggered
183 def onConfiguration (self):
184 if self.current_db is None:
185 PyQt4.QtGui.QMessageBox.critical (self, "Error",
186 "Cannot edit configuration. You need to create or open a website first")
187 else:
188 dlg = scd.SiteConfigDialog (self)
189 configs = biaweb_db.get_configuration (self.current_db)
190
191 if not configs:
192 PyQt4.QtGui.QMessageBox.critical (self, "Error", "SQLite 3 error in reading configuration")
193 return
194
195 # set the data
196 dlg.site_url.setText (configs[0])
197 dlg.site_title.setText (configs[1])
198 dlg.keywords.setText (configs[2])
199 dlg.description.setPlainText (configs[3])
200 dlg.num_rss_items.setValue (configs[4])
201 dlg.destination.setText (configs[5])
202 dlg.copyright.setText (configs[6])
203
204 if (dlg.exec_ () == PyQt4.QtGui.QDialog.Accepted):
205 # if accepted, get the data and store in database
206 site_title = str (dlg.site_title.text ()).strip ()
207 site_url = str (dlg.site_url.text ()).strip ()
208 keywords = str (dlg.keywords.text ()).strip ()
209 destination = str (dlg.destination.text ()).strip ()
210 description = str (dlg.description.toPlainText ()).strip ()
211 num_rss = dlg.num_rss_items.value ()
212 copyright = str (dlg.copyright.text ()).strip ()
213 # database update
214 flag = biaweb_db.set_configuration (self.current_db, site_title, site_url, keywords, description,
215 copyright, num_rss, destination)
216 if not flag:
217 PyQt4.QtGui.QMessageBox.critical (self, "Error",
218 "SQLite 3 error in updating configuration")
219
220 # when templates menu is triggered
221 def onTemplates (self):
222 if self.current_db is None:
223 PyQt4.QtGui.QMessageBox.critical (self, "Error",
224 "Cannot edit templates. You need to create or open a website first")
225 else:
226 tdlg = tpld.TemplatesDialog (self, self.current_db)
227 tdlg.exec_ ()
228
229 # function to get the category or article ID from current selected item in a tree widget
230 def get_selected_item_id (self, twidget):
231 selitems = twidget.selectedItems ()
232 if selitems:
233 # get the first column data as integer
234 selindex = selitems[0].data(0, 0).toInt ()[0]
235 return selindex
236 else:
237 return None
238
239 # category edit action
240 def onCategoryEdit (self):
241 # if no database is open
242 if self.current_db is None:
243 PyQt4.QtGui.QMessageBox.critical (self, "Error",
244 "Cannot edit category. You need to create or open a website first")
245 # database is open
246 else:
247 catid = self.get_selected_item_id (self.categories)
248 # if no category is selected, display an error
249 if catid is None:
250 PyQt4.QtGui.QMessageBox.critical (self, "Error", "No category selected")
251 # category is selected
252 else:
253 cat = biaweb_db.get_category (self.current_db, catid)
254 # if the category cannot be retrieved from database
255 if not cat:
256 PyQt4.QtGui.QMessageBox.critical (self, "Error", "SQLite 3 error in reading category")
257 return
258
259 # set the data in the dialog
260 dlg = catd.CategoryDialog (self)
261 dlg.category_name.setText (cat[1])
262 dlg.category_desc.setText (cat[2])
263 dlg.category_stub.setText (cat[3])
264
265 # if accepted
266 if dlg.exec_ () == PyQt4.QtGui.QDialog.Accepted:
267 category_name = str (dlg.category_name.text ()).strip ()
268 category_desc = str (dlg.category_desc.text ()).strip ()
269 category_stub = str (dlg.category_stub.text ()).strip ()
270
271 ret = biaweb_db.update_category (self.current_db,
272 catid, category_name, category_desc, category_stub)
273 if ret:
274 PyQt4.QtGui.QMessageBox.information (self, "Success", "Category successfully updated")
275 self.repopulate_categories ()
276 else:
277 PyQt4.QtGui.QMessageBox.critical (self, "Error", "SQLite 3 error in updating category")
278
279
280 # category delete action
281 def onCategoryDelete (self):
282 # if there is no database
283 if self.current_db is None:
284 PyQt4.QtGui.QMessageBox.critical (self, "Error",
285 "Cannot delete category. You need to create or open a website first")
286 else:
287 # get the selected category
288 catid = self.get_selected_item_id (self.categories)
289 if catid is None:
290 PyQt4.QtGui.QMessageBox.critical (self, "Error", "No category selected")
291 # category is selected
292 else:
293 # get confirmation first
294 flag = PyQt4.QtGui.QMessageBox.question (self, "Confirm",
295 "This will delete the category and all associated articles. Are you sure you wish to continue?",
296 PyQt4.QtGui.QMessageBox.Yes, PyQt4.QtGui.QMessageBox.No)
297 # if confirmed
298 if flag == PyQt4.QtGui.QMessageBox.Yes:
299 ret = biaweb_db.remove_category (self.current_db, catid)
300 if not ret:
301 PyQt4.QtGui.QMessageBox.critical (self, "Error", "SQLite 3 error in deleting category")
302 else:
303 self.repopulate_categories ()
304 self.repopulate_articles ()
305
306 # category add action
307 def onCategoryAdd (self):
308 # if there is no database
309 if self.current_db is None:
310 PyQt4.QtGui.QMessageBox.critical (self, "Error",
311 "Cannot add category. You need to create or open a website first")
312 else:
313 # show the category add dialog
314 dlg = catd.CategoryDialog (self)
315 # if OK button is pressed
316 if dlg.exec_ () == PyQt4.QtGui.QDialog.Accepted:
317 cat_name = str (dlg.category_name.text ()).strip ()
318 cat_desc = str (dlg.category_desc.text ()).strip ()
319 cat_stub = str (dlg.category_stub.text ()).strip ()
320 ret = biaweb_db.create_category (self.current_db, cat_name, cat_desc, cat_stub)
321 if ret:
322 PyQt4.QtGui.QMessageBox.information (self, "Success", "Category successfully created")
323 self.repopulate_categories ()
324 self.repopulate_articles ()
325 else:
326 PyQt4.QtGui.QMessageBox.critical (self, "Error", "SQLite 3 error in creating category")
327
328 # file open menu is clicked
329 def onFileOpen (self):
330 filename = PyQt4.QtGui.QFileDialog.getOpenFileName (self, "Open Site Database")
331 if filename:
332 self.current_db = str (filename)
333 self.setWindowTitle ("BiaWeb - " + self.current_db)
334 self.repopulate_categories ()
335 self.repopulate_articles ()
336
337 # file new menu is clicked
338 def onFileNew (self):
339 # show the site configuration dialog to get the new site details
340 dlg = scd.SiteConfigDialog (self)
341 # if OK button is pressed
342 if dlg.exec_ () == PyQt4.QtGui.QDialog.Accepted:
343 site_title = str (dlg.site_title.text ()).strip ()
344 site_url = str (dlg.site_url.text ()).strip ()
345 keywords = str (dlg.keywords.text ()).strip ()
346 destination = str (dlg.destination.text ()).strip ()
347 description = str (dlg.description.toPlainText ()).strip ()
348 num_rss = dlg.num_rss_items.value ()
349 copyright = str (dlg.copyright.text ()).strip ()
350
351 savefilename = PyQt4.QtGui.QFileDialog.getSaveFileName (self, "Save site database to")
352
353 if savefilename:
354 self.current_db = str (savefilename)
355 self.setWindowTitle ("BiaWeb - " + self.current_db)
356 flag = biaweb_db.create_db (self.current_db, site_title, site_url, keywords, description,
357 copyright, num_rss, destination)
358 if flag:
359 PyQt4.QtGui.QMessageBox.information (self, "Success",
360 "New site db successfully created")
361 self.articles.clear ()
362 self.categories.clear ()
363 else:
364 PyQt4.QtGui.QMessageBox.critical (self, "Error", "System or SQLite 3 error in creating database")
365
366 # when generate site menu is triggered
367 def onGenerateSite (self):
368 if self.current_db is None:
369 PyQt4.QtGui.QMessageBox.critical (self, "Error",
370 "Cannot generate site. You need to create or open a website first")
371 else:
372 # run the generate site dialog
373 gendlg = gend.GenerateDialog (self, self.current_db)
374 gendlg.exec_ ()
375
376 # about menu is triggered
377 def onAbout (self):
378 PyQt4.QtGui.QMessageBox.about (self, "BiaWeb Qt",
379 "<b>A static website/weblog content management system</b><br /><br />\
380 Copyright &copy; 2010 <a href=\"http://www.harishankar.org\">Harishankar</a><br />\
381 Licensed under GNU/GPL v3")
382
383 # file quit is clicked
384 def onFileQuit (self):
385 sys.exit (0)