1 from PyQt4.QtCore import *
2 from PyQt4.QtGui import *
3 from PyQt4.QtSql import *
5 from chooseaction import ChooseAction
6 from editperson import EditPerson
7 from mergephotos import MergePhotos
8 from odtwriter import ODTWriter
9 from analytics import Analytics
11 class MainApp (QMainWindow):
12 schema = "CREATE TABLE people ( id INTEGER PRIMARY KEY AUTOINCREMENT, forename TEXT NOT NULL, surname TEXT NOT NULL, netid TEXT NOT NULL, email TEXT, birthday TEXT, phone TEXT, major TEXT, dorm TEXT, room INTEGER, photo BLOB, createtime TEXT NOT NULL, mtime TEXT NOT NULL);"
13 def __init__(self, Parent=None):
14 QMainWindow.__init__(self, Parent)
15 self.setWindowTitle("Whitepages V3")
17 self.db = QSqlDatabase.addDatabase("QSQLITE")
18 self.db.setDatabaseName("families.db")
20 q = QSqlQuery(self.db)
21 q.exec_(MainApp.schema)
23 self.center = QStackedWidget()
24 self.chooseaction = ChooseAction(self,self.db)
25 self.editperson = EditPerson(self,self.db)
26 self.mergephotos = MergePhotos(self,self.db)
27 self.analytics = Analytics(self,self.db)
28 self.center.addWidget(self.chooseaction)
29 self.center.addWidget(self.editperson)
30 self.center.addWidget(self.mergephotos)
31 self.center.addWidget(self.analytics)
32 self.setCentralWidget(self.center)
37 self.statusBar().showMessage("Ready")
38 self.setUnifiedTitleAndToolBarOnMac(True);
42 def createActions(self):
43 self.fileNewAction = QAction("&New Database",self)
44 QObject.connect( self.fileNewAction, SIGNAL("triggered()"), self.newFile)
45 self.fileOpenAction = QAction("&Open Database",self)
46 QObject.connect( self.fileOpenAction, SIGNAL("triggered()"), self.openFile)
47 self.fileImportAction = QAction("&Import (Merge)", self)
48 QObject.connect( self.fileImportAction, SIGNAL("triggered()"), self.mergeWizard)
49 self.fileQuitAction = QAction("&Quit",self)
50 QObject.connect( self.fileQuitAction, SIGNAL("triggered()"), self.quit)
51 QObject.connect( self.chooseaction, SIGNAL("editPerson()"), self.editPersonSlot)
52 QObject.connect( self.chooseaction, SIGNAL("mergePhotos()"), self.mergePhotosSlot)
53 QObject.connect( self.chooseaction, SIGNAL("exportDocument(QString)"), self.exportDocumentSlot)
54 QObject.connect( self.chooseaction, SIGNAL("runAnalytics()"), self.runAnalyticsSlot)
55 QObject.connect( self.editperson, SIGNAL("done()"), self.returnToMainMenu)
56 QObject.connect( self.mergephotos, SIGNAL("done()"), self.returnToMainMenu)
57 QObject.connect( self.analytics, SIGNAL("done()"), self.returnToMainMenu)
58 QObject.connect( self, SIGNAL("databaseChanged(QString)"), self.editperson.updateDB)
59 QObject.connect( self, SIGNAL("databaseChanged(QString)"), self.analytics.updateDB)
60 QObject.connect( self, SIGNAL("mergeDone()"), self.editperson.reselect )
63 def createMenus(self):
64 self.fileMenu = self.menuBar().addMenu("&File")
65 self.fileMenu.addAction(self.fileNewAction)
66 self.fileMenu.addAction(self.fileOpenAction)
67 self.fileMenu.addAction(self.fileImportAction)
68 self.fileMenu.addSeparator()
69 self.fileMenu.addAction(self.fileQuitAction)
73 fileName = QFileDialog.getSaveFileName(self, "Save new file as:", ".", "Databases (*.db)")
74 if not fileName.isEmpty(): # If they cancelled, do nothing
75 if not fileName.endsWith(".db"): # if they leave off the extension, add it
76 fileName = fileName.append(".db")
78 self.db.setDatabaseName(fileName)
80 q = QSqlQuery(self.db)
81 q.exec_(MainApp.schema)
82 self.statusBar().showMessage("Closed the existing database, created " + fileName)
83 self.emit(SIGNAL("databaseChanged(QString)"),self.db.databaseName())
85 self.statusBar().showMessage("Cancelled creating new database")
87 fileName = QFileDialog.getOpenFileName(self, "Open dataset", ".", "Databases (*.db)")
88 if not fileName.isEmpty():
90 self.db.setDatabaseName(fileName)
92 self.statusBar().showMessage("Successfully loaded database " + fileName)
93 self.returnToMainMenu()
94 self.emit(SIGNAL("databaseChanged(QString)"),self.db.databaseName())
96 self.statusBar().showMessage("Canceled loading database")
97 def mergeWizard(self):
98 fileName = QFileDialog.getOpenFileName(self, "Import which dataset?", ".", "Databases (*.db)" )
99 if not fileName.isEmpty():
100 tempdb = QSqlDatabase.addDatabase("QSQLITE","tempdb")
101 tempdb.setDatabaseName(fileName)
103 q = QSqlQuery(self.db)
104 import_q = QSqlQuery(tempdb)
105 import_q.exec_("SELECT * FROM people;")
106 rec = import_q.record()
107 col_id = rec.indexOf("id")
108 col_forename = rec.indexOf("forename")
109 col_surname = rec.indexOf("surname")
110 col_netid = rec.indexOf("netid")
111 col_email = rec.indexOf("email")
112 col_birthday = rec.indexOf("birthday")
113 col_phone = rec.indexOf("phone")
114 col_major = rec.indexOf("major")
115 col_dorm = rec.indexOf("dorm")
116 col_room = rec.indexOf("room")
117 col_photo = rec.indexOf("photo")
118 col_createtime = rec.indexOf("createtime")
119 col_mtime = rec.indexOf("mtime")
120 #print "Number of columns:",rec.count()
122 while import_q.next():
123 qtestnewnetid = QSqlQuery(self.db)
124 qtestnewnetid.prepare("SELECT * FROM people WHERE netid = :netid")
125 qtestnewnetid.bindValue(":netid", import_q.value(col_netid) )
126 qtestnewnetid.exec_()
127 if qtestnewnetid.next(): # if the person's already in the DB, keep the old data
129 q.prepare("INSERT INTO people (netid, forename, surname, email, birthday, phone, major, dorm, room, createtime, mtime, photo )"
130 "VALUES (:netid, :forename, :surname, :email, :birthday, :phone, :major, :dorm, :room, :createtime, :mtime, :photo )" )
131 q.bindValue(":netid", import_q.value(col_netid) )
132 q.bindValue(":forename", import_q.value(col_forename) )
133 q.bindValue(":surname", import_q.value(col_surname) )
134 q.bindValue(":email", import_q.value(col_email) )
135 q.bindValue(":birthday", import_q.value(col_birthday) )
136 q.bindValue(":phone", import_q.value(col_phone) )
137 q.bindValue(":major", import_q.value(col_major) )
138 q.bindValue(":dorm", import_q.value(col_dorm) )
139 q.bindValue(":room", import_q.value(col_room) )
140 q.bindValue(":createtime", import_q.value(col_createtime) )
141 q.bindValue(":mtime", import_q.value(col_mtime) )
142 q.bindValue(":photo", import_q.value(col_photo) )
144 print "Inserted", import_q.value(col_forename).toString(), import_q.value(col_surname).toString(), "into DB"
145 records_merged = records_merged + 1
146 self.statusBar().showMessage(QString("Successfully merged %1 records from %2").arg(QString(str(records_merged))).arg(fileName))
148 self.emit(SIGNAL("mergeDone()"))
150 self.statusBar().showMessage("Canceled merging databases")
152 # You could do cleanup, like closing/flushing the database, an "Are you sure you want to quit?"
153 # modal dialog, or saving the window layout/state.
155 def returnToMainMenu(self):
156 self.center.setCurrentWidget(self.chooseaction)
157 def editPersonSlot(self):
158 self.editperson.model.select() # update the table
159 self.center.setCurrentWidget(self.editperson)
160 def mergePhotosSlot(self):
161 print "beginning photo merge"
162 self.center.setCurrentWidget(self.mergephotos)
163 #self.mergephotos.beginMerge()
164 def exportDocumentSlot(self, filename):
165 writer = ODTWriter(self.db)
166 writer.write(filename)
167 def runAnalyticsSlot(self):
168 print "Running analytics"
169 self.analytics.generateReport()
170 self.center.setCurrentWidget(self.analytics)
173 if __name__ == "__main__" :
174 app = QApplication([""])