Пример #1
0
    def createReference(self):
        sections = self.reference.allSections()
        progressDlg = Gui.ProgressDialog(self.tr("Updating reference"),
                                         self.tr("Cancel"), len(sections),
                                         self.parent())

        for columnName in sections:
            progressDlg.step()
            if progressDlg.wasCanceled():
                break

            refSection = self.reference.section(columnName)
            if isinstance(refSection, CrossReferenceSection):
                rel = refSection.model.relationModel(1)
                for i in range(rel.rowCount()):
                    data = rel.data(rel.index(i, rel.fieldIndex('value')))
                    parentId = rel.data(rel.index(i, rel.fieldIndex('id')))
                    query = QSqlQuery(self.db)
                    sql = "SELECT DISTINCT %s FROM coins WHERE %s<>'' AND %s IS NOT NULL AND %s=?" % (
                        columnName, columnName, columnName,
                        refSection.parentName)
                    query.prepare(sql)
                    query.addBindValue(data)
                    query.exec_()
                    refSection.fillFromQuery(parentId, query)
            else:
                sql = "SELECT DISTINCT %s FROM coins WHERE %s<>'' AND %s IS NOT NULL" % (
                    columnName, columnName, columnName)
                query = QSqlQuery(sql, self.db)
                refSection.fillFromQuery(query)

        progressDlg.reset()
Пример #2
0
    def _delete(self, indexes=None):
        if not indexes:
            indexes = self.selectedRows()

        result = QMessageBox.information(
            self, self.tr("Delete"),
            self.tr("Are you sure to remove a %n coin(s)?", '', len(indexes)),
            QMessageBox.Yes | QMessageBox.Cancel, QMessageBox.Cancel)
        if result == QMessageBox.Yes:
            progressDlg = Gui.ProgressDialog(self.tr("Deleting records"),
                                             self.tr("Cancel"), len(indexes),
                                             self)

            model = self.model()
            for index in indexes:
                progressDlg.step()
                if progressDlg.wasCanceled():
                    break

                model.removeRow(index.row())

            progressDlg.setLabelText(self.tr("Saving..."))
            model.submitAll()

            progressDlg.reset()
Пример #3
0
    def generate(self, records, single_file=False):
        if os.path.exists(os.path.join(self.srcFolder, 'coin.htm')):
            has_item_template = True
        else:
            has_item_template = False
            single_file = True

        self.mapping = {'single_file': single_file,
                        'date': QtCore.QDate.currentDate().toString(QtCore.Qt.DefaultLocaleLongDate)}

        self.mapping['collection'] = {'title': self.model.description.title,
                            'description': self.model.description.description,
                            'author': self.model.description.author}

        if not self.fileName:
            if len(records) == 1 and has_item_template:
                self.fileName = "coin_%d.htm" % records[0].value('id')
            else:
                self.fileName = "coins.htm"
        static_files = QtCore.QFileInfo(self.fileName).baseName() + '_files'
        self.contentDir = os.path.join(self.dstFolder, static_files)

        self.mapping['static_files'] = static_files

        copyFolder(os.path.join(self.srcFolder, 'files'), self.contentDir)

        loader = FileSystemLoader(self.srcFolder)
        self.env = Environment(loader=loader, autoescape=True)

        titles_mapping = {}
        for field in self.model.fields:
            titles_mapping[field.name] = field.title
        self.mapping['titles'] = titles_mapping

        if len(records) == 1 and has_item_template:
            self.mapping['record'] = self.__recordMapping(records[0])
            dstFile = self.__render('coin.htm', self.fileName)
        else:
            progressDlg = Gui.ProgressDialog(self.tr("Generating report"),
                            self.tr("Cancel"), len(records), self.parent())

            record_data = []
            for record in records:
                progressDlg.step()
                if progressDlg.wasCanceled():
                    return None

                recordMapping = self.__recordMapping(record)
                record_data.append(recordMapping)
                if not single_file:
                    self.mapping['record'] = recordMapping
                    self.__render('coin.htm', "coin_%d.htm" % record.value('id'))

            self.mapping['records'] = record_data

            dstFile = self.__render('coins.htm', self.fileName)

            progressDlg.reset()

        return dstFile
Пример #4
0
    def __init__(self, collection, parent=None):
        super().__init__(parent)

        self.collection = collection
        self.db = collection.db

        self.totalCount = self.getTotalCount()

        self.progressDlg = Gui.ProgressDialog(
            QApplication.translate('_Updater', "Updating records"), None,
            self.totalCount, collection.parent())
