예제 #1
0
 def extract_rmc(self, data):
     self.info.latitude = data.latitude
     self.info.longitude = data.longitude
     self.info.speed = KNOTS_TO_KM * safe_float(data.spd_over_grnd)
     self.info.status = data.data_validity
     self.info.direction = safe_float(data.true_course)
     if data.datestamp and data.timestamp:
         date = QDate(data.datestamp.year, data.datestamp.month, data.datestamp.day)
         time = QTime(data.timestamp.hour, data.timestamp.minute, data.timestamp.second)
         dt = QDateTime()
         self.info.utcDateTime.setTimeSpec(Qt.UTC)
         self.info.utcDateTime.setDate(date)
         self.info.utcDateTime.setTime(time)
     return self.info
예제 #2
0
    def data(self, index, role):

        if not index.isValid():
            return QVariant()
        elif role == Qt.TextAlignmentRole and index.column() != SAMPLE_COLUMN:
            return QVariant(Qt.AlignHCenter | Qt.AlignVCenter)
        elif role != Qt.DisplayRole:
            return QVariant()

        if index.column() == DATE_COLUMN:
            return QDate(self.arraydata[index.row()][index.column()])
        elif index.column() == TIME_COLUMN:
            return QTime(self.arraydata[index.row()][index.column()])
        else:
            return QVariant(self.arraydata[index.row()][index.column()])
예제 #3
0
    def test__years_QDate(self):
        """
		Überprüft, daß die Funktion der Berechnung der Jahre auch Ergebnisse im zu erwartenden Rahmen zurückgibt.
		"""

        DATE_STEP = 1
        DATE_YEAR = {
            "min": -1,
            "max": 2,
        }

        ## Eine Liste mit Daten anlegen
        dates_all = []

        ## Von ...
        year_min = DATE_YEAR["min"]
        ## ... bis
        year_max = DATE_YEAR["max"]

        ## Startdatum
        date_store = QDate(year_min, 1, 1)
        date_max = QDate(year_max, 1, 1)

        ## Die Listen tatsächlich anlegen
        while date_store < date_max:
            dates_all.append(date_store)
            date_store = date_store.addDays(DATE_STEP)

        ## Kopie erstellen
        dates_to_compare = dates_all[:]
        results_expected = tuple(range(year_max - year_min + 1))

        for date_1 in dates_all:
            dates_to_compare.remove(date_1)
            for date_2 in dates_to_compare:
                self.assertIn(Calc.years(date_1, date_2), results_expected)
예제 #4
0
    def setDateEnd(self, dateEnd):
        """
        Sets the end date for this item.  This method will only affect the 
        start date if the end date is set to occur before its start, in which
        case it will set the start date as the same date.  (1 day duration)
        Otherwise, this method will scale the duration of the event.
        
        :param      dateEnd | <QDate>
        """
        dateEnd = QDate(dateEnd)

        if (dateEnd < self._dateStart):
            self._dateStart = dateEnd
        self._dateEnd = dateEnd
        self.markForRebuild()
예제 #5
0
def toVariant(v):
    if v is None:
        return QVariant()
    t = type(v)
    if t == QVariant:
        return v
    elif t == datetime.time:
        return QVariant(QTime(v))
    elif t == datetime.datetime:
        return QVariant(QDateTime(v))
    elif t == datetime.date:
        return QVariant(QDate(v))
    elif t == Decimal:
        return QVariant(unicode(v))
    else:
        return QVariant(v)
예제 #6
0
    def setDateStart(self, dateStart):
        """
        Sets the start date for this item.  This will automatically push the
        end date to match the duration for this item.  So if the item starts
        on 1/1/12 and ends on 1/2/12, and the start date is changed to 2/1/12,
        the end date will change to 2/2/12.  To affect the duration of the 
        item, use either setDuration, or setDateEnd.
        
        :param      dateStart | <QDate>
        """
        dateStart = QDate(dateStart)

        duration = self.duration()
        self._dateStart = dateStart
        self._dateEnd = dateStart.addDays(duration - 1)
        self.markForRebuild()
예제 #7
0
def setupCalendar(calendarWidget, timeEdit):
    timeGuiLaunched = datetime.now()
    timeGuiLaunchedStr = str(timeGuiLaunched)

    year = timeGuiLaunchedStr[0:4]
    month = timeGuiLaunchedStr[5:7]
    day = timeGuiLaunchedStr[8:10]

    dateLaunched = QDate(int(year), int(month), int(day))

    # Set current date for GUI calendar
    calendarWidget.setSelectedDate(dateLaunched)
    timeGuiLaunched = timeGuiLaunchedStr[11:16]

    # Set current time for GUI time field
    timeEdit.setTime(
        QTime(int(timeGuiLaunched[0:2]), int(timeGuiLaunched[3:5])))
예제 #8
0
    def __init__(self, parent=None):
        super(NewTaskDialog, self).__init__(parent)
        # task name
        nameLabel = QLabel(self.tr("Name:"))
        self.name = QLineEdit()
        nameLabel.setBuddy(self.name)
        # priority
        priorityLabel = QLabel(self.tr("Priority:"))
        self.priority = QComboBox()
        priorityLabel.setBuddy(self.priority)

        dateLabel = QLabel(self.tr("Deadline:"))
        self.deadline = QDateEdit()
        dateLabel.setBuddy(self.deadline)

        self.deadline.setCalendarPopup(True)
        self.deadline.calendarWidget().setFirstDayOfWeek(Qt.Monday)
        self.deadline.setDate(QDate(date.today()))

        createButton = QPushButton(self.tr("Save"))
        cancelButton = QPushButton(self.tr("Cancel"))

        buttonLayout = QHBoxLayout()
        buttonLayout.addStretch()
        buttonLayout.addWidget(createButton)
        buttonLayout.addWidget(cancelButton)

        layout = QGridLayout()
        layout.addWidget(nameLabel, 0, 0)
        layout.addWidget(self.name, 0, 1)

        layout.addWidget(priorityLabel, 1, 0)
        layout.addWidget(self.priority, 1, 1)

        layout.addWidget(dateLabel, 2, 0)
        layout.addWidget(self.deadline, 2, 1)
        layout.addLayout(buttonLayout, 3, 0, 3, 2)
        self.setLayout(layout)

        self.connect(self.deadline, SIGNAL("dateChanged(const QDate&)"), self, SLOT("changed()"))
        self.connect(createButton, SIGNAL("clicked()"), self, SLOT("accept()"))
        self.connect(cancelButton, SIGNAL("clicked()"), self, SLOT("reject()"))
        self.setWindowTitle(self.tr("Task"))
        self.resize(350, 120)
        self.setMinimumSize(QSize(250, 120))
        self.setMaximumSize(QSize(450, 120))
예제 #9
0
 def loadQDataStream(self):
     error = None
     fh = None
     try:
         fh = QFile(self.__fname)
         if not fh.open(QIODevice.ReadOnly):
             raise IOError(str(fh.errorString()))
         stream = QDataStream(fh)
         magic = stream.readInt32()
         if magic != MovieContainer.MAGIC_NUMBER:
             raise IOError("unrecognized file type")
         version = stream.readInt32()
         if version < MovieContainer.OLD_FILE_VERSION:
             raise IOError("old and unreadable file format")
         elif version > MovieContainer.FILE_VERSION:
             raise IOError("new and unreadable file format")
         old = False
         if version == MovieContainer.OLD_FILE_VERSION:
             old = True
         stream.setVersion(QDataStream.Qt_4_2)
         self.clear(False)
         while not stream.atEnd():
             title = QString()
             acquired = QDate()
             location = QString()
             notes = QString()
             stream >> title
             year = stream.readInt16()
             minutes = stream.readInt16()
             if old:
                 stream >> acquired >> notes
             else:
                 stream >> acquired >> location >> notes
             self.add(Movie(title, year, minutes, acquired, location,
                            notes))
     except EnvironmentError as e:
         error = "Failed to load: {0}".format(e)
     finally:
         if fh is not None:
             fh.close()
         if error is not None:
             return False, error
         self.__dirty = False
         return True, "Loaded {0} movie records from {1}".format(
             len(self.__movies),
             QFileInfo(self.__fname).fileName())
예제 #10
0
    def on_exception_but_clicked(self):
        #Local vars for testing value display in debugger
        t01 = QgsApplication.pluginPath()
        t02 = QgsApplication.svgPaths()
        #t03 = QChar('x')
        t04 = QPoint(4, 5)
        t05 = QPointF(4.1, 5.1)
        t06 = QDate()
        t07 = QTime()
        t08 = QDir()
        t09 = QFile()
        t10 = QUrl()

        x01 = 42
        x02 = 'fortytwo'

        raise Exception(
            "Exception raised. Check local variables in your debugger.")
예제 #11
0
파일: dbhandler.py 프로젝트: ZeeD/calendar
 def update_db_content(self):
     """Populate the payment table ensuring all "visible" data"""
     today = QDate.currentDate()
     first_month_day = QDate(today.year(), today.month(), 1)
     datebefore = first_month_day.addMonths(-self.months_before)
     dateafter = first_month_day.addMonths(self.months_after)
     query = QSqlQuery(
         'SELECT client, machine, selldate, deltamonth, '
         'anticiped FROM clients', self._db)
     if not query.exec_():
         raise StandardError('SYNTAX ERROR')
     while query.next():
         client = Client(query)
         payments_date = client.selldate.addMonths(
             0 if client.anticiped else client.deltamonth)
         while payments_date < datebefore:  # ignora date non visibili
             payments_date = payments_date.addMonths(client.deltamonth)
         while payments_date < dateafter:
             query2 = QSqlQuery(
                 'SELECT effective_datepayd FROM payments '
                 'WHERE clients_client = :client AND clients_machine = '
                 ':machine AND clients_selldate = :selldate AND '
                 'expected_datepayd = :expected_datepayd', self._db)
             query2.bindValue(':client', QVariant(client.client))
             query2.bindValue(':machine', QVariant(client.machine))
             query2.bindValue(':selldate', QVariant(client.selldate))
             query2.bindValue(':expected_datepayd', QVariant(payments_date))
             if not query2.exec_():
                 raise StandardError('SYNTAX ERROR')
             if not query2.first():
                 query3 = QSqlQuery(
                     'INSERT INTO payments (clients_client, '
                     'clients_machine, clients_selldate, '
                     'expected_datepayd) VALUES (:client, :machine, '
                     ':selldate, :expected_datepayd)', self._db)
                 query3.bindValue(':client', QVariant(client.client))
                 query3.bindValue(':machine', QVariant(client.machine))
                 query3.bindValue(':selldate', QVariant(client.selldate))
                 query3.bindValue(':expected_datepayd',
                                  QVariant(payments_date))
                 if not query3.exec_():
                     raise StandardError('SYNTAX ERROR')
             payments_date = payments_date.addMonths(client.deltamonth)
     self.emit(SIGNAL("layoutChanged()"))
