Compare commits

...

71 Commits

Author SHA1 Message Date
Laurent Trinques 75fafd5acc Revert "Draw the folio with inverted lightness on a dark palette" 2026-09-20 06:57:56 +02:00
Laurent Trinques 3394c1246c Merge pull request #954 from jp2images/feature-dark-canvas
Linux build and tests / Build and test (Qt 6, Debug) (push) Failing after 2m12s
Draw the folio with inverted lightness on a dark palette
2026-09-20 06:44:09 +02:00
Jeff Patterson 3e34a6d55f Fill the dark canvas buffer and keep one scene connection
QGraphicsView::render() paints only what the scene draws, so a scene
without a background brush left the off-screen buffer uninitialized
and the inversion turned that memory into noise. The buffer is now
filled white first, which the inversion turns into the Base color.

listenToScene() connected a new receiver on every setScene() call and
never dropped the previous scene's. It now keeps a single connection
and replaces it.

Test in tst_qetpalette: paletteViewFillsWhatTheSceneLeavesBlank.
2026-09-19 18:27:00 -05:00
Jeff Patterson 50792ba1ad Repaint the whole dark canvas when the application palette changes
After a live light/dark switch only the sheet changed colors; the
viewport around it kept the previous palette. Qt repaints a widget on
an application palette change only when the widget's own palette
changed with it, and under the folio tab widget's style sheet it does
not, so the only repaints came from the scene and covered the scene
rectangle alone. PaletteGraphicsView now watches the application
object for ApplicationPaletteChange, the one receiver Qt always
notifies, and repaints its whole viewport.

The test paletteViewFollowsTheApplicationUnderAStyleSheet now also
requires a full-viewport repaint after each switch, before anything
asks the view for a rendering.
2026-09-19 18:27:00 -05:00
Jeff Patterson 6404612014 Follow the application palette, not the view's, on the dark canvas
The folio tab widget carries a style sheet, and QStyleSheetStyle pins
the palette of every widget under it to the application palette in
force when the sheet was applied. After a live light/dark switch the
view's own palette() is therefore stale: the folio kept its dark sheet
after a switch to light, and kept its white sheet after a switch to
dark. PaletteGraphicsView now reads the application palette both for
the decision to invert and for the sheet and ink colors.

Test in tst_qetpalette: paletteViewFollowsTheApplicationUnderAStyleSheet
puts the view in a tab widget with a style sheet and switches the
application palette to dark and back.
2026-09-19 18:27:00 -05:00
Jeff Patterson eaf15faaa3 Move the dark canvas into PaletteGraphicsView and test it directly
The inverted painting, the rubber band replay and the changed()
receiver lived in DiagramView, which the unit tests cannot link, so the
update-flag regression was only covered through a stand-in view. They
now live in PaletteGraphicsView, a QGraphicsView subclass with no
other dependency, and DiagramView derives from it. The view tells a
subclass through paintingInverted(bool) when it renders for an
inverted display; DiagramView forwards that to the diagram. The grid
dot rule moves out of Diagram::drawBackground into
QET::Palette::gridDotColor().

tst_qetpalette now links the real class: gridDotColorSoftensInvertedDots,
paletteViewFollowsThePalette (light sheet, dark sheet at text contrast
with a red box still red and the paintingInverted calls in order, back
to light), paletteViewKeepsSceneUpdatesFlowing (three whole-scene
updates and a selection each repaint, scene set after construction),
paletteViewDrawsTheRubberBand.
2026-09-19 18:27:00 -05:00
Jeff Patterson b8c9e670c4 Keep scene updates flowing on the dark canvas and soften its grid
On a dark palette the folio view paints through QGraphicsView::render()
instead of onto its viewport. In that case QGraphicsView never clears
the scene's "update everything" flag, and while the flag is set every
further QGraphicsScene::update() and item update is dropped: from the
second Diagram::update() on, the grid toggle, the white/gray toggle and
even a selection waited for an unrelated repaint. With a receiver on
QGraphicsScene::changed() the scene clears the flag before it emits, so
DiagramView now connects an empty receiver in its constructor.

While the view paints for inversion, Diagram draws the grid dots a
third of the way from the sheet color to black, so they come out as a
soft gray on the dark sheet instead of as bright as the ink. Printing
and export never take that path.

Test in tst_qetpalette: sceneUpdatesReachARenderedView.
2026-09-19 18:26:45 -05:00
Jeff Patterson 85dc638a42 Draw the folio with inverted lightness on a dark palette
On a dark palette the folio stayed a white sheet with black ink, and
the white/gray toggle only darkened the sheet while the ink stayed
black. DiagramView now renders each repaint into an image and inverts
its lightness before blitting it: white becomes the palette's Base,
black becomes its Text, and colored conductors and elements keep their
hue. The document, printing and export are untouched; only the screen
rendering changes, and only while the palette is dark.

QET::Palette::invertLightness does the inversion in one integer pass
(adding 255 - max - min to the three channels inverts the HSL lightness
and keeps hue and saturation), then stretches the result between the
sheet and ink colors through three lookup tables. A 4K viewport costs
about 9 ms in a release build. QGraphicsView::render() skips the
selection rubber band, so the view draws it again after the inversion.

