[general]
name=FiberQ
description=Open-source fiber network design tools for QGIS (FTTH/GPON/FTTx)
about=FiberQ helps telecom engineers and GIS professionals design, analyze, and document fiber optic networks inside QGIS. FiberQ supports QGIS 4 / Qt6 while keeping support for QGIS 3.22 LTR and later, and clears all findings from the QGIS repository security scan. Some advanced features may require an activation key.

version=1.6.0
qgisMinimumVersion=3.22
qgisMaximumVersion=4.99

author=Vladimir Vukovic
email=vukovicvl@fiberq.net

icon=icons/fiberq.svg
category=Vector
tags=fiber,ftth,gpon,fttx,telecom,postgis,network,design

homepage=https://www.fiberq.net/
repository=https://github.com/vukovicvl/fiberq
tracker=https://github.com/vukovicvl/fiberq/issues

license=GPL-3.0-or-later

class_name=FiberQPlugin

changelog=
    1.6.0 - Fast on large projects, and failures you can see
        * Faster on large projects: the Optical Schematic View, the list of
          latent elements, the route correction check, Generate terminal
          slacks, placing a slack, FiberQ's own snapping in the placement
          tools, the undo record after every placement, and Lay cable now use
          spatial indexes and batched reads instead of scanning every feature.
          Measured before and after on generated test cities of 13,800 to
          88,600 features: docs/performance.md.
        * Failures are reported instead of hidden. These operations now say
          when something went wrong, and why, instead of failing silently or
          reporting success: Save all layers to GeoPackage, Auto-save to
          GeoPackage, Export layer, the BOM export, Import points, Import
          route, Merge routes, Change route type, Change element type, Delete
          selected, Undo and Redo, Lay cable, and reading the project's
          relations, latent elements and colour catalogues - an unreadable
          entry is no longer read as empty and then saved over. One message
          per operation; the details are in Log Messages > FiberQ.
        * Unhandled Python errors fixed: route correction (a pole without a
          geometry, a multipart route, a raster layer in the project), the
          Optical Schematic View's Center button, Import route on point or
          empty geometry (it also left the Route layer in edit mode), Import
          points and Import route on a coordinate that cannot be transformed,
          the BOM export to a locked or read-only file, and Generate terminal
          slacks and Place slack on a pre-1.0 project. On QGIS 4, clicking an
          element with a picture now opens the picture.
        * The hardening covers the operations that write, export, import or
          migrate data, not every error handler in the plugin; a test now
          stops silent handlers from growing back.
        * Lengths follow your edits: change a route's or a cable's geometry
          and its stored length follows by the time the edit is saved (except
          in projects using buffered transaction groups).
        * The placement tools follow QGIS's snapping settings and show QGIS's
          snap indicator. With snapping off, FiberQ's own snap measures
          distances correctly, prefers a vertex, and works with pre-1.0 layer
          names.
        * Validation settings (snap tolerance, length tolerances, disabled
          rules, severity overrides) are stored in the project, and every run
          and Recalculate lengths read them. docs/validation-rules.md shows how
          to set them.
        * Interchange bundles: an import adds and never replaces what the
          project already has; side-car tables and columns a later format
          version adds, date-time text exactly as stored and text in any
          encoding all travel through; an export refuses or warns instead of
          writing something other than the project. Exporting a project edited
          in the latent elements dialog no longer fails, and the dialog's Save
          keeps the cable's order.
        * Picture and drawing links survive saving the project in QGIS 3. A
          project saved in QGIS 4 and opened in QGIS 3 warns once, and the
          exports no longer write its unreadable entries over good data.
        * Save all layers to GeoPackage keeps the metadata other tools stored
          in the file. Auto-save gives one warning naming the file instead of
          one per layer, asks again for a missing target, and no longer
          overwrites an existing table when a layer is renamed.
        * Lay cable no longer discards unsaved edits in projects using
          transaction groups. A closed Optical Schematic View no longer
          rebuilds after every edit.
        * Publish to PostGIS reports a failed export instead of "has been
          published", refuses a table name already in use, checks that every
          feature arrived, and never edits the published layer.
        * FiberQ follows QGIS's language until you pick one in FiberQ's own
          menu, and only finished translations ship. Service Area area and
          perimeter are ground measurements. The plugin loads on QGIS 3.22
          again, as its metadata promises, and so do the duct tools.
        * Route correction no longer reports a route end that meets a joint
          closure, an element or a vertex of another route. An end that
          touches another route between two of its vertices is reported with
          what to do about it, and Select on map selects the route and
          centres the map on that end.
        * The Optical Schematic View opens fitted to its window, with its
          controls in two rows. Center zooms in on the element and rings it,
          finds a name in any case and says when none matches, and Enter in
          the Find box runs it. The PNG, JPG and SVG exports show the whole
          drawing, and a file that could not be written is reported.
        * Import route reads every folder of a KML file and the tracks and
          routes of a GPX file, and says what it left out: features that are
          not lines, folders with no lines, waypoints.
        * The placement and drawing tools, Add breakpoint and Branch cables
          say when the layer refused a save, and why, instead of reporting
          success or saying nothing. Add breakpoint saves the two halves
          before it removes the original, so a refused save no longer loses
          the route.
        * FiberQ adds its own columns, such as the feature ID, with a type
          every data source accepts. On PostGIS the add failed and left every
          later save on that layer failing; on a shapefile, a column name
          longer than ten characters is refused instead of being added again,
          shortened, at every placement and project open. When FiberQ cannot
          finish upgrading a project, it says so, and tries again the next
          time the project is opened.
        * With snapping off, a joint closure also snaps along a route or
          cable span, as the other placement tools do.
        * FiberQ no longer fills QGIS's logs: no "Entry token invalid" lines
          for each feature clicked on the map in QGIS 3, and no deprecation
          warnings when it creates fields, saves layer styles or makes a
          relation on recent QGIS versions.
        * Smaller fixes: the fibre-break distance, the mid-span slack point,
          the slack tool on multipart cables, Delete selected on "Optical
          slacks", route correction with old layer names and manholes, the
          Import points file filter, the schematic view following layers
          added after it opened, a cable's type shown as "(Optical)" in the
          attribute form, a GeoPackage layer's fid labelled "Cable feature
          ID", and the pipe tools on a pipe layer without a length column.
        * Changed: the "Check (health check)" button is gone; Validate project
          covers the same checks in more detail.
        * Changed: the BOM now measures lengths the way the attribute table
          does, on the ground in each layer's own CRS, so its figures differ
          from 1.5.0's. The new ones are correct.
        * Changed: Merge routes, Change route type, Change element type, Lay
          cable and Undo no longer save your other unsaved edits; use Layer >
          Save Layer Edits. Change route type refuses on a Route layer without
          a tip_trase column, and the BOM offers Excel only when xlsxwriter is
          installed.
        * Changed: FiberQ's own snap skips features with broken geometry (a
          coordinate that is not a number, a one-vertex part, a degenerate
          arc).
        * Changed: Publish to PostGIS no longer has the "Delete existing table
          and recreate" box (it never took effect), and publishes column names
          in lowercase.
        * Changed: three toolbar icons (Change element type, Clear picture,
          Open drawing). A slack layer still named Opticke_rezerve is no longer
          restyled when the project opens. After upgrading from 1.5.0 without
          restarting QGIS, restart it once.
        * Changed: Save all layers to GeoPackage, and turning Auto-save on,
          ask before writing over a table of the same name that no layer of
          the project uses (1.5.0 wrote over it without asking): replace it,
          keep it and save beside it, or cancel. Their file dialogs no longer
          offer to replace the whole file, which FiberQ never does.
        * Changed: Route correction's Correct moves a route end onto the
          nearest pole, manhole, joint closure or element within 5 m, and
          leaves it where it is, saying why, when a cable or duct passes
          through or ends there.
        * Changed: Add breakpoint and Digitized object (from selection), on a
          layer you already have in edit mode, no longer save your other
          unsaved edits: their result stays in your edit session; use Layer >
          Save Layer Edits.
        (The spatial indexing and batching behind the speed-ups, their
        benchmark, the failure reporting and the crash fixes were developed
        with support from the NLnet NGI0 Commons Fund. Everything else in this
        release, including the fixes made during its release testing, was not
        funded by it.)
        If FiberQ helps your work, you can sponsor its development:
        https://github.com/sponsors/vukovicvl

    1.5.0 - An open interchange format: move a design between tools, lose nothing
        * New: "Export interchange bundle" writes the whole design as an open,
          documented format - a GeoPackage any GIS tool can open, or a folder of
          GeoJSON files. It carries the things a generic export loses: which
          cable a slack loop belongs to, which elements a cable passes through,
          and the named groupings of cables, all referenced by stable feature
          identity rather than by row numbers that mean nothing in another tool.
        * New: "Import interchange bundle" reads one back. Foreign data is
          adapted into FiberQ's own layers, with FiberQ's own field names and
          values - your data model does not change to accommodate a file.
        * New: anything FiberQ has no model for survives a round trip. An element
          type it lacks, an attribute it has no column for, and relational data
          it does not implement - fibre splices, trays, duct occupancy - are all
          carried through unchanged rather than dropped. Nothing is ever
          reclassified to the nearest familiar type, because that cannot be
          undone and the import would look like it worked.
        * New: the format is published as a specification anyone can implement,
          docs/interchange-format.md, with the full field and value mapping in
          docs/interchange-mapping.md. The spec is CC-BY-4.0 so it can be used in
          any tool, open or closed.
        * A bundle carries canonical English field names and values, so a
          receiving tool does not have to learn FiberQ's stored schema. Your
          project keeps its own field names and values exactly as they are - the
          translation happens only in the exported copy.
        * A pre-1.0 project with the original Serbian layer and field names now
          exports the same bundle as a new one - including the slack loops and
          fibre breaks whose cable reference such a project still stores as
          kabl_layer_id / kabl_fid.
        * Metadata another tool wrote into the same file is merged, never
          replaced, and survives a round trip through FiberQ.
        * Importing into a new project puts it back into the CRS the design was
          authored in, instead of leaving it in whatever CRS QGIS gave the new
          project. A project that already holds layers keeps its own CRS - an
          import adds to your work, it does not reproject it.
        * A bundle from a newer major version of the format is refused with a
          clear message rather than imported partially. Importing the same bundle
          twice changes nothing.
        (The interchange format, its export and its import were developed with
        support from the NLnet NGI0 Commons Fund.)

    1.4.0 - Project validation: find the problems before the client does
        * New: "Validate project" runs fourteen checks over the whole design and
          lists what it finds in a dockable panel - topology and connectivity,
          referential integrity, feature identity, required attributes, value
          domains, length coherence, CRS consistency and geometry health.
          Filter by severity, layer or rule; double-click any issue to jump to it.
        * New: export the results as a self-contained HTML report (for handover
          and audit files), JSON (machine-readable, stable keys) or CSV (for
          spreadsheets and issue trackers).
        * New: "Recalculate lengths" rewrites stored lengths that disagree with
          the drawn geometry. It shows exactly what will change before writing
          anything, and never touches slack values.
        * Fix: lengths are now measured on the project ellipsoid - true metres on
          the ground - everywhere. Routes and cables previously stored the length
          in map units, which in Web Mercator is inflated by 1/cos(latitude):
          about 1.4x at Serbian latitudes, 1.6x in the Netherlands, 2x in
          southern Finland.
          Pipes were already correct, so a trench and the duct inside it could
          disagree by that margin in the same project, and a bill of materials
          over-ordered cable to match. New features are measured correctly;
          use "Recalculate lengths" to repair existing ones.
        * Fix: placing an extension or a fiber break no longer creates an empty
          "Poles" layer as a side effect.
        * Fix: shipped layer styles named "MS Shell Dlg 2", a Windows-only font,
          so every Linux and macOS user got substituted label fonts and a warning
          per layer on load. They now use the portable "Sans Serif".
        * Fix: opening a project saved in QGIS 4 no longer re-runs the schema
          migration in QGIS 3. QGIS 4 stores project properties in a form QGIS 3
          cannot read, so the schema marker now falls back to the copy in the
          GeoPackage. Validation also reports a project left with no CRS, which
          is what that same QGIS limitation does to a downgraded project.
        * Fix: the fiber break tool accepted a click near any line, so a break
          could be recorded against a route or a duct and stored as if it were
          on a cable. It now targets cable layers only, and B1/B2 report the
          bad references already in your projects.
        * Docs: docs/validation-rules.md documents every rule - what it checks,
          why it matters, and what to do about a finding. docs/samples/ ships a
          small demo project you can open and validate yourself, alongside the
          report it produces.
        * i18n: the plugin is now translatable, with the English source catalogue
          and tooling in place; translations welcome.
        * The plugin now has a Support page - if FiberQ saves you time, you can
          help fund its development.
        (The validation engine and its reporting were developed with support from
        the NLnet NGI0 Commons Fund. The length-measurement fix, the stray-layer
        fix, the i18n groundwork and the support links were not funded by it.)

    1.3.0 - Project schema versioning, safe migrations, and stable feature IDs
        * New: every FiberQ project now carries a schema-version marker, also
          mirrored into the GeoPackage, so future releases can recognise and
          upgrade older projects safely.
        * New: a versioned migration runner upgrades older projects automatically
          on load (e.g. schema 0 -> 1.0) - losslessly and idempotently - and
          reports a summary in the QGIS log. Blank or non-FiberQ projects are
          left untouched.
        * New: the fiberq_uuid identity invariant. Every FiberQ feature carries a
          stable, cross-system UUID. Loading an older project assigns UUIDs to all
          existing features; new features receive one on creation across every
          tool (routes, cables, slack, pipes, service areas, objects, ...).
        * Fix: the cable "Number of fibers" field now follows the computed total
          instead of freezing at an intermediate value while typing.
        * Fix: the Objects draw tools (3-point / N-point / ortho / digitize) no
          longer raise an ImportError after the module split.
        * Fix: "Cut infrastructure" no longer fails to save on a duplicate primary
          key; the two halves get fresh feature ids and fresh fiberq_uuids.
        * Fix: the Optical Schematic View now draws pipes in the legend orange for
          English-named layers (previously grey), matching the "Pipes" legend.
        * Fix: renamed the mislabeled "FiberQ web browser" action to "Preview Map".
        * Compat: scoped all QGIS enum accesses (e.g. QgsWkbTypes.PointGeometry ->
          QgsWkbTypes.GeometryType.PointGeometry) for PyQt6 / QGIS 4; unchanged
          behaviour on QGIS 3 / Qt5.
        * Hardening: previously-silent exception handlers now log at debug level
          instead of swallowing errors, and the local lint gate runs Bandit at all
          severities to match the plugins.qgis.org scanner.
        * Quality: the maintainer manually reviewed the entire plugin source -
          every Python module - prior to this release. Lint (flake8 + Bandit)
          remains at zero findings on the plugins.qgis.org scan, and the pytest
          suite runs green on QGIS 3 (Qt5) and QGIS 4 (Qt6).
        (This release was developed with support from the NLnet NGI0 Commons Fund.)

    1.2.3 - Repository scan: zero findings (code hygiene, no functional change)
        * The plugin now scans clean on the plugins.qgis.org Security & Quality
          scan: flake8 (--max-line-length=120 --ignore=E501) and Bandit
          (medium/high) both report 0 findings.
        * Removed unused exception variables (except ... as e where e was never
          used). The handlers still catch the same exceptions; behavior unchanged.
        * Normalized whitespace around operators, continuation-line indentation,
          and split a few compound statements (autopep8). No logic change.
        * Removed a duplicate LayerNames / is_route_layer / is_cable_layer import
          in utils (kept the definitions already active at runtime; no change).
        * Annotated intentional multi-line conditions, conditional imports and
          accepted names with targeted "# noqa" instead of rewriting working code.
        * Packaging: the development flake8 config is no longer shipped inside
          the plugin package.

    1.2.2 - Housekeeping (code cleanup, no functional change)
        * Removed dead leftover code from the v1.x monolith split:
          extracted_classes.py (deprecated re-export shim) and two unused
          addon modules (settings, styles).
        * main_plugin.py: removed duplicate/unused imports and dead leftover
          import blocks. No behavior change.
        * Repo-wide style cleanup (unused imports, whitespace, blank lines).

    1.2.1 - QGIS 4 / Qt6 compatibility and repository scan compliance
        Compatibility
        * Full support for QGIS 4 / Qt6 while preserving QGIS 3.22 LTR and later.
        * Replaced 29 QDialog.exec_() call sites with exec() across 16 files;
          the underscored alias is gone in PyQt6 and previously caused
          "object has no attribute 'exec_'" errors on QGIS 4.
        * Fixed "QgsMapMouseEvent object has no attribute 'x'" in five map
          tools (Move Elements, Branch Info, Drawing, Image, Element
          placement). Replaced the Qt5-only event.x() / .y() with pos().x()
          / pos().y(), which works on both Qt5 and Qt6.
        * Fixed "QTableWidget object has no attribute SelectRows" crash when
          opening the List of Latent Elements dialog on Qt6. Now uses the
          Qt6-scoped QAbstractItemView.SelectionBehavior.SelectRows.
        * Fixed Drawing map tool right-click and Escape on Qt6. Replaced the
          flat Qt5 enums with Qt.MouseButton.RightButton and Qt.Key.Key_Escape.
        * Fixed sip imports for QGIS 4 / PyQt6, and Qt enum usage affecting
          QToolButton and QImage on QGIS 4.

        Optical schematic view
        * PE pipes and Transition pipes were always filtered out by the cable
          subtype filter and never drawn. Pipes are now detected from the
          source layer name (English and legacy Serbian names supported) and
          are always included when the Underground checkbox is on. Dashed
          rendering is applied via the same flag instead of a
          language-specific substring check.
        * Pan button: reworked so left-button drag panning works identically
          on Qt5 and Qt6. Replaced the built-in QGraphicsView.ScrollHandDrag
          (behaviour diverged across Qt versions) with explicit mouse
          handlers. Scroll-bar deltas are cast to int for PyQt6's stricter
          setValue() signature.

        Repository security scan
        * Replaced urllib.request.urlopen with QgsBlockingNetworkRequest in
          the Locator dialog and preview map. Eliminates the last two Bandit
          B310 findings and routes geocoding through QGIS's native network
          stack (proxy and SSL aware). Removed the now-unused urllib.request
          and ssl imports.
        * Added URL scheme validation for remote requests (http / https only).
        * Cleaned formatting issues relevant to repository scanning (trailing
          whitespace, blank-line whitespace).