예제 #12
0
    def __init__(self):
        QARecord.__init__()
        self.Type = QARecordType.Session

        self.NULLDATE = QDateTime(QDate(2222, 2, 22), QTime(22, 22, 22, 22))
        self.dwgCreated = QDateTime()
        self.dwgSaved = QDateTime()
        self.dwgFileName = None
        self.dwgSizeOpened = 0
        self.dwgSizeClosed = 0
        self.tagName = None
        self.tagProject = None
        self.tagReason = None
        self.tagSection = None
        self.sessionType = None
        self.qaLastSaved = QDateTime()
        self.closed = QDateTime()
        self.correlation = None
        self.corrupted = None
예제 #13
0
파일: data.py 프로젝트: cb-flts/stdm
 def to_pyqt(obj, type_=None):
     """
     Converts data from python object type to PyQt equivalent
     :param obj: Python object
     :type obj: Multiple types
     :param type_: Cast type
     :type type_: Object
     :return: Converted value
     :rtype: Multiple types
     """
     if isinstance(obj, int):
         return obj
     if isinstance(obj, (Decimal, float)):
         obj = Decimal(obj).normalize()
     elif type(obj) is datetime.date:
         return QDate(obj)
     elif type(obj) is datetime.datetime:
         return QDateTime(obj).toLocalTime()
     return unicode(obj) if obj is not None else obj
    def test_metadata_date(self):
        metadata = OutputLayerMetadata('random_layer_id')
        path = TEST_XML_BASEPATH + 'gco:Date'

        # using QDate
        test_value = QDate(2015, 6, 7)
        metadata.set('ISO19115_TEST', test_value, path)
        self.assertEqual(metadata.get_xml_value('ISO19115_TEST'), '2015-06-07')

        # using datetime
        test_value = datetime(2015, 6, 7)
        metadata.update('ISO19115_TEST', test_value)
        self.assertEqual(metadata.get_xml_value('ISO19115_TEST'), '2015-06-07')

        # using date
        test_value = date(2015, 6, 7)
        metadata.set('ISO19115_TEST', test_value, path)
        self.assertEqual(metadata.get_xml_value('ISO19115_TEST'), '2015-06-07')

        # using str should fail
        test_value = 'String'
        with self.assertRaises(TypeError):
            metadata.update('ISO19115_TEST', test_value)
예제 #15
0
    def __init_sale_date(cls):
        cls.grid_layout_widget_10.setGeometry(QRect(450, 110, 101, 41))
        cls.grid_layout_widget_10.setObjectName(
            _fromUtf8("gridLayoutWidget_10"))
        cls.grid_layout_10.setObjectName(_fromUtf8("gridLayout_10"))
        cls.sale_date_title.setFont(WindowCons.get_font(bold=True))
        cls.sale_date_title.setTextFormat(Qt.PlainText)
        cls.sale_date_title.setAlignment(Qt.AlignCenter)
        cls.sale_date_title.setObjectName(_fromUtf8("buy_date_title_2"))
        cls.grid_layout_10.addWidget(cls.sale_date_title, 0, 0, 1, 1)

        cls.grid_layout_widget_20.setGeometry(QRect(570, 110, 141, 41))
        cls.grid_layout_widget_20.setObjectName(
            _fromUtf8("gridLayoutWidget_20"))
        cls.grid_layout_20.setObjectName(_fromUtf8("gridLayout_20"))
        cls.sale_date_input.setFont(
            WindowCons.get_font(size=12, family=WindowCons.YAHEI_LIGHT_FAMILY))
        cls.sale_date_input.setWrapping(False)
        cls.sale_date_input.setFrame(False)
        cls.sale_date_input.setCalendarPopup(True)
        cls.sale_date_input.setDate(
            QDate(datetime.datetime.date(datetime.datetime.now())))
        cls.sale_date_input.setObjectName(_fromUtf8("sale_date_input"))
        cls.grid_layout_20.addWidget(cls.sale_date_input, 0, 0, 1, 1)
예제 #16
0
    def __init__(self, parent=None):
        super(TalkDetailsWidget, self).__init__(parent)

        self.layout = QGridLayout()
        self.setLayout(self.layout)

        self.buttonLayout = QHBoxLayout()

        saveIcon = QIcon.fromTheme("document-save")
        self.saveButton = QPushButton('Save Talk')
        self.saveButton.setIcon(saveIcon)
        self.buttonLayout.addWidget(self.saveButton)

        self.layout.addLayout(self.buttonLayout, 0, 1, 1, 1)

        self.titleLabel = QLabel('Title')
        self.titleLineEdit = QLineEdit()
        self.presenterLabel = QLabel('Presenter')
        self.presenterLineEdit = QLineEdit()
        self.layout.addWidget(self.titleLabel, 1, 0, 1, 1)
        self.layout.addWidget(self.titleLineEdit, 1, 1, 1, 1)
        self.layout.addWidget(self.presenterLabel, 1, 2, 1, 1)
        self.layout.addWidget(self.presenterLineEdit, 1, 3, 1, 1)

        self.eventLabel = QLabel('Event')
        self.eventLineEdit = QLineEdit()
        self.categoryLabel = QLabel('Category')
        self.categoryLineEdit = QLineEdit()

        self.layout.addWidget(self.eventLabel, 2, 0, 1, 1)
        self.layout.addWidget(self.eventLineEdit, 2, 1, 1, 1)
        self.layout.addWidget(self.categoryLabel, 2, 2, 1, 1)
        self.layout.addWidget(self.categoryLineEdit, 2, 3, 1, 1)

        self.roomLabel = QLabel('Room')
        self.roomLineEdit = QLineEdit()
        self.dateLayout = QHBoxLayout()
        self.dateLabel = QLabel('Date')
        self.dateEdit = QDateEdit()
        currentDate = QDate()
        self.dateEdit.setDate(currentDate.currentDate())
        self.dateEdit.setCalendarPopup(True)

        self.layout.addWidget(self.roomLabel, 3, 0, 1, 1)
        self.layout.addWidget(self.roomLineEdit, 3, 1, 1, 1)
        self.dateLayout.addWidget(self.dateEdit)
        self.layout.addWidget(self.dateLabel, 3, 2, 1, 1)
        self.layout.addLayout(self.dateLayout, 3, 3, 1, 1)

        self.startTimeLayout = QHBoxLayout()
        self.startTimeLabel = QLabel('Start Time')
        self.startTimeEdit = QTimeEdit()
        self.startTimeLayout.addWidget(self.startTimeEdit)
        self.endTimeLayout = QHBoxLayout()
        self.endTimeLabel = QLabel('End Time')
        self.endTimeEdit = QTimeEdit()
        self.endTimeLayout.addWidget(self.endTimeEdit)

        self.layout.addWidget(self.startTimeLabel, 4, 0, 1, 1)
        self.layout.addLayout(self.startTimeLayout, 4, 1, 1, 1)
        self.layout.addWidget(self.endTimeLabel, 4, 2, 1, 1)
        self.layout.addLayout(self.endTimeLayout, 4, 3, 1, 1)

        self.descriptionLabel = QLabel('Description')
        self.descriptionLabel.setAlignment(Qt.AlignTop)
        self.descriptionTextEdit = QPlainTextEdit()
        self.layout.addWidget(self.descriptionLabel, 5, 0, 1, 1)
        self.layout.addWidget(self.descriptionTextEdit, 5, 1, 1, 3)
예제 #17
0
    def __init__(self,
                 table_p,
                 parent,
                 scoop=None,
                 member=None,
                 *args,
                 **kwargs):
        FWidget.__init__(self, parent, *args, **kwargs)

        self.table_p = table_p
        self.member = member
        self.scoop = scoop
        self.parent = parent
        full_name = ""
        self.ddn_field = FormatDate(QDate(QDate.currentDate()))

        addres = ""
        nationality = ""
        phone = ""
        if self.member:
            self.new = False
            full_name = self.member.full_name
            mddn = self.member.ddn
            if mddn:
                day, month, year = mddn.split("/")
                ddn = datetime.strptime(mddn, '%d/%m/%Y')
                self.ddn_field.setDate(QDate(ddn))
            addres = self.member.addres
            nationality = self.member.nationality
            phone = str(self.member.phone or "")

            self.title = u"Modification de {}".format(self.member)
            self.succes_msg = u"{} a été bien mise à jour".format(self.member)
        else:
            self.new = True
            self.succes_msg = u"Client a été bien enregistré"
            self.title = u"Ajout nouveau membre"
            self.member = CooperativeMember()
        self.setWindowTitle(self.title)

        vbox = QVBoxLayout()
        # vbox.addWidget(FPageTitle(u"Utilisateur: %s " % self.member.name))

        self.full_name_field = LineEdit(full_name)
        self.sex_list = CooperativeMember.SEX.items()
        # Combobox widget
        self.sex_box = QComboBox()

        for index, value in enumerate(self.sex_list):
            # form = self.sex_list[index]
            self.sex_box.addItem("{}".format(value[1].upper()), value[0])
            if self.member.sex == value[0]:
                self.sex_box.setCurrentIndex(index)
        # print("DE", ddn)
        # self.ddn_field.setDate(ddn)
        # self.ddn_field = QDateEdit(QDate(ddn))
        self.addres_field = QTextEdit(addres)
        self.nationality_field = LineEdit(nationality)
        self.phone_field = IntLineEdit(phone)
        self.phone_field.setInputMask("## ## ## ##")
        self.poste_list = get_postes()
        self.poste_box = QComboBox()
        for index, value in enumerate(self.poste_list):
            self.poste_box.addItem(
                "{}".format(self.poste_list.get(value).upper()), value)
            if self.member.poste == value:
                print(value)
                self.poste_box.setCurrentIndex(index)

        formbox = QFormLayout()
        formbox.addRow(FormLabel(u"Nom complet : *"), self.full_name_field)
        formbox.addRow(FormLabel(u"Sexe *:"), self.sex_box)
        formbox.addRow(FormLabel(u"Date de naissance *:"), self.ddn_field)
        formbox.addRow(FormLabel(u"Poste occupé *:"), self.poste_box)
        formbox.addRow(FormLabel(u"Nationalité *:"), self.nationality_field)
        formbox.addRow(FormLabel(u"Téléphone :"), self.phone_field)
        formbox.addRow(FormLabel(u"Adresse :"), self.addres_field)

        butt = Button(u"Enregistrer")
        butt.clicked.connect(self.save_edit)
        formbox.addRow("", butt)

        vbox.addLayout(formbox)
        self.setLayout(vbox)