Пример #5
0
    def _multiEdit(self, indexes=None):
        if not indexes:
            indexes = self.selectedRows()

        # Fill multi record for editing
        multiRecord = self.model().record(indexes[0].row())
        usedFields = [Qt.Checked] * multiRecord.count()
        for index in indexes:
            record = self.model().record(index.row())
            for i in range(multiRecord.count()):
                value = record.value(i)
                if multiRecord.value(i) != value or not value:
                    multiRecord.setNull(i)
                    usedFields[i] = Qt.Unchecked

        dialog = EditCoinDialog(self.model(), multiRecord, self, usedFields)
        result = dialog.exec_()
        if result == QDialog.Accepted:
            progressDlg = Gui.ProgressDialog(self.tr("Updating records"),
                                             self.tr("Cancel"), len(indexes),
                                             self)

            # Fill records by used fields in multi record
            multiRecord = dialog.getRecord()
            usedFields = dialog.getUsedFields()

            # Sort and reverse indexes for updating records that out
            # filtered after updating
            rindexes = sorted(indexes,
                              key=operator.methodcaller('row'),
                              reverse=True)
            for index in rindexes:
                progressDlg.step()
                if progressDlg.wasCanceled():
                    break

                record = self.model().record(index.row())
                for i in range(multiRecord.count()):
                    if usedFields[i] == Qt.Checked:
                        record.setValue(i, multiRecord.value(i))
                self.model().setRecord(index.row(), record)

            progressDlg.setLabelText(self.tr("Saving..."))
            self.model().submitAll()

            progressDlg.reset()
Пример #6
0
    def _multiEdit(self):
        self.changingEnabled = False
        storedFilter = self.model.intFilter
        self.model.setFilter('')
        self.changingEnabled = True

        # Fill multi record for editing
        multiRecord = self.model.record(0)
        usedFields = [Qt.Checked] * multiRecord.count()
        for i in range(self.model.rowCount()):
            record = self.model.record(i)
            for j in range(multiRecord.count()):
                value = record.value(j)
                if multiRecord.value(j) != value or not value:
                    multiRecord.setNull(j)
                    usedFields[j] = Qt.Unchecked

        # TODO: Make identical with ListView._multiEdit
        dialog = EditCoinDialog(self.model, multiRecord, self, usedFields)
        result = dialog.exec_()
        if result == QDialog.Accepted:
            progressDlg = Gui.ProgressDialog(self.tr("Updating records"),
                                             self.tr("Cancel"),
                                             self.model.rowCount(), self)

            # Fill records by used fields in multi record
            multiRecord = dialog.getRecord()
            usedFields = dialog.getUsedFields()
            for i in range(self.model.rowCount()):
                progressDlg.setValue(i)
                if progressDlg.wasCanceled():
                    break

                record = self.model.record(i)
                for j in range(multiRecord.count()):
                    if usedFields[j] == Qt.Checked:
                        record.setValue(j, multiRecord.value(j))
                self.model.setRecord(i, record)

            self.model.submitAll()
            progressDlg.reset()

        self.model.setFilter(storedFilter)
