From: Drew Fisher Date: Sat, 12 Sep 2009 19:12:08 +0000 (-0500) Subject: ODT exporter, done right. X-Git-Url: http://git.zarvox.org/static/%24c%5B5%5D?a=commitdiff_plain;h=52cbbcb1eab2c951a89b19d362bc433724d3668d;p=wp3.git ODT exporter, done right. This commit adds support for actually exporting the document in some fashion that would actually be worth printing. I couldn't figure out how to make the tables stick to one page or the next, so you still have to manually insert page breaks (and of course, check for any other visual defects). In general, though, this should minimize the amount of manual effort that you have to put into preparing the document for printing. --- diff --git a/mainapp.py b/mainapp.py index 037c082..0dd18e6 100644 --- a/mainapp.py +++ b/mainapp.py @@ -163,7 +163,11 @@ class MainApp (QMainWindow): #self.mergephotos.beginMerge() def exportDocumentSlot(self, filename): writer = ODTWriter(self.db) - writer.write(filename) + success = writer.write(filename) + if success: + self.statusBar().showMessage(QString("Successfully exported to %1").arg(filename)) + else: + self.statusBar().showMessage(QString("Document export cancelled or failed")) def runAnalyticsSlot(self): print "Running analytics" self.analytics.generateReport() diff --git a/odtwriter.py b/odtwriter.py index ddaf83b..14de92c 100644 --- a/odtwriter.py +++ b/odtwriter.py @@ -9,13 +9,20 @@ class ODTWriter(): def write(self, filename): doc = QTextDocument() cur = QTextCursor(doc) + cur.movePosition(QTextCursor.Start) defaultFormat = QTextCharFormat() - defaultFormat.setFontPointSize(12) + defaultFormat.setFontPointSize(8) + defaultFormat.setFontFamily("Serif") nameFormat = QTextCharFormat() - nameFormat.setFontPointSize(12) + nameFormat.setFontPointSize(10) nameFormat.setFontWeight(QFont.Bold) q = QSqlQuery(self.db) - q.exec_("SELECT * FROM people") + q.exec_("SELECT id FROM people") + rec = q.record() + total = 0 + while q.next(): + total = total + 1 + q.exec_("SELECT * FROM people ORDER BY surname, forename") rec = q.record() col_id = rec.indexOf("id") col_forename = rec.indexOf("forename") @@ -30,34 +37,93 @@ class ODTWriter(): col_photo = rec.indexOf("photo") col_createtime = rec.indexOf("createtime") col_mtime = rec.indexOf("mtime") + topFrame = cur.currentFrame() + n = 0 + + progress = QProgressDialog("Preparing document...", "Cancel", 0, total) + progress.setWindowModality(Qt.WindowModal) + progress.setMinimumDuration(0) + while q.next(): - # Write this record to the document - id = q.value(col_id).toString() - forename = q.value(col_forename).toString() - surname = q.value(col_surname).toString() - email = q.value(col_email).toString() - birthday = q.value(col_birthday).toString() - phone = q.value(col_phone).toString() - if phone.localeAwareCompare(QString("()==")) == 0: # if they didn't put one in the DB - phone = QString("") - photo_bin = q.value(col_photo).toByteArray() - photo = QImage() - photo.loadFromData(photo_bin) - # We probably need to normalize photo size here, or set up a QTextFrameFormat - if photo.isNull(): # make a black photo for people without one - photo = QImage(100,100,QImage.Format_RGB32) - photo.fill(0) - print "No photo for",forename,surname - name = QString("mydata://") + id + QString(".jpg") - doc.addResource(QTextDocument.ImageResource, QUrl(name), photo) - imageFormat = QTextImageFormat() - imageFormat.setName(name) - imageFormat.setHeight(100.) - imageFormat.setWidth(100.) -# cur.insertImage(photo) - cur.insertText(QString("%1 %2\n").arg(forename).arg(surname), nameFormat ) - cur.insertText(QString("%1").arg(q.value(col_email).toString()), defaultFormat) - cur.insertImage(imageFormat, QTextFrameFormat.FloatLeft) - cur.insertText(QString("\n") , defaultFormat) + table_row = [] + while len(table_row) < 2: + progress.setValue(n) + if progress.wasCanceled(): + progress.setValue(total) + return False + progress.setLabelText(QString("Adding %1 %2").arg(q.value(col_forename).toString()).arg(q.value(col_surname).toString())) + n = n + 1 + # Write this record to the document + id = q.value(col_id).toString() + phone = q.value(col_phone).toString() + if phone.size() == 4: # if they didn't put one in the DB + phone = QString("") + photo_bin = q.value(col_photo).toByteArray() + photo = QImage() + photo.loadFromData(photo_bin) + if photo.isNull(): # make a black photo for people without one + photo = QImage(1,1,QImage.Format_RGB32) + photo.fill(0) + print str(QString("No photo for %1 %2").arg(q.value(col_forename).toString()).arg(q.value(col_surname).toString())) + else: # Shrink what is probably a ~20MB pixel buffer into something slightly more usable + photo = photo.scaled( 400, 400, Qt.KeepAspectRatio, Qt.SmoothTransformation) + name = QString("mydata://") + id + QString(".jpg") + doc.addResource(QTextDocument.ImageResource, QUrl(name), photo) + imageFormat = QTextImageFormat() + imageFormat.setName(name) + imageFormat.setHeight(99.) + imageFormat.setWidth(132.) + imageFormat.setVerticalAlignment(QTextCharFormat.AlignMiddle) + table_row.append({ "imageformat": imageFormat, + "forename": q.value(col_forename).toString(), + "surname" : q.value(col_surname).toString(), + "email" : q.value(col_email).toString(), + "phone" : phone, + "birthday" : q.value(col_birthday).toString(), + "dorm" : q.value(col_dorm).toString(), + "room" : q.value(col_room).toString() } ) + if len(table_row) < 2: + if not q.next(): + break + # Now table_row has either: + # - Two records in sequence + # - The lone final record + tableformat = QTextTableFormat() + tableformat.setAlignment(Qt.AlignCenter) + tableformat.setPageBreakPolicy(QTextFormat.PageBreak_AlwaysAfter) + table = cur.insertTable(5, 4, tableformat) + table.mergeCells(0,0,5,1) + table.mergeCells(0,2,5,1) + for i in xrange(len(table_row)): + p = table_row[i] + cur.insertText(QString(" ")) + cur.insertImage(p["imageformat"], QTextFrameFormat.FloatLeft) + cur.movePosition(QTextCursor.NextCell) + cur.insertText(QString("%1 %2").arg(p["forename"]).arg(p["surname"]), nameFormat ) + cur.movePosition(QTextCursor.Down) + cur.insertText(QString("%1").arg(p["email"]), defaultFormat) + cur.movePosition(QTextCursor.Down) + cur.insertText(QString("%1").arg(p["phone"]), defaultFormat) + cur.movePosition(QTextCursor.Down) + cur.insertText(QString("%1").arg(p["birthday"]), defaultFormat) + cur.movePosition(QTextCursor.Down) + cur.insertText(QString("%1 %2").arg(p["dorm"]).arg(p["room"]), defaultFormat ) + if i == 0 and len(table_row) == 2: + cur = table.cellAt(0,2).firstCursorPosition() + else: + cur.setPosition(topFrame.lastPosition()) + progress.setLabelText(QString("Writing output document (this might take a while)...")) + progress.setValue(total-1) writer = QTextDocumentWriter(filename, QByteArray("odt")) - return writer.write(doc) + success = writer.write(doc) + progress.setValue(total) + return success + +# Desired output +# ------ +# | -- | forename surname +# | |^^| | email +# | -- | birthday +# | /||\ | phone +# | || | dorm, room +# ------