예제 #18
0
def details(regdent, trtdent, startdate, enddate, filters=""):
    '''
    returns an html table, for regdent, trtdent,startdate,enddate
    '''
    dent_conditions = ""
    dents = []
    try:
        if regdent != "*ALL*":
            dent_conditions = 'dntid=%s and '
            dents.append(localsettings.ops_reverse[regdent])
        if trtdent != "*ALL*":
            dent_conditions += 'trtid=%s and '
            dents.append(localsettings.ops_reverse[trtdent])
    except KeyError:
        print "Key Error - %s or %s unregconised" % (regdent, trtdent)
        return '<html><body>%s</body></html>' % _(
            "Error - unrecognised practioner- sorry")

    total, nettotal = 0, 0

    iterDate = QDate(startdate.year(), startdate.month(), 1)

    retarg = '''
    <html><body><h4>%s %s %s %s %s %s %s %s %s</h4>''' % (
        _("Patients of"), regdent, _("treated by"), trtdent, _("between"),
        localsettings.formatDate(startdate.toPyDate()), _("and"),
        localsettings.formatDate(enddate.toPyDate()), filters)

    retarg += '''<table width="100%" border="1"><tr><th>DATE</th>
    <th>Dents</th><th>Serial Number</th><th>Name</th>
    <th>Pt Type</th><th>Treatment</th><th></th>
    <th>Gross Fee</th><th>Net Fee</th>'''

    db = connect.connect()
    cursor = db.cursor()

    query = DETAILS_QUERY.replace("{{DENT CONDITIONS}}", dent_conditions)
    query = query.replace("{{FILTERS}}", filters)

    while enddate >= iterDate:
        monthtotal, monthnettotal = 0, 0

        if startdate > iterDate:
            queryStartDate = startdate
        else:
            queryStartDate = iterDate

        queryEndDate = iterDate.addMonths(1).addDays(-1)
        if enddate < queryEndDate:
            queryEndDate = enddate

        values = tuple(
            dents + [queryStartDate.toPyDate(), queryEndDate.toPyDate()])

        cursor.execute(query, (values))

        rows = cursor.fetchall()

        for i, row in enumerate(rows):
            retarg += '<tr>' if i % 2 else '<tr bgcolor="#eeeeee">'

            retarg += "<td>%s</td>" % row[0]
            try:
                retarg += '<td> %s / ' % localsettings.ops[row[4]]
            except KeyError:
                retarg += "<td>?? / "
            try:
                retarg += localsettings.ops[row[5]]
            except KeyError:
                retarg += "??"

            retarg += '</td><td>%s</td><td>%s</td><td>%s</td>' % (row[1:4])

            tx = ""
            for item in (6, 7, 8, 9, 10, 11, 12, 13, 14, 15):
                if row[item] is not None and row[item] != "":
                    tx += "%s " % row[item]

            if ALLOW_TX_EDITS:
                extra_link = ' / <a href="daybook_id_edit?%s">%s</a>' % (
                    row[19], _("Edit Tx"))
            else:
                extra_link = ""
            retarg += '''<td>%s</td>
            <td><a href="daybook_id?%sfeesa=%sfeesb=%s">%s</a>%s</td>
            <td align="right">%s</td>
            <td align="right">%s</td></tr>''' % (tx.strip("%s " % chr(0)),
                                                 row[19], row[16], row[17],
                                                 _("Ests"),
                                                 extra_link,
                                                 localsettings.formatMoney(
                                                 row[16]),
                                                 localsettings.formatMoney(row[17]))

            total += int(row[16])
            monthtotal += int(row[16])

            nettotal += int(row[17])
            monthnettotal += int(row[17])
        retarg += '''<tr><td colspan="6"></td><td><b>SUBTOTAL - %s %s</b></td>
        <td align="right"><b>%s</b></td>
        <td align="right"><b>%s</b></td></tr>''' % (
            localsettings.monthName(iterDate.toPyDate()),
            iterDate.year(),
            localsettings.formatMoney(monthtotal),
            localsettings.formatMoney(monthnettotal))
        iterDate = iterDate.addMonths(1)
    cursor.close()
    # db.close()

    retarg += '''<tr><td colspan="6"></td><td><b>GRAND TOTAL</b></td>
    <td align="right"><b>%s</b></td>
    <td align="right"><b>%s</b></td></tr></table></body></html>''' % (
        localsettings.formatMoney(total), localsettings.formatMoney(nettotal))

    return retarg
예제 #19
0
            _("You can filter using the following fields.")
        )
        for i, field in enumerate(self.field_names):
            if i == 0:
                html += "<tr>"
            elif i % 5 == 0:
                html += "</tr><tr>"
            html += "<td>%s</td>" % field

        html += "</tr></table><h5>%s</h5><pre>%s</pre></body></html>" % (
            _("Examples"),
            'patients.serialno=1 AND chart REGEXP ".*MOD,CO.*"\n'
            'ndu="SR/F"\nexmpt="M"\n')
        return html

_filter_help = FilterHelp()


def filter_help_text():
    return _filter_help.help_text()

if __name__ == "__main__":
    localsettings.initiate()

    for combo in (("*ALL*", "NW"), ("NW", "AH"), ("NW", "NW")):
        r = details(combo[0], combo[1], QDate(
            2008, 10, 31), QDate(2008, 11, 11))
        print r.encode("ascii", "replace")

    print filter_help_text()
예제 #20
0
 def qDateFromSeconds(self, seconds):
     t = time.localtime(seconds)
     return QDate(*t[0:3])
예제 #21
0
    def __init__(self, template, parent=None):
        """
		\todo Eigentlich benötigt Subpower keinen eigenen Datentyp. Da die ganzen Zusatzinformationen ja nur im Template zu stehen haben und nicht auch für den Charakter bekannt sein müssen. Der Wert "level" ist aber interessant und gilt für andere Klassen nicht.
		"""

        super(StorageCharacter, self).__init__(parent)

        self.__storage = template

        self.isLoading = False
        self.__modified = False
        self.__dateBirth = QDate(1, 1, 1)
        self.__dateBecoming = QDate(1, 1, 1)
        self.__dateGame = QDate(1, 1, 1)
        self.__age = 0
        self.__ageBecoming = 0
        self.__species = ""
        self.__virtue = ""
        self.__vice = ""
        self.__breed = ""
        self.__bonus = {}
        self.__kith = ""
        self.__faction = ""
        self.__organisation = ""
        self.__party = ""
        self.__height = 0.0
        self.__weight = 0.0
        self.__eyes = ""
        self.__hair = ""
        self.__nationality = ""
        self.__description = ""
        self.__powerstat = 0
        self.__morality = 0
        self.__era = ""
        self.__picture = None
        self.__armor = {
            "name": "",
            "dedicated": False,
        }
        self.__equipment = []
        self.__magicalTool = ""

        self.identity = Identity()

        self.__derangements = {}

        self.__nimbus = ""
        self.__paradoxMarks = ""

        self.__vinculi = []
        for i in range(Config.VINCULI_COUNT_MAX):
            vinculum = AbstractTrait()
            self.__vinculi.append(vinculum)
            vinculum.traitChanged.connect(self.setModified)

        self.__companionName = ""
        self.__companionPower = 0
        self.__companionFinesse = 0
        self.__companionResistance = 0
        self.__companionSize = 0
        self.__companionSpeedFactor = 0
        self.__companionFuel = 0
        self.__companionInfluences = []
        for i in range(Config.COMPANION_INFLUENCES_MAX):
            companionInfluence = AbstractTrait()
            self.__companionInfluences.append(companionInfluence)
            companionInfluence.traitChanged.connect(self.setModified)
        self.__companionNumina = []
        self.__companionBan = ""

        self.dateBirthChanged.connect(self.__calcAge)
        self.dateGameChanged.connect(self.__calcAge)
        self.dateBirthChanged.connect(self.__calcAgeBecoming)
        self.dateBecomingChanged.connect(self.__calcAgeBecoming)
        self.weaponAdded.connect(self.weaponsChanged)
        self.weaponRemoved.connect(self.weaponsChanged)
        self.equipmentAdded.connect(self.automobilesChanged)
        self.equipmentRemoved.connect(self.equipmentChanged)
        self.automobileAdded.connect(self.automobilesChanged)
        self.automobileRemoved.connect(self.automobilesChanged)
        self.extraordinaryItemAdded.connect(self.extraordinaryItemsChanged)
        self.extraordinaryItemRemoved.connect(self.extraordinaryItemsChanged)

        # Die Eigenschaften in den Charakter laden.
        self.__traits = {}
        # Eigenschaften setzen.
        for typ in self.__storage.traits.keys():
            self.__traits.setdefault(typ, {})
            for item in template.traits[typ]:
                self.__traits[typ].setdefault(item, {})
                for subitem in template.traits[typ][item].items():
                    #Debug.debug(subitem)
                    val = 2  # Dies mache ich, damit beim initialen Charakter-Reset, auch alle Voraussetzungen überprüft werden.
                    # Eigenschaften, die Zusaztext erhalten können (bspw. Language), werden mehrfach in das Dictionary eingefügt. Aber da ein Dictonary immer nur einen Eintrag desselben Namens haben kann, muß selbiger um ein numerisches Suffix erweitert werden.
                    loop = 1
                    custom = False
                    customText = None
                    if typ != "Subpower" and subitem[1]["custom"]:
                        loop = Config.MULTIPLE_TRAITS_MAX
                        custom = True

                    for i in range(loop):
                        trait = None
                        if typ == "Subpower":
                            trait = SubPowerTrait(self, subitem[1]["name"],
                                                  val)
                            trait.level = subitem[1]["level"]
                            trait.powers = subitem[1]["powers"]
                        else:
                            if typ == "Attribute" or typ == "Skill":
                                trait = BonusTrait(self, subitem[1]["name"],
                                                   val)
                            else:
                                trait = StandardTrait(self, subitem[1]["name"],
                                                      val)
                            trait.age = subitem[1]["age"]
                            trait.era = subitem[1]["era"]
                            trait.custom = custom
                            trait.customText = customText
                        trait.identifier = subitem[0]
                        trait.species = subitem[1]["species"]
                        trait.cheap = subitem[1]["cheap"]
                        #if typ == "Subpower" and trait.species == "Werewolf":
                        #Debug.debug(subitem[1]["name"], subitem[1]["only"])
                        trait.only = subitem[1]["only"]
                        if "prerequisites" in subitem[1] and subitem[1][
                                "prerequisites"]:
                            trait.hasPrerequisites = True
                            trait.prerequisitesText = subitem[1][
                                "prerequisites"]
                        # In der Eigenschaft steht der richtige Name aber im Dictionary der Name mit einem numerischen Suffix, damit die Eigenschaft häufiger auftauchen kann.
                        dictKey = subitem[0]
                        if custom:
                            dictKey = "{}{}".format(subitem[0], i)
                        self.__traits[typ][item].setdefault(dictKey, trait)

                        # Wenn sich eine Eigenschaft ändert, gilt der Charakter als modifiziert.
                        trait.traitChanged.connect(self.setModified)
                #if typ == "Subpower":
                #Debug.debug(self.__traits[typ][item])

        self.bonusChanged.connect(self.__changeBonusTrait)

        # Sobald irgendein Aspekt des Charakters verändert wird, muß festgelegt werden, daß sich der Charkater seit dem letzten Speichern verändert hat.
        # Es ist Aufgabe der Speicher-Funktion, dafür zu sorgen, daß beim Speichern diese Inforamtion wieder zurückgesetzt wird.
        self.identity.identityChanged.connect(self.setModified)
        self.eraChanged.connect(self.setModified)
        self.dateBirthChanged.connect(self.setModified)
        self.dateBecomingChanged.connect(self.setModified)
        self.dateGameChanged.connect(self.setModified)
        # Unerwünschte Wirkung
        #self.speciesChanged.connect(self.clearUnusableTraits)
        self.speciesChanged.connect(self.setModified)
        self.virtueChanged.connect(self.setModified)
        self.viceChanged.connect(self.setModified)
        self.breedChanged.connect(self.setModified)
        self.kithChanged.connect(self.setModified)
        self.bonusChanged.connect(self.setModified)
        self.factionChanged.connect(self.setModified)
        self.partyChanged.connect(self.setModified)
        self.descriptionChanged.connect(self.setModified)
        self.powerstatChanged.connect(self.setModified)
        self.moralityChanged.connect(self.setModified)
        self.derangementChanged.connect(self.setModified)
        self.pictureChanged.connect(self.setModified)
        self.weaponsChanged.connect(self.setModified)
        self.armorChanged.connect(self.setModified)
        self.equipmentChanged.connect(self.setModified)
        self.automobilesChanged.connect(self.setModified)
        self.extraordinaryItemsChanged.connect(self.setModified)
        self.magicalToolChanged.connect(self.setModified)
        self.nimbusChanged.connect(self.setModified)
        self.paradoxMarksChanged.connect(self.setModified)
        self.companionPowerChanged.connect(self.setModified)
        self.companionFinesseChanged.connect(self.setModified)
        self.companionResistanceChanged.connect(self.setModified)
        self.companionSizeChanged.connect(self.setModified)
        self.companionSpeedFactorChanged.connect(self.setModified)
        self.companionFuelChanged.connect(self.setModified)
        self.companionNuminaChanged.connect(self.setModified)
        self.companionBanChanged.connect(self.setModified)

        self.ageChanged.connect(self.deselctTraitsWithWrongAge)

        self.speciesChanged.connect(self.__emitTraitVisibleReasonChanged)
        self.ageChanged.connect(self.__emitTraitVisibleReasonChanged)
        self.eraChanged.connect(self.__emitTraitVisibleReasonChanged)
        self.breedChanged.connect(self.__emitTraitVisibleReasonChanged)
        self.factionChanged.connect(self.__emitTraitVisibleReasonChanged)