Пример #7
0
def exportToMobile(model, params):
    IMAGE_FORMAT = 'jpg'
    IMAGE_COMPRESS = 50
    USED_FIELDS = ('title', 'unit', 'country', 'year', 'mint', 'mintmark',
                   'issuedate', 'type', 'series', 'subjectshort', 'material',
                   'fineness', 'diameter', 'thickness', 'weight', 'mintage',
                   'rarity', 'obverseimg', 'reverseimg', 'subject', 'price1',
                   'price2', 'price3', 'price4')

    if os.path.isfile(params['file']):
        os.remove(params['file'])

    db = QSqlDatabase.addDatabase('QSQLITE', 'mobile')
    db.setDatabaseName(params['file'])
    if not db.open():
        print(db.lastError().text())
        QMessageBox.critical(None, "Create mobile collection",
                             "Can't open collection")
        return

    sql = """CREATE TABLE "android_metadata" ("locale" TEXT DEFAULT 'en_US')"""
    QSqlQuery(sql, db)
    sql = """INSERT INTO "android_metadata" VALUES ('en_US')"""
    QSqlQuery(sql, db)

    mobile_settings = {
        'Version': 1,
        'Type': 'MobilePro',
        'Filter': params['filter']
    }

    sql = """CREATE TABLE settings (
        title CHAR NOT NULL UNIQUE,
        value CHAR)"""
    QSqlQuery(sql, db)
    for key, value in mobile_settings.items():
        query = QSqlQuery(db)
        query.prepare("""INSERT INTO settings (title, value)
                VALUES (?, ?)""")
        query.addBindValue(key)
        query.addBindValue(str(value))
        query.exec_()

    sql = """CREATE TABLE updates (
        title CHAR NOT NULL UNIQUE,
        value CHAR)"""
    QSqlQuery(sql, db)

    sql = """INSERT INTO updates (title, value)
                VALUES ('160203', '2016-02-03T10:19:00')"""
    QSqlQuery(sql, db)

    sql = """CREATE TABLE photos (
        id INTEGER PRIMARY KEY,
        image BLOB)"""
    QSqlQuery(sql, db)

    sql = """CREATE TABLE coins (
        id INTEGER PRIMARY KEY,
        description_id INTEGER,
        grade INTEGER,
        createdat STRING)"""
    QSqlQuery(sql, db)

    sql = """CREATE INDEX coins_descriptions ON coins(description_id)"""
    QSqlQuery(sql, db)

    sqlFields = []
    fields = CollectionFieldsBase()
    for field in fields:
        if field.name == 'id':
            sqlFields.append('id INTEGER PRIMARY KEY')
        elif field.name == 'image':
            sqlFields.append('image INTEGER')
        elif field.name in USED_FIELDS:
            sqlFields.append("%s %s" % (field.name, Type.toSql(field.type)))

    sql = "CREATE TABLE descriptions (" + ", ".join(sqlFields) + ")"
    QSqlQuery(sql, db)

    while model.canFetchMore():
        model.fetchMore()

    dest_model = QSqlTableModel(None, db)
    dest_model.setEditStrategy(QSqlTableModel.OnManualSubmit)
    dest_model.setTable('descriptions')
    dest_model.select()

    height = 64
    if params['density'] == 'HDPI':
        height *= 1.5
    elif params['density'] == 'XHDPI':
        height *= 2
    elif params['density'] == 'XXHDPI':
        height *= 3
    elif params['density'] == 'XXXHDPI':
        height *= 4
    maxHeight = height * 4

    is_obverse_enabled = params['image'] in (ExportDialog.IMAGE_OBVERSE,
                                             ExportDialog.IMAGE_BOTH)
    is_reverse_enabled = params['image'] in (ExportDialog.IMAGE_REVERSE,
                                             ExportDialog.IMAGE_BOTH)

    fields = CollectionFieldsBase()
    count = model.rowCount()
    progressDlg = Gui.ProgressDialog("Exporting records", "Cancel", count,
                                     None)

    for i in range(count):
        progressDlg.step()
        if progressDlg.wasCanceled():
            break

        coin = model.record(i)
        if coin.value('status') in ('pass', 'sold'):
            continue

        dest_record = dest_model.record()

        for field in fields:
            if field.name in ('id', 'image', 'obverseimg', 'reverseimg'):
                continue
            if field.name in USED_FIELDS:
                val = coin.value(field.name)
                if val is None or val == '':
                    continue

                dest_record.setValue(field.name, val)

        # Process images
        is_obverse_present = not coin.isNull('obverseimg')
        is_reverse_present = not coin.isNull('reverseimg')
        if is_obverse_present or is_reverse_present:
            obverseImage = QImage()
            reverseImage = QImage()

            if is_obverse_present:
                ba = QtCore.QByteArray()
                buffer = QtCore.QBuffer(ba)
                buffer.open(QtCore.QIODevice.WriteOnly)

                obverseImage.loadFromData(coin.value('obverseimg'))
                if not obverseImage.isNull() and not params[
                        'fullimage'] and obverseImage.height() > maxHeight:
                    scaledImage = obverseImage.scaled(maxHeight, maxHeight,
                                                      Qt.KeepAspectRatio,
                                                      Qt.SmoothTransformation)
                    scaledImage.save(buffer, IMAGE_FORMAT, IMAGE_COMPRESS)
                    save_data = ba
                else:
                    if not obverseImage.isNull():
                        obverseImage.save(buffer, IMAGE_FORMAT, IMAGE_COMPRESS)
                        save_data = ba
                    else:
                        save_data = coin.value('obverseimg')

                query = QSqlQuery(db)
                query.prepare("""INSERT INTO photos (image)
                        VALUES (?)""")
                query.addBindValue(save_data)
                query.exec_()
                img_id = query.lastInsertId()
                dest_record.setValue('obverseimg', img_id)
            if not obverseImage.isNull():
                obverseImage = obverseImage.scaledToHeight(
                    height, Qt.SmoothTransformation)

            if is_reverse_present:
                ba = QtCore.QByteArray()
                buffer = QtCore.QBuffer(ba)
                buffer.open(QtCore.QIODevice.WriteOnly)

                reverseImage.loadFromData(coin.value('reverseimg'))
                if not reverseImage.isNull() and not params[
                        'fullimage'] and reverseImage.height() > maxHeight:
                    scaledImage = reverseImage.scaled(maxHeight, maxHeight,
                                                      Qt.KeepAspectRatio,
                                                      Qt.SmoothTransformation)
                    scaledImage.save(buffer, IMAGE_FORMAT, IMAGE_COMPRESS)
                    save_data = ba
                else:
                    if not reverseImage.isNull():
                        reverseImage.save(buffer, IMAGE_FORMAT, IMAGE_COMPRESS)
                        save_data = ba
                    else:
                        save_data = coin.value('reverseimg')

                query = QSqlQuery(db)
                query.prepare("""INSERT INTO photos (image)
                        VALUES (?)""")
                query.addBindValue(save_data)
                query.exec_()
                img_id = query.lastInsertId()
                dest_record.setValue('reverseimg', img_id)
            if not reverseImage.isNull():
                reverseImage = reverseImage.scaledToHeight(
                    height, Qt.SmoothTransformation)

            if not is_obverse_enabled:
                obverseImage = QImage()
            if not is_reverse_enabled:
                reverseImage = QImage()

            image = QImage(obverseImage.width() + reverseImage.width(), height,
                           QImage.Format_RGB32)
            image.fill(QColor(Qt.white).rgb())

            paint = QPainter(image)
            if is_obverse_present and is_obverse_enabled:
                paint.drawImage(
                    QtCore.QRectF(0, 0, obverseImage.width(), height),
                    obverseImage,
                    QtCore.QRectF(0, 0, obverseImage.width(), height))
            if is_reverse_present and is_reverse_enabled:
                paint.drawImage(
                    QtCore.QRectF(obverseImage.width(), 0,
                                  reverseImage.width(), height), reverseImage,
                    QtCore.QRectF(0, 0, reverseImage.width(), height))
            paint.end()

            ba = QtCore.QByteArray()
            buffer = QtCore.QBuffer(ba)
            buffer.open(QtCore.QIODevice.WriteOnly)
            image.save(buffer, IMAGE_FORMAT, 75)

            query = QSqlQuery(db)
            query.prepare("""INSERT INTO photos (image)
                    VALUES (?)""")
            query.addBindValue(ba)
            query.exec_()
            img_id = query.lastInsertId()
            dest_record.setValue('image', img_id)

        dest_model.insertRecord(-1, dest_record)

    progressDlg.setLabelText("Saving...")
    dest_model.submitAll()

    progressDlg.setLabelText("Compact...")
    QSqlQuery(
        """UPDATE descriptions
SET
reverseimg = (select t2.id from descriptions t3 join (select id, image from photos group by image having count(*) > 1) t2 on t1.image = t2.image join photos t1 on t3.reverseimg = t1.id where t1.id <> t2.id and t3.id = descriptions.id)
WHERE descriptions.id in (select t3.id from descriptions t3 join (select id, image from photos group by image having count(*) > 1) t2 on t1.image = t2.image join photos t1 on t3.reverseimg = t1.id where t1.id <> t2.id)
""", db)
    QSqlQuery(
        """UPDATE descriptions
SET
obverseimg = (select t2.id from descriptions t3 join (select id, image from photos group by image having count(*) > 1) t2 on t1.image = t2.image join photos t1 on t3.obverseimg = t1.id where t1.id <> t2.id and t3.id = descriptions.id)
WHERE descriptions.id in (select t3.id from descriptions t3 join (select id, image from photos group by image having count(*) > 1) t2 on t1.image = t2.image join photos t1 on t3.obverseimg = t1.id where t1.id <> t2.id)
""", db)
    QSqlQuery(
        """UPDATE descriptions
SET
image = (select t2.id from descriptions t3 join (select id, image from photos group by image having count(*) > 1) t2 on t1.image = t2.image join photos t1 on t3.image = t1.id where t1.id <> t2.id and t3.id = descriptions.id)
WHERE descriptions.id in (select t3.id from descriptions t3 join (select id, image from photos group by image having count(*) > 1) t2 on t1.image = t2.image join photos t1 on t3.image = t1.id where t1.id <> t2.id)
""", db)

    QSqlQuery(
        """DELETE FROM photos
        WHERE id NOT IN (SELECT id FROM photos GROUP BY image)""", db)

    db.close()

    progressDlg.setLabelText("Vacuum...")
    db = QSqlDatabase.addDatabase('QSQLITE', 'mobile')
    db.setDatabaseName(params['file'])
    if not db.open():
        print(db.lastError().text())
        QMessageBox.critical(None, "Create mobile collection",
                             "Can't open collection")
        return
    QSqlQuery("VACUUM", db)
    db.close()

    progressDlg.reset()