Tests in tst_qetpalette: invertLightnessMapsSheetAndInk,
invertedViewReadsOnDarkSheet, invertLightnessSpeed.
2026-09-19 18:26:45 -05:00
Laurent Trinques dfe56cddbd Merge pull request #928 from ispyisail/fix/903-escape-cancels-text-tool
Let Escape cancel the text tool, like every other placement (#903)
2026-09-19 23:43:31 +02:00
Laurent Trinques ef1fbd79b4 Merge pull request #942 from elevatormind/gitignore-ide-addition
Linux build and tests / Build and test (Qt 6, Debug) (push) Failing after 2m1s
chore: ignore IDE settings and cache files
2026-09-19 20:25:12 +02:00
Laurent Trinques eb7abdfbc6 Merge pull request #946 from jp2images/feature-panels-follow-palette
Let the Collections and Projects panels follow the palette
2026-09-19 20:24:05 +02:00
Laurent Trinques f574d28340 Merge pull request #947 from jp2images/fix-dark-theme-light-icons
Redraw the Add PDF and folio icons as SVGs, stop inverting page-shaped icons in the dark theme
2026-09-19 20:22:29 +02:00
Laurent Trinques 31f90e2c46 Merge pull request #949 from jp2images/fix-menubar-test-macos
Make the menu bar keyboard test pass on macOS
2026-09-19 20:20:58 +02:00
Laurent Trinques 45bd8256b3 Merge pull request #950 from jp2images/feature-icon-hover
Give icons a hover state through a proxy style
2026-09-19 20:18:20 +02:00
Jeff Patterson 4e43cde063 Give icons a hover state through a proxy style
Hovering a tool button changed only its frame, and on the dark palette
Fusion's hover frame is too faint to notice, so nothing told the user
which button was under the pointer (GitHub #870, PR 3 of the plan).

QETStyle wraps the running style. For QIcon::Active it returns line-art
icons tinted in the palette's highlight color, lightened until the tint
reads at 3:1 on the Light role, which is the top of Fusion's hover
gradient. Colored icons keep their colors, using the same line-art rule
as misc/make_icon_themes.py. Every other mode goes to the base style.

Fusion also asks for QIcon::Active for the icon of a highlighted menu
item and paints it on the highlight bar, where the tint would vanish.
The generated pixmap is cached per icon and cannot tell a menu from a
toolbar, so drawControl(CE_MenuItem) hands the base style an icon whose
Active pixmap is in the HighlightedText color instead.

QETApp::initStyle() installs the proxy on every platform, keeping the
base style's object name so the Fusion checks still match.

tests/qttest/tst_qeticons: hovering changes the icon ink to the tint and
stays at 3:1 on both palettes, on a raised button and on a checked one
drawn sunken, where the frame gives no hover cue at all; a colored icon is unchanged on hover; a
highlighted menu item's icon reads at 3:1 on the highlight bar.
inkcontrast.h gains background() and ink() helpers for those checks.
2026-09-19 12:26:06 -05:00
Jeff Patterson aef56fe41d Make the menu bar keyboard test pass on macOS
tst_menubarkeyboard's control case presses Alt+F and expects the File
menu to open. On macOS it never did, for two reasons unrelated to the
F10 shortcut it guards: a QMenuBar is native there, so its menus live
in the system menu bar where QTest key events do not reach them, and Qt
does not turn "&File" into an Alt+F mnemonic on macOS at all. The test
has failed on every Mac build since bd6bed8d6 added it.

On macOS the test now uses an in-window menu bar and switches auto
mnemonics on for its own process, which runs the same QMenuBar code the
other platforms exercise. What it still does not prove on macOS is the
native bar: QETMainWindow::activateMenuBar() calls setActiveAction() on
a bar the system draws, and only F10 in the running application can
say what that does there. Other platforms are unchanged.

Fixes #948.
2026-09-19 12:24:57 -05:00
Jeff Patterson 0395f90f75 Let the Collections and Projects panels follow the palette
Both panels forced a light palette on themselves (white rows, black
text, their own selection blue) so that element previews, which are
black line art drawn for the white sheet, would stay visible on a dark
desktop (bugtracker 335). On a dark palette the two docks were the
only white windows left.

The forced palettes are gone. Element previews are now kept as drawn,
on a transparent background, and adapted where they are shown:
ElementPreviewDelegate, installed on the collection tree, hands the
view a copy with its lightness inverted when the palette is dark
(QET::Palette::forPalette), so black ink becomes the palette's light
gray while colored icons such as folders stay as they are; the drag
pixmap is adapted the same way. A light palette shows the previews
untouched. This fixes bugtracker 335 on every dark desktop rather than
masking it with a white panel.

The preview cache stored the old white-sheet pictures; it records the
format now and drops a cache written before this change once. The
amber "show this directory" highlight sets black text so it reads on
both palettes. The Projects panel only shows icons from the icon
theme, which has a dark variant, so nothing else changes there.

tests/qttest/tst_qetpalette: the line-art rule tells ink from color;
inversion keeps hue and alpha; a preview reads at 3:1 on the Base
color of both palettes; in a tree on the dark palette the delegate
inverts a line-art icon and leaves a colored one alone.

Fixes #945.
2026-09-19 12:22:24 -05:00
Jeff Patterson a4d5b7a12a Draw the folio icons as SVGs
The folio icons (Add, Remove, Properties, New folio, Title block
template) were anti-aliased gray page drawings, and the previous commit
left them untouched on the dark palette, where their soft gray fills
read blurry next to the line-art icons. They are now pixel-grid SVGs in
ico/scalable/ in the style of the Add PDF icon: a landscape sheet with
a title block line, a plus or minus badge in the corner, text lines for
properties, a filled title block for the template. Same 24 pixel canvas
as pdf-import.svg, same currentColor recoloring for the dark theme.

Only the 22 pixel PNGs go: five files leave ico/22x22 and both .qrc
files, and the alias list in misc/make_icon_themes.py that exposed
three of them under a second name is down to conductor2.png. The 16
pixel files stay, so menus and the projects panel keep their icons at
that size, and the 128 pixel diagram.png stays for the configuration
page list.

tests/qttest/tst_qeticons: every file in ico/scalable/ resolves in both
themes at 22, 24, 32 and 64 pixels, dark ink on light and light ink on
dark, with no 22 pixel PNG left beside it; the light-art check reads
the folio family at 16 pixels, where the page art remains.
2026-09-19 12:02:55 -05:00
Jeff Patterson ba29dc45a0 Draw the Add PDF icon as an SVG
The "Add PDF" action used ico/22x22/pdf-import.png, a white page with a
red PDF mark that sat apart from its neighbors "Add text" and "Add
image", both gray line art in a square frame with a plus. It is now
ico/scalable/pdf-import.svg, the same pixel design as insert-image.png:
a frame, the letters PDF, a plus in the corner. One file serves every
slot and stays sharp on high-DPI screens; the PNG is gone from both
.qrc files.

The canvas is 24 pixels with the art offset by one, like the Breeze
SVGs already in the theme. Fusion's toolbar slot is 24 pixels: a 22
pixel PNG is drawn unscaled inside it, but a scalable icon is rendered
at the slot size, and a 22 pixel grid stretched to 24 puts every one
pixel line between pixels and reads blurry.

The file uses currentColor like the Breeze SVGs already in the theme,
so misc/make_icon_themes.py produces the dark copy the same way. A new
ico/scalable/ folder holds QET's own vector icons; the direction
arummler asked for in #690.

tests/qttest/tst_qeticons: the icon resolves in both themes at 16, 22,
32 and 64 pixels, dark ink on the light theme and light ink on the dark
one, and no 22 pixel PNG remains.
2026-09-19 12:02:54 -05:00
Jeff Patterson d06c7be606 Leave light icons out of the dark theme
misc/make_icon_themes.py sorted icons by saturation alone, so a white
page with a small red mark counted as line art and its dark copy turned
the page black: the PDF import icon read black on black (#919,
Kellermorph), and the folio, diagram and label icons came out as dark
pages with a light border.

An icon whose visible pixels are at least 30% near white is now "light
art" and inherits from the qet theme untouched; it already reads on a
dark toolbar. The generator also removes dark files it no longer
produces, so a reclassified icon falls back to the light theme instead
of keeping a stale copy. Thirteen files leave ico/themes/qet-dark.

tests/qttest/tst_qeticons: every dark theme file, taken as its mean
visible color, reaches 3:1 on the dark palette's window color; the
lightest-pixel check it replaces let a black page with a light border
through. Asking the dark theme for pdf-import, diagram, label, the
folio icons and diagram_bg returns the light art.
2026-09-19 12:02:54 -05:00
Magnus Hellströmer 56cbd6e23d chore: ignore IDE settings and cache files 2026-09-19 18:10:37 +02:00
Laurent Trinques 8bbc2da5c7 Merge pull request #940 from Kellermorph/german-translation
Linux build and tests / Build and test (Qt 6, Debug) (push) Failing after 2m17s
Update German translation
2026-09-19 14:11:15 +02:00
Kellermorph 4b8db6be0e Update German translation 2026-09-19 13:25:39 +02:00
Laurent Trinques a6b4c3c673 Merge pull request #930 from ispyisail/feat/923-forum-auto-conductor-shortcut
List auto conductor creation in the Shortcuts page
2026-09-19 13:04:44 +02:00
Laurent Trinques 8f0ee06a4f Merge pull request #929 from ispyisail/feat/461-conductor-color-quick-access
Add a one-click conductor colour to the toolbar (#461)
2026-09-19 13:00:14 +02:00
ispyisail 70599c4ae1 List auto conductor creation in the Shortcuts page
"Est il possible dans les raccourcis d'ajouter un pour création
automatique de conducteur ? Je n'utilise pas par défaut, mais
ponctuellement c'est très pratique." -- oc67, an electrician, on the
forum (viewtopic.php?pid=23296).

The action itself has existed for a long time: m_auto_conductor is a
checkable QAction in the Schéma toolbar and the Project menu. It was
simply never handed to ShortcutManager, so it did not appear in
Configuration > Raccourcis and there was no way to reach it from the
keyboard. This registers it.

No default sequence is set. That is the request read literally -- he
asked for it to be *in* the shortcuts list so he can bind it himself --
and it avoids spending one of the few free keys on a setting many people
never touch. The Shortcuts page already treats "no shortcut" as a normal
state: it renders an empty field and its quick filter can list actions
with and without a binding separately.

Verified on a virtual display. With shortcuts/diagrameditor.auto_conductor
set to Ctrl+Alt+A:

  Configuration > Raccourcis, filtered on "conducteur", lists
  "Création automatique de conducteur(s)" under "Éditeur de schémas"
  showing that binding.

  Mouse parked away from the toolbar, pressing it twice: the toolbar
  button changes on each press and returns to its starting appearance
  after the second, so the key toggles the setting exactly as clicking
  the button does.

Two things that misled the first run, recorded so the next person does
not repeat them: F7 is already registered to panel.move_diagram_downx100
in the elements panel, and a screenshot taken with the pointer resting on
the button shows its hover state, not its checked state.

ctest 12/12, Qt 6.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CaKympWT3owLotCpEN2CFj
2026-09-19 09:18:04 +12:00
ispyisail e42ebdc861 Add a conductor colour button to the Schéma toolbar (#461)
An electrician on the forum draws 400 V and 24 V circuits in the same
folio and wants the colour to be one click away
(qelectrotech.org/forum, viewtopic pid=23296). Today the quickest route
is F2, which opens a colour dialog and refuses to act unless exactly one
conductor is selected, so colouring a run means one conductor, one
dialog, at a time.

This adds a swatch button beside the auto-conductor actions. Picking a
colour does two things:

  - recolours every conductor currently selected, as ONE undo step;
  - becomes the colour of the next conductor drawn, through the
    LastUsedStyle mechanism #888 already added and Conductor's
    constructor already reads.

Either half is useful alone: with nothing selected it just sets the pen
for what comes next.

The menu lists the colours the trade names -- the three phases, neutral,
earth, and the ones used for control and extra-low-voltage circuits --
then any custom colours picked this session, then the full colour
dialog. A colour already in the standard list is not repeated under
"recently used".

Nothing is written to the project or to QSettings. That is deliberate:
it is the same session-scoped "what did I just use" idea as
LastUsedStyle, so it adds no persisted state and no file-format change.
Named presets stored per project -- what #461 actually asks for -- are a
larger feature that needs a maintainer decision first; the question is
still open on that issue since 21 June.

Verified on a virtual display against examples/Habitat-Schemas_developpes.qet,
reading colours back from the saved project rather than the screen:

  select all on folio 1, pick Rouge
      21 conductors {none:1, #ff5500:2, #ff0000:6, #00aa00:5, #0000ff:7}
      -> all 21 #ff0000
  one Ctrl+Z
      -> back to the original five-colour mix, exactly
  pick Marron with nothing selected, then draw a conductor
      -> the new conductor is #7b3f00

ctest 12/12, Qt 6.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CaKympWT3owLotCpEN2CFj
2026-09-19 09:02:58 +12:00
ispyisail 3c1fb2fe72 Let Escape cancel the text tool, like every other placement (#903)
Issue #903 reported that Escape stopped cancelling an in-progress
placement. PR #899 fixed that by letting Escape through to the active
tool whenever Diagram::eventInterfaceIsRunning(), and 863ac5f0a tightened
it to isRunning() so a second Escape cannot retrigger an abort already in
flight. That covers seven of the eight tools. It cannot cover the eighth.

eventInterfaceIsRunning() is m_event_interface && isRunning(), and
isRunning() returns m_running. DiagramEventAddText is the only class
under sources/diagramevent/ that never sets m_running, so the guard reads
false for the whole time the tool is armed and DiagramView::keyPressEvent
keeps swallowing Escape for its own selection/focus handling.

It is also the only one of the eight with no RightButton branch --
right-clicking the folio with the text tool armed opens the folio context
menu. So this tool currently has no way to cancel at all: the only way
out is to pick a different tool, and any stray click drops a text field
the user did not want.

The tool is armed from the moment it is attached, so m_running is set in
the constructor and cleared where the text is placed, before finish().

Measured on a virtual display against a fixture holding one free text
field, counting diagram-level text fields in the saved project:

  arm the text tool, click            2 fields   places, as it should
  arm it, press Escape, then click    2 fields   before  -- not cancelled
                                      1 field    after   -- cancelled

The same run on master's rectangle tool cancels correctly, which is what
made the text tool look fixed when it was not.

ctest 12/12, Qt 6.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-19 08:32:58 +12:00
Laurent Trinques 2da516667e Merge pull request #918 from Kellermorph/fix-colour-selection
Linux build and tests / Build and test (Qt 6, Debug) (push) Failing after 1m41s
Persist QColorDialog custom colors across application restarts
2026-09-18 19:36:25 +02:00
Laurent Trinques b62b118d45 Merge pull request #919 from jp2images/feature-icon-themes
Add a "qet-dark" icon theme for dark palettes
2026-09-18 19:00:47 +02:00
Laurent Trinques b0b7814015 Merge pull request #925 from arummler/fix-undo-stack
Fix issues with undo stack
2026-09-18 18:54:11 +02:00
Laurent Trinques c9a63b5bce Merge pull request #921 from arummler/master-fix-group-rotation
Fix: "group rotate"
2026-09-18 18:52:04 +02:00
Andre Rummler 059d179d9b Fix:
a) Project stayed in modified state even after undoing all changes.
b) Saving the project deleted the undo stack.
2026-09-18 18:28:48 +02:00
Kellermorph fa52aab149 Persist QColorDialog custom colors across application restarts
Qt's QColorDialog loads custom colors from QSettings on startup but
never writes them back, so user-defined colors in the color picker
are lost when the application exits.

Save and load the 16 custom color slots explicitly via QSettings
in QETApp's constructor (after initStyle) and destructor (before
other settings are flushed). This covers every QColorDialog usage
in the application transparently.

Also fixes a QColorDialog memory leak in DiagramView.
2026-09-18 13:53:14 +02:00
Andre Rummler 54e61d482d Fix: "group rotate" of elements detached the conductors as those were not rotated. 2026-09-18 12:35:08 +02:00
Jeff Patterson 800ddfbcbe Add a "qet-dark" icon theme for dark palettes
189 of QET's 266 fixed-size icons are black line art with no dark
variant, so on a dark palette they were black on a dark toolbar, and
Fusion's disabled rendering lightened them into something more readable
than the enabled state (GitHub #466, #870; bugtracker 335 for the
element panels, which keep their own fix).

The theme "qet-dark" holds light-ink copies of the line-art icons in
ico/themes/qet-dark, generated by misc/make_icon_themes.py. Colored
icons are not copied; the theme inherits them from "qet". An icon counts
as line art when fewer than 20% of its visible pixels are saturated. The
copies keep hue and alpha and invert lightness, scaled so each icon's
darkest ink becomes (220,220,220), the dark palette's text color. The
eight SVG icons get their color replaced the same way.

QETApp::applyIconTheme() picks "qet-dark" for a dark palette and "qet"
otherwise. It runs from initIconTheme(), again from initStyle() once the
palette is final, and on the OS color scheme switch. Icons created with
QIcon::fromTheme() re-resolve on their next paint, so nothing else
changes.

With light-ink files, Fusion's own disabled rendering comes out dimmer
than enabled with no extra code.

tests/qttest/tst_qeticons: every name resolves in both themes, every
dark file has light ink, and a Fusion tool button shows its icon at 3:1
in both themes with disabled weaker than enabled.
2026-09-18 05:06:51 -05:00
Laurent Trinques 0258d1a74f Merge pull request #917 from ispyisail/fix/913-paste-under-cursor
Linux build and tests / Build and test (Qt 6, Debug) (push) Failing after 1m43s
Paste under the cursor, and restore the folio context menu after a paste (#913)
2026-09-18 10:26:00 +02:00
ispyisail dd0c194a3c Paste under the cursor, and give the context menu back (#913)
Two fixes in the placement tool Ctrl+V starts.

Paste appeared on top of the original, not under the cursor. 55c2c0df9
added the placement tool precisely so the copy would not land invisibly
on top of what was copied, but 53a0f07ca then warped the pointer to the
group's grid-snapped origin -- which is the original's position -- so the
copy reappeared exactly over the original until the mouse was moved. The
start_pos the caller computes from the cursor was left unread: three
mentions in the file, all declaration or comment. Reported on #913,
where it reads as Ctrl+V pasting in place.

Move the group to the cursor instead of the cursor to the group. Both put
the copy under the pointer; only one of them takes the pointer away from
where the user put it. start_pos is honoured, the items are translated
once at construction, their conductors re-routed before anything is
drawn, and the movement baseline is set there too rather than waiting for
the first mouse move.

That made the baseline sentinel matter, so it is now the
m_baseline_captured flag the header already declared and nothing used,
rather than m_initial_cursor.isNull() -- which cannot tell "not set yet"
from a baseline that is legitimately scene (0,0).

Separately: one Ctrl+V killed the folio's right-click menu for the rest
of the session. init() sets Qt::NoContextMenu so a right click cancels
the placement instead of opening a menu over it, and nothing ever set it
back, taking "Coller ici", "Collage multiple", the folio properties and
add/remove column/row with it. Every other DiagramEvent* class restores
the policy in its destructor; this one did not. Confirmed against an
unmodified master build: the menu opens before a paste and not after one.
It matters here because "use the right-click menu instead" is the answer
people are given when Ctrl+V does not place where they wanted.

Verified on a built binary driven through a virtual X display, against
examples/741.qet and convertisseur.qet:

- the pointer does not move across Ctrl+V (1300,870 before and after;
  on master it jumps to the original at 798,455), and the copy is under it
- a multi-element selection keeps its layout and its conductors re-route
- Escape and right-click both cancel, leaving nothing behind and nothing
  on the undo stack; click and Return both commit; one undo removes the
  whole paste and redo restores it
- with the pointer outside the viewport the copy lands at the viewport
  centre, visible, and follows correctly once the mouse enters
- pasting into a different folio from the one copied from works
- the context menu opens before a paste, after a cancelled one, and after
  a committed one, with "Coller ici" present

ctest 9/9.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 19:57:59 +12:00
Laurent Trinques 3ba7de3284 CI: fix skip SignPath signing until the API token is configured 2026-09-18 08:33:45 +02:00
Laurent Trinques 0067ba1dca Merge pull request #905 from ispyisail/harden/crash-reporter
Linux build and tests / Build and test (Qt 6, Debug) (push) Failing after 2m1s
Harden the crash reporter: keep every dump, and say what crashed
2026-09-18 04:59:45 +02:00
ispyisail 16220af012 Merge remote-tracking branch 'upstream/master' into harden/crash-reporter 2026-09-18 14:31:54 +12:00
ispyisail f8c1b5206a Address review on #905: offered-list semantics, dump ordering, FreeBSD, legacy dumps
Five things raised in review, plus tests for the parts that were only
described in prose.

clearPendingCrashDump() did not do what its comment said. It called
pendingCrashDumpFiles() again at clear time, so it deleted whatever was
in the directory then, not what had been offered. The offer sits inside a
modal dialog that stays open as long as the user reads it, and
SingleApplication keys its socket on the binary path, so a second
QElectroTech build running alongside is a separate process that can crash
and write a dump in that window. Re-listing deleted that dump unseen --
the exact failure this change exists to fix. The list is now taken once
in QETApp::checkCrashDump() and passed to both
pendingCrashDumpContents() and clearPendingCrashDump().

The ring is now written before the backtrace. backtrace() unwinds through
libgcc, which calls dl_iterate_phdr and takes the loader lock; warming it
in install() removes the allocation but not the lock. Crashing inside
dlopen() (Qt plugin loading), or on a corrupted stack, could therefore
hang or re-fault the handler at the backtrace and lose the ring with it.
Order is now header, signal, ring, backtrace, so the cheapest and most
valuable part is already on disk before anything that can block. The
class comment claimed the handler takes no locks; that was not strictly
true and now says so.

QET_CRASH_BACKTRACE comes from find_package(Backtrace) rather than
__has_include(<execinfo.h>). The header exists on FreeBSD but backtrace()
lives in libexecinfo there, so the probe compiled and the link failed.

A crash_dump.log left by a pre-#905 version is migrated into crashes/ at
startup, named from its own mtime. Otherwise upgrading stranded it: the
new code never looks at that path, so the dump from the crash that
prompted the upgrade would sit there unoffered forever.

Also from the review: dumps are capped at the 10 newest, so a crash loop
cannot fill the log directory before any dialog is shown; crashDumpDir()
no longer creates the directory as a side effect of a const getter
(ensureCrashDumpDir() does that for the callers that write); and redact()
now masks an AppImage's per-run /tmp/.mount_XXXXXX prefix, which
backtrace_symbols_fd() writes into every frame.

Two test executables, both of which were checked to fail against the
behaviour they replace:

- tst_crashhandler covers CrashHandler::formatInt(), which had no
  coverage at all despite running only inside a signal handler, where
  nothing can assert: zero, negatives, INT_MIN (negated through unsigned,
  since -INT_MIN is UB), INT_MAX, truncation and a zero-sized buffer,
  each checked against a sentinel-filled buffer so a write past the
  reported length fails.
- tst_crashdumps covers the bookkeeping: ordering, empty dumps, the
  exclusion of this run's own path, the cap, concatenation of every
  offered dump, that clearing deletes only what was offered, and what
  redact() masks. qetlogger.cpp needs exactly one symbol from the
  application, QETApp::dataDir(), which the test supplies itself.

Not addressed here: the timestamp in crash_<timestamp>_<pid> is the
launch time, not the crash time -- correct as observed, and the commit
message that implied otherwise was the thing that was wrong. Resolvable
QET frames for AppImage/Flatpak/Snap/Debian need -rdynamic and archived
debug symbols, which is a packaging discussion, not this change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 14:31:49 +12:00
Laurent Trinques 4d800de26a Merge pull request #908 from ispyisail/fix/904-quit-during-modal
Refuse to close an editor while a modal dialog is running
2026-09-18 04:15:03 +02:00
ispyisail d3c8544fd9 Stop the quit-during-modal test taking its full watchdog period every run
The test bounded gdb with a backgrounded watchdog:

    ( sleep 120; kill -9 "$GDB_PID" 2>/dev/null ) &
    WATCHDOG_PID=$!
    wait "$GDB_PID"
    kill "$WATCHDOG_PID" 2>/dev/null

sleep runs as a child of the subshell, so killing the subshell leaves the
sleep orphaned -- and the orphan still holds the write end of whatever this
script's stdout is. Run from a terminal that costs nothing. Run through a
pipe, which is how CTest invokes it, the reader sees no EOF until the sleep
expires, so every run lasted the full 120 seconds regardless of how fast
gdb finished. gdb itself takes ten.

That made modal_quit_regression 92% of the runtime of the entire ctest
suite (122 s of 133 s) and left it 60 s short of its own 180 s CTest
timeout -- near enough that a loaded CI machine could have turned it into
a flaky failure in somebody else's build.

Use timeout(1) instead, which leaves nothing behind, with a plain gdb call
as a fallback where it is unavailable. Suite time drops to 12 s.

Verified on the merged branch: fixed build passes both the .qet and the
read-only .elmt scenario, and with the fix commit reverted both still fail
with signal 6, under ~QETDiagramEditor() and ~QETElementEditor()
respectively.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 13:53:16 +12:00
ispyisail eea939c31c Merge remote-tracking branch 'upstream/master' into fix/904-quit-during-modal 2026-09-18 13:34:58 +12:00
ispyisail 599228fe6e Register the quit-during-modal test with CTest, and fix two bugs in it
The test added with the #904 fix was run by hand. Register it so it runs
with the rest of the suite, and fix two defects found while extending it
to the element editor -- both of which made it report success it had not
earned.

nm -C "$BINARY" | grep -q <sym> under `set -o pipefail`: grep exits at the
first match, nm dies of SIGPIPE, and the pipeline reports failure. The
symbol check therefore skipped the test on every build that could actually
run it. Read nm's output into a variable once and match with `case`.

The input file was copied to a hardcoded "$SANDBOX/project.qet".
QElectroTech picks the editor from the extension, so passing a .elmt gave
a failed project load in the diagram editor rather than an element editor
-- the run still found a dialog, still called quitQET(), and still
reported a result, just for the wrong window. Preserve the basename.

With that fixed, the element-editor path is exercised on its own: a
read-only .elmt opens a message box, and on a build without the fix the
run aborts with "double free or corruption" under ~QETElementEditor(),
where before it named ~QETDiagramEditor(). The guard QETElementEditor
calls from its closeEvent() covers a real crash, not a theoretical one.

Registered on Linux only, and it reports 77 -- CTest's SKIP_RETURN_CODE --
when it cannot run at all: no gdb, a gdb built without Python, or a
stripped binary whose QETApp symbols it cannot call. A release build that
this test cannot drive is not a failing build.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 13:34:45 +12:00
Laurent Trinques 3ff02e528d Merge pull request #912 from Kellermorph/fix-checkbox-pdf-export
Fix PDF export checkbox state not being remembered
2026-09-18 01:49:39 +02:00
Kellermorph 520f4245b3 Fix PDF export checkbox state not being remembered
- Save and restore the state of m_component_info_cb, m_fit_in_page_cb,
  and m_use_full_page_cb via QSettings, in addition to the existing
  ExportProperties-based checkboxes (border, titleblock, terminals, etc.)
- Add savePrintProperties() to persist all checkbox states after
  print/export under the "print/default" settings prefix
- Remove unused QPrinter(HighResolution) local variable in launchDialog()
  that caused an unnecessary ~2s CUPS round-trip on Linux
2026-09-17 21:33:05 +02:00
Laurent Trinques 918756a91a Merge pull request #911 from Kellermorph/copying-fix
Linux build and tests / Build and test (Qt 6, Debug) (push) Failing after 2m2s
Fix copy-paste bugs in DiagramEventAddPaste and PasteDiagramCommand
2026-09-17 18:39:54 +02:00
Kellermorph 7a73e8075f Merge remote-tracking branch 'upstream/master' into copying-fix
# Conflicts:
#	sources/diagramevent/diagrameventaddpaste.cpp
2026-09-17 17:59:12 +02:00
Kellermorph 53a0f07ca3 Fix copy-paste bugs in DiagramEventAddPaste and PasteDiagramCommand
Fix multiple issues introduced by commit 55c2c0df9 (interactive paste):

Paste placement (diagrameventaddpaste):
- Items now load at their original XML coordinates instead of being
  snapped to the cursor position, preventing jumps on initial placement
- Use delta-based movement: record the actual grid-snapped cursor
  position on first mouseMoveEvent as baseline, then compute
  grid-snapped deltas from there
- Bypass Diagram::snapToGrid() in moveTo() to avoid Ctrl modifier
  causing pixel-snapping instead of grid-snapping
- Remove moveTo() from mouseReleaseEvent to prevent a final jump
  on click
- Warp cursor to group bounding rect origin for visual feedback

Paste command (diagramcommands):
- Always clear PLC slave data (type, address, function, comment,
  cross-ref, label, TC, T1-T4) on paste regardless of the
  erase-label-on-copy user preference
- Block alignment (m_block_alignment / blockAlignmentUpdate) before
  setElementInformations() for both slaves and non-slaves, preventing
  finishAlignment() from shifting right/center-aligned text items
- Clear non-UserText items directly after setElementInformations()
  for slaves as a safety net
2026-09-17 17:54:57 +02:00
Laurent Trinques 864e651966 Merge pull request #910 from arummler/fix-alignment
Fix alignment when pasting an element
2026-09-17 17:49:23 +02:00
Andre Rummler 26285373a3 Fix alignment when pasting an element. 2026-09-17 17:05:15 +02:00
Laurent Trinques b4fcef1829 CI: install the Qt SVG icon engine instead of breeze-icon-theme
draw-bezier-curves only exists as SVG in the qet icon theme; on
Debian/Ubuntu the SVG icon engine lives in qt6-svg-plugins, which
--no-install-recommends leaves out. breeze-icon-theme is not needed:
the test uses the qet theme compiled into the binary.
2026-09-17 15:57:05 +02:00
Laurent Trinques 9519b70826 CI: skip SignPath signing until the API token is configured 2026-09-17 15:46:26 +02:00
Laurent Trinques 218e70c759 CI: install an icon theme for tst_qeticons
The ubuntu:26.04 container has no icon theme, so
QIcon::fromTheme() returns null icons and tst_qeticons fails
on first CI run. Install breeze-icon-theme so the test runs
against a real theme, as it does on developer machines.
2026-09-17 15:27:26 +02:00
Laurent Trinques 26c0fc9812 Merge pull request #872 from ispyisail/ci/linux-build-and-tests
Add Linux CI: build, unit tests, and the IPC regression gate
2026-09-17 15:08:05 +02:00
Laurent Trinques 8c135a009d Clear the tools dock when an editor refuses the selection 2026-09-17 13:59:32 +02:00
Laurent Trinques 261b0f9e12 Merge pull request #675 from IBSYSLevi/improvement/avoid-needless-dock-churn
Avoid needless dock churn in QETElementEditor::updateInformations()
2026-09-17 13:49:52 +02:00
Laurent Trinques 1183849ce2 Merge pull request #895 from Kellermorph/fix-copy-page-plc-cleanup
Clean up stale data when duplicating diagram pages
2026-09-17 13:38:20 +02:00
Laurent Trinques 2b30083193 Merge pull request #909 from arummler/fix-move-insert
additional fix requested in #899
2026-09-17 13:29:07 +02:00
Andre Rummler 863ac5f0ae avoid that another action triggers while aborting operation 2026-09-17 13:25:17 +02:00
ispyisail 8623dd4c6f Refuse to close an editor while a modal dialog is running (#904)
openAndAddProject() shows BackupDialog as a stack object parented to the
editor and exec()s it; every QET::QetMessageBox does the same. exec() runs a
nested event loop, and closing the editor during it turns WA_DeleteOnClose
into a deleteLater() that the nested loop processes: ~QWidget() deletes the
editor's children, the stack-allocated dialog among them, and the process
aborts. Reported on macOS, where File > Quit lives in the application menu
and stays usable while the backup question is up.

The close is now refused while any modal widget is active, and the dialog is
raised so the refused quit is not silent. It is done in QETMainWindow::event()
rather than in closeEvent(), because QETDiagramEditor::closeEvent() starts
closing projects before it decides whether to accept. That covers the diagram
and title-block editors; QETElementEditor is a plain QMainWindow, so its
closeEvent() calls the same helper before canClose(), which itself opens a
modal. QETApp::quitQET() needs nothing: closeEveryEditor() goes through each
editor's close(), and quitQET() already only quits when every close succeeded.

Rejected alternatives, both suggested on the issue:

- Giving the dialog no parent stops the abort but not the deletion. One
  caller of openAndAddProject() is the editor's own constructor, which goes
  on to open the next file and call slot_updateActions() on this -- a loud
  abort would become a silent use-after-free.
- Guarding only QETApp::closeEveryEditor(), which I first recommended on the
  issue, misses the reported route entirely: File > Quit is connected to
  QETDiagramEditor::close(), not to quitQET().

Verified on Linux, where there is nothing to click (the menu bar belongs to
the blocked window, and Qt ignores window-manager close requests for it), by
calling close() from gdb while the dialog's loop was running -- both
QETApp::quitQET() and QWidget::close() on the editor. Unfixed, both abort
with "free(): invalid size" in QObjectPrivate::deleteChildren() under
~QETDiagramEditor(), matching the report frame for frame; fixed, close()
returns false, the editor and the dialog stay up, and after answering the
dialog Ctrl+Q exits normally. The element-editor guard is the same helper
but was not exercised separately.

tests/modal-quit-regression/ turns that into a gate: it breaks on
QDialog::exec(), interrupts inside the nested loop, calls quitQET() and
checks the process survives. It matches no window titles (translated) and no
window ids, runs on the offscreen platform, and needs only gdb with Python.
Checked both ways: exit 1 with the backtrace above on a build without this
change, exit 0 with it.

ctest 8/8.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 23:19:59 +12:00
Laurent Trinques 6a84ada6a6 Merge pull request #906 from jp2images/feature-icon-theme-plumbing
Add a "qet" icon theme and load icons by name
2026-09-17 13:19:11 +02:00
Kellermorph b7f516d485 Clean up stale data when duplicating diagram pages
When duplicating a diagram page, copied slave elements retain stale
data from the source: labels, descriptions, link references, and PLC
master information (type, address, function, comment, cross-ref, timer
values) remain in the copies.

Fix by adding clearPendingLinks() to Element to prevent copies from
linking back to source elements via stale UUIDs, and by cleaning up
copied element data after fromXml():

- Slaves always lose their label, formula, comment, location, and
  PLC master data, since their text comes from a master element which
  is not available on the copy. The displayed text on slave elements
  is cleared directly via setPlainText(), but UserText items (free
  text typed by the user) are preserved.

- For PLC slaves, setElementInformations() is called without
  m_block_alignment so that elementInfoChanged() can run
  finishAlignment() to correctly adjust text positions for the
  cleared content.

- Non-slave elements respect the existing erase-label-on-copy
  preference, same as PasteDiagramCommand::redo().

- Conductor labels are also reset when erase-label-on-copy is
  active, matching PasteDiagramCommand::redo() (issue #413).

- Text alignment is preserved by wrapping setElementInformations()
  with m_block_alignment for non-slave elements, same as
  Element::fromXml().
2026-09-17 13:12:15 +02:00
ispyisail 0646f9ca4f Harden the crash reporter: keep every dump, and say what crashed
Three weaknesses, all visible in ChuckNr11's report on #898 -- "the report
appeared only once despite there being 10 or more crashes".

One dump per run instead of one per install
-------------------------------------------
crashDumpPath() was a single fixed crash_dump.log, and the handler opens it
O_TRUNC, so each crash destroyed the evidence from the one before. Ten
crashes left one dump. Dumps now go to a crashes/ directory named
crash_<timestamp>_<pid>.log, and every pending one is offered together,
newest first, with a banner saying how many there are. A crash that repeats
is exactly the case where the earlier dumps matter, because the difference
between them is the evidence.

The name is built in normal context and handed to CrashHandler::install(),
which copies it into a preallocated buffer as before -- the handler still
writes to one fixed path, so its no-allocation invariant is untouched.

The dump now says which signal fired
------------------------------------
The header is built once at install(), so every dump looked identical no
matter what killed the process -- and SIGSEGV and SIGABRT point at very
different bugs. Written with an async-signal-safe integer formatter into a
stack buffer, since snprintf is not on the POSIX safe list.

...and where it was
-------------------
The ring said what the program was doing; nothing said where it died. The
dump now carries a backtrace. backtrace() is warmed once in install() so
its first-call lazy resolution cannot allocate inside the handler, and
backtrace_symbols_fd() writes straight to the fd -- unlike
backtrace_symbols(), which mallocs and must never be used here. Guarded on
__has_include(<execinfo.h>) so platforms without it are unaffected.

QET's own frames currently resolve as offsets rather than names, since the
binary does not export its dynamic symbols. They are still resolvable
offline: the header records the exact git SHA. Building with -rdynamic
would give names directly, but that is a build-flag decision for its own
change.

Deliberately unchanged: the four invariants in crashhandler.h. Nothing
added here allocates, blocks, takes a lock, or swallows the crash.

Verified: three consecutive SIGSEGVs now leave three separate dumps, each
carrying "Signal: 11" and a backtrace with resolved Qt frames; launching
afterwards offers all three in one dialog, newest first, and clears them
once shown. ctest 8/8.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 22:44:59 +12:00
Jeff Patterson 8ef130a59d Add a "qet" icon theme and load icons by name
QET had no icon theme: the 446 entries of the icon table and the 116
iconsets in .ui files each named a resource path, so an icon could only
ever be one file, and a variant for another palette or a vector source
had nowhere to go (GitHub #466, #690, #870). This adds the theme layout
without changing a single pixel; a dark variant comes in a follow-up.

The theme "qet" follows the freedesktop layout Qt's icon loader
understands. misc/make_icon_themes.py generates ico/icon-themes.qrc,
which aliases the existing ico/<size>/<name>.png files into
themes/qet/<size>/<name>.png, and ico/themes/qet/index.theme. No file
moves. The four table entries that paired a 16 pixel file with a 22
pixel file of another name (ConductorSettings, DiagramAdd,
DiagramDelete, DialogInformation) get the 22 pixel file aliased under
the 16 pixel name.

QETApp::initIconTheme() registers the theme before initIcons() and makes
it current on every platform, so a desktop icon theme cannot replace
QET's icons. Icons are then looked up by name: QIcon::fromTheme() in
qeticons.cpp and in the few places that built a QIcon from a resource
path directly, and theme="..." on the iconsets in .ui files, with the
resource path kept as fallback. Flags, color swatches, application and
MIME icons stay on their paths.

One entry does not go through the theme. The elements panel draws the
project root with ProjectFileGP in the 50 pixel slot it reserves for
element previews, and the name "project" also carries the 128 pixel
file the configuration dialog uses. On a 2x display Qt's loader picks
that file for a 50 pixel request and fills the slot. ProjectFileGP
loads the 16 and 22 pixel files directly, as before.

tests/qttest/tst_qeticons: every name in the theme resolves, the four
aliases resolve at 22 pixels, a Fusion tool button shows its icon at
3:1 with disabled weaker than enabled, and the project root icon stays
at 22 pixels or less when asked for 50 at 2x while the configuration
dialog still gets its 128 pixel file. The rendering helpers shared
with tst_qetpalette moved to tests/qttest/inkcontrast.h.
2026-09-17 05:41:50 -05:00
ispyisail 7a85e2592c Fix stale geometry in LineEditor on multi-select
LineEditor::setPart() no-ops (skipping updateForm()) when the part
passed in is already m_part. That is harmless when the editor widget
is torn down between selections, but this branch keeps the same
editor instance installed across selection changes instead of
recreating it, so a line already shown alone can also be
parts.first() of a later multi-selection -- and the x1/y1/x2/y2
spinboxes then keep showing whatever was in them before, not this
selection's actual first line.

setParts() now always calls updateForm() after setPart() succeeds,
closing the gap regardless of the identity check inside setPart().

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 21:27:22 +12:00
ispyisail 7183ed3d99 Merge remote-tracking branch 'upstream/master' into fix/675-line-editor-stale-refresh 2026-09-16 21:21:08 +12:00
ispyisail a106395679 Add Linux CI: build, unit tests, and the IPC regression gate
Nothing currently builds QElectroTech on Linux in CI, and nothing runs tests/
at all -- the existing workflows build Windows and generate documentation.

Adds one job: configure and build with Qt 6 Debug, run ctest, then run the
IPC open-forwarding regression test.

Verified by running the job's exact step sequence in a clean ubuntu:26.04
container, in both directions:

  with the #868 fix     5/5 unit tests pass, gate passes,  job green
  with the fix reverted 5/5 unit tests pass, gate fails,   job red

The unit tests passing in both arms is the point: the existing suite cannot
see this class of bug, which is what the gate is for.

Three choices that are not cosmetic:

- Runs in an ubuntu:26.04 container rather than on the runner. ubuntu-latest
  ships Qt 6.4; the gate needs 6.10.2, and whether the crash reproduces on
  6.4 has never been checked. A job that cannot go red is worse than none.
- Debug, not Release. The pre-fix commit survives every attempt built
  -O3 -DNDEBUG, so a Release job would never catch a regression here.
- An inconclusive gate run warns rather than fails. It means the crash path
  was not exercised, which proves nothing and is not the same as a
  regression; failing on it would make the job flaky rather than useful.

extra-cmake-modules and the KF6 libraries are installed rather than left to
FetchContent, which otherwise builds ECM from source and fails the configure
demanding Qt6 documentation tools.

Depends on the regression test added in #871.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 07:38:24 +12:00
Levi Jetzer 72c8008218 Avoid needless dock churn in QETElementEditor::updateInformations()
updateInformations() runs on every selection change and on every undo
stack index change. It unconditionally called clearToolsDock(), which
removes and hides the current editor widget, and then re-inserted the
same widget into the stack. When the editor for the new selection is
the one already shown, that means removing, hiding, reparenting and
re-adding a widget only to end up in the same state.

Look up the editor first and only clear and re-insert the tools dock
when a different editor is needed. setPart()/setParts() still updates
the contents in every case, so the visible result is unchanged.
2026-08-06 17:20:48 +02:00
292 changed files with 5316 additions and 963 deletions
+79
View File
@@ -0,0 +1,79 @@
# Linux build, unit tests, and the IPC open-forwarding regression gate.
#
# The existing workflows build Windows and generate documentation; nothing
# builds QElectroTech on Linux or runs tests/ in CI. This does both.
#
# It runs inside an ubuntu:26.04 container rather than directly on the runner
# because the IPC gate below needs Qt 6.10.2. The ubuntu-latest image ships
# Qt 6.4, and whether the crash that gate covers reproduces on 6.4 has never
# been checked -- a gate that cannot go red is worse than no gate.
name: Linux build and tests
on:
push:
branches: [master]
pull_request:
workflow_dispatch:
jobs:
linux:
name: Build and test (Qt 6, Debug)
runs-on: ubuntu-latest
container: ubuntu:26.04
steps:
- name: Install build and test dependencies
run: |
apt-get update
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
ca-certificates build-essential cmake ninja-build git pkg-config \
qt6-base-dev qt6-base-private-dev qt6-tools-dev qt6-tools-dev-tools \
libqt6svg6-dev libqt6sql6-sqlite libsqlite3-dev libcups2-dev \
libxkbcommon-x11-0 \
xvfb openbox xdotool x11-utils
# extra-cmake-modules and the KF6 libraries are installed rather than
# left to FetchContent: without them CMake builds extra-cmake-modules
# from source, and its Qt Help documentation target then demands
# Qt6{Core,Gui,Widgets,DBus}Tools, failing the configure with an error
# that appears to be about QElectroTech and is not.
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
extra-cmake-modules libkf6coreaddons-dev libkf6widgetsaddons-dev \
qt6-svg-plugins
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Configure
# Debug, not Release. Whether a use-after-free faults depends on what
# the allocator does with the freed block: the commit before #868
# crashes every time built Debug and survives every time built
# -O3 -DNDEBUG, so a Release job would never catch a regression here.
run: |
git config --global --add safe.directory "$GITHUB_WORKSPACE"
cmake -B build -G Ninja \
-DCMAKE_BUILD_TYPE=Debug \
-DQT_VERSION_MAJOR=6
- name: Build
run: cmake --build build --parallel $(nproc)
- name: Unit tests
run: xvfb-run -a ctest --test-dir build --output-on-failure
- name: IPC open-forwarding regression (#868)
# Fails the job only on an actual crash. An inconclusive run means the
# crash path was not exercised -- it proves nothing, which is not the
# same as a regression, and failing on it would make this job flaky
# rather than informative.
run: |
set +e
tests/ipc-regression/run.sh --binary build/qelectrotech
status=$?
set -e
case $status in
0) echo "::notice::IPC gate passed" ;;
2) echo "::warning::IPC gate inconclusive -- the crash path was not exercised, nothing was proven" ;;
*) echo "::error::IPC gate failed -- forwarded files are being opened inside the socket handler again"
exit 1 ;;
esac
+29 -2
View File
@@ -42,6 +42,9 @@ jobs:
pages: write
id-token: write # Required by SignPath
env:
SIGNPATH_API_TOKEN: ${{ secrets.SIGNPATH_API_TOKEN }}
outputs:
qt6_msi: ${{ steps.export.outputs.msi_name_qt6 }}
@@ -289,8 +292,15 @@ jobs:
# check: forks never have the SignPath secrets, and a fork-originated
# PR/run must never attempt a signing request.
# (cf. DieterMayerOSS:fix/msi-signing-fork-guard, d3f60c88)
# continue-on-error: SignPath's certificate is still pending validation
# (Sept 2026) — the signing request currently fails with a 500 on the
# SignPath side. Kept non-blocking so the nightly MSI still ships
# (unsigned) while the certificate is pending. Remove
# continue-on-error once the certificate is confirmed active.
- name: Sign MSI via SignPath
if: github.repository == 'qelectrotech/qelectrotech-source-mirror'
id: sign
if: github.repository == 'qelectrotech/qelectrotech-source-mirror' && env.SIGNPATH_API_TOKEN != ''
continue-on-error: true
uses: signpath/github-action-submit-signing-request@v2
with:
api-token: ${{ secrets.SIGNPATH_API_TOKEN }}
@@ -302,7 +312,22 @@ jobs:
wait-for-completion: true
output-artifact-directory: 'dist\'
# If signing succeeded, SignPath already overwrote dist\*.msi with the
# signed copy (output-artifact-directory above) — nothing to do here.
# If it failed/was skipped, dist\*.msi is still the unsigned MSI from
# the "Build MSI" step, so the rest of the pipeline just ships that.
- name: Report signing status
if: always()
shell: pwsh
run: |
if ("${{ steps.sign.outcome }}" -eq "success") {
Write-Host "MSI signed successfully via SignPath."
} else {
Write-Warning "MSI signing skipped or failed (outcome: ${{ steps.sign.outcome }}) — shipping UNSIGNED MSI. Likely cause: SignPath certificate still pending validation."
}
- name: Upload signed MSI artifact
if: always()
uses: actions/upload-artifact@v7
with:
name: qelectrotech-windows-msi-${{ matrix.flavor }}
@@ -311,6 +336,7 @@ jobs:
if-no-files-found: error
- name: Delete old nightly .msi asset
if: always()
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
@@ -324,6 +350,7 @@ jobs:
shell: pwsh
- name: Upload MSI to nightly release
if: always()
uses: softprops/action-gh-release@v3
with:
tag_name: nightly
@@ -345,7 +372,7 @@ jobs:
run: |
Write-Host "=== MSI build summary (${{ matrix.flavor }}) ==="
Write-Host "Version : ${{ steps.version.outputs.VERSION_DISPLAY }}"
Write-Host "Signed : true"
Write-Host "Signed : ${{ steps.sign.outcome == 'success' }}"
# ---------------------------------------------------------------------------
# Job 2 : Génère et déploie la page GitHub Pages une fois le MSI publié,
+8
View File
@@ -8,3 +8,11 @@ doc/*
QElectroTech.tag
!doc/doc-utils
lang/*.qm
# -- IDE settings/intermediate files --
# zed
.zed
.cache
# VS Code
.vscode
+17
View File
@@ -101,6 +101,21 @@ else()
message(STATUS "Qt Qml module not available: JavaScript scripting (--run) disabled")
endif()
# The crash handler writes a backtrace into the dump. Detecting this with
# __has_include(<execinfo.h>) is not enough: the header is present on FreeBSD
# too, but backtrace() lives in a separate libexecinfo there, so the compile
# succeeds and the link fails. FindBacktrace resolves both the header and
# whichever library actually provides the symbol, so gate on it instead - see
# the QET_CRASH_BACKTRACE guard in sources/logging/crashhandler.cpp.
find_package(Backtrace QUIET)
if(Backtrace_FOUND)
list(APPEND QET_PRIVATE_LIBRARIES ${Backtrace_LIBRARIES})
include_directories(${Backtrace_INCLUDE_DIRS})
add_compile_definitions(QET_CRASH_BACKTRACE)
else()
message(STATUS "backtrace() not available: crash dumps will carry the log ring without a backtrace")
endif()
find_package(SQLite3 REQUIRED)
# CMake < 4.3 only creates the SQLite::SQLite3 target (no SQLite3::SQLite3
@@ -139,6 +154,7 @@ if(WIN32)
${QET_SRC_FILES}
${QM_FILES}
${QET_DIR}/qelectrotech.qrc
${QET_DIR}/ico/icon-themes.qrc
)
else()
add_executable(
@@ -147,6 +163,7 @@ else()
${QET_SRC_FILES}
${QM_FILES}
${QET_DIR}/qelectrotech.qrc
${QET_DIR}/ico/icon-themes.qrc
)
endif()
+6
View File
@@ -250,6 +250,8 @@ set(QET_SRC_FILES
${QET_DIR}/sources/qeticons.h
${QET_DIR}/sources/qetpalette.cpp
${QET_DIR}/sources/qetpalette.h
${QET_DIR}/sources/qetstyle.cpp
${QET_DIR}/sources/qetstyle.h
${QET_DIR}/sources/qetinformation.cpp
${QET_DIR}/sources/qetinformation.h
${QET_DIR}/sources/qetmainwindow.cpp
@@ -434,6 +436,8 @@ set(QET_SRC_FILES
${QET_DIR}/sources/ElementsCollection/elementcollectionhandler.h
${QET_DIR}/sources/ElementsCollection/elementcollectionitem.cpp
${QET_DIR}/sources/ElementsCollection/elementcollectionitem.h
${QET_DIR}/sources/ElementsCollection/elementpreviewdelegate.cpp
${QET_DIR}/sources/ElementsCollection/elementpreviewdelegate.h
${QET_DIR}/sources/ElementsCollection/elementscollectionmodel.cpp
${QET_DIR}/sources/ElementsCollection/elementscollectionmodel.h
${QET_DIR}/sources/ElementsCollection/elementscollectionwidget.cpp
@@ -699,6 +703,8 @@ set(QET_SRC_FILES
${QET_DIR}/sources/ui/contactgroupselectiondialog.h
${QET_DIR}/sources/ui/conductorpropertiesdialog.cpp
${QET_DIR}/sources/ui/conductorpropertiesdialog.h
${QET_DIR}/sources/ui/conductorcolortoolbutton.cpp
${QET_DIR}/sources/ui/conductorcolortoolbutton.h
${QET_DIR}/sources/ui/conductorpropertieswidget.cpp
${QET_DIR}/sources/ui/conductorpropertieswidget.h
${QET_DIR}/sources/ui/configsaveloaderwidget.cpp
Binary file not shown.

Before

Width:  |  Height:  |  Size: 216 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 262 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 247 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 271 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 233 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

+2
View File
@@ -216,6 +216,8 @@ Clarification:
ico/128x128/diagram.png by the QElectroTech team (License CC BY-ND 3.0)
ico/128x128/document-export.png by the QElectroTech team (License CC BY-ND 3.0)
ico/128x128/project.png by the QElectroTech team (License CC BY-ND 3.0)
ico/scalable/pdf-import.svg by Jeff Patterson from the QElectroTech team (License CC BY-ND 3.0), laid out like ico/22x22/insert-image.png
ico/scalable/diagram.svg, folio-new.svg, folio-delete.svg, folio-properties.svg, label.svg by Jeff Patterson from the QElectroTech team (License CC BY-ND 3.0), the folio icons redrawn in the same style
ico/256x256/* by Nuri from the QElectroTech team (License CC BY-ND 3.0)
ico/breeze-icons/* by Nuri from the QElectroTech team (License CC BY-ND 3.0)
ico/diagram.png by Nuri from the QElectroTech team (License CC BY-ND 3.0)
+473
View File
@@ -0,0 +1,473 @@
<!DOCTYPE RCC>
<!-- Generated by misc/make_icon_themes.py. Do not edit. -->
<RCC version="1.0">
<qresource prefix="/ico">
<file>themes/qet/index.theme</file>
<file>themes/qet-dark/index.theme</file>
<file alias="themes/qet/16x16/application-exit.png">16x16/application-exit.png</file>
<file alias="themes/qet/16x16/arrow-left-double.png">16x16/arrow-left-double.png</file>
<file alias="themes/qet/16x16/arrow-left.png">16x16/arrow-left.png</file>
<file alias="themes/qet/16x16/arrow-right-double.png">16x16/arrow-right-double.png</file>
<file alias="themes/qet/16x16/arrow-right.png">16x16/arrow-right.png</file>
<file alias="themes/qet/16x16/circle.png">16x16/circle.png</file>
<file alias="themes/qet/16x16/conductor-edit.png">16x16/conductor-edit.png</file>
<file alias="themes/qet/16x16/conductor-reset.png">16x16/conductor-reset.png</file>
<file alias="themes/qet/16x16/conductor.png">16x16/conductor.png</file>
<file alias="themes/qet/16x16/configure-toolbars.png">16x16/configure-toolbars.png</file>
<file alias="themes/qet/16x16/configure.png">16x16/configure.png</file>
<file alias="themes/qet/16x16/diagram.png">16x16/diagram.png</file>
<file alias="themes/qet/16x16/dialog-cancel.png">16x16/dialog-cancel.png</file>
<file alias="themes/qet/16x16/dialog-ok.png">16x16/dialog-ok.png</file>
<file alias="themes/qet/16x16/document-close.png">16x16/document-close.png</file>
<file alias="themes/qet/16x16/document-export.png">16x16/document-export.png</file>
<file alias="themes/qet/16x16/document-import.png">16x16/document-import.png</file>
<file alias="themes/qet/16x16/document-new.png">16x16/document-new.png</file>
<file alias="themes/qet/16x16/document-open-recent.png">16x16/document-open-recent.png</file>
<file alias="themes/qet/16x16/document-open.png">16x16/document-open.png</file>
<file alias="themes/qet/16x16/document-print-frame.png">16x16/document-print-frame.png</file>
<file alias="themes/qet/16x16/document-print.png">16x16/document-print.png</file>
<file alias="themes/qet/16x16/document-save-all.png">16x16/document-save-all.png</file>
<file alias="themes/qet/16x16/document-save-as.png">16x16/document-save-as.png</file>
<file alias="themes/qet/16x16/document-save.png">16x16/document-save.png</file>
<file alias="themes/qet/16x16/east.png">16x16/east.png</file>
<file alias="themes/qet/16x16/edit-clear-locationbar-ltr.png">16x16/edit-clear-locationbar-ltr.png</file>
<file alias="themes/qet/16x16/edit-clear-locationbar-rtl.png">16x16/edit-clear-locationbar-rtl.png</file>
<file alias="themes/qet/16x16/edit-clear.png">16x16/edit-clear.png</file>
<file alias="themes/qet/16x16/edit-copy.png">16x16/edit-copy.png</file>
<file alias="themes/qet/16x16/edit-cut.png">16x16/edit-cut.png</file>
<file alias="themes/qet/16x16/edit-delete.png">16x16/edit-delete.png</file>
<file alias="themes/qet/16x16/edit-download.png">16x16/edit-download.png</file>
<file alias="themes/qet/16x16/edit-paste.png">16x16/edit-paste.png</file>
<file alias="themes/qet/16x16/edit-redo.png">16x16/edit-redo.png</file>
<file alias="themes/qet/16x16/edit-rename.png">16x16/edit-rename.png</file>
<file alias="themes/qet/16x16/edit-select-all.png">16x16/edit-select-all.png</file>
<file alias="themes/qet/16x16/edit-select-invert.png">16x16/edit-select-invert.png</file>
<file alias="themes/qet/16x16/edit-select-none.png">16x16/edit-select-none.png</file>
<file alias="themes/qet/16x16/edit-table-cell-merge.png">16x16/edit-table-cell-merge.png</file>
<file alias="themes/qet/16x16/edit-table-cell-split.png">16x16/edit-table-cell-split.png</file>
<file alias="themes/qet/16x16/edit-table-delete-column.png">16x16/edit-table-delete-column.png</file>
<file alias="themes/qet/16x16/edit-table-delete-row.png">16x16/edit-table-delete-row.png</file>
<file alias="themes/qet/16x16/edit-table-insert-column-left.png">16x16/edit-table-insert-column-left.png</file>
<file alias="themes/qet/16x16/edit-table-insert-column-right.png">16x16/edit-table-insert-column-right.png</file>
<file alias="themes/qet/16x16/edit-table-insert-row-above.png">16x16/edit-table-insert-row-above.png</file>
<file alias="themes/qet/16x16/edit-table-insert-row-under.png">16x16/edit-table-insert-row-under.png</file>
<file alias="themes/qet/16x16/edit-undo.png">16x16/edit-undo.png</file>
<file alias="themes/qet/16x16/element-delete.png">16x16/element-delete.png</file>
<file alias="themes/qet/16x16/element-edit.png">16x16/element-edit.png</file>
<file alias="themes/qet/16x16/element-master.png">16x16/element-master.png</file>
<file alias="themes/qet/16x16/element-new.png">16x16/element-new.png</file>
<file alias="themes/qet/16x16/element-slave.png">16x16/element-slave.png</file>
<file alias="themes/qet/16x16/element.png">16x16/element.png</file>
<file alias="themes/qet/16x16/endline-circle.png">16x16/endline-circle.png</file>
<file alias="themes/qet/16x16/endline-diamond.png">16x16/endline-diamond.png</file>
<file alias="themes/qet/16x16/endline-none.png">16x16/endline-none.png</file>
<file alias="themes/qet/16x16/endline-simple.png">16x16/endline-simple.png</file>
<file alias="themes/qet/16x16/endline-triangle.png">16x16/endline-triangle.png</file>
<file alias="themes/qet/16x16/export-csv.png">16x16/export-csv.png</file>
<file alias="themes/qet/16x16/flip.png">16x16/flip.png</file>
<file alias="themes/qet/16x16/folder-delete.png">16x16/folder-delete.png</file>
<file alias="themes/qet/16x16/folder-edit.png">16x16/folder-edit.png</file>
<file alias="themes/qet/16x16/folder-new.png">16x16/folder-new.png</file>
<file alias="themes/qet/16x16/folder-only-this.png">16x16/folder-only-this.png</file>
<file alias="themes/qet/16x16/folder-open.png">16x16/folder-open.png</file>
<file alias="themes/qet/16x16/folder-properties.png">16x16/folder-properties.png</file>
<file alias="themes/qet/16x16/folder-show-all.png">16x16/folder-show-all.png</file>
<file alias="themes/qet/16x16/folder.png">16x16/folder.png</file>
<file alias="themes/qet/16x16/folio-delete.png">16x16/folio-delete.png</file>
<file alias="themes/qet/16x16/folio-new.png">16x16/folio-new.png</file>
<file alias="themes/qet/16x16/folio-properties.png">16x16/folio-properties.png</file>
<file alias="themes/qet/16x16/folio-ref-coming.png">16x16/folio-ref-coming.png</file>
<file alias="themes/qet/16x16/go-bottom.png">16x16/go-bottom.png</file>
<file alias="themes/qet/16x16/go-company.png">16x16/go-company.png</file>
<file alias="themes/qet/16x16/go-down-double.png">16x16/go-down-double.png</file>
<file alias="themes/qet/16x16/go-down.png">16x16/go-down.png</file>
<file alias="themes/qet/16x16/go-home.png">16x16/go-home.png</file>
<file alias="themes/qet/16x16/go-top.png">16x16/go-top.png</file>
<file alias="themes/qet/16x16/go-up-double.png">16x16/go-up-double.png</file>
<file alias="themes/qet/16x16/go-up.png">16x16/go-up.png</file>
<file alias="themes/qet/16x16/grid.png">16x16/grid.png</file>
<file alias="themes/qet/16x16/ground.png">16x16/ground.png</file>
<file alias="themes/qet/16x16/help-contents.png">16x16/help-contents.png</file>
<file alias="themes/qet/16x16/help-donate.png">16x16/help-donate.png</file>
<file alias="themes/qet/16x16/item-cancel.png">16x16/item-cancel.png</file>
<file alias="themes/qet/16x16/item-copy.png">16x16/item-copy.png</file>
<file alias="themes/qet/16x16/item-move.png">16x16/item-move.png</file>
<file alias="themes/qet/16x16/kdenlive-show-video.png">16x16/kdenlive-show-video.png</file>
<file alias="themes/qet/16x16/label.png">16x16/label.png</file>
<file alias="themes/qet/16x16/list-add.png">16x16/list-add.png</file>
<file alias="themes/qet/16x16/list-remove.png">16x16/list-remove.png</file>
<file alias="themes/qet/16x16/masquer.png">16x16/masquer.png</file>
<file alias="themes/qet/16x16/mirror.png">16x16/mirror.png</file>
<file alias="themes/qet/16x16/move.png">16x16/move.png</file>
<file alias="themes/qet/16x16/neutral.png">16x16/neutral.png</file>
<file alias="themes/qet/16x16/north.png">16x16/north.png</file>
<file alias="themes/qet/16x16/object-group.png">16x16/object-group.png</file>
<file alias="themes/qet/16x16/object-rotate-right.png">16x16/object-rotate-right.png</file>
<file alias="themes/qet/16x16/orientations.png">16x16/orientations.png</file>
<file alias="themes/qet/16x16/phase.png">16x16/phase.png</file>
<file alias="themes/qet/16x16/preferences-desktop-user.png">16x16/preferences-desktop-user.png</file>
<file alias="themes/qet/16x16/project-close.png">16x16/project-close.png</file>
<file alias="themes/qet/16x16/project-delete.png">16x16/project-delete.png</file>
<file alias="themes/qet/16x16/project-new.png">16x16/project-new.png</file>
<file alias="themes/qet/16x16/project-properties.png">16x16/project-properties.png</file>
<file alias="themes/qet/16x16/project.png">16x16/project.png</file>
<file alias="themes/qet/16x16/qet.png">16x16/qet.png</file>
<file alias="themes/qet/16x16/qt.png">16x16/qt.png</file>
<file alias="themes/qet/16x16/run-dxf.png">16x16/run-dxf.png</file>
<file alias="themes/qet/16x16/select.png">16x16/select.png</file>
<file alias="themes/qet/16x16/south.png">16x16/south.png</file>
<file alias="themes/qet/16x16/table-of-content.png">16x16/table-of-content.png</file>
<file alias="themes/qet/16x16/terminal.png">16x16/terminal.png</file>
<file alias="themes/qet/16x16/terminalstrip.png">16x16/terminalstrip.png</file>
<file alias="themes/qet/16x16/text-xml.png">16x16/text-xml.png</file>
<file alias="themes/qet/16x16/transform-rotate.png">16x16/transform-rotate.png</file>
<file alias="themes/qet/16x16/user-busy.png">16x16/user-busy.png</file>
<file alias="themes/qet/16x16/user-online.png">16x16/user-online.png</file>
<file alias="themes/qet/16x16/view-fullscreen.png">16x16/view-fullscreen.png</file>
<file alias="themes/qet/16x16/view-refresh.png">16x16/view-refresh.png</file>
<file alias="themes/qet/16x16/view-restore.png">16x16/view-restore.png</file>
<file alias="themes/qet/16x16/west.png">16x16/west.png</file>
<file alias="themes/qet/16x16/window-new.png">16x16/window-new.png</file>
<file alias="themes/qet/16x16/zoom-draw.png">16x16/zoom-draw.png</file>
<file alias="themes/qet/16x16/zoom-fit-best.png">16x16/zoom-fit-best.png</file>
<file alias="themes/qet/16x16/zoom-in.png">16x16/zoom-in.png</file>
<file alias="themes/qet/16x16/zoom-original.png">16x16/zoom-original.png</file>
<file alias="themes/qet/16x16/zoom-out.png">16x16/zoom-out.png</file>
<file alias="themes/qet/22x22/Actions-player-time-icon.png">22x22/Actions-player-time-icon.png</file>
<file alias="themes/qet/22x22/all_pages.png">22x22/all_pages.png</file>
<file alias="themes/qet/22x22/application-exit.png">22x22/application-exit.png</file>
<file alias="themes/qet/22x22/applications-development-translation.png">22x22/applications-development-translation.png</file>
<file alias="themes/qet/22x22/arc.png">22x22/arc.png</file>
<file alias="themes/qet/22x22/arrow-left-double.png">22x22/arrow-left-double.png</file>
<file alias="themes/qet/22x22/arrow-left.png">22x22/arrow-left.png</file>
<file alias="themes/qet/22x22/arrow-right-double.png">22x22/arrow-right-double.png</file>
<file alias="themes/qet/22x22/arrow-right.png">22x22/arrow-right.png</file>
<file alias="themes/qet/22x22/autoconnect.png">22x22/autoconnect.png</file>
<file alias="themes/qet/22x22/bring_forward.png">22x22/bring_forward.png</file>
<file alias="themes/qet/22x22/conductor2.png">22x22/conductor2.png</file>
<file alias="themes/qet/22x22/conductor-reset.png">22x22/conductor2.png</file>
<file alias="themes/qet/22x22/configure-toolbars.png">22x22/configure-toolbars.png</file>
<file alias="themes/qet/22x22/configure.png">22x22/configure.png</file>
<file alias="themes/qet/22x22/diagram_bg.png">22x22/diagram_bg.png</file>
<file alias="themes/qet/22x22/dialog-cancel.png">22x22/dialog-cancel.png</file>
<file alias="themes/qet/22x22/dialog-ok.png">22x22/dialog-ok.png</file>
<file alias="themes/qet/22x22/document-close.png">22x22/document-close.png</file>
<file alias="themes/qet/22x22/document-export.png">22x22/document-export.png</file>
<file alias="themes/qet/22x22/document-import.png">22x22/document-import.png</file>
<file alias="themes/qet/22x22/document-new.png">22x22/document-new.png</file>
<file alias="themes/qet/22x22/document-open-recent.png">22x22/document-open-recent.png</file>
<file alias="themes/qet/22x22/document-open.png">22x22/document-open.png</file>
<file alias="themes/qet/22x22/document-print-frame.png">22x22/document-print-frame.png</file>
<file alias="themes/qet/22x22/document-print.png">22x22/document-print.png</file>
<file alias="themes/qet/22x22/document-save-all.png">22x22/document-save-all.png</file>
<file alias="themes/qet/22x22/document-save-as.png">22x22/document-save-as.png</file>
<file alias="themes/qet/22x22/document-save.png">22x22/document-save.png</file>
<file alias="themes/qet/22x22/edit-clear-locationbar-ltr.png">22x22/edit-clear-locationbar-ltr.png</file>
<file alias="themes/qet/22x22/edit-clear-locationbar-rtl.png">22x22/edit-clear-locationbar-rtl.png</file>
<file alias="themes/qet/22x22/edit-clear.png">22x22/edit-clear.png</file>
<file alias="themes/qet/22x22/edit-copy.png">22x22/edit-copy.png</file>
<file alias="themes/qet/22x22/edit-cut.png">22x22/edit-cut.png</file>
<file alias="themes/qet/22x22/edit-delete.png">22x22/edit-delete.png</file>
<file alias="themes/qet/22x22/edit-paste.png">22x22/edit-paste.png</file>
<file alias="themes/qet/22x22/edit-redo.png">22x22/edit-redo.png</file>
<file alias="themes/qet/22x22/edit-rename.png">22x22/edit-rename.png</file>
<file alias="themes/qet/22x22/edit-select-all.png">22x22/edit-select-all.png</file>
<file alias="themes/qet/22x22/edit-table-cell-merge.png">22x22/edit-table-cell-merge.png</file>
<file alias="themes/qet/22x22/edit-table-cell-split.png">22x22/edit-table-cell-split.png</file>
<file alias="themes/qet/22x22/edit-table-delete-column.png">22x22/edit-table-delete-column.png</file>
<file alias="themes/qet/22x22/edit-table-delete-row.png">22x22/edit-table-delete-row.png</file>
<file alias="themes/qet/22x22/edit-table-insert-column-left.png">22x22/edit-table-insert-column-left.png</file>
<file alias="themes/qet/22x22/edit-table-insert-column-right.png">22x22/edit-table-insert-column-right.png</file>
<file alias="themes/qet/22x22/edit-table-insert-row-above.png">22x22/edit-table-insert-row-above.png</file>
<file alias="themes/qet/22x22/edit-table-insert-row-under.png">22x22/edit-table-insert-row-under.png</file>
<file alias="themes/qet/22x22/edit-undo.png">22x22/edit-undo.png</file>
<file alias="themes/qet/22x22/element-delete.png">22x22/element-delete.png</file>
<file alias="themes/qet/22x22/element-edit.png">22x22/element-edit.png</file>
<file alias="themes/qet/22x22/element-new.png">22x22/element-new.png</file>
<file alias="themes/qet/22x22/ellipse.png">22x22/ellipse.png</file>
<file alias="themes/qet/22x22/export-csv.png">22x22/export-csv.png</file>
<file alias="themes/qet/22x22/folder-delete.png">22x22/folder-delete.png</file>
<file alias="themes/qet/22x22/folder-edit.png">22x22/folder-edit.png</file>
<file alias="themes/qet/22x22/folder-new.png">22x22/folder-new.png</file>
<file alias="themes/qet/22x22/folder-open.png">22x22/folder-open.png</file>
<file alias="themes/qet/22x22/format-text-subscript.png">22x22/format-text-subscript.png</file>
<file alias="themes/qet/22x22/format-text-superscript.png">22x22/format-text-superscript.png</file>
<file alias="themes/qet/22x22/go-company.png">22x22/go-company.png</file>
<file alias="themes/qet/22x22/go-down.png">22x22/go-down.png</file>
<file alias="themes/qet/22x22/go-home.png">22x22/go-home.png</file>
<file alias="themes/qet/22x22/go-up.png">22x22/go-up.png</file>
<file alias="themes/qet/22x22/grid.png">22x22/grid.png</file>
<file alias="themes/qet/22x22/guides.png">22x22/guides.png</file>
<file alias="themes/qet/22x22/hotspot.png">22x22/hotspot.png</file>
<file alias="themes/qet/22x22/insert-image.png">22x22/insert-image.png</file>
<file alias="themes/qet/22x22/landscape.png">22x22/landscape.png</file>
<file alias="themes/qet/22x22/line.png">22x22/line.png</file>
<file alias="themes/qet/22x22/list-add.png">22x22/list-add.png</file>
<file alias="themes/qet/22x22/list-remove.png">22x22/list-remove.png</file>
<file alias="themes/qet/22x22/lower.png">22x22/lower.png</file>
<file alias="themes/qet/22x22/move.png">22x22/move.png</file>
<file alias="themes/qet/22x22/names.png">22x22/names.png</file>
<file alias="themes/qet/22x22/object-locked.png">22x22/object-locked.png</file>
<file alias="themes/qet/22x22/object-rotate-right.png">22x22/object-rotate-right.png</file>
<file alias="themes/qet/22x22/object-unlocked.png">22x22/object-unlocked.png</file>
<file alias="themes/qet/22x22/polygon.png">22x22/polygon.png</file>
<file alias="themes/qet/22x22/portrait.png">22x22/portrait.png</file>
<file alias="themes/qet/22x22/preferences-desktop-user.png">22x22/preferences-desktop-user.png</file>
<file alias="themes/qet/22x22/project-close.png">22x22/project-close.png</file>
<file alias="themes/qet/22x22/project-delete.png">22x22/project-delete.png</file>
<file alias="themes/qet/22x22/project-new.png">22x22/project-new.png</file>
<file alias="themes/qet/22x22/project.png">22x22/project.png</file>
<file alias="themes/qet/22x22/raise.png">22x22/raise.png</file>
<file alias="themes/qet/22x22/rectangle.png">22x22/rectangle.png</file>
<file alias="themes/qet/22x22/restaurer.png">22x22/restaurer.png</file>
<file alias="themes/qet/22x22/select.png">22x22/select.png</file>
<file alias="themes/qet/22x22/send_backward.png">22x22/send_backward.png</file>
<file alias="themes/qet/22x22/single_page.png">22x22/single_page.png</file>
<file alias="themes/qet/22x22/start.png">22x22/start.png</file>
<file alias="themes/qet/22x22/terminal.png">22x22/terminal.png</file>
<file alias="themes/qet/22x22/terminalstrip.png">22x22/terminalstrip.png</file>
<file alias="themes/qet/22x22/text-xml.png">22x22/text-xml.png</file>
<file alias="themes/qet/22x22/text.png">22x22/text.png</file>
<file alias="themes/qet/22x22/textfield.png">22x22/textfield.png</file>
<file alias="themes/qet/22x22/titleblock-bottom.png">22x22/titleblock-bottom.png</file>
<file alias="themes/qet/22x22/titleblock-right.png">22x22/titleblock-right.png</file>
<file alias="themes/qet/22x22/transform-scale.png">22x22/transform-scale.png</file>
<file alias="themes/qet/22x22/two_pages.png">22x22/two_pages.png</file>
<file alias="themes/qet/22x22/view-fit-window.png">22x22/view-fit-window.png</file>
<file alias="themes/qet/22x22/view-fullscreen.png">22x22/view-fullscreen.png</file>
<file alias="themes/qet/22x22/view-refresh.png">22x22/view-refresh.png</file>
<file alias="themes/qet/22x22/view-restore.png">22x22/view-restore.png</file>
<file alias="themes/qet/22x22/view_fit_width.png">22x22/view_fit_width.png</file>
<file alias="themes/qet/22x22/window-new.png">22x22/window-new.png</file>
<file alias="themes/qet/22x22/zoom-draw.png">22x22/zoom-draw.png</file>
<file alias="themes/qet/22x22/zoom-fit-best.png">22x22/zoom-fit-best.png</file>
<file alias="themes/qet/22x22/zoom-in.png">22x22/zoom-in.png</file>
<file alias="themes/qet/22x22/zoom-original.png">22x22/zoom-original.png</file>
<file alias="themes/qet/22x22/zoom-out.png">22x22/zoom-out.png</file>
<file alias="themes/qet/32x32/application-pdf.png">32x32/application-pdf.png</file>
<file alias="themes/qet/32x32/format-text-bold.png">32x32/format-text-bold.png</file>
<file alias="themes/qet/32x32/format-text-color.png">32x32/format-text-color.png</file>
<file alias="themes/qet/32x32/format-text-italic.png">32x32/format-text-italic.png</file>
<file alias="themes/qet/32x32/format-text-underline.png">32x32/format-text-underline.png</file>
<file alias="themes/qet/32x32/image-x-eps.png">32x32/image-x-eps.png</file>
<file alias="themes/qet/32x32/insert-link.png">32x32/insert-link.png</file>
<file alias="themes/qet/32x32/printer.png">32x32/printer.png</file>
<file alias="themes/qet/32x32/qt.png">32x32/qt.png</file>
<file alias="themes/qet/32x32/simplifyrichtext.png">32x32/simplifyrichtext.png</file>
<file alias="themes/qet/32x32/text-xml.png">32x32/text-xml.png</file>
<file alias="themes/qet/48x48/document-print-frame.png">48x48/document-print-frame.png</file>
<file alias="themes/qet/48x48/user-away-extended.png">48x48/user-away-extended.png</file>
<file alias="themes/qet/48x48/user-away.png">48x48/user-away.png</file>
<file alias="themes/qet/48x48/view-pim-journal.png">48x48/view-pim-journal.png</file>
<file alias="themes/qet/128x128/diagram.png">128x128/diagram.png</file>
<file alias="themes/qet/128x128/document-export.png">128x128/document-export.png</file>
<file alias="themes/qet/128x128/plasmagik.png">128x128/plasmagik.png</file>
<file alias="themes/qet/128x128/printer.png">128x128/printer.png</file>
<file alias="themes/qet/128x128/project.png">128x128/project.png</file>
<file alias="themes/qet/128x128/settings.png">128x128/settings.png</file>
<file alias="themes/qet/scalable/diagram.svg">scalable/diagram.svg</file>
<file alias="themes/qet/scalable/folio-delete.svg">scalable/folio-delete.svg</file>
<file alias="themes/qet/scalable/folio-new.svg">scalable/folio-new.svg</file>
<file alias="themes/qet/scalable/folio-properties.svg">scalable/folio-properties.svg</file>
<file alias="themes/qet/scalable/label.svg">scalable/label.svg</file>
<file alias="themes/qet/scalable/pdf-import.svg">scalable/pdf-import.svg</file>
<file alias="themes/qet/scalable/edit-opacity.svg">breeze-icons/scalable/apps/hidef/edit-opacity.svg</file>
<file alias="themes/qet/scalable/image-flip-horizontal.svg">breeze-icons/scalable/apps/hidef/image-flip-horizontal-symbolic.svg</file>
<file alias="themes/qet/scalable/image-flip-vertical.svg">breeze-icons/scalable/apps/hidef/image-flip-vertical-symbolic.svg</file>
<file alias="themes/qet/scalable/draw-bezier-curves.svg">breeze-icons/scalable/apps/hidef/draw-bezier-curves.svg</file>
<file alias="themes/qet/scalable/transform-crop.svg">breeze-icons/scalable/apps/hidef/transform-crop.svg</file>
<file alias="themes/qet/scalable/ellipse-to-bezier.svg">generated/ellipse-to-bezier.svg</file>
<file alias="themes/qet/scalable/rect-to-bezier.svg">generated/rect-to-bezier.svg</file>
<file alias="themes/qet/scalable/rect-to-polyline.svg">generated/rect-to-polyline.svg</file>
<file>themes/qet-dark/16x16/arrow-left-double.png</file>
<file>themes/qet-dark/16x16/arrow-left.png</file>
<file>themes/qet-dark/16x16/arrow-right-double.png</file>
<file>themes/qet-dark/16x16/arrow-right.png</file>
<file>themes/qet-dark/16x16/circle.png</file>
<file>themes/qet-dark/16x16/conductor-edit.png</file>
<file>themes/qet-dark/16x16/configure-toolbars.png</file>
<file>themes/qet-dark/16x16/configure.png</file>
<file>themes/qet-dark/16x16/dialog-cancel.png</file>
<file>themes/qet-dark/16x16/dialog-ok.png</file>
<file>themes/qet-dark/16x16/document-export.png</file>
<file>themes/qet-dark/16x16/document-import.png</file>
<file>themes/qet-dark/16x16/document-new.png</file>
<file>themes/qet-dark/16x16/document-open-recent.png</file>
<file>themes/qet-dark/16x16/document-print-frame.png</file>
<file>themes/qet-dark/16x16/document-print.png</file>
<file>themes/qet-dark/16x16/document-save-all.png</file>
<file>themes/qet-dark/16x16/document-save-as.png</file>
<file>themes/qet-dark/16x16/document-save.png</file>
<file>themes/qet-dark/16x16/edit-clear-locationbar-ltr.png</file>
<file>themes/qet-dark/16x16/edit-clear-locationbar-rtl.png</file>
<file>themes/qet-dark/16x16/edit-clear.png</file>
<file>themes/qet-dark/16x16/edit-copy.png</file>
<file>themes/qet-dark/16x16/edit-cut.png</file>
<file>themes/qet-dark/16x16/edit-download.png</file>
<file>themes/qet-dark/16x16/edit-paste.png</file>
<file>themes/qet-dark/16x16/edit-redo.png</file>
<file>themes/qet-dark/16x16/edit-rename.png</file>
<file>themes/qet-dark/16x16/edit-select-all.png</file>
<file>themes/qet-dark/16x16/edit-select-invert.png</file>
<file>themes/qet-dark/16x16/edit-table-cell-merge.png</file>
<file>themes/qet-dark/16x16/edit-undo.png</file>
<file>themes/qet-dark/16x16/element-delete.png</file>
<file>themes/qet-dark/16x16/element-edit.png</file>
<file>themes/qet-dark/16x16/element-new.png</file>
<file>themes/qet-dark/16x16/element.png</file>
<file>themes/qet-dark/16x16/endline-circle.png</file>
<file>themes/qet-dark/16x16/endline-diamond.png</file>
<file>themes/qet-dark/16x16/endline-none.png</file>
<file>themes/qet-dark/16x16/endline-simple.png</file>
<file>themes/qet-dark/16x16/endline-triangle.png</file>
<file>themes/qet-dark/16x16/flip.png</file>
<file>themes/qet-dark/16x16/folder-delete.png</file>
<file>themes/qet-dark/16x16/folder-edit.png</file>
<file>themes/qet-dark/16x16/folder-new.png</file>
<file>themes/qet-dark/16x16/folder-open.png</file>
<file>themes/qet-dark/16x16/folder-show-all.png</file>
<file>themes/qet-dark/16x16/folder.png</file>
<file>themes/qet-dark/16x16/folio-ref-coming.png</file>
<file>themes/qet-dark/16x16/go-company.png</file>
<file>themes/qet-dark/16x16/go-down-double.png</file>
<file>themes/qet-dark/16x16/go-down.png</file>
<file>themes/qet-dark/16x16/go-home.png</file>
<file>themes/qet-dark/16x16/go-up-double.png</file>
<file>themes/qet-dark/16x16/go-up.png</file>
<file>themes/qet-dark/16x16/grid.png</file>
<file>themes/qet-dark/16x16/help-contents.png</file>
<file>themes/qet-dark/16x16/help-donate.png</file>
<file>themes/qet-dark/16x16/item-cancel.png</file>
<file>themes/qet-dark/16x16/item-copy.png</file>
<file>themes/qet-dark/16x16/item-move.png</file>
<file>themes/qet-dark/16x16/kdenlive-show-video.png</file>
<file>themes/qet-dark/16x16/list-add.png</file>
<file>themes/qet-dark/16x16/list-remove.png</file>
<file>themes/qet-dark/16x16/masquer.png</file>
<file>themes/qet-dark/16x16/mirror.png</file>
<file>themes/qet-dark/16x16/move.png</file>
<file>themes/qet-dark/16x16/object-group.png</file>
<file>themes/qet-dark/16x16/object-rotate-right.png</file>
<file>themes/qet-dark/16x16/orientations.png</file>
<file>themes/qet-dark/16x16/preferences-desktop-user.png</file>
<file>themes/qet-dark/16x16/select.png</file>
<file>themes/qet-dark/16x16/table-of-content.png</file>
<file>themes/qet-dark/16x16/terminal.png</file>
<file>themes/qet-dark/16x16/text-xml.png</file>
<file>themes/qet-dark/16x16/transform-rotate.png</file>
<file>themes/qet-dark/16x16/view-fullscreen.png</file>
<file>themes/qet-dark/16x16/view-restore.png</file>
<file>themes/qet-dark/16x16/window-new.png</file>
<file>themes/qet-dark/16x16/zoom-draw.png</file>
<file>themes/qet-dark/16x16/zoom-fit-best.png</file>
<file>themes/qet-dark/16x16/zoom-in.png</file>
<file>themes/qet-dark/16x16/zoom-original.png</file>
<file>themes/qet-dark/16x16/zoom-out.png</file>
<file>themes/qet-dark/22x22/Actions-player-time-icon.png</file>
<file>themes/qet-dark/22x22/all_pages.png</file>
<file>themes/qet-dark/22x22/applications-development-translation.png</file>
<file>themes/qet-dark/22x22/arc.png</file>
<file>themes/qet-dark/22x22/arrow-left-double.png</file>
<file>themes/qet-dark/22x22/arrow-left.png</file>
<file>themes/qet-dark/22x22/arrow-right-double.png</file>
<file>themes/qet-dark/22x22/arrow-right.png</file>
<file>themes/qet-dark/22x22/configure-toolbars.png</file>
<file>themes/qet-dark/22x22/configure.png</file>
<file>themes/qet-dark/22x22/dialog-cancel.png</file>
<file>themes/qet-dark/22x22/dialog-ok.png</file>
<file>themes/qet-dark/22x22/document-export.png</file>
<file>themes/qet-dark/22x22/document-import.png</file>
<file>themes/qet-dark/22x22/document-new.png</file>
<file>themes/qet-dark/22x22/document-open-recent.png</file>
<file>themes/qet-dark/22x22/document-print-frame.png</file>
<file>themes/qet-dark/22x22/document-print.png</file>
<file>themes/qet-dark/22x22/document-save-all.png</file>
<file>themes/qet-dark/22x22/document-save-as.png</file>
<file>themes/qet-dark/22x22/document-save.png</file>
<file>themes/qet-dark/22x22/edit-clear-locationbar-ltr.png</file>
<file>themes/qet-dark/22x22/edit-clear-locationbar-rtl.png</file>
<file>themes/qet-dark/22x22/edit-clear.png</file>
<file>themes/qet-dark/22x22/edit-copy.png</file>
<file>themes/qet-dark/22x22/edit-cut.png</file>
<file>themes/qet-dark/22x22/edit-paste.png</file>
<file>themes/qet-dark/22x22/edit-redo.png</file>
<file>themes/qet-dark/22x22/edit-rename.png</file>
<file>themes/qet-dark/22x22/edit-select-all.png</file>
<file>themes/qet-dark/22x22/edit-table-cell-merge.png</file>
<file>themes/qet-dark/22x22/edit-undo.png</file>
<file>themes/qet-dark/22x22/element-delete.png</file>
<file>themes/qet-dark/22x22/element-edit.png</file>
<file>themes/qet-dark/22x22/element-new.png</file>
<file>themes/qet-dark/22x22/ellipse.png</file>
<file>themes/qet-dark/22x22/folder-delete.png</file>
<file>themes/qet-dark/22x22/folder-edit.png</file>
<file>themes/qet-dark/22x22/folder-new.png</file>
<file>themes/qet-dark/22x22/folder-open.png</file>
<file>themes/qet-dark/22x22/go-company.png</file>
<file>themes/qet-dark/22x22/go-down.png</file>
<file>themes/qet-dark/22x22/go-home.png</file>
<file>themes/qet-dark/22x22/go-up.png</file>
<file>themes/qet-dark/22x22/grid.png</file>
<file>themes/qet-dark/22x22/insert-image.png</file>
<file>themes/qet-dark/22x22/landscape.png</file>
<file>themes/qet-dark/22x22/line.png</file>
<file>themes/qet-dark/22x22/list-add.png</file>
<file>themes/qet-dark/22x22/list-remove.png</file>
<file>themes/qet-dark/22x22/lower.png</file>
<file>themes/qet-dark/22x22/move.png</file>
<file>themes/qet-dark/22x22/names.png</file>
<file>themes/qet-dark/22x22/object-locked.png</file>
<file>themes/qet-dark/22x22/object-rotate-right.png</file>
<file>themes/qet-dark/22x22/object-unlocked.png</file>
<file>themes/qet-dark/22x22/polygon.png</file>
<file>themes/qet-dark/22x22/portrait.png</file>
<file>themes/qet-dark/22x22/preferences-desktop-user.png</file>
<file>themes/qet-dark/22x22/raise.png</file>
<file>themes/qet-dark/22x22/rectangle.png</file>
<file>themes/qet-dark/22x22/restaurer.png</file>
<file>themes/qet-dark/22x22/select.png</file>
<file>themes/qet-dark/22x22/single_page.png</file>
<file>themes/qet-dark/22x22/start.png</file>
<file>themes/qet-dark/22x22/text-xml.png</file>
<file>themes/qet-dark/22x22/text.png</file>
<file>themes/qet-dark/22x22/textfield.png</file>
<file>themes/qet-dark/22x22/transform-scale.png</file>
<file>themes/qet-dark/22x22/two_pages.png</file>
<file>themes/qet-dark/22x22/view-fit-window.png</file>
<file>themes/qet-dark/22x22/view-fullscreen.png</file>
<file>themes/qet-dark/22x22/view-restore.png</file>
<file>themes/qet-dark/22x22/view_fit_width.png</file>
<file>themes/qet-dark/22x22/window-new.png</file>
<file>themes/qet-dark/22x22/zoom-draw.png</file>
<file>themes/qet-dark/22x22/zoom-fit-best.png</file>
<file>themes/qet-dark/22x22/zoom-in.png</file>
<file>themes/qet-dark/22x22/zoom-original.png</file>
<file>themes/qet-dark/22x22/zoom-out.png</file>
<file>themes/qet-dark/32x32/format-text-bold.png</file>
<file>themes/qet-dark/32x32/format-text-color.png</file>
<file>themes/qet-dark/32x32/format-text-italic.png</file>
<file>themes/qet-dark/32x32/format-text-underline.png</file>
<file>themes/qet-dark/32x32/insert-link.png</file>
<file>themes/qet-dark/32x32/printer.png</file>
<file>themes/qet-dark/32x32/text-xml.png</file>
<file>themes/qet-dark/48x48/user-away-extended.png</file>
<file>themes/qet-dark/48x48/user-away.png</file>
<file>themes/qet-dark/48x48/view-pim-journal.png</file>
<file>themes/qet-dark/128x128/plasmagik.png</file>
<file>themes/qet-dark/128x128/settings.png</file>
<file>themes/qet-dark/scalable/diagram.svg</file>
<file>themes/qet-dark/scalable/folio-delete.svg</file>
<file>themes/qet-dark/scalable/folio-new.svg</file>
<file>themes/qet-dark/scalable/folio-properties.svg</file>
<file>themes/qet-dark/scalable/label.svg</file>
<file>themes/qet-dark/scalable/pdf-import.svg</file>
<file>themes/qet-dark/scalable/edit-opacity.svg</file>
<file>themes/qet-dark/scalable/image-flip-horizontal.svg</file>
<file>themes/qet-dark/scalable/image-flip-vertical.svg</file>
<file>themes/qet-dark/scalable/draw-bezier-curves.svg</file>
<file>themes/qet-dark/scalable/transform-crop.svg</file>
<file>themes/qet-dark/scalable/ellipse-to-bezier.svg</file>
<file>themes/qet-dark/scalable/rect-to-bezier.svg</file>
<file>themes/qet-dark/scalable/rect-to-polyline.svg</file>
</qresource>
</RCC>
+12
View File
@@ -0,0 +1,12 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">
.ColorScheme-Text {
color:#4d4d4d;
}
</style>
</defs>
<g transform="translate(1,1)">
<path style="fill:currentColor;fill-opacity:1;stroke:none" d="M 3 5 h 1 v 1 h -1 Z M 3 6 h 1 v 1 h -1 Z M 3 7 h 1 v 1 h -1 Z M 3 8 h 1 v 1 h -1 Z M 3 9 h 1 v 1 h -1 Z M 3 10 h 1 v 1 h -1 Z M 3 11 h 1 v 1 h -1 Z M 3 12 h 1 v 1 h -1 Z M 3 13 h 1 v 1 h -1 Z M 3 14 h 1 v 1 h -1 Z M 3 15 h 1 v 1 h -1 Z M 3 16 h 1 v 1 h -1 Z M 4 5 h 1 v 1 h -1 Z M 4 13 h 1 v 1 h -1 Z M 4 16 h 1 v 1 h -1 Z M 5 5 h 1 v 1 h -1 Z M 5 13 h 1 v 1 h -1 Z M 5 16 h 1 v 1 h -1 Z M 6 5 h 1 v 1 h -1 Z M 6 13 h 1 v 1 h -1 Z M 6 16 h 1 v 1 h -1 Z M 7 5 h 1 v 1 h -1 Z M 7 13 h 1 v 1 h -1 Z M 7 16 h 1 v 1 h -1 Z M 8 5 h 1 v 1 h -1 Z M 8 13 h 1 v 1 h -1 Z M 8 16 h 1 v 1 h -1 Z M 9 5 h 1 v 1 h -1 Z M 9 13 h 1 v 1 h -1 Z M 9 16 h 1 v 1 h -1 Z M 10 5 h 1 v 1 h -1 Z M 10 13 h 1 v 1 h -1 Z M 10 16 h 1 v 1 h -1 Z M 11 5 h 1 v 1 h -1 Z M 11 13 h 1 v 1 h -1 Z M 11 14 h 1 v 1 h -1 Z M 11 15 h 1 v 1 h -1 Z M 11 16 h 1 v 1 h -1 Z M 12 5 h 1 v 1 h -1 Z M 12 13 h 1 v 1 h -1 Z M 12 16 h 1 v 1 h -1 Z M 13 5 h 1 v 1 h -1 Z M 13 13 h 1 v 1 h -1 Z M 13 16 h 1 v 1 h -1 Z M 14 5 h 1 v 1 h -1 Z M 14 13 h 1 v 1 h -1 Z M 14 16 h 1 v 1 h -1 Z M 15 5 h 1 v 1 h -1 Z M 15 13 h 1 v 1 h -1 Z M 15 16 h 1 v 1 h -1 Z M 16 5 h 1 v 1 h -1 Z M 16 13 h 1 v 1 h -1 Z M 16 16 h 1 v 1 h -1 Z M 17 5 h 1 v 1 h -1 Z M 17 13 h 1 v 1 h -1 Z M 17 16 h 1 v 1 h -1 Z M 18 5 h 1 v 1 h -1 Z M 18 6 h 1 v 1 h -1 Z M 18 7 h 1 v 1 h -1 Z M 18 8 h 1 v 1 h -1 Z M 18 9 h 1 v 1 h -1 Z M 18 10 h 1 v 1 h -1 Z M 18 11 h 1 v 1 h -1 Z M 18 12 h 1 v 1 h -1 Z M 18 13 h 1 v 1 h -1 Z M 18 14 h 1 v 1 h -1 Z M 18 15 h 1 v 1 h -1 Z M 18 16 h 1 v 1 h -1 Z" class="ColorScheme-Text"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

+12
View File
@@ -0,0 +1,12 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">
.ColorScheme-Text {
color:#4d4d4d;
}
</style>
</defs>
<g transform="translate(1,1)">
<path style="fill:currentColor;fill-opacity:1;stroke:none" d="M 3 5 h 1 v 1 h -1 Z M 3 6 h 1 v 1 h -1 Z M 3 7 h 1 v 1 h -1 Z M 3 8 h 1 v 1 h -1 Z M 3 9 h 1 v 1 h -1 Z M 3 10 h 1 v 1 h -1 Z M 3 11 h 1 v 1 h -1 Z M 3 12 h 1 v 1 h -1 Z M 3 13 h 1 v 1 h -1 Z M 3 14 h 1 v 1 h -1 Z M 3 15 h 1 v 1 h -1 Z M 3 16 h 1 v 1 h -1 Z M 4 5 h 1 v 1 h -1 Z M 4 13 h 1 v 1 h -1 Z M 4 16 h 1 v 1 h -1 Z M 5 5 h 1 v 1 h -1 Z M 5 13 h 1 v 1 h -1 Z M 5 16 h 1 v 1 h -1 Z M 6 5 h 1 v 1 h -1 Z M 6 13 h 1 v 1 h -1 Z M 6 16 h 1 v 1 h -1 Z M 7 5 h 1 v 1 h -1 Z M 7 13 h 1 v 1 h -1 Z M 7 16 h 1 v 1 h -1 Z M 8 5 h 1 v 1 h -1 Z M 8 13 h 1 v 1 h -1 Z M 8 16 h 1 v 1 h -1 Z M 9 5 h 1 v 1 h -1 Z M 9 13 h 1 v 1 h -1 Z M 9 16 h 1 v 1 h -1 Z M 10 5 h 1 v 1 h -1 Z M 10 13 h 1 v 1 h -1 Z M 10 16 h 1 v 1 h -1 Z M 11 5 h 1 v 1 h -1 Z M 11 13 h 1 v 1 h -1 Z M 11 14 h 1 v 1 h -1 Z M 11 15 h 1 v 1 h -1 Z M 11 16 h 1 v 1 h -1 Z M 12 5 h 1 v 1 h -1 Z M 12 13 h 1 v 1 h -1 Z M 12 16 h 1 v 1 h -1 Z M 13 5 h 1 v 1 h -1 Z M 14 5 h 1 v 1 h -1 Z M 14 17 h 1 v 1 h -1 Z M 15 5 h 1 v 1 h -1 Z M 15 17 h 1 v 1 h -1 Z M 16 5 h 1 v 1 h -1 Z M 16 17 h 1 v 1 h -1 Z M 17 5 h 1 v 1 h -1 Z M 17 17 h 1 v 1 h -1 Z M 18 5 h 1 v 1 h -1 Z M 18 6 h 1 v 1 h -1 Z M 18 7 h 1 v 1 h -1 Z M 18 8 h 1 v 1 h -1 Z M 18 9 h 1 v 1 h -1 Z M 18 10 h 1 v 1 h -1 Z M 18 11 h 1 v 1 h -1 Z M 18 12 h 1 v 1 h -1 Z M 18 17 h 1 v 1 h -1 Z M 19 17 h 1 v 1 h -1 Z" class="ColorScheme-Text"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

+12
View File
@@ -0,0 +1,12 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">
.ColorScheme-Text {
color:#4d4d4d;
}
</style>
</defs>
<g transform="translate(1,1)">
<path style="fill:currentColor;fill-opacity:1;stroke:none" d="M 3 5 h 1 v 1 h -1 Z M 3 6 h 1 v 1 h -1 Z M 3 7 h 1 v 1 h -1 Z M 3 8 h 1 v 1 h -1 Z M 3 9 h 1 v 1 h -1 Z M 3 10 h 1 v 1 h -1 Z M 3 11 h 1 v 1 h -1 Z M 3 12 h 1 v 1 h -1 Z M 3 13 h 1 v 1 h -1 Z M 3 14 h 1 v 1 h -1 Z M 3 15 h 1 v 1 h -1 Z M 3 16 h 1 v 1 h -1 Z M 4 5 h 1 v 1 h -1 Z M 4 13 h 1 v 1 h -1 Z M 4 16 h 1 v 1 h -1 Z M 5 5 h 1 v 1 h -1 Z M 5 13 h 1 v 1 h -1 Z M 5 16 h 1 v 1 h -1 Z M 6 5 h 1 v 1 h -1 Z M 6 13 h 1 v 1 h -1 Z M 6 16 h 1 v 1 h -1 Z M 7 5 h 1 v 1 h -1 Z M 7 13 h 1 v 1 h -1 Z M 7 16 h 1 v 1 h -1 Z M 8 5 h 1 v 1 h -1 Z M 8 13 h 1 v 1 h -1 Z M 8 16 h 1 v 1 h -1 Z M 9 5 h 1 v 1 h -1 Z M 9 13 h 1 v 1 h -1 Z M 9 16 h 1 v 1 h -1 Z M 10 5 h 1 v 1 h -1 Z M 10 13 h 1 v 1 h -1 Z M 10 16 h 1 v 1 h -1 Z M 11 5 h 1 v 1 h -1 Z M 11 13 h 1 v 1 h -1 Z M 11 14 h 1 v 1 h -1 Z M 11 15 h 1 v 1 h -1 Z M 11 16 h 1 v 1 h -1 Z M 12 5 h 1 v 1 h -1 Z M 12 13 h 1 v 1 h -1 Z M 12 16 h 1 v 1 h -1 Z M 13 5 h 1 v 1 h -1 Z M 14 5 h 1 v 1 h -1 Z M 14 17 h 1 v 1 h -1 Z M 15 5 h 1 v 1 h -1 Z M 15 17 h 1 v 1 h -1 Z M 16 5 h 1 v 1 h -1 Z M 16 17 h 1 v 1 h -1 Z M 17 5 h 1 v 1 h -1 Z M 17 14 h 1 v 1 h -1 Z M 17 15 h 1 v 1 h -1 Z M 17 16 h 1 v 1 h -1 Z M 17 17 h 1 v 1 h -1 Z M 17 18 h 1 v 1 h -1 Z M 17 19 h 1 v 1 h -1 Z M 18 5 h 1 v 1 h -1 Z M 18 6 h 1 v 1 h -1 Z M 18 7 h 1 v 1 h -1 Z M 18 8 h 1 v 1 h -1 Z M 18 9 h 1 v 1 h -1 Z M 18 10 h 1 v 1 h -1 Z M 18 11 h 1 v 1 h -1 Z M 18 12 h 1 v 1 h -1 Z M 18 17 h 1 v 1 h -1 Z M 19 17 h 1 v 1 h -1 Z" class="ColorScheme-Text"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

+12
View File
@@ -0,0 +1,12 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">
.ColorScheme-Text {
color:#4d4d4d;
}
</style>
</defs>
<g transform="translate(1,1)">
<path style="fill:currentColor;fill-opacity:1;stroke:none" d="M 3 5 h 1 v 1 h -1 Z M 3 6 h 1 v 1 h -1 Z M 3 7 h 1 v 1 h -1 Z M 3 8 h 1 v 1 h -1 Z M 3 9 h 1 v 1 h -1 Z M 3 10 h 1 v 1 h -1 Z M 3 11 h 1 v 1 h -1 Z M 3 12 h 1 v 1 h -1 Z M 3 13 h 1 v 1 h -1 Z M 3 14 h 1 v 1 h -1 Z M 3 15 h 1 v 1 h -1 Z M 3 16 h 1 v 1 h -1 Z M 4 5 h 1 v 1 h -1 Z M 4 13 h 1 v 1 h -1 Z M 4 16 h 1 v 1 h -1 Z M 5 5 h 1 v 1 h -1 Z M 5 13 h 1 v 1 h -1 Z M 5 16 h 1 v 1 h -1 Z M 6 5 h 1 v 1 h -1 Z M 6 8 h 1 v 1 h -1 Z M 6 10 h 1 v 1 h -1 Z M 6 13 h 1 v 1 h -1 Z M 6 16 h 1 v 1 h -1 Z M 7 5 h 1 v 1 h -1 Z M 7 8 h 1 v 1 h -1 Z M 7 10 h 1 v 1 h -1 Z M 7 13 h 1 v 1 h -1 Z M 7 16 h 1 v 1 h -1 Z M 8 5 h 1 v 1 h -1 Z M 8 8 h 1 v 1 h -1 Z M 8 10 h 1 v 1 h -1 Z M 8 13 h 1 v 1 h -1 Z M 8 16 h 1 v 1 h -1 Z M 9 5 h 1 v 1 h -1 Z M 9 8 h 1 v 1 h -1 Z M 9 10 h 1 v 1 h -1 Z M 9 13 h 1 v 1 h -1 Z M 9 16 h 1 v 1 h -1 Z M 10 5 h 1 v 1 h -1 Z M 10 8 h 1 v 1 h -1 Z M 10 10 h 1 v 1 h -1 Z M 10 13 h 1 v 1 h -1 Z M 10 16 h 1 v 1 h -1 Z M 11 5 h 1 v 1 h -1 Z M 11 8 h 1 v 1 h -1 Z M 11 10 h 1 v 1 h -1 Z M 11 13 h 1 v 1 h -1 Z M 11 14 h 1 v 1 h -1 Z M 11 15 h 1 v 1 h -1 Z M 11 16 h 1 v 1 h -1 Z M 12 5 h 1 v 1 h -1 Z M 12 8 h 1 v 1 h -1 Z M 12 10 h 1 v 1 h -1 Z M 12 13 h 1 v 1 h -1 Z M 12 16 h 1 v 1 h -1 Z M 13 5 h 1 v 1 h -1 Z M 13 8 h 1 v 1 h -1 Z M 13 10 h 1 v 1 h -1 Z M 13 13 h 1 v 1 h -1 Z M 13 16 h 1 v 1 h -1 Z M 14 5 h 1 v 1 h -1 Z M 14 8 h 1 v 1 h -1 Z M 14 10 h 1 v 1 h -1 Z M 14 13 h 1 v 1 h -1 Z M 14 16 h 1 v 1 h -1 Z M 15 5 h 1 v 1 h -1 Z M 15 8 h 1 v 1 h -1 Z M 15 10 h 1 v 1 h -1 Z M 15 13 h 1 v 1 h -1 Z M 15 16 h 1 v 1 h -1 Z M 16 5 h 1 v 1 h -1 Z M 16 13 h 1 v 1 h -1 Z M 16 16 h 1 v 1 h -1 Z M 17 5 h 1 v 1 h -1 Z M 17 13 h 1 v 1 h -1 Z M 17 16 h 1 v 1 h -1 Z M 18 5 h 1 v 1 h -1 Z M 18 6 h 1 v 1 h -1 Z M 18 7 h 1 v 1 h -1 Z M 18 8 h 1 v 1 h -1 Z M 18 9 h 1 v 1 h -1 Z M 18 10 h 1 v 1 h -1 Z M 18 11 h 1 v 1 h -1 Z M 18 12 h 1 v 1 h -1 Z M 18 13 h 1 v 1 h -1 Z M 18 14 h 1 v 1 h -1 Z M 18 15 h 1 v 1 h -1 Z M 18 16 h 1 v 1 h -1 Z" class="ColorScheme-Text"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

+12
View File
@@ -0,0 +1,12 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">
.ColorScheme-Text {
color:#4d4d4d;
}
</style>
</defs>
<g transform="translate(1,1)">
<path style="fill:currentColor;fill-opacity:1;stroke:none" d="M 3 5 h 1 v 1 h -1 Z M 3 6 h 1 v 1 h -1 Z M 3 7 h 1 v 1 h -1 Z M 3 8 h 1 v 1 h -1 Z M 3 9 h 1 v 1 h -1 Z M 3 10 h 1 v 1 h -1 Z M 3 11 h 1 v 1 h -1 Z M 3 12 h 1 v 1 h -1 Z M 3 13 h 1 v 1 h -1 Z M 3 14 h 1 v 1 h -1 Z M 3 15 h 1 v 1 h -1 Z M 3 16 h 1 v 1 h -1 Z M 4 5 h 1 v 1 h -1 Z M 4 13 h 1 v 1 h -1 Z M 4 14 h 1 v 1 h -1 Z M 4 15 h 1 v 1 h -1 Z M 4 16 h 1 v 1 h -1 Z M 5 5 h 1 v 1 h -1 Z M 5 13 h 1 v 1 h -1 Z M 5 14 h 1 v 1 h -1 Z M 5 15 h 1 v 1 h -1 Z M 5 16 h 1 v 1 h -1 Z M 6 5 h 1 v 1 h -1 Z M 6 13 h 1 v 1 h -1 Z M 6 14 h 1 v 1 h -1 Z M 6 15 h 1 v 1 h -1 Z M 6 16 h 1 v 1 h -1 Z M 7 5 h 1 v 1 h -1 Z M 7 13 h 1 v 1 h -1 Z M 7 14 h 1 v 1 h -1 Z M 7 15 h 1 v 1 h -1 Z M 7 16 h 1 v 1 h -1 Z M 8 5 h 1 v 1 h -1 Z M 8 13 h 1 v 1 h -1 Z M 8 14 h 1 v 1 h -1 Z M 8 15 h 1 v 1 h -1 Z M 8 16 h 1 v 1 h -1 Z M 9 5 h 1 v 1 h -1 Z M 9 13 h 1 v 1 h -1 Z M 9 14 h 1 v 1 h -1 Z M 9 15 h 1 v 1 h -1 Z M 9 16 h 1 v 1 h -1 Z M 10 5 h 1 v 1 h -1 Z M 10 13 h 1 v 1 h -1 Z M 10 14 h 1 v 1 h -1 Z M 10 15 h 1 v 1 h -1 Z M 10 16 h 1 v 1 h -1 Z M 11 5 h 1 v 1 h -1 Z M 11 13 h 1 v 1 h -1 Z M 11 14 h 1 v 1 h -1 Z M 11 15 h 1 v 1 h -1 Z M 11 16 h 1 v 1 h -1 Z M 12 5 h 1 v 1 h -1 Z M 12 13 h 1 v 1 h -1 Z M 12 14 h 1 v 1 h -1 Z M 12 15 h 1 v 1 h -1 Z M 12 16 h 1 v 1 h -1 Z M 13 5 h 1 v 1 h -1 Z M 13 13 h 1 v 1 h -1 Z M 13 14 h 1 v 1 h -1 Z M 13 15 h 1 v 1 h -1 Z M 13 16 h 1 v 1 h -1 Z M 14 5 h 1 v 1 h -1 Z M 14 13 h 1 v 1 h -1 Z M 14 14 h 1 v 1 h -1 Z M 14 15 h 1 v 1 h -1 Z M 14 16 h 1 v 1 h -1 Z M 15 5 h 1 v 1 h -1 Z M 15 13 h 1 v 1 h -1 Z M 15 14 h 1 v 1 h -1 Z M 15 15 h 1 v 1 h -1 Z M 15 16 h 1 v 1 h -1 Z M 16 5 h 1 v 1 h -1 Z M 16 13 h 1 v 1 h -1 Z M 16 14 h 1 v 1 h -1 Z M 16 15 h 1 v 1 h -1 Z M 16 16 h 1 v 1 h -1 Z M 17 5 h 1 v 1 h -1 Z M 17 13 h 1 v 1 h -1 Z M 17 14 h 1 v 1 h -1 Z M 17 15 h 1 v 1 h -1 Z M 17 16 h 1 v 1 h -1 Z M 18 5 h 1 v 1 h -1 Z M 18 6 h 1 v 1 h -1 Z M 18 7 h 1 v 1 h -1 Z M 18 8 h 1 v 1 h -1 Z M 18 9 h 1 v 1 h -1 Z M 18 10 h 1 v 1 h -1 Z M 18 11 h 1 v 1 h -1 Z M 18 12 h 1 v 1 h -1 Z M 18 13 h 1 v 1 h -1 Z M 18 14 h 1 v 1 h -1 Z M 18 15 h 1 v 1 h -1 Z M 18 16 h 1 v 1 h -1 Z" class="ColorScheme-Text"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

+13
View File
@@ -0,0 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">
.ColorScheme-Text {
color:#4d4d4d;
}
</style>
</defs>
<g transform="translate(1,1)">
<path style="fill:currentColor;fill-opacity:1;stroke:none" d="M 3 3 h 16 v 1 h -16 Z M 3 4 h 1 v 15 h -1 Z M 4 18 h 10 v 1 h -10 Z M 18 4 h 1 v 8 h -1 Z M 16 14 h 1 v 5 h -1 Z M 14 16 h 5 v 1 h -5 Z" class="ColorScheme-Text"/>
<path style="fill:currentColor;fill-opacity:1;stroke:none" d="M 5 7 h 1 v 1 h -1 Z M 6 7 h 1 v 1 h -1 Z M 7 7 h 1 v 1 h -1 Z M 5 8 h 1 v 1 h -1 Z M 7 8 h 1 v 1 h -1 Z M 5 9 h 1 v 1 h -1 Z M 6 9 h 1 v 1 h -1 Z M 7 9 h 1 v 1 h -1 Z M 5 10 h 1 v 1 h -1 Z M 5 11 h 1 v 1 h -1 Z M 9 7 h 1 v 1 h -1 Z M 10 7 h 1 v 1 h -1 Z M 9 8 h 1 v 1 h -1 Z M 11 8 h 1 v 1 h -1 Z M 9 9 h 1 v 1 h -1 Z M 11 9 h 1 v 1 h -1 Z M 9 10 h 1 v 1 h -1 Z M 11 10 h 1 v 1 h -1 Z M 9 11 h 1 v 1 h -1 Z M 10 11 h 1 v 1 h -1 Z M 13 7 h 1 v 1 h -1 Z M 14 7 h 1 v 1 h -1 Z M 15 7 h 1 v 1 h -1 Z M 13 8 h 1 v 1 h -1 Z M 13 9 h 1 v 1 h -1 Z M 14 9 h 1 v 1 h -1 Z M 13 10 h 1 v 1 h -1 Z M 13 11 h 1 v 1 h -1 Z" class="ColorScheme-Text"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 359 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 391 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 297 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 297 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 337 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 324 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 409 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 453 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 453 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 469 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 391 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 437 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 533 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 394 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 334 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 399 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 B

Some files were not shown because too many files have changed in this diff Show More