예제 #22
0
    def resetCharacter(self):
        ## Der Charkater wird umorganisiert, ohne daß wir haufenweise Warnhinweise haben wollen.
        self.isLoading = True
        # Standardspezies ist der Mensch.
        self.species = Config.SPECIES_INITIAL
        # Zeitalter festlegen.
        self.era = Config.ERA_INITIAL
        ## Anfangsdatum setzen.
        self.dateGame = QDate.currentDate()
        self.dateBirth = QDate(self.dateGame.year() - Config.AGE_INITIAL,
                               self.dateGame.month(), self.dateGame.day())
        self.dateBecoming = QDate(self.dateGame.year() - Config.AGE_ADULT,
                                  self.dateGame.month(), self.dateGame.day())

        # Löschen aller Identitäten.
        self.identity.reset()

        #Debug.debug(self.__storage.virtues[0])
        #Debug.debug(self.__storage.virtues[0]["name"])
        self.virtue = self.__storage.virtues[0]["name"]
        self.vice = self.__storage.vices[0]["name"]
        self.breed = ""
        self.bonus = ""
        self.kith = ""
        self.faction = ""
        self.height = 1.60
        self.weight = 60
        self.eyes = ""
        self.hair = ""
        self.nationality = ""
        # Nicht notwendig, da ja schon die Spezies gewechselt wird, was automatisch diese Felder zurücksetzt.
        #self.breed = self.__storage.breeds(Config.SPECIES_INITIAL)[0]
        self.__derangements = {}
        self.party = ""
        self.description = ""

        # Menschen haben eine Leere liste, also kann ich auch die Indizes nicht ändern.
        #// setBreed(storage.breedNames(species()).at(0));
        #// setFaction(storage.breedNames(species()).at(0));

        # Attribute und andere Eigenschaften auf Anfangswerte setzen.
        for item in self.__traits:
            val = 0
            if item == "Attribute":
                val = 1
            for subitem in self.__traits[item]:
                for subsubitem in self.__traits[item][subitem].values():
                    subsubitem.value = val
                    subsubitem.customText = ""
                    subsubitem.specialties = []

        self.morality = Config.TRAIT_MORALITY_VALUE_DEFAULT

        # Übernatürliche Eigenschaft festlegen.
        self.powerstat = Config.TRAIT_POWERSTAT_VALUE_DEFAULT

        # Beim Löschen ist darauf zu achten, daß ich nicht aus der Liste löschen kann, über die ich iteriere. Sonst wird nicht alles gelöscht.
        for category in self.__weapons:
            ## Kopie erstellen
            weaponList = self.__weapons[category][:]
            for weapon in weaponList:
                self.deleteWeapon(category, weapon)
        self.setArmor(name="")
        ## Kopie erstellen
        eqipmentList = self.__equipment[:]
        for item in eqipmentList:
            self.deleteEquipment(item)
        for category in self.__automobiles:
            ## Kopie erstellen
            automobileList = self.__automobiles[category][:]
            for automobile in automobileList:
                self.deleteAutomobile(category, automobile)
        for typ in self.__extraordinaryItems:
            ## Kopie erstellen
            extraordinaryItemList = self.__extraordinaryItems[typ][:]
            for item in extraordinaryItemList:
                self.deleteExtraordinaryItem(typ, item)
        self.magicalTool = ""
        self.nimbus = ""
        self.paradoxMarks = ""
        for vinculum in self.__vinculi:
            vinculum.name = ""
            vinculum.value = 0

        self.companionName = ""
        self.companionPower = 0
        self.companionFinesse = 0
        self.companionResistance = 0
        self.companionSize = 0
        self.companionSpeedFactor = 0
        self.companionFuel = 0
        for companionInfluence in self.__companionInfluences:
            companionInfluence.name = ""
            companionInfluence.value = 0
        self.companionNumina = []
        self.companionBan = ""

        self.picture = QPixmap()

        ## Fertig mit dem Laden der enuen Werte.
        self.isLoading = False
예제 #23
0
    def __init__(self, template, character, parent=None):
        super(TemplateWidget, self).__init__(parent)

        self.ui = Ui_TemplateWidget()
        self.ui.setupUi(self)

        self.__storage = template
        self.__character = character

        speciesList = [
            species[0] for species in self.__storage.species.items()
            if species[1]["playable"]
        ]
        speciesList.sort()
        #self.ui.comboBox_species.addItems(speciesList)
        for species in speciesList:
            self.ui.comboBox_species.addItem(
                QIcon(":/icons/images/species/{}/Skull.png".format(species)),
                species)

        self.ui.dateEdit_dateBecoming.setMinimumDate(QDate(100, 1, 1))

        ## Speichern der vom Benutzer veränderten Werte
        self.ui.dateEdit_dateBecoming.dateChanged.connect(
            self.__character.setDateBecoming)
        self.ui.comboBox_species.currentIndexChanged[str].connect(
            self.__character.setSpecies)
        self.ui.comboBox_breed.currentIndexChanged[str].connect(
            self.__character.setBreed)
        self.ui.comboBox_bonus.currentIndexChanged[str].connect(
            self.setCharacterBonus)
        self.ui.comboBox_kith.currentIndexChanged[str].connect(
            self.__character.setKith)
        self.ui.comboBox_faction.currentIndexChanged[str].connect(
            self.__character.setFaction)
        self.ui.lineEdit_faction.textEdited.connect(
            self.__character.setFaction)
        self.ui.comboBox_organisation.currentIndexChanged[str].connect(
            self.__character.setOrganisation)
        self.ui.lineEdit_party.textEdited.connect(self.__character.setParty)

        ## Aktualisieren der Darstellung der im Charakter veränderten Werte.
        self.__character.dateBecomingChanged.connect(
            self.ui.dateEdit_dateBecoming.setDate)
        self.__character.ageBecomingChanged.connect(
            self.ui.label_ageBecoming.setNum)
        self.__character.speciesChanged.connect(self.updateSpecies)
        self.__character.breedChanged.connect(self.updateBreed)
        self.__character.breedChanged.connect(self.repopulateBonus)
        self.__character.breedChanged.connect(self.repopulateKiths)
        self.__character.bonusChanged.connect(self.updateBonus)
        self.__character.kithChanged.connect(self.updateKith)
        self.__character.speciesChanged.connect(self.updateBreedTitle)
        self.__character.speciesChanged.connect(self.repopulateBreeds)
        self.__character.factionChanged.connect(self.updateFaction)
        self.__character.speciesChanged.connect(self.updateFactionTitle)
        self.__character.speciesChanged.connect(self.repopulateFactions)
        self.__character.organisationChanged.connect(self.updateOrganisation)
        self.__character.speciesChanged.connect(self.updateOrganisationTitle)
        self.__character.speciesChanged.connect(self.repopulateOrganisations)
        self.__character.partyChanged.connect(self.ui.lineEdit_party.setText)
        self.__character.speciesChanged.connect(self.updatePartyTitle)
        # Menschen können ihre Fraktion selbst eintragen und haben einige Angaben einfach nicht nötig.
        self.__character.speciesChanged.connect(self.hideShowWidgets_species)

        ## Das Alter darf nie negativ werden können
        self.__character.dateBirthChanged.connect(
            self.ui.dateEdit_dateBecoming.setMinimumDate)
        self.__character.dateGameChanged.connect(
            self.ui.dateEdit_dateBecoming.setMaximumDate)
예제 #24
0
import time_util
import bcdate_util
import conf
import layer_settings

"""
The QTSlider only supports integers as the min and max, therefore the maximum maximum value
is whatever can be stored in an int. Making it a signed int to be sure.
(http://qt-project.org/doc/qt-4.8/qabstractslider.html)
"""
MAX_TIME_LENGTH_SECONDS_SLIDER = 2 ** 31 - 1
"""
according to the docs of QDateTime, the minimum date supported is the first day of
year 100  (http://qt-project.org/doc/qt-4.8/qdatetimeedit.html#minimumDate-prop)
"""
MIN_QDATE = QDate(100, 1, 1)