Пример #8
0
    def _paste(self):
        clipboard = QApplication.clipboard()
        mime = clipboard.mimeData()
        progressDlg = None

        if mime.hasFormat(ListView.MimeType):
            # Load data stored by application
            pickleData = pickle.loads(mime.data(ListView.MimeType))
            for progress, recordData in enumerate(pickleData):
                if progressDlg:
                    progressDlg.setValue(progress)
                    if progressDlg.wasCanceled():
                        break

                record = self.model().record()
                for i in range(self.model().columnCount()):
                    if isinstance(recordData[i], bytes):
                        # Note: Qt::QVariant convert Python bytes type to
                        # str type
                        record.setValue(i, QtCore.QByteArray(recordData[i]))
                    else:
                        record.setValue(i, recordData[i])

                if progressDlg:
                    self.model().appendRecord(record)
                else:
                    btn = self.__insertCoin(record, len(pickleData) - progress)
                    if btn == QDialogButtonBox.Abort:
                        break
                    if btn == QDialogButtonBox.SaveAll:
                        progressDlg = Gui.ProgressDialog(
                            self.tr("Inserting records"), self.tr("Cancel"),
                            len(pickleData), self)

            if progressDlg:
                progressDlg.reset()

        elif mime.hasText():
            # Load data stored by another application (Excel)
            # TODO: Process fields with \n and \t
            # http://docs.python.org/3.2/library/csv.html#csv.excel_tab
            textData = clipboard.text().split('\n')
            for progress, recordData in enumerate(textData):
                if progressDlg:
                    progressDlg.setValue(progress)
                    if progressDlg.wasCanceled():
                        break

                data = recordData.split('\t')
                # Skip very short (must contain ID and NAME) and too large data
                if len(data) < 2 or len(data) > self.model().columnCount():
                    return

                record = self.model().record()
                for i in range(len(data)):
                    record.setValue(i, clipboardToText(data[i]))

                if progressDlg:
                    self.model().appendRecord(record)
                else:
                    btn = self.__insertCoin(record, len(textData) - progress)
                    if btn == QDialogButtonBox.Abort:
                        break
                    if btn == QDialogButtonBox.SaveAll:
                        progressDlg = Gui.ProgressDialog(
                            self.tr("Inserting records"), self.tr("Cancel"),
                            len(pickleData), self)

            if progressDlg:
                progressDlg.reset()