DOCK_WIDGET_FILE = "dockwidget2.ui"
ADD_VECTOR_LAYER_WIDGET_FILE = "addLayer.ui"
ADD_RASTER_LAYER_WIDGET_FILE = "addRasterLayer.ui"
ARCH_WIDGET_FILE = "arch.ui"
OPTIONS_WIDGET_FILE = "options.ui"
ANIMATION_WIDGET_FILE = "animate.ui"


class TimestampLabelConfig(object):
    """Object that has the settings for rendering timestamp labels. Can be customized via the UI"""
    PLACEMENTS = ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW']
    DEFAULT_FONT_SIZE = 25
    font = "Arial"  # Font names or family, comma-separated CSS style
    size = DEFAULT_FONT_SIZE  # Relative values between 1-7
예제 #25
0
파일: Types.py 프로젝트: dio4/vista_1
 def dateFromJSON(strDate):
     pyDate = datetime.datetime.strptime(
         strDate, "%Y-%m-%d").date() if strDate else None
     return QDate(pyDate.year, pyDate.month,
                  pyDate.day) if pyDate else QDate()
예제 #26
0
    def __init__(self, session, parent=None):
        super(ExpensesDialog, self).__init__(parent)
        self.session = session
        session = self.pullOnes('session', session)
        self.sessionname = str(session['name']) + ' Session'
        self.pagetitle = self.sessionname
        self.tableFont = QFont('Century Gothic', 8)
        #self.tableFont.setFamily('Century Gothic')
        self.tableHeaderStyle = "::section {" "background-color: teal; color:white}"
        #pull all CA
        self.editID = 0
        self.hold_account = {}
        self.hold_expenses = {}
        self.hold_expensesGroup = {}

        from_label = QLabel('From:')
        to_label = QLabel('To:')
        self.fromData = QDateEdit()
        self.toData = QDateEdit()
        currentDate = QDate()
        self.fromData.setDate(currentDate.currentDate())
        self.fromData.setCalendarPopup(True)
        self.toData.setDate(currentDate.currentDate())
        self.toData.setCalendarPopup(True)
        self.pull_btn = QPushButton()
        self.pull_btn.setText("Load")
        h_pull_box = QHBoxLayout()
        h_pull_box.addWidget(from_label)
        h_pull_box.addWidget(self.fromData)
        h_pull_box.addWidget(to_label)
        h_pull_box.addWidget(self.toData)
        h_pull_box.addWidget(self.pull_btn)

        expensesGroup = self.pullGroupExpenses()
        account = self.pullAccount()

        self.expenseGroupText = QLabel('Category')
        self.expenseGroupData = QComboBox()
        self.expenseGroupData.currentIndexChanged.connect(self.reloadExpenses)
        self.expenseText = QLabel('Expenses')
        self.expenseData = QComboBox()
        self.amountText = QLabel('Amount')
        self.amountData = QLineEdit()
        self.amountData.setPlaceholderText('0000.00')
        self.tellerText = QLabel('Teller/Reciept No.')
        self.tellerData = QLineEdit()
        self.tellerData.setPlaceholderText('xxxxxxxxx')
        self.accountText = QLabel('Account')
        self.accountData = QComboBox()
        self.dateText = QLabel('Date')
        self.dateData = QDateEdit()
        self.dateData.setDate(currentDate.currentDate())
        self.dateData.setCalendarPopup(True)
        self.descriptionText = QLabel('Brief Description')
        self.descriptionData = QPlainTextEdit()
        self.descriptionData.move(200, 100)
        hboz = QHBoxLayout()
        self.gender = QLabel('State')
        self.r1 = QRadioButton('Expenses')
        self.r1.setChecked(True)
        self.r2 = QRadioButton('Refund')
        hboz.addWidget(self.r1)
        hboz.addWidget(self.r2)

        i = 0
        for a in expensesGroup:
            self.hold_expensesGroup[i] = a['id']
            tex = str(a['name']).upper()
            self.expenseGroupData.addItem(tex)
            i += 1

        i = 0
        exp_key = self.hold_expensesGroup[self.expenseGroupData.currentIndex()]
        expenses = self.pullExpenses(exp_key)
        for a in expenses:
            self.hold_expenses[i] = a['id']
            tex = str(a['name']).upper()
            self.expenseData.addItem(tex)
            i += 1

        i = 0
        for a in account:
            self.hold_account[i] = a['id']
            tex = str(a['name']).upper()
            self.accountData.addItem(tex)
            i += 1

        self.FormLayout = QFormLayout()
        self.FormLayout.addRow(self.expenseGroupText, self.expenseGroupData)
        self.FormLayout.addRow(self.expenseText, self.expenseData)
        self.FormLayout.addRow(self.accountText, self.accountData)
        self.FormLayout.addRow(self.tellerText, self.tellerData)
        self.FormLayout.addRow(self.amountText, self.amountData)
        self.FormLayout.addRow(self.gender, hboz)
        self.FormLayout.addRow(self.dateText, self.dateData)
        self.FormLayout.addRow(self.descriptionText, self.descriptionData)

        groupBox1 = QGroupBox('Add Expenses')
        groupBox1.setLayout(self.FormLayout)

        self.pb = QPushButton()
        self.pb.setObjectName("Add")
        self.pb.setText("Add Expenses")

        self.pb1 = QPushButton()
        self.pb1.setObjectName("Edit")
        self.pb1.setText("Edit Row")
        self.pb1.setEnabled(False)

        self.pb2 = QPushButton()
        self.pb2.setObjectName("Close")
        self.pb2.setText("Close")

        self.pb3 = QPushButton()
        self.pb3.setObjectName("Delete")
        self.pb3.setText("Delete Row")
        self.pb3.setEnabled(False)

        self.pb4 = QPushButton()
        self.pb4.setObjectName("Reset")
        self.pb4.setText("Reset")
        self.pb4.hide()

        self.pb5 = QPushButton()
        self.pb5.setObjectName("Change")
        self.pb5.setText("Change Expenses")
        self.pb5.hide()

        self.pb6 = QPushButton()
        self.pb6.setObjectName("Clear")
        self.pb6.setText("Clear Selection")
        self.pb6.setEnabled(False)

        hbo = QHBoxLayout()
        hbo.addWidget(self.pb)
        hbo.addWidget(self.pb5)
        hbo.addWidget(self.pb4)
        hbo.addWidget(self.pb2)
        groupBox2 = QGroupBox('Expenses Data')
        groupBox2.setLayout(hbo)

        self.cols = ['SN', 'EXPENSES', 'ACCOUNT', 'AMOUNT', 'DATE']
        al = self.pullExpensesData()
        if len(al) > 0:
            al = al
        else:
            al = {}

        self.table = QTableWidget()
        header = self.table.horizontalHeader()
        header.setResizeMode(QHeaderView.ResizeToContents)
        header.setStretchLastSection(True)
        header.setStyleSheet(self.tableHeaderStyle)
        vheader = self.table.verticalHeader()
        vheader.setStyleSheet(self.tableHeaderStyle)
        # Body
        self.table.setWindowTitle("Expenses")
        self.table.resize(300, 250)
        self.table.setFont(self.tableFont)
        self.table.setSortingEnabled(2)
        #self.table.resizeColumnsToContents()
        self.table.setRowCount(len(al))
        self.table.setColumnCount(len(self.cols))
        self.table.setHorizontalHeaderLabels(self.cols)
        self.table.setContextMenuPolicy(Qt.CustomContextMenu)
        self.table.customContextMenuRequested.connect(self.handleHeaderMenu)
        self.table.hideColumn(0)
        self.table.setSelectionMode(QAbstractItemView.MultiSelection)
        self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table.setEditTriggers(QAbstractItemView.NoEditTriggers)

        i = 0
        for q in al:
            #row id
            self.table.setItem(i, 0, QTableWidgetItem(str(q['id'])))
            self.table.setItem(i, 1,
                               QTableWidgetItem(str(q['expensename']).upper()))
            self.table.setItem(i, 2,
                               QTableWidgetItem(str(q['accountname']).upper()))
            zamt = str("{:,}".format(float(q['amount'])))
            self.table.setItem(i, 3, QTableWidgetItem(zamt))
            damz = float(q['datepaid'])
            damt = datetime.utcfromtimestamp(damz).strftime('%d-%m-%Y')
            self.table.setItem(i, 4, QTableWidgetItem(str(damt)))
            i += 1
        self.table.itemSelectionChanged.connect(self.confirmSelection)
        self.table.resizeRowsToContents()
        v_pull_box = QVBoxLayout()
        self.h1_pull_box = QVBoxLayout()
        self.h1_pull_box.addWidget(self.table)
        v_pull_box.addLayout(h_pull_box)
        v_pull_box.addLayout(self.h1_pull_box)
        h2_pull_box = QHBoxLayout()
        h2_pull_box.addWidget(self.pb1)
        h2_pull_box.addWidget(self.pb3)
        h2_pull_box.addWidget(self.pb6)
        v_pull_box.addLayout(h2_pull_box)

        groupBox3 = QGroupBox()
        groupBox3.setLayout(hbo)
        groupBox2.setLayout(v_pull_box)

        grid = QGridLayout()
        grid.addWidget(groupBox1, 0, 0)
        grid.addWidget(groupBox2, 0, 1, 2, 1)
        grid.addWidget(groupBox3, 1, 0)

        self.setLayout(grid)
        self.connect(self.pb, SIGNAL("clicked()"), lambda: self.button_click())
        self.connect(self.pb1, SIGNAL("clicked()"),
                     lambda: self.button_editshow())
        self.connect(self.pb2, SIGNAL("clicked()"),
                     lambda: self.button_close(self))
        self.connect(self.pb3, SIGNAL("clicked()"),
                     lambda: self.button_delete())
        self.connect(self.pb4, SIGNAL("clicked()"),
                     lambda: self.button_reset())
        self.connect(self.pb5, SIGNAL("clicked()"), lambda: self.button_edit())
        self.connect(self.pb6, SIGNAL("clicked()"),
                     lambda: self.button_clear())
        self.connect(self.pull_btn,
                     SIGNAL("clicked()"),
                     lambda x=1: self.reloadTable(x))

        self.setWindowTitle(self.pagetitle)
예제 #27
0
    def __init__(self, table_p, report, parent, *args, **kwargs):
        QDialog.__init__(self, parent, *args, **kwargs)

        self.setWindowTitle(u"Modification")
        self.table_p = table_p
        self.rpt = report
        self.parent = parent

        self.out_op = True
        if self.rpt.type_ == Report.E:
            self.out_op = False

        self.selling_price_field = IntLineEdit(unicode(self.rpt.selling_price))
        self.cost_buying_field = IntLineEdit(unicode(self.rpt.cost_buying))
        self.qty_field = IntLineEdit(unicode(self.rpt.qty))

        self.date_field = FormatDate(QDate(self.rpt.date))
        self.date_field.setEnabled(False)

        butt = Button(u"Mise à jour")
        butt.clicked.connect(self.edit_report)
        cancel_but = Button(u"Annuler")
        cancel_but.clicked.connect(self.cancel)

        # Combobox widget
        i = 0
        self.liste_type = [Report.E, Report.S]
        self.box_type = QComboBox()
        self.box_type.setEnabled(False)
        for index in xrange(0, len(self.liste_type)):
            ty = self.liste_type[index]
            if ty == self.rpt.type_:
                i = index
            sentence = u"%(ty)s" % {'ty': ty}
            self.box_type.addItem(sentence, ty)
            self.box_type.setCurrentIndex(i)
        # Combobox widget
        # self.liste_store = Store.order_by(desc(Store.id)).all()
        # self.box_mag = QComboBox()
        # for index in xrange(0, len(self.liste_store)):
        #     op = self.liste_store[index]
        #     sentence = u"%(name)s" % {'name': op.name}
        #     self.box_mag.addItem(sentence, QVariant(op.id))
        # Combobox widget

        self.liste_product = Product.all()
        self.box_prod_field = QComboBox()
        self.box_prod_field.setEnabled(False)

        for index in xrange(0, len(self.liste_product)):
            prod = self.liste_product[index]
            if prod.name == self.rpt.product.name:
                i = index
            sentence = u"%(name)s" % {'name': prod.name}
            self.box_prod_field.addItem(sentence, prod.id)
            self.box_prod_field.setCurrentIndex(i)
        vbox = QVBoxLayout()
        formbox = QFormLayout()
        # editbox.addWidget(FormLabel((_(u"Store"))), 0, 1)
        # editbox.addWidget(self.box_mag, 1, 1)
        formbox.addRow(FormLabel(u"Type"), FormLabel(self.rpt.type_))
        formbox.addRow(FormLabel(u"Désignation"), self.box_prod_field)
        formbox.addRow(FormLabel(u"Quantité"), self.qty_field)
        formbox.addRow(FormLabel("Prix d'achat"), self.cost_buying_field)
        formbox.addRow(FormLabel("Prix vente"), self.selling_price_field)
        formbox.addRow(FormLabel(u"Date"), self.date_field)
        formbox.addRow(butt, cancel_but)
        vbox.addLayout(formbox)
        self.setLayout(vbox)
예제 #28
0
 def populateBirth(self):
     for noi, vals in self.scenario.indiv.iteritems():
         birth = QDate(vals['birth'])
         self._listPerson[noi][S.birth].setDate(birth)
예제 #29
0
    def processAlgorithm(self, progress):
        inLayer = dataobjects.getObjectFromUri(
            self.getParameterValue(self.INPUT))
        boundary = self.getParameterValue(self.MODE) == self.MODE_BOUNDARY
        smallestArea = self.getParameterValue(
            self.MODE) == self.MODE_SMALLEST_AREA
        keepSelection = self.getParameterValue(self.KEEPSELECTION)

        if not keepSelection:
            # Make a selection with the values provided
            attribute = self.getParameterValue(self.ATTRIBUTE)
            comparison = self.comparisons[self.getParameterValue(
                self.COMPARISON)]
            comparisonvalue = self.getParameterValue(self.COMPARISONVALUE)

            selectindex = inLayer.dataProvider().fieldNameIndex(attribute)
            selectType = inLayer.dataProvider().fields()[selectindex].type()
            selectionError = False

            if selectType == 2:
                try:
                    y = int(comparisonvalue)
                except ValueError:
                    selectionError = True
                    msg = self.tr('Cannot convert "%s" to integer' %
                                  unicode(comparisonvalue))
            elif selectType == 6:
                try:
                    y = float(comparisonvalue)
                except ValueError:
                    selectionError = True
                    msg = self.tr('Cannot convert "%s" to float' %
                                  unicode(comparisonvalue))
            elif selectType == 10:
                # 10: string, boolean
                try:
                    y = unicode(comparisonvalue)
                except ValueError:
                    selectionError = True
                    msg = self.tr('Cannot convert "%s" to unicode' %
                                  unicode(comparisonvalue))
            elif selectType == 14:
                # date
                dateAndFormat = comparisonvalue.split(' ')

                if len(dateAndFormat) == 1:
                    # QtCore.QDate object
                    y = QLocale.system().toDate(dateAndFormat[0])

                    if y.isNull():
                        msg = self.tr(
                            'Cannot convert "%s" to date with system date format %s'
                            % (unicode(dateAndFormat),
                               QLocale.system().dateFormat()))
                elif len(dateAndFormat) == 2:
                    y = QDate.fromString(dateAndFormat[0], dateAndFormat[1])

                    if y.isNull():
                        msg = self.tr(
                            'Cannot convert "%s" to date with format string "%s"'
                            % (unicode(dateAndFormat[0]), dateAndFormat[1]))
                else:
                    y = QDate()
                    msg = ''

                if y.isNull():
                    # Conversion was unsuccessfull
                    selectionError = True
                    msg += self.tr(
                        'Enter the date and the date format, e.g. "07.26.2011" "MM.dd.yyyy".'
                    )

            if (comparison == 'begins with' or comparison == 'contains') \
               and selectType != 10:
                selectionError = True
                msg = self.tr('"%s" can only be used with string fields' %
                              comparison)

            selected = []

            if selectionError:
                raise GeoAlgorithmExecutionException(
                    self.tr('Error in selection input: %s' % msg))
            else:
                for feature in inLayer.getFeatures():
                    aValue = feature.attributes()[selectindex]

                    if aValue is None:
                        continue

                    if selectType == 2:
                        x = int(aValue)
                    elif selectType == 6:
                        x = float(aValue)
                    elif selectType == 10:
                        # 10: string, boolean
                        x = unicode(aValue)
                    elif selectType == 14:
                        # date
                        x = aValue  # should be date

                    match = False

                    if comparison == '==':
                        match = x == y
                    elif comparison == '!=':
                        match = x != y
                    elif comparison == '>':
                        match = x > y
                    elif comparison == '>=':
                        match = x >= y
                    elif comparison == '<':
                        match = x < y
                    elif comparison == '<=':
                        match = x <= y
                    elif comparison == 'begins with':
                        match = x.startswith(y)
                    elif comparison == 'contains':
                        match = x.find(y) >= 0

                    if match:
                        selected.append(feature.id())

            inLayer.setSelectedFeatures(selected)

        if inLayer.selectedFeatureCount() == 0:
            ProcessingLog.addToLog(
                ProcessingLog.LOG_WARNING,
                self.tr('%s: (No selection in input layer "%s")' %
                        (self.commandLineName(),
                         self.getParameterValue(self.INPUT))))

        # Keep references to the features to eliminate
        featToEliminate = []
        for aFeat in inLayer.selectedFeatures():
            featToEliminate.append(aFeat)

        # Delete all features to eliminate in inLayer (we won't save this)
        inLayer.startEditing()
        inLayer.deleteSelectedFeatures()

        # ANALYZE
        if len(featToEliminate) > 0:  # Prevent zero division
            start = 20.00
            add = 80.00 / len(featToEliminate)
        else:
            start = 100

        progress.setPercentage(start)
        madeProgress = True

        # We go through the list and see if we find any polygons we can
        # merge the selected with. If we have no success with some we
        # merge and then restart the whole story.
        while madeProgress:  # Check if we made any progress
            madeProgress = False
            featNotEliminated = []

            # Iterate over the polygons to eliminate
            for i in range(len(featToEliminate)):
                feat = featToEliminate.pop()
                geom2Eliminate = feat.geometry()
                bbox = geom2Eliminate.boundingBox()
                fit = inLayer.getFeatures(
                    QgsFeatureRequest().setFilterRect(bbox))
                mergeWithFid = None
                mergeWithGeom = None
                max = 0
                min = -1
                selFeat = QgsFeature()

                while fit.nextFeature(selFeat):
                    selGeom = selFeat.geometry()

                    if geom2Eliminate.intersects(selGeom):
                        # We have a candidate
                        iGeom = geom2Eliminate.intersection(selGeom)

                        if iGeom is None:
                            continue

                        if boundary:
                            selValue = iGeom.length()
                        else:
                            # area. We need a common boundary in
                            # order to merge
                            if 0 < iGeom.length():
                                selValue = selGeom.area()
                            else:
                                selValue = -1

                        if -1 != selValue:
                            useThis = True

                            if smallestArea:
                                if -1 == min:
                                    min = selValue
                                else:
                                    if selValue < min:
                                        min = selValue
                                    else:
                                        useThis = False
                            else:
                                if selValue > max:
                                    max = selValue
                                else:
                                    useThis = False

                            if useThis:
                                mergeWithFid = selFeat.id()
                                mergeWithGeom = QgsGeometry(selGeom)
                # End while fit

                if mergeWithFid is not None:
                    # A successful candidate
                    newGeom = mergeWithGeom.combine(geom2Eliminate)

                    if inLayer.changeGeometry(mergeWithFid, newGeom):
                        madeProgress = True
                    else:
                        raise GeoAlgorithmExecutionException(
                            self.
                            tr('Could not replace geometry of feature with id %s'
                               % mergeWithFid))

                    start = start + add
                    progress.setPercentage(start)
                else:
                    featNotEliminated.append(feat)

            # End for featToEliminate

            featToEliminate = featNotEliminated

        # End while

        # Create output
        provider = inLayer.dataProvider()
        output = self.getOutputFromName(self.OUTPUT)
        writer = output.getVectorWriter(provider.fields(),
                                        provider.geometryType(), inLayer.crs())

        # Write all features that are left over to output layer
        iterator = inLayer.getFeatures()
        for feature in iterator:
            writer.addFeature(feature)

        # Leave inLayer untouched
        inLayer.rollBack()

        for feature in featNotEliminated:
            writer.addFeature(feature)