Пример #9
0
    def saveTable(self):
        filters = [
            self.tr("Excel document (*.xls)"),
            self.tr("Web page (*.htm *.html)"),
            self.tr("Text file (*.csv)"),
            self.tr("Text file UTF-8 (*.csv)")
        ]

        defaultFileName = self.listParam.page.title
        settings = QtCore.QSettings()
        lastExportDir = settings.value('export_table/last_dir')
        if lastExportDir:
            defaultFileName = os.path.join(lastExportDir, defaultFileName)

        fileName, selectedFilter = QFileDialog.getSaveFileName(
            self,
            self.tr("Save as"),
            defaultFileName,
            filter=';;'.join(filters))
        if fileName:
            file_info = QtCore.QFileInfo(fileName)
            settings.setValue('export_table/last_dir',
                              file_info.absolutePath())

            model = self.model()
            progressDlg = Gui.ProgressDialog(self.tr("Saving list"),
                                             self.tr("Cancel"),
                                             model.rowCount(), self)

            if filters.index(selectedFilter) == 0:  # Excel documents
                export = ExportToExcel(fileName, self.listParam.page.title)
            elif filters.index(selectedFilter) == 1:  # Excel documents
                export = ExportToHtml(fileName, self.listParam.page.title)
            elif filters.index(selectedFilter) == 2:  # Excel documents
                export = ExportToCsv(fileName, self.listParam.page.title)
            elif filters.index(selectedFilter) == 3:  # Excel documents
                export = ExportToCsvUtf8(fileName, self.listParam.page.title)
            else:
                raise

            export.open()

            parts = []
            for param in self.listParam.columns:
                field = model.fields.field(param.fieldid)
                if field.type in Type.ImageTypes:
                    continue

                if not param.enabled:
                    continue

                parts.append(field.title)

            export.writeHeader(parts)

            for i in range(model.rowCount()):
                progressDlg.step()
                if progressDlg.wasCanceled():
                    break

                index = self.__mapToSource(self.proxyModel.index(i, 0))
                record = model.record(index.row())
                parts = []
                for param in self.listParam.columns:
                    field = model.fields.field(param.fieldid)
                    if field.type in Type.ImageTypes:
                        continue

                    if not param.enabled:
                        continue

                    if record.isNull(param.fieldid):
                        parts.append('')
                    else:
                        parts.append(record.value(param.fieldid))

                export.writeRow(parts)

            export.close()

            progressDlg.reset()