예제 #30
0
    def run(self):
        """Run method that performs all the real work"""
        self.dlg.show()  # show the dialog
        result = self.dlg.exec_()  # Run the dialog event loop

        if result:  # The user pressed OK, and this is what happened next!

            survex3dfile = self.dlg.selectedFile.text()
            gpkg_file = self.dlg.selectedGPKG.text()

            include_legs = self.dlg.Legs.isChecked()
            include_stations = self.dlg.Stations.isChecked()
            include_polygons = self.dlg.Polygons.isChecked()
            include_walls = self.dlg.Walls.isChecked()
            include_xsections = self.dlg.XSections.isChecked()
            include_traverses = self.dlg.Traverses.isChecked()

            exclude_surface_legs = not self.dlg.LegsSurface.isChecked()
            exclude_splay_legs = not self.dlg.LegsSplay.isChecked()
            exclude_duplicate_legs = not self.dlg.LegsDuplicate.isChecked()

            exclude_surface_stations = not self.dlg.StationsSurface.isChecked()

            use_clino_wgt = self.dlg.UseClinoWeights.isChecked()
            include_up_down = self.dlg.IncludeUpDown.isChecked()

            discard_features = not self.dlg.KeepFeatures.isChecked()

            get_crs_from_file = self.dlg.CRSFromFile.isChecked()
            get_crs_from_project = self.dlg.CRSFromProject.isChecked()

            if not os.path.exists(survex3dfile):
                raise Exception("File '%s' doesn't exist" % survex3dfile)

            if discard_features:
                self.leg_list = []
                self.station_list = []
                self.station_xyz = {}
                self.xsect_list = []

            # Read .3d file as binary, parse, and save data structures

            with open(survex3dfile, 'rb') as fp:

                line = fp.readline().rstrip()  # File ID check

                if not line.startswith(b'Survex 3D Image File'):
                    raise IOError('Not a survex .3d file: ' + survex3dfile)

                line = fp.readline().rstrip()  # File format version

                if not line.startswith(b'v'):
                    raise IOError('Unrecognised survex .3d version in ' +
                                  survex3dfile)

                version = int(line[1:])
                if version < 8:
                    raise IOError('Survex .3d version >= 8 required in ' +
                                  survex3dfile)

                line = fp.readline().rstrip(
                )  # Metadata (title and coordinate system)
                fields = line.split(b'\x00')

                previous_title = '' if discard_features else self.title

                if previous_title:
                    self.title = previous_title + ' + ' + fields[0]
                else:
                    self.title = fields[0]

                # Try to work out EPSG number from second field if available.
                # The project_crs should end up as a lowercase string like 'epsg:27700'

                if get_crs_from_project:
                    project_crs = self.iface.mapCanvas().mapRenderer(
                    ).destinationCrs()
                    self.extract_epsg(project_crs.authid().lower())
                elif get_crs_from_file and len(fields) > 1:
                    self.extract_epsg(fields[1])
                else:
                    self.epsg = None

                line = fp.readline().rstrip(
                )  # Timestamp, unused in present application

                if not line.startswith(b'@'):
                    raise IOError('Unrecognised timestamp in ' + survex3dfile)

                # timestamp = int(line[1:])

                flag = ord(fp.read(1))  # file-wide flag

                if flag & 0x80:  # abort if extended elevation
                    raise IOError("Can't deal with extended elevation in " +
                                  survex3dfile)

                # All front-end data read in, now read byte-wise
                # according to .3d spec.  Note that all elements must
                # be processed, in order, otherwise we get out of sync.

                # We first define some baseline dates

                date0 = QDate(1900, 1, 1)
                date1 = QDate(1900, 1, 1)
                date2 = QDate(1900, 1, 1)

                label, style = '', 0xff  # initialise label and style

                legs = []  # will be used to capture leg data between MOVEs
                xsect = []  # will be used to capture XSECT data
                nlehv = None  # .. remains None if there isn't any error data...

                while True:  # start of byte-gobbling while loop

                    char = fp.read(1)

                    if not char:  # End of file (reached prematurely?)
                        raise IOError('Premature end of file in ' +
                                      survex3dfile)

                    byte = ord(char)

                    if byte <= 0x05:  # STYLE
                        if byte == 0x00 and style == 0x00:  # this signals end of data
                            if legs:  # there may be a pending list of legs to save
                                self.leg_list.append((legs, nlehv))
                            break  # escape from byte-gobbling while loop
                        else:
                            style = byte

                    elif byte <= 0x0e:  # Reserved
                        continue

                    elif byte == 0x0f:  # MOVE
                        xyz = self.read_xyz(fp)
                        if legs:
                            self.leg_list.append((legs, nlehv))
                            legs = []

                    elif byte == 0x10:  # DATE (none)
                        date1 = date2 = date0

                    elif byte == 0x11:  # DATE (single date)
                        days = unpack('<H', fp.read(2))[0]
                        date1 = date2 = date0.addDays(days)

                    elif byte == 0x12:  # DATE (date range, short format)
                        days, extra = unpack('<HB', fp.read(3))
                        date1 = date0.addDays(days)
                        date2 = date0.addDays(days + extra + 1)

                    elif byte == 0x13:  # DATE (date range, long format)
                        days1, days2 = unpack('<HH', fp.read(4))
                        date1 = date0.addDays(days1)
                        date2 = date0.addDays(days2)

                    elif byte <= 0x1e:  # Reserved
                        continue

                    elif byte == 0x1f:  # Error info
                        nlehv = unpack('<iiiii', fp.read(20))

                    elif byte <= 0x2f:  # Reserved
                        continue

                    elif byte <= 0x33:  # XSECT
                        label = self.read_label(fp, label)
                        if byte & 0x02:
                            lrud = unpack('<iiii', fp.read(16))
                        else:
                            lrud = unpack('<hhhh', fp.read(8))
                        xsect.append((label, lrud))
                        if byte & 0x01:  # XSECT_END
                            self.xsect_list.append(xsect)
                            xsect = []

                    elif byte <= 0x3f:  # Reserved
                        continue

                    elif byte <= 0x7f:  # LINE
                        flag = byte & 0x3f
                        if not (flag & 0x20):
                            label = self.read_label(fp, label)
                        xyz_prev = xyz
                        xyz = self.read_xyz(fp)
                        while (True):  # code pattern to implement logic
                            if exclude_surface_legs and flag & 0x01: break
                            if exclude_duplicate_legs and flag & 0x02: break
                            if exclude_splay_legs and flag & 0x04: break
                            legs.append(((xyz_prev, xyz), label, style, date1,
                                         date2, flag))
                            break

                    elif byte <= 0xff:  # LABEL (or NODE)
                        flag = byte & 0x7f
                        label = self.read_label(fp, label)
                        xyz = self.read_xyz(fp)
                        while (True):  # code pattern to implement logic
                            if exclude_surface_stations and flag & 0x01 and not flag & 0x02:
                                break
                            self.station_list.append((xyz, label, flag))
                            break
                        self.station_xyz[label] = xyz

                # End of byte-gobbling while loop

            # file closes automatically, with open(survex3dfile, 'rb') as fp:

            # Now create the layers in QGIS.  Attributes are inserted
            # like pushing onto a stack, so in reverse order.  Layers
            # are created only if required and data is available.
            # If nlehv is still None, then no error data has been provided.

            layers = []  # used to keep a list of the created layers

            if include_stations and self.station_list:  # station layer

                station_layer = self.add_layer('stations', 'Point')

                attrs = [
                    QgsField(self.station_attr[k], QVariant.Int)
                    for k in self.station_flags
                ]
                attrs.insert(0, QgsField('ELEVATION', QVariant.Double))
                attrs.insert(0, QgsField('NAME', QVariant.String))
                station_layer.dataProvider().addAttributes(attrs)
                station_layer.updateFields()

                features = []

                for (xyz, label, flag) in self.station_list:
                    xyz = [0.01 * v for v in xyz]
                    attrs = [1 if flag & k else 0 for k in self.station_flags]
                    attrs.insert(0, round(xyz[2], 2))  # elevation
                    attrs.insert(0, label)
                    feat = QgsFeature()
                    geom = QgsGeometry(QgsPointV2(QgsWKBTypes.PointZ, *xyz))
                    feat.setGeometry(geom)
                    feat.setAttributes(attrs)
                    features.append(feat)

                station_layer.dataProvider().addFeatures(features)
                layers.append(station_layer)

            if include_legs and self.leg_list:  # leg layer

                leg_layer = self.add_layer('legs', 'LineString')

                attrs = [
                    QgsField(self.leg_attr[k], QVariant.Int)
                    for k in self.leg_flags
                ]
                if nlehv:
                    [
                        attrs.insert(0, QgsField(s, QVariant.Double))
                        for s in self.error_fields
                    ]
                    attrs.insert(0, QgsField('NLEGS', QVariant.Int))
                attrs.insert(0, QgsField('DATE2', QVariant.Date))
                attrs.insert(0, QgsField('DATE1', QVariant.Date))
                attrs.insert(0, QgsField('STYLE', QVariant.String))
                attrs.insert(0, QgsField('ELEVATION', QVariant.Double))
                attrs.insert(0, QgsField('NAME', QVariant.String))
                leg_layer.dataProvider().addAttributes(attrs)
                leg_layer.updateFields()

                features = []

                for legs, nlehv in self.leg_list:
                    for (xyz_pair, label, style, from_date, to_date,
                         flag) in legs:
                        elev = 0.5 * sum([0.01 * xyz[2] for xyz in xyz_pair])
                        points = []
                        for xyz in xyz_pair:
                            xyz = [0.01 * v for v in xyz]
                            points.append(QgsPointV2(QgsWKBTypes.PointZ, *xyz))
                        attrs = [1 if flag & k else 0 for k in self.leg_flags]
                        if nlehv:
                            [
                                attrs.insert(0, 0.01 * v)
                                for v in reversed(nlehv[1:5])
                            ]
                            attrs.insert(0, nlehv[0])
                        attrs.insert(0, to_date)
                        attrs.insert(0, from_date)
                        attrs.insert(0, self.style_type[style])
                        attrs.insert(0, round(elev, 2))
                        attrs.insert(0, label)
                        linestring = QgsLineStringV2()
                        linestring.setPoints(points)
                        feat = QgsFeature()
                        geom = QgsGeometry(linestring)
                        feat.setGeometry(geom)
                        feat.setAttributes(attrs)
                        features.append(feat)

                leg_layer.dataProvider().addFeatures(features)
                layers.append(leg_layer)

            # Now do wall features if asked

            if (include_traverses or include_xsections or include_walls
                    or include_polygons) and self.xsect_list:

                trav_features = []
                wall_features = []
                xsect_features = []
                quad_features = []

                for xsect in self.xsect_list:

                    if len(xsect) < 2:  # if there's only one station ..
                        continue  # .. give up as we don't know which way to face

                    centerline = [
                    ]  # will contain the station position and LRUD data

                    for label, lrud in xsect:
                        xyz = self.station_xyz[
                            label]  # look up coordinates from label
                        lrud_or_zero = tuple([max(0, v) for v in lrud
                                              ])  # deal with missing data
                        centerline.append(
                            xyz + lrud_or_zero)  # and collect as 7-uple

                    direction = [
                    ]  # will contain the corresponding direction vectors

                    # The calculations below use integers for xyz and lrud, and
                    # conversion to metres is left to the end.  Then dh2 is an
                    # integer and the test for a plumb is safely dh2 = 0.

                    # The directions are unit vectors optionally weighted by
                    # cos(inclination) = dh/dl where dh^2 = dx^2 + dy^2 + dz^2
                    # and dl^2 = dh^2 + dz^2.  The normalisation is correspondingly
                    # either 1/dh, or 1/dh * dh/dl = 1/dl.

                    for i, xyzlrud in enumerate(centerline):
                        x, y, z = xyzlrud[0:3]
                        if i > 0:
                            dx, dy, dz = x - xp, y - yp, z - zp
                            dh2 = dx * dx + dy * dy  # integer horizontal displacement (mm^2)
                            norm = sqrt(dh2 + dz *
                                        dz) if use_clino_wgt else sqrt(dh2)
                            dx, dy = (dx / norm, dy /
                                      norm) if dh2 > 0 and norm > 0 else (0, 0)
                            direction.append((dx, dy))
                        xp, yp, zp = x, y, z

                    left_wall = []
                    right_wall = []
                    up_down = []

                    # We build the walls by walking through the list
                    # of stations and directions, with simple defaults
                    # for the start and end stations

                    for i, (x, y, z, l, r, u, d) in enumerate(centerline):
                        d1x, d1y = direction[i - 1] if i > 0 else (0, 0)
                        d2x, d2y = direction[i] if i + 1 < len(
                            centerline) else (0, 0)
                        dx, dy = d1x + d2x, d1y + d2y  # mean (sum of) direction vectors
                        norm = sqrt(dx * dx +
                                    dy * dy)  # normalise to unit vector
                        ex, ey = (dx / norm, dy / norm) if norm > 0 else (0, 0)
                        # Convert to metres when saving the points
                        left_wall.append((0.01 * (x - l * ey),
                                          0.01 * (y + l * ex), 0.01 * z))
                        right_wall.append((0.01 * (x + r * ey),
                                           0.01 * (y - r * ex), 0.01 * z))
                        up_down.append((0.01 * u, 0.01 * d))

                    # Mean elevation of centerline, used for elevation attribute

                    elev = 0.01 * sum([xyzlrud[2] for xyzlrud in centerline
                                       ]) / len(centerline)
                    attrs = [round(elev, 2)]

                    # Now create the feature sets - first the centerline traverse

                    points = []

                    for xyzlrud in centerline:
                        xyz = [0.01 * v for v in xyzlrud[0:3]
                               ]  # These were mm, convert to metres
                        points.append(QgsPointV2(QgsWKBTypes.PointZ, *xyz))

                    linestring = QgsLineStringV2()
                    linestring.setPoints(points)
                    feat = QgsFeature()
                    geom = QgsGeometry(linestring)
                    feat.setGeometry(geom)
                    feat.setAttributes(attrs)
                    trav_features.append(feat)

                    # The walls as line strings

                    for wall in (left_wall, right_wall):

                        points = [
                            QgsPointV2(QgsWKBTypes.PointZ, *xyz)
                            for xyz in wall
                        ]
                        linestring = QgsLineStringV2()
                        linestring.setPoints(points)
                        feat = QgsFeature()
                        geom = QgsGeometry(linestring)
                        feat.setGeometry(geom)
                        feat.setAttributes(attrs)
                        wall_features.append(feat)

                    # Slightly more elaborate, pair up points on left
                    # and right walls, and build a cross section as a
                    # 2-point line string, and a quadrilateral polygon
                    # with a closed 5-point line string for the
                    # exterior ring.  Note that QGIS polygons are
                    # supposed to have their points ordered clockwise.

                    for i, xyz_pair in enumerate(zip(left_wall, right_wall)):

                        elev = 0.01 * centerline[i][
                            2]  # elevation of station in centerline
                        attrs = [round(elev, 2)]
                        points = [
                            QgsPointV2(QgsWKBTypes.PointZ, *xyz)
                            for xyz in xyz_pair
                        ]
                        linestring = QgsLineStringV2()
                        linestring.setPoints(points)
                        feat = QgsFeature()
                        geom = QgsGeometry(linestring)
                        feat.setGeometry(geom)
                        feat.setAttributes(attrs)
                        xsect_features.append(feat)

                        if i > 0:
                            elev = 0.5 * (prev_xyz_pair[0][2] + xyz_pair[0][2]
                                          )  # average elevation
                            attrs = [round(elev, 2)]
                            if include_up_down:  # average up / down
                                attrs += [
                                    0.5 * (v1 + v2)
                                    for (v1,
                                         v2) in zip(up_down[i - 1], up_down[i])
                                ]
                            points = [
                            ]  # will contain the exterior 5-point ring, as follows...
                            for xyz in tuple(
                                    reversed(prev_xyz_pair)) + xyz_pair + (
                                        prev_xyz_pair[1], ):
                                points.append(
                                    QgsPointV2(QgsWKBTypes.PointZ, *xyz))
                            linestring = QgsLineStringV2()
                            linestring.setPoints(points)
                            polygon = QgsPolygonV2()
                            polygon.setExteriorRing(linestring)
                            feat = QgsFeature()
                            geom = QgsGeometry(polygon)
                            feat.setGeometry(geom)
                            feat.setAttributes(attrs)
                            quad_features.append(feat)

                        prev_xyz_pair = xyz_pair

                # End of processing xsect_list - now add features to requested layers

                attrs = [QgsField('ELEVATION',
                                  QVariant.Double)]  # common to all

                if include_traverses and trav_features:  # traverse layer
                    travs_layer = self.add_layer('traverses', 'LineString')
                    travs_layer.dataProvider().addAttributes(attrs)
                    travs_layer.updateFields()
                    travs_layer.dataProvider().addFeatures(trav_features)
                    layers.append(travs_layer)

                if include_xsections and xsect_features:  # xsection layer
                    xsects_layer = self.add_layer('xsections', 'LineString')
                    xsects_layer.dataProvider().addAttributes(attrs)
                    xsects_layer.updateFields()
                    xsects_layer.dataProvider().addFeatures(xsect_features)
                    layers.append(xsects_layer)

                if include_walls and wall_features:  # wall layer
                    walls_layer = self.add_layer('walls', 'LineString')
                    walls_layer.dataProvider().addAttributes(attrs)
                    walls_layer.updateFields()
                    walls_layer.dataProvider().addFeatures(wall_features)
                    layers.append(walls_layer)

                if include_up_down:  # add fields if requested for polygons
                    attrs += [
                        QgsField(s, QVariant.Double)
                        for s in ('MEAN_UP', 'MEAN_DOWN')
                    ]

                if include_polygons and quad_features:  # polygon layer
                    quads_layer = self.add_layer('polygons', 'Polygon')
                    quads_layer.dataProvider().addAttributes(attrs)
                    quads_layer.updateFields()
                    quads_layer.dataProvider().addFeatures(quad_features)
                    layers.append(quads_layer)

            # All layers have been created, now update extents and add to QGIS registry

            if layers:
                [layer.updateExtents() for layer in layers]
                QgsMapLayerRegistry.instance().addMapLayers(layers)

            # Save layers to a GeoPackage if selected.

            # QgsVectorFileWriter would be ideal but it can only write
            # single layers (afaik!), so the GeoPackage layers,
            # fields, and attributes are created using OGR calls,
            # translating the corresponding QGIS objects on the fly.

            # It's possible this could be done faster by iterating
            # numerically over the attributes but I'm not sure the OGR
            # features would be visited in the right order, so here
            # use the field names as indices.  Meanwhile, the user is
            # appraised of progress by a progress bar.

            if gpkg_file:

                nfeatures = 0  # how many features in total
                for layer in layers:
                    nfeatures += layer.featureCount()

                if nfeatures > 100:  # create a progress bar
                    progress_bar = QProgressBar()
                    progress_bar.setMaximum(nfeatures)
                    progress_bar.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
                    msg = 'Saving ' + QFileInfo(gpkg_file).fileName()
                    progressMessageBar = self.iface.messageBar().createMessage(
                        msg)
                    progressMessageBar.layout().addWidget(progress_bar)
                    self.iface.messageBar().pushWidget(
                        progressMessageBar,
                        self.iface.messageBar().INFO)
                    ntrack = int(10**(floor(log10(nfeatures)) -
                                      1))  # update frequency
                else:
                    progress_bar = None

                gpkg_driver = ogr.GetDriverByName('GPKG')

                if os.path.exists(gpkg_file):
                    gpkg_driver.DeleteDataSource(gpkg_file)

                ogr_dataset = gpkg_driver.CreateDataSource(gpkg_file)

                if self.epsg:  # figure out the spatial reference system in OGR terms
                    ogr_srs = osr.SpatialReference()
                    ogr_srs.ImportFromEPSG(self.epsg)
                else:
                    ogr_srs = None

                ncount = 0  # to keep track of number of features processed

                for layer in layers:  # go through all the layers

                    qgis_name = layer.name()
                    match = search(' - ([a-z]*)', qgis_name)
                    ogr_name = str(match.group(
                        1)) if match else qgis_name  # ie, legs, stations, etc
                    ogr_type = self.ogr_vec_type[layer.wkbType()]
                    ogr_layer = ogr_dataset.CreateLayer(ogr_name,
                                                        srs=ogr_srs,
                                                        geom_type=ogr_type)

                    qgis_fields = layer.pendingFields()
                    names = [str(field.name()) for field in qgis_fields]
                    types = [
                        self.ogr_type[field.type()] for field in qgis_fields
                    ]
                    ogr_type_of_ = dict(zip(
                        names, types))  # map field names to OGR field types

                    [
                        ogr_layer.CreateField(
                            ogr.FieldDefn(name, ogr_type_of_[name]))
                        for name in names
                    ]

                    ogr_schema = ogr_layer.GetLayerDefn(
                    )  # for creating features in the OGR layer

                    for qgis_feat in layer.getFeatures(
                    ):  # go through all the features

                        ncount += 1  # update feature count

                        if progress_bar and ncount % ntrack:  # update progress bar
                            progress_bar.setValue(ncount)

                        ogr_feat = ogr.Feature(ogr_schema)

                        ogr_wkt = qgis_feat.geometry().exportToWkt().replace(
                            *self.wkt_replace[ogr_type])
                        ogr_feat.SetGeometry(
                            ogr.CreateGeometryFromWkt(ogr_wkt))

                        qgis_attrs = qgis_feat.attributes()

                        for name, qgis_attr in zip(names, qgis_attrs):
                            if ogr_type_of_[
                                    name] == ogr.OFTString:  # fix for strings
                                ogr_feat.SetField(name, str(qgis_attr))
                            elif ogr_type_of_[
                                    name] == ogr.OFTDate:  # translate dates
                                ogr_feat.SetField(
                                    name, str(qgis_attr.toString(Qt.ISODate)))
                            else:  # everything else just passes through
                                ogr_feat.SetField(name, qgis_attr)

                        ogr_layer.CreateFeature(ogr_feat)

                ogr_dataset = None  # all done, flush to disk

                if progress_bar:  # clean up and free resources
                    self.iface.messageBar().clearWidgets()
                    progress_bar = None

                msg = QFileInfo(gpkg_file).fileName() + ' to ' + QFileInfo(
                    gpkg_file).path()
                QgsMessageLog.logMessage('Saved ' + msg,
                                         tag='Import .3d',
                                         level=QgsMessageLog.INFO)
                self.iface.messageBar().pushMessage('Saved',
                                                    msg,
                                                    level=QgsMessageBar.INFO,
                                                    duration=5)