Пример #10
0
    def exportToMobile(self, params):
        IMAGE_FORMAT = 'jpg'
        SKIPPED_FIELDS = ('edgeimg', 'photo1', 'photo2', 'photo3', 'photo4',
                          'obversedesigner', 'reversedesigner', 'catalognum2',
                          'catalognum3', 'catalognum4', 'saledate',
                          'saleprice', 'totalsaleprice', 'buyer', 'saleplace',
                          'saleinfo', 'paydate', 'payprice', 'totalpayprice',
                          'saller', 'payplace', 'payinfo', 'url',
                          'obversedesigner', 'reversedesigner')

        if os.path.isfile(params['file']):
            os.remove(params['file'])

        db = QSqlDatabase.addDatabase('QSQLITE', 'mobile')
        db.setDatabaseName(params['file'])
        if not db.open():
            print(db.lastError().text())
            QMessageBox.critical(self.parent(),
                                 self.tr("Create mobile collection"),
                                 self.tr("Can't open collection"))
            return

        mobile_settings = {
            'Version': 5,
            'Type': 'Mobile',
            'Filter': params['filter']
        }

        sql = """CREATE TABLE settings (
            title CHAR NOT NULL UNIQUE,
            value CHAR)"""
        QSqlQuery(sql, db)
        for key, value in mobile_settings.items():
            query = QSqlQuery(db)
            query.prepare("""INSERT INTO settings (title, value)
                    VALUES (?, ?)""")
            query.addBindValue(key)
            query.addBindValue(str(value))
            query.exec_()

        sql = """CREATE TABLE updates (
            title CHAR NOT NULL UNIQUE,
            value CHAR)"""
        QSqlQuery(sql, db)

        sql = """CREATE TABLE photos (
            id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
            image BLOB)"""
        QSqlQuery(sql, db)

        sqlFields = []
        fields = CollectionFieldsBase()
        for field in fields:
            if field.name == 'id':
                sqlFields.append(
                    'id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT')
            elif field.name == 'image':
                sqlFields.append('image INTEGER')
            elif field.name in SKIPPED_FIELDS:
                continue
            else:
                sqlFields.append("%s %s" %
                                 (field.name, Type.toSql(field.type)))

        sql = "CREATE TABLE coins (" + ", ".join(sqlFields) + ")"
        QSqlQuery(sql, db)

        model = self.model()
        while model.canFetchMore():
            model.fetchMore()

        dest_model = QSqlTableModel(self.parent(), db)
        dest_model.setEditStrategy(QSqlTableModel.OnManualSubmit)
        dest_model.setTable('coins')
        dest_model.select()

        height = 64
        if params['density'] == 'HDPI':
            height *= 1.5
        elif params['density'] == 'XHDPI':
            height *= 2
        elif params['density'] == 'XXHDPI':
            height *= 3
        elif params['density'] == 'XXXHDPI':
            height *= 4
        maxHeight = height * 4

        is_obverse_enabled = params['image'] in (ExportDialog.IMAGE_OBVERSE,
                                                 ExportDialog.IMAGE_BOTH)
        is_reverse_enabled = params['image'] in (ExportDialog.IMAGE_REVERSE,
                                                 ExportDialog.IMAGE_BOTH)

        fields = CollectionFieldsBase()
        count = model.rowCount()
        progressDlg = Gui.ProgressDialog(self.tr("Exporting records"),
                                         self.tr("Cancel"), count,
                                         self.parent())

        for i in range(count):
            progressDlg.step()
            if progressDlg.wasCanceled():
                break

            coin = model.record(i)
            if coin.value('status') in ('pass', 'sold'):
                continue

            dest_record = dest_model.record()

            for field in fields:
                if field.name in ('id', 'image', 'obverseimg', 'reverseimg'):
                    continue
                if field.name in SKIPPED_FIELDS:
                    continue

                val = coin.value(field.name)
                if val is None or val == '':
                    continue

                dest_record.setValue(field.name, val)

            # Process images
            is_obverse_present = not coin.isNull('obverseimg')
            is_reverse_present = not coin.isNull('reverseimg')
            if is_obverse_present or is_reverse_present:
                obverseImage = QImage()
                reverseImage = QImage()

                if is_obverse_present:
                    ba = QtCore.QByteArray()
                    buffer = QtCore.QBuffer(ba)
                    buffer.open(QtCore.QIODevice.WriteOnly)

                    obverseImage.loadFromData(coin.value('obverseimg'))
                    if not obverseImage.isNull() and not params[
                            'fullimage'] and obverseImage.height() > maxHeight:
                        scaledImage = obverseImage.scaled(
                            maxHeight, maxHeight, Qt.KeepAspectRatio,
                            Qt.SmoothTransformation)
                        scaledImage.save(buffer, IMAGE_FORMAT, 50)
                        save_data = ba
                    else:
                        if not obverseImage.isNull():
                            obverseImage.save(buffer, IMAGE_FORMAT, 50)
                            save_data = ba
                        else:
                            save_data = coin.value('obverseimg')

                    query = QSqlQuery(db)
                    query.prepare("""INSERT INTO photos (image)
                            VALUES (?)""")
                    query.addBindValue(save_data)
                    query.exec_()
                    img_id = query.lastInsertId()
                    dest_record.setValue('obverseimg', img_id)
                if not obverseImage.isNull():
                    obverseImage = obverseImage.scaledToHeight(
                        height, Qt.SmoothTransformation)

                if is_reverse_present:
                    ba = QtCore.QByteArray()
                    buffer = QtCore.QBuffer(ba)
                    buffer.open(QtCore.QIODevice.WriteOnly)

                    reverseImage.loadFromData(coin.value('reverseimg'))
                    if not reverseImage.isNull() and not params[
                            'fullimage'] and reverseImage.height() > maxHeight:
                        scaledImage = reverseImage.scaled(
                            maxHeight, maxHeight, Qt.KeepAspectRatio,
                            Qt.SmoothTransformation)
                        scaledImage.save(buffer, IMAGE_FORMAT, 50)
                        save_data = ba
                    else:
                        if not reverseImage.isNull():
                            reverseImage.save(buffer, IMAGE_FORMAT, 50)
                            save_data = ba
                        else:
                            save_data = coin.value('reverseimg')

                    query = QSqlQuery(db)
                    query.prepare("""INSERT INTO photos (image)
                            VALUES (?)""")
                    query.addBindValue(save_data)
                    query.exec_()
                    img_id = query.lastInsertId()
                    dest_record.setValue('reverseimg', img_id)
                if not reverseImage.isNull():
                    reverseImage = reverseImage.scaledToHeight(
                        height, Qt.SmoothTransformation)

                if not is_obverse_enabled:
                    obverseImage = QImage()
                if not is_reverse_enabled:
                    reverseImage = QImage()

                image = QImage(obverseImage.width() + reverseImage.width(),
                               height, QImage.Format_RGB32)
                image.fill(QColor(Qt.white).rgb())

                paint = QPainter(image)
                if is_obverse_present and is_obverse_enabled:
                    paint.drawImage(
                        QtCore.QRectF(0, 0, obverseImage.width(), height),
                        obverseImage,
                        QtCore.QRectF(0, 0, obverseImage.width(), height))
                if is_reverse_present and is_reverse_enabled:
                    paint.drawImage(
                        QtCore.QRectF(obverseImage.width(), 0,
                                      reverseImage.width(), height),
                        reverseImage,
                        QtCore.QRectF(0, 0, reverseImage.width(), height))
                paint.end()

                ba = QtCore.QByteArray()
                buffer = QtCore.QBuffer(ba)
                buffer.open(QtCore.QIODevice.WriteOnly)

                # Store as PNG for better view
                image.save(buffer, 'png')
                dest_record.setValue('image', ba)

            dest_model.insertRecord(-1, dest_record)

        progressDlg.setLabelText(self.tr("Saving..."))
        dest_model.submitAll()

        progressDlg.setLabelText(self.tr("Compact..."))
        QSqlQuery(
            """UPDATE coins
SET
  reverseimg = (select t2.id from coins t3 join (select id, image from photos group by image having count(*) > 1) t2 on t1.image = t2.image join photos t1 on t3.reverseimg = t1.id where t1.id <> t2.id and t3.id = coins.id)
WHERE coins.id in (select t3.id from coins t3 join (select id, image from photos group by image having count(*) > 1) t2 on t1.image = t2.image join photos t1 on t3.reverseimg = t1.id where t1.id <> t2.id)
""", db)
        QSqlQuery(
            """UPDATE coins
SET
  obverseimg = (select t2.id from coins t3 join (select id, image from photos group by image having count(*) > 1) t2 on t1.image = t2.image join photos t1 on t3.obverseimg = t1.id where t1.id <> t2.id and t3.id = coins.id)
WHERE coins.id in (select t3.id from coins t3 join (select id, image from photos group by image having count(*) > 1) t2 on t1.image = t2.image join photos t1 on t3.obverseimg = t1.id where t1.id <> t2.id)
""", db)

        QSqlQuery(
            """DELETE FROM photos
            WHERE id NOT IN (SELECT id FROM photos GROUP BY image)""", db)

        db.close()

        progressDlg.setLabelText(self.tr("Vacuum..."))
        db = QSqlDatabase.addDatabase('QSQLITE', 'mobile')
        db.setDatabaseName(params['file'])
        db.open()
        QSqlQuery("VACUUM", db)
        db.close()

        progressDlg.reset()
Пример #11
0
    def merge(self, fileName):
        db = QSqlDatabase.addDatabase('QSQLITE', 'merge')
        db.setDatabaseName(fileName)
        if not db.open():
            print(db.lastError().text())
            QMessageBox.critical(self.parent(), self.tr("Merge collections"),
                                 self.tr("Can't open collection"))
            return

        settings = CollectionSettings(db)
        if self.settings['Type'] != version.AppName:
            QMessageBox.critical(
                self.parent(), self.tr("Merge collections"),
                self.tr("Collection %s in wrong format %s") %
                (fileName, version.AppName))

        if int(settings['Version']) != CollectionSettings.Default['Version']:
            QMessageBox.critical(
                self.parent(), self.tr("Merge collections"),
                self.
                tr("Source collection %s in old format %d.\n(Try to open it before merging.)"
                   ) % (fileName, int(settings['Version'])))
            return

        if settings['Password'] != cryptPassword():
            dialog = PasswordDialog(settings, self.parent())
            result = dialog.exec_()
            if result == QDialog.Rejected:
                return False

        query = QSqlQuery("SELECT COUNT(id) FROM coins", db)
        query.first()
        count = query.record().value(0)
        progressDlg = Gui.ProgressDialog(self.tr("Inserting records"),
                                         self.tr("Cancel"), count,
                                         self.parent())

        big_query = QSqlQuery(
            """SELECT coins.title AS title, "value", "unit", "country",
        "year", "period", "mint", "mintmark", "issuedate", "type", "series",
        "subjectshort", "status", "material", "fineness", "shape", "diameter",
        "thickness", "weight", "grade", "edge", "edgelabel", "obvrev",
        "quality", "mintage", "dateemis", "catalognum1", "catalognum2",
        "catalognum3", "catalognum4", "rarity", "price1", "price2", "price3",
        "price4", "variety", "obversevar", "reversevar", "edgevar", "paydate",
        "payprice", "totalpayprice", "saller", "payplace", "payinfo",
        "saledate", "saleprice", "totalsaleprice", "buyer", "saleplace",
        "saleinfo", "note", "obversedesign",
        "obversedesigner", "reversedesign", "reversedesigner",
        "subject", "defect",
        "storage", "features", "createdat", "updatedat", "quantity", "url",
        "barcode",
        coins.image AS image, images.image AS images_image,
        obverseimg, obverseimg.image AS obverseimg_image, obverseimg.title AS obverseimg_title,
        reverseimg, reverseimg.image AS reverseimg_image, reverseimg.title AS reverseimg_title,
        edgeimg, edgeimg.image AS edgeimg_image, edgeimg.title AS edgeimg_title,
        photo1, photo1.image AS photo1_image, photo1.title AS photo1_title,
        photo2, photo2.image AS photo2_image, photo2.title AS photo2_title,
        photo3, photo3.image AS photo3_image, photo3.title AS photo3_title,
        photo4, photo4.image AS photo4_image, photo4.title AS photo4_title
          FROM coins
            LEFT OUTER JOIN images ON coins.image=images.id
            LEFT OUTER JOIN photos AS obverseimg ON coins.obverseimg=obverseimg.id
            LEFT OUTER JOIN photos AS reverseimg ON coins.reverseimg=reverseimg.id
            LEFT OUTER JOIN photos AS edgeimg ON coins.edgeimg=edgeimg.id
            LEFT OUTER JOIN photos AS photo1 ON coins.photo1=photo1.id
            LEFT OUTER JOIN photos AS photo2 ON coins.photo2=photo2.id
            LEFT OUTER JOIN photos AS photo3 ON coins.photo3=photo3.id
            LEFT OUTER JOIN photos AS photo4 ON coins.photo4=photo4.id""", db)

        _model = QSqlTableModel(db=self.db)
        _model.setTable('coins')
        _model.select()

        while big_query.next():
            progressDlg.step()
            if progressDlg.wasCanceled():
                break

            record = big_query.record()

            record.setNull('id')  # remove ID value from record

            for field in [
                    'obverseimg', 'reverseimg', 'edgeimg', 'photo1', 'photo2',
                    'photo3', 'photo4'
            ]:
                value = record.value(field + '_image')
                if value:
                    query = QSqlQuery(self.db)
                    query.prepare(
                        "INSERT INTO photos (title, image) VALUES (?, ?)")
                    query.addBindValue(record.value(field + '_title'))
                    query.addBindValue(value)
                    query.exec_()

                    img_id = query.lastInsertId()
                else:
                    img_id = None

                record.setValue(field, img_id)
                record.remove(record.indexOf(field + '_image'))
                record.remove(record.indexOf(field + '_title'))

            value = record.value('images_image')
            if value:
                query = QSqlQuery(self.db)
                query.prepare("INSERT INTO images (image) VALUES (?)")
                query.addBindValue(value)
                query.exec_()

                img_id = query.lastInsertId()
            else:
                img_id = None
            record.setValue('image', img_id)
            record.remove(record.indexOf('images_image'))

            _model.insertRecord(-1, record)
            _model.submitAll()

        progressDlg.reset()

        db.close()

        QMessageBox.warning(
            self.parent(), self.tr("Merge collections"),
            self.tr("The application will need to restart now"))
        self.parent().restart()
Пример #12
0
    def saveTable(self):
        filters = (self.tr("Excel document (*.xls)"),
                   self.tr("Web page (*.htm *.html)"),
                   self.tr("Text file (*.csv)"),
                   self.tr("Text file UTF-8 (*.csv)"))
        if not ExportToExcel.isAvailable():
            filters = filters[1:]

        defaultFileName = self.listParam.page.title
        fileName, selectedFilter = getSaveFileName(
            self, 'export_table', defaultFileName,
            OpenNumismat.HOME_PATH, filters)
        if fileName:
            model = self.model()
            progressDlg = Gui.ProgressDialog(self.tr("Saving list"),
                                    self.tr("Cancel"), model.rowCount(), self)

            if filters.index(selectedFilter) == 0:  # Excel documents
                export = ExportToExcel(fileName, self.listParam.page.title)
            elif filters.index(selectedFilter) == 1:  # Web page
                export = ExportToHtml(fileName, self.listParam.page.title)
            elif filters.index(selectedFilter) == 2:  # Text file
                export = ExportToCsv(fileName, self.listParam.page.title)
            elif filters.index(selectedFilter) == 3:  # Text file UTF-8
                export = ExportToCsvUtf8(fileName, self.listParam.page.title)
            else:
                raise

            export.open()

            parts = []
            for param in self.listParam.columns:
                if not param.enabled:
                    continue

                field = model.fields.field(param.fieldid)
                if field.type in Type.ImageTypes:
                    continue

                parts.append(field.title)

            export.writeHeader(parts)

            for i in range(model.rowCount()):
                progressDlg.step()
                if progressDlg.wasCanceled():
                    break

                index = self.__mapToSource(self.proxyModel.index(i, 0))
                record = model.record(index.row())
                parts = []
                for param in self.listParam.columns:
                    field = model.fields.field(param.fieldid)
                    if field.type in Type.ImageTypes:
                        continue

                    if not param.enabled:
                        continue

                    if record.isNull(param.fieldid):
                        parts.append('')
                    else:
                        parts.append(record.value(param.fieldid))

                export.writeRow(parts)

            export.close()

            progressDlg.reset()