Compare commits

...

44 commits

Author SHA1 Message Date
Anton Thomasson
38975d1f64 Fix pkgconfig includes 2023-03-04 13:27:38 +01:00
Anton Thomasson
53f458d71a Fix exec in .desktop 2023-03-04 12:58:51 +01:00
Anton Thomasson
f138f0b89d Add missing files 2023-03-04 12:41:12 +01:00
Anton Thomasson
1d71f3477a Enforce legacy compression for rpm 2023-03-04 12:20:13 +01:00
Anton Thomasson
2d0d61f3e5 Update german translation.
Partially based on #77
2023-03-04 12:12:02 +01:00
Anton Thomasson
1905cec933 Improve integer input hints/labels 2023-02-25 16:15:45 +01:00
Anton Thomasson
912bc36dad Remove empty translations 2023-02-25 14:51:45 +01:00
Anton Thomasson
317a864ff6 Add net.attah.seaprint DBus methods 2023-02-20 20:45:20 +01:00
Anton Thomasson
d473d23d55 Support getting text data from dbus in PlatformData 2023-02-19 21:14:09 +01:00
Anton Thomasson
29c5bbf62b Make it DBusActivatable 2023-02-19 17:08:46 +01:00
Anton Thomasson
e4038db1b0 Update copyright year 2023-01-31 21:34:20 +01:00
Anton Thomasson
fce00048ef Adjust label text size 2023-01-29 15:47:38 +01:00
Anton Thomasson
62bcecccbe Add basic label printer support 2023-01-29 13:47:43 +01:00
Anton Thomasson
d3bc294f0a Sync submodules 2023-01-16 20:35:43 +01:00
Anton Thomasson
5d5e86dc6b Fix image-to-pdf in flowchart, break apart pdf2printable and ppm2pwg boxes 2022-12-17 20:51:01 +01:00
Anton Thomasson
3045244c71 Update README.md 2022-12-17 17:46:08 +01:00
Anton Thomasson
3aad66c714 Adjust format flowchart 2022-12-17 17:35:17 +01:00
Anton Thomasson
31bfd08fae Add format flowchart 2022-12-17 17:19:19 +01:00
Anton Thomasson
6f4d602456 Fix advanced page range input 2022-11-17 20:21:43 +01:00
Anton Thomasson
3d8ade0bef Sync submodules 2022-10-22 13:24:22 +02:00
Anton Thomasson
7a144471e3 Fix German translation 2022-10-22 13:22:36 +02:00
wheelseal
5433d81764 Update harbour-seaprint-de.ts
Update harbour-seaprint-de.ts

Update harbour-seaprint-de.ts

Update harbour-seaprint-de.ts

Update harbour-seaprint-de.ts

Update harbour-seaprint-de.ts

Update harbour-seaprint-de.ts

Update harbour-seaprint-de.ts

Update harbour-seaprint-de.ts

Update harbour-seaprint-de.ts

Update harbour-seaprint-de.ts

Update harbour-seaprint-de.ts

Update harbour-seaprint-de.ts

Is Line 5146-5149 needed?

Update the German Translation

Line 1381 + 1386: I don´t know this format, sorry.

missing changes of update German translation

You are right. My two different translations of Hagaki was a bit confusing. But so many lines... so I forgot that I had translated it before.
2022-10-22 13:11:32 +02:00
Anton Thomasson
a51061df7c Hide identify-menu if empty 2022-08-27 11:17:06 +02:00
Anton Thomasson
741bdd7724 Sync submodules 2022-08-19 20:25:24 +02:00
Anton Thomasson
f9b740c94b Ensure increasing page range list 2022-08-19 18:32:06 +02:00
Anton Thomasson
371c06b430 Sync submodules 2022-08-19 18:30:29 +02:00
Anton Thomasson
38d5a95982 Reset position for decoded answer when passed as failure response 2022-08-13 21:02:00 +02:00
Anton Thomasson
ac84fe079e Use PrintParameters for paper sizes 2022-08-13 20:04:10 +02:00
Anton Thomasson
53ca370f92 Add advanced page ranges (list of ranges) 2022-08-13 16:35:03 +02:00
Anton Thomasson
3abd1e103f Enable encoding 1-set-of 2022-08-13 16:34:00 +02:00
Anton Thomasson
8712ee6eea Remove unneccessary function argument 2022-08-13 12:10:40 +02:00
Anton Thomasson
9287da53aa Move some raster compensation to where it belongs 2022-08-01 20:30:22 +02:00
Anton Thomasson
6a06fa5ffd Add support for client-side copies 2022-07-31 22:08:54 +02:00
Anton Thomasson
b7aeb097a3 Optimize raster logic a bit 2022-07-31 19:47:45 +02:00
Anton Thomasson
b70be18897 Sync submodules 2022-07-29 14:07:24 +02:00
Anton Thomasson
15cae28413 Improve PrinterWorker threading
Let PrinterWorker own its thread.
Don't access IppPrinter from PrinterWorker.
2022-07-20 15:18:49 +02:00
Anton Thomasson
5f71f2dd64 Add optional job-id to prioritized/sorted operation attributes
Some printers are really picky...
2022-07-18 22:27:39 +02:00
Anton Thomasson
51c90e6443 Add two-stage create/send print job support 2022-07-17 17:28:03 +02:00
Anton Thomasson
d037600d0f Don't use chunked encoding when there is no document 2022-07-17 17:28:03 +02:00
Anton Thomasson
d094db4d89 Update translation credits 2022-07-17 17:07:41 +02:00
archon
515d3944e7
Update harbour-seaprint-pl.ts (#69)
* Update harbour-seaprint-pl.ts

Improved polish translation - I have filled the blanks.
2022-07-17 17:05:16 +02:00
Anton Thomasson
31cdaf0939 Mark some empty translations unfinished 2022-07-13 10:11:02 +02:00
Anton Thomasson
2cd0bb2812 Fix binary installation directive 2022-07-12 14:57:23 +02:00
Anton Thomasson
445cc19b10 Improve rpm spec 2022-07-12 10:47:39 +02:00
45 changed files with 2903 additions and 1837 deletions

View file

@ -20,7 +20,7 @@ For PDFs, your printer needs to support one of the following formats:
For Postscript, your printer needs to support Postscript natively. (SeaPrint just sends it as-is)
For Plaintext, SeaPrint can render it to PDF internally and then the requirements follow those of PDF.
You can also send Plaintext to supporting printers and leave the rendering up to the printer (SeaPrint will strip leading and trailing Form Feed characters and ensure CR-NL newlines, but not do any reflow or similar). Since rendering will differ between printers, this has lowest priority for automatic format selection.
You can also send Plaintext to supporting printers and leave the rendering up to the printer (SeaPrint will strip leading and trailing Form Feed characters and ensure CR+LF newlines, but not do any reflow or similar). Since rendering will differ between printers, this has lowest priority for automatic format selection.
For printing "Office" files, like .doc(x) and odt, you need to install
`calligraconverter` (from the `calligra` package in Sailfish OS 4.2 onwards).
@ -41,6 +41,12 @@ For printing JPEG images, transferring them as JPEG has highest priority.
JPEGs are then (losslessly) re-encoded to the baseline encoding profile to work with all printers (since SeaPrint 1.1).
For other image formats JPEG has lowest priority as transfer format since it is lossy.
![Format flowchart](doc/pipeline.svg)
Flowchart made with [GoAT](https://github.com/blampe/goat).
pdf2printable, ppm2pwg and baselinify were made especially for SeaPrint and can be found [here](https://github.com/attah/ppm2pwg).
Printers with any of these IPP certifications and derivative standards should likely be supported:
* IPP Everywhere

27
doc/pipeline.goat Normal file
View file

@ -0,0 +1,27 @@
Normal flow:
.---------------.
PDF -------------------------------------------->| +----------------------> PDF 1.5
.-----------------. | |
Plaintext ---->| QTextDocument +------------------>| pdf2printable +----------------------> Postscript 2
'-----------------' | |
DOC/PPT .-------------------. | (Poppler+Cairo) | .---------.
ODT/ODP ---->| Calligraconverter +---------------->| | | |
| (optional) | | +---->| +----> PWG-Raster
'-------------------' .--------. | | | ppm2pwg |
Images --------------------------->| +---->| | | +----> URF-Raster
| | '---------------' | |
| QImage +---------------------------->| |
.--------------. | | '---------'
SVG ---->| QSvgRenderer +---->| +----------------------------------------------> PNG, JPEG,
'--------------' '--------' Reverse BMP
If target format is the same:
Postscript --------------------------------------------------------------------------------------> Postscript
.-----------------------.
Plaintext ---->| ensure CR+LF newlines +------------------------------------------------------> Plaintext
'-----------------------'
PNG --------------------------------------------------------------------------------------> PNG
.------------.
JPEG ---->| baselinify +-----------------------------------------------------------------> JPEG
'------------' (Baseline profile)

444
doc/pipeline.svg Normal file
View file

@ -0,0 +1,444 @@
<svg xmlns='http://www.w3.org/2000/svg' version='1.1' height='441' width='976' font-family='Menlo,Lucida Console,monospace'>
<style type="text/css">
svg {
color: #000000;
}
@media (prefers-color-scheme: dark) {
svg {
color: #FFFFFF;
}
}
</style>
<g transform='translate(8,16)'>
<path d='M 496,16 L 608,16' fill='none' stroke='currentColor'></path>
<path d='M 120,32 L 472,32' fill='none' stroke='currentColor'></path>
<path d='M 624,32 L 808,32' fill='none' stroke='currentColor'></path>
<path d='M 176,48 L 304,48' fill='none' stroke='currentColor'></path>
<path d='M 120,64 L 152,64' fill='none' stroke='currentColor'></path>
<path d='M 320,64 L 472,64' fill='none' stroke='currentColor'></path>
<path d='M 624,64 L 808,64' fill='none' stroke='currentColor'></path>
<path d='M 176,80 L 304,80' fill='none' stroke='currentColor'></path>
<path d='M 176,96 L 320,96' fill='none' stroke='currentColor'></path>
<path d='M 688,96 L 752,96' fill='none' stroke='currentColor'></path>
<path d='M 120,112 L 152,112' fill='none' stroke='currentColor'></path>
<path d='M 336,112 L 472,112' fill='none' stroke='currentColor'></path>
<path d='M 624,128 L 664,128' fill='none' stroke='currentColor'></path>
<path d='M 768,128 L 808,128' fill='none' stroke='currentColor'></path>
<path d='M 176,144 L 320,144' fill='none' stroke='currentColor'></path>
<path d='M 360,144 L 416,144' fill='none' stroke='currentColor'></path>
<path d='M 120,160 L 336,160' fill='none' stroke='currentColor'></path>
<path d='M 432,160 L 472,160' fill='none' stroke='currentColor'></path>
<path d='M 768,160 L 808,160' fill='none' stroke='currentColor'></path>
<path d='M 496,176 L 608,176' fill='none' stroke='currentColor'></path>
<path d='M 432,192 L 664,192' fill='none' stroke='currentColor'></path>
<path d='M 176,208 L 280,208' fill='none' stroke='currentColor'></path>
<path d='M 688,208 L 752,208' fill='none' stroke='currentColor'></path>
<path d='M 120,224 L 152,224' fill='none' stroke='currentColor'></path>
<path d='M 296,224 L 336,224' fill='none' stroke='currentColor'></path>
<path d='M 432,224 L 808,224' fill='none' stroke='currentColor'></path>
<path d='M 176,240 L 280,240' fill='none' stroke='currentColor'></path>
<path d='M 360,240 L 416,240' fill='none' stroke='currentColor'></path>
<path d='M 120,304 L 808,304' fill='none' stroke='currentColor'></path>
<path d='M 176,320 L 352,320' fill='none' stroke='currentColor'></path>
<path d='M 120,336 L 152,336' fill='none' stroke='currentColor'></path>
<path d='M 368,336 L 808,336' fill='none' stroke='currentColor'></path>
<path d='M 176,352 L 352,352' fill='none' stroke='currentColor'></path>
<path d='M 120,368 L 808,368' fill='none' stroke='currentColor'></path>
<path d='M 176,384 L 264,384' fill='none' stroke='currentColor'></path>
<path d='M 120,400 L 152,400' fill='none' stroke='currentColor'></path>
<path d='M 280,400 L 808,400' fill='none' stroke='currentColor'></path>
<path d='M 176,416 L 264,416' fill='none' stroke='currentColor'></path>
<path d='M 160,112 L 160,128' fill='none' stroke='currentColor'></path>
<path d='M 336,112 L 336,128' fill='none' stroke='currentColor'></path>
<path d='M 344,160 L 344,224' fill='none' stroke='currentColor'></path>
<path d='M 432,160 L 432,192' fill='none' stroke='currentColor'></path>
<path d='M 432,192 L 432,224' fill='none' stroke='currentColor'></path>
<path d='M 480,32 L 480,160' fill='none' stroke='currentColor'></path>
<path d='M 624,32 L 624,64' fill='none' stroke='currentColor'></path>
<path d='M 624,64 L 624,128' fill='none' stroke='currentColor'></path>
<path d='M 624,128 L 624,160' fill='none' stroke='currentColor'></path>
<path d='M 672,112 L 672,192' fill='none' stroke='currentColor'></path>
<path d='M 768,112 L 768,128' fill='none' stroke='currentColor'></path>
<path d='M 768,128 L 768,160' fill='none' stroke='currentColor'></path>
<path d='M 768,160 L 768,192' fill='none' stroke='currentColor'></path>
<polygon points='160.000000,64.000000 148.000000,58.400002 148.000000,69.599998' fill='currentColor' transform='rotate(0.000000, 152.000000, 64.000000)'></polygon>
<polygon points='160.000000,112.000000 148.000000,106.400002 148.000000,117.599998' fill='currentColor' transform='rotate(0.000000, 152.000000, 112.000000)'></polygon>
<polygon points='160.000000,224.000000 148.000000,218.399994 148.000000,229.600006' fill='currentColor' transform='rotate(0.000000, 152.000000, 224.000000)'></polygon>
<polygon points='160.000000,336.000000 148.000000,330.399994 148.000000,341.600006' fill='currentColor' transform='rotate(0.000000, 152.000000, 336.000000)'></polygon>
<polygon points='160.000000,400.000000 148.000000,394.399994 148.000000,405.600006' fill='currentColor' transform='rotate(0.000000, 152.000000, 400.000000)'></polygon>
<polygon points='344.000000,160.000000 332.000000,154.399994 332.000000,165.600006' fill='currentColor' transform='rotate(0.000000, 336.000000, 160.000000)'></polygon>
<polygon points='344.000000,224.000000 332.000000,218.399994 332.000000,229.600006' fill='currentColor' transform='rotate(0.000000, 336.000000, 224.000000)'></polygon>
<polygon points='480.000000,32.000000 468.000000,26.400000 468.000000,37.599998' fill='currentColor' transform='rotate(0.000000, 472.000000, 32.000000)'></polygon>
<polygon points='480.000000,64.000000 468.000000,58.400002 468.000000,69.599998' fill='currentColor' transform='rotate(0.000000, 472.000000, 64.000000)'></polygon>
<polygon points='480.000000,112.000000 468.000000,106.400002 468.000000,117.599998' fill='currentColor' transform='rotate(0.000000, 472.000000, 112.000000)'></polygon>
<polygon points='480.000000,160.000000 468.000000,154.399994 468.000000,165.600006' fill='currentColor' transform='rotate(0.000000, 472.000000, 160.000000)'></polygon>
<polygon points='672.000000,128.000000 660.000000,122.400002 660.000000,133.600006' fill='currentColor' transform='rotate(0.000000, 664.000000, 128.000000)'></polygon>
<polygon points='672.000000,192.000000 660.000000,186.399994 660.000000,197.600006' fill='currentColor' transform='rotate(0.000000, 664.000000, 192.000000)'></polygon>
<polygon points='816.000000,32.000000 804.000000,26.400000 804.000000,37.599998' fill='currentColor' transform='rotate(0.000000, 808.000000, 32.000000)'></polygon>
<polygon points='816.000000,64.000000 804.000000,58.400002 804.000000,69.599998' fill='currentColor' transform='rotate(0.000000, 808.000000, 64.000000)'></polygon>
<polygon points='816.000000,128.000000 804.000000,122.400002 804.000000,133.600006' fill='currentColor' transform='rotate(0.000000, 808.000000, 128.000000)'></polygon>
<polygon points='816.000000,160.000000 804.000000,154.399994 804.000000,165.600006' fill='currentColor' transform='rotate(0.000000, 808.000000, 160.000000)'></polygon>
<polygon points='816.000000,224.000000 804.000000,218.399994 804.000000,229.600006' fill='currentColor' transform='rotate(0.000000, 808.000000, 224.000000)'></polygon>
<polygon points='816.000000,304.000000 804.000000,298.399994 804.000000,309.600006' fill='currentColor' transform='rotate(0.000000, 808.000000, 304.000000)'></polygon>
<polygon points='816.000000,336.000000 804.000000,330.399994 804.000000,341.600006' fill='currentColor' transform='rotate(0.000000, 808.000000, 336.000000)'></polygon>
<polygon points='816.000000,368.000000 804.000000,362.399994 804.000000,373.600006' fill='currentColor' transform='rotate(0.000000, 808.000000, 368.000000)'></polygon>
<polygon points='816.000000,400.000000 804.000000,394.399994 804.000000,405.600006' fill='currentColor' transform='rotate(0.000000, 808.000000, 400.000000)'></polygon>
<path d='M 496,16 A 16,16 0 0,0 480,32' fill='none' stroke='currentColor'></path>
<path d='M 608,16 A 16,16 0 0,1 624,32' fill='none' stroke='currentColor'></path>
<path d='M 176,48 A 16,16 0 0,0 160,64' fill='none' stroke='currentColor'></path>
<path d='M 304,48 A 16,16 0 0,1 320,64' fill='none' stroke='currentColor'></path>
<path d='M 160,64 A 16,16 0 0,0 176,80' fill='none' stroke='currentColor'></path>
<path d='M 320,64 A 16,16 0 0,1 304,80' fill='none' stroke='currentColor'></path>
<path d='M 176,96 A 16,16 0 0,0 160,112' fill='none' stroke='currentColor'></path>
<path d='M 320,96 A 16,16 0 0,1 336,112' fill='none' stroke='currentColor'></path>
<path d='M 688,96 A 16,16 0 0,0 672,112' fill='none' stroke='currentColor'></path>
<path d='M 752,96 A 16,16 0 0,1 768,112' fill='none' stroke='currentColor'></path>
<path d='M 160,128 A 16,16 0 0,0 176,144' fill='none' stroke='currentColor'></path>
<path d='M 336,128 A 16,16 0 0,1 320,144' fill='none' stroke='currentColor'></path>
<path d='M 360,144 A 16,16 0 0,0 344,160' fill='none' stroke='currentColor'></path>
<path d='M 416,144 A 16,16 0 0,1 432,160' fill='none' stroke='currentColor'></path>
<path d='M 480,160 A 16,16 0 0,0 496,176' fill='none' stroke='currentColor'></path>
<path d='M 624,160 A 16,16 0 0,1 608,176' fill='none' stroke='currentColor'></path>
<path d='M 176,208 A 16,16 0 0,0 160,224' fill='none' stroke='currentColor'></path>
<path d='M 280,208 A 16,16 0 0,1 296,224' fill='none' stroke='currentColor'></path>
<path d='M 672,192 A 16,16 0 0,0 688,208' fill='none' stroke='currentColor'></path>
<path d='M 768,192 A 16,16 0 0,1 752,208' fill='none' stroke='currentColor'></path>
<path d='M 160,224 A 16,16 0 0,0 176,240' fill='none' stroke='currentColor'></path>
<path d='M 296,224 A 16,16 0 0,1 280,240' fill='none' stroke='currentColor'></path>
<path d='M 344,224 A 16,16 0 0,0 360,240' fill='none' stroke='currentColor'></path>
<path d='M 432,224 A 16,16 0 0,1 416,240' fill='none' stroke='currentColor'></path>
<path d='M 176,320 A 16,16 0 0,0 160,336' fill='none' stroke='currentColor'></path>
<path d='M 352,320 A 16,16 0 0,1 368,336' fill='none' stroke='currentColor'></path>
<path d='M 160,336 A 16,16 0 0,0 176,352' fill='none' stroke='currentColor'></path>
<path d='M 368,336 A 16,16 0 0,1 352,352' fill='none' stroke='currentColor'></path>
<path d='M 176,384 A 16,16 0 0,0 160,400' fill='none' stroke='currentColor'></path>
<path d='M 264,384 A 16,16 0 0,1 280,400' fill='none' stroke='currentColor'></path>
<path d='M 160,400 A 16,16 0 0,0 176,416' fill='none' stroke='currentColor'></path>
<path d='M 280,400 A 16,16 0 0,1 264,416' fill='none' stroke='currentColor'></path>
<style>
text {
text-anchor: middle;
font-family: "Menlo","Lucida Console","monospace";
fill: currentColor;
font-size: 1em;
}
</style>
<text x='16' y='4'>N</text>
<text x='24' y='4'>o</text>
<text x='32' y='4'>r</text>
<text x='40' y='4'>m</text>
<text x='48' y='4'>a</text>
<text x='56' y='4'>l</text>
<text x='72' y='4'>f</text>
<text x='80' y='4'>l</text>
<text x='88' y='4'>o</text>
<text x='96' y='4'>w</text>
<text x='104' y='4'>:</text>
<text x='32' y='36'>P</text>
<text x='40' y='36'>D</text>
<text x='48' y='36'>F</text>
<text x='824' y='36'>P</text>
<text x='832' y='36'>D</text>
<text x='840' y='36'>F</text>
<text x='856' y='36'>1</text>
<text x='864' y='36'>.</text>
<text x='872' y='36'>5</text>
<text x='32' y='68'>P</text>
<text x='40' y='68'>l</text>
<text x='48' y='68'>a</text>
<text x='56' y='68'>i</text>
<text x='64' y='68'>n</text>
<text x='72' y='68'>t</text>
<text x='80' y='68'>e</text>
<text x='88' y='68'>x</text>
<text x='96' y='68'>t</text>
<text x='192' y='68'>Q</text>
<text x='200' y='68'>T</text>
<text x='208' y='68'>e</text>
<text x='216' y='68'>x</text>
<text x='224' y='68'>t</text>
<text x='232' y='68'>D</text>
<text x='240' y='68'>o</text>
<text x='248' y='68'>c</text>
<text x='256' y='68'>u</text>
<text x='264' y='68'>m</text>
<text x='272' y='68'>e</text>
<text x='280' y='68'>n</text>
<text x='288' y='68'>t</text>
<text x='504' y='68'>p</text>
<text x='512' y='68'>d</text>
<text x='520' y='68'>f</text>
<text x='528' y='68'>2</text>
<text x='536' y='68'>p</text>
<text x='544' y='68'>r</text>
<text x='552' y='68'>i</text>
<text x='560' y='68'>n</text>
<text x='568' y='68'>t</text>
<text x='576' y='68'>a</text>
<text x='584' y='68'>b</text>
<text x='592' y='68'>l</text>
<text x='600' y='68'>e</text>
<text x='824' y='68'>P</text>
<text x='832' y='68'>o</text>
<text x='840' y='68'>s</text>
<text x='848' y='68'>t</text>
<text x='856' y='68'>s</text>
<text x='864' y='68'>c</text>
<text x='872' y='68'>r</text>
<text x='880' y='68'>i</text>
<text x='888' y='68'>p</text>
<text x='896' y='68'>t</text>
<text x='912' y='68'>2</text>
<text x='32' y='100'>D</text>
<text x='40' y='100'>O</text>
<text x='48' y='100'>C</text>
<text x='56' y='100'>/</text>
<text x='64' y='100'>P</text>
<text x='72' y='100'>P</text>
<text x='80' y='100'>T</text>
<text x='496' y='100'>(</text>
<text x='504' y='100'>P</text>
<text x='512' y='100'>o</text>
<text x='520' y='100'>p</text>
<text x='528' y='100'>p</text>
<text x='536' y='100'>l</text>
<text x='544' y='100'>e</text>
<text x='552' y='100'>r</text>
<text x='560' y='100'>+</text>
<text x='568' y='100'>C</text>
<text x='576' y='100'>a</text>
<text x='584' y='100'>i</text>
<text x='592' y='100'>r</text>
<text x='600' y='100'>o</text>
<text x='608' y='100'>)</text>
<text x='32' y='116'>O</text>
<text x='40' y='116'>D</text>
<text x='48' y='116'>T</text>
<text x='56' y='116'>/</text>
<text x='64' y='116'>O</text>
<text x='72' y='116'>D</text>
<text x='80' y='116'>P</text>
<text x='184' y='116'>C</text>
<text x='192' y='116'>a</text>
<text x='200' y='116'>l</text>
<text x='208' y='116'>l</text>
<text x='216' y='116'>i</text>
<text x='224' y='116'>g</text>
<text x='232' y='116'>r</text>
<text x='240' y='116'>a</text>
<text x='248' y='116'>c</text>
<text x='256' y='116'>o</text>
<text x='264' y='116'>n</text>
<text x='272' y='116'>v</text>
<text x='280' y='116'>e</text>
<text x='288' y='116'>r</text>
<text x='296' y='116'>t</text>
<text x='304' y='116'>e</text>
<text x='312' y='116'>r</text>
<text x='208' y='132'>(</text>
<text x='216' y='132'>o</text>
<text x='224' y='132'>p</text>
<text x='232' y='132'>t</text>
<text x='240' y='132'>i</text>
<text x='248' y='132'>o</text>
<text x='256' y='132'>n</text>
<text x='264' y='132'>a</text>
<text x='272' y='132'>l</text>
<text x='280' y='132'>)</text>
<text x='824' y='132'>P</text>
<text x='832' y='132'>W</text>
<text x='840' y='132'>G</text>
<text x='848' y='132'>-</text>
<text x='856' y='132'>R</text>
<text x='864' y='132'>a</text>
<text x='872' y='132'>s</text>
<text x='880' y='132'>t</text>
<text x='888' y='132'>e</text>
<text x='896' y='132'>r</text>
<text x='696' y='148'>p</text>
<text x='704' y='148'>p</text>
<text x='712' y='148'>m</text>
<text x='720' y='148'>2</text>
<text x='728' y='148'>p</text>
<text x='736' y='148'>w</text>
<text x='744' y='148'>g</text>
<text x='32' y='164'>I</text>
<text x='40' y='164'>m</text>
<text x='48' y='164'>a</text>
<text x='56' y='164'>g</text>
<text x='64' y='164'>e</text>
<text x='72' y='164'>s</text>
<text x='824' y='164'>U</text>
<text x='832' y='164'>R</text>
<text x='840' y='164'>F</text>
<text x='848' y='164'>-</text>
<text x='856' y='164'>R</text>
<text x='864' y='164'>a</text>
<text x='872' y='164'>s</text>
<text x='880' y='164'>t</text>
<text x='888' y='164'>e</text>
<text x='896' y='164'>r</text>
<text x='368' y='196'>Q</text>
<text x='376' y='196'>I</text>
<text x='384' y='196'>m</text>
<text x='392' y='196'>a</text>
<text x='400' y='196'>g</text>
<text x='408' y='196'>e</text>
<text x='32' y='228'>S</text>
<text x='40' y='228'>V</text>
<text x='48' y='228'>G</text>
<text x='184' y='228'>Q</text>
<text x='192' y='228'>S</text>
<text x='200' y='228'>v</text>
<text x='208' y='228'>g</text>
<text x='216' y='228'>R</text>
<text x='224' y='228'>e</text>
<text x='232' y='228'>n</text>
<text x='240' y='228'>d</text>
<text x='248' y='228'>e</text>
<text x='256' y='228'>r</text>
<text x='264' y='228'>e</text>
<text x='272' y='228'>r</text>
<text x='824' y='228'>P</text>
<text x='832' y='228'>N</text>
<text x='840' y='228'>G</text>
<text x='848' y='228'>,</text>
<text x='864' y='228'>J</text>
<text x='872' y='228'>P</text>
<text x='880' y='228'>E</text>
<text x='888' y='228'>G</text>
<text x='896' y='228'>,</text>
<text x='824' y='244'>R</text>
<text x='832' y='244'>e</text>
<text x='840' y='244'>v</text>
<text x='848' y='244'>e</text>
<text x='856' y='244'>r</text>
<text x='864' y='244'>s</text>
<text x='872' y='244'>e</text>
<text x='888' y='244'>B</text>
<text x='896' y='244'>M</text>
<text x='904' y='244'>P</text>
<text x='16' y='276'>I</text>
<text x='24' y='276'>f</text>
<text x='40' y='276'>t</text>
<text x='48' y='276'>a</text>
<text x='56' y='276'>r</text>
<text x='64' y='276'>g</text>
<text x='72' y='276'>e</text>
<text x='80' y='276'>t</text>
<text x='96' y='276'>f</text>
<text x='104' y='276'>o</text>
<text x='112' y='276'>r</text>
<text x='120' y='276'>m</text>
<text x='128' y='276'>a</text>
<text x='136' y='276'>t</text>
<text x='152' y='276'>i</text>
<text x='160' y='276'>s</text>
<text x='176' y='276'>t</text>
<text x='184' y='276'>h</text>
<text x='192' y='276'>e</text>
<text x='208' y='276'>s</text>
<text x='216' y='276'>a</text>
<text x='224' y='276'>m</text>
<text x='232' y='276'>e</text>
<text x='240' y='276'>:</text>
<text x='32' y='308'>P</text>
<text x='40' y='308'>o</text>
<text x='48' y='308'>s</text>
<text x='56' y='308'>t</text>
<text x='64' y='308'>s</text>
<text x='72' y='308'>c</text>
<text x='80' y='308'>r</text>
<text x='88' y='308'>i</text>
<text x='96' y='308'>p</text>
<text x='104' y='308'>t</text>
<text x='824' y='308'>P</text>
<text x='832' y='308'>o</text>
<text x='840' y='308'>s</text>
<text x='848' y='308'>t</text>
<text x='856' y='308'>s</text>
<text x='864' y='308'>c</text>
<text x='872' y='308'>r</text>
<text x='880' y='308'>i</text>
<text x='888' y='308'>p</text>
<text x='896' y='308'>t</text>
<text x='32' y='340'>P</text>
<text x='40' y='340'>l</text>
<text x='48' y='340'>a</text>
<text x='56' y='340'>i</text>
<text x='64' y='340'>n</text>
<text x='72' y='340'>t</text>
<text x='80' y='340'>e</text>
<text x='88' y='340'>x</text>
<text x='96' y='340'>t</text>
<text x='184' y='340'>e</text>
<text x='192' y='340'>n</text>
<text x='200' y='340'>s</text>
<text x='208' y='340'>u</text>
<text x='216' y='340'>r</text>
<text x='224' y='340'>e</text>
<text x='240' y='340'>C</text>
<text x='248' y='340'>R</text>
<text x='256' y='340'>+</text>
<text x='264' y='340'>L</text>
<text x='272' y='340'>F</text>
<text x='288' y='340'>n</text>
<text x='296' y='340'>e</text>
<text x='304' y='340'>w</text>
<text x='312' y='340'>l</text>
<text x='320' y='340'>i</text>
<text x='328' y='340'>n</text>
<text x='336' y='340'>e</text>
<text x='344' y='340'>s</text>
<text x='824' y='340'>P</text>
<text x='832' y='340'>l</text>
<text x='840' y='340'>a</text>
<text x='848' y='340'>i</text>
<text x='856' y='340'>n</text>
<text x='864' y='340'>t</text>
<text x='872' y='340'>e</text>
<text x='880' y='340'>x</text>
<text x='888' y='340'>t</text>
<text x='32' y='372'>P</text>
<text x='40' y='372'>N</text>
<text x='48' y='372'>G</text>
<text x='824' y='372'>P</text>
<text x='832' y='372'>N</text>
<text x='840' y='372'>G</text>
<text x='32' y='404'>J</text>
<text x='40' y='404'>P</text>
<text x='48' y='404'>E</text>
<text x='56' y='404'>G</text>
<text x='184' y='404'>b</text>
<text x='192' y='404'>a</text>
<text x='200' y='404'>s</text>
<text x='208' y='404'>e</text>
<text x='216' y='404'>l</text>
<text x='224' y='404'>i</text>
<text x='232' y='404'>n</text>
<text x='240' y='404'>i</text>
<text x='248' y='404'>f</text>
<text x='256' y='404'>y</text>
<text x='824' y='404'>J</text>
<text x='832' y='404'>P</text>
<text x='840' y='404'>E</text>
<text x='848' y='404'>G</text>
<text x='824' y='420'>(</text>
<text x='832' y='420'>B</text>
<text x='840' y='420'>a</text>
<text x='848' y='420'>s</text>
<text x='856' y='420'>e</text>
<text x='864' y='420'>l</text>
<text x='872' y='420'>i</text>
<text x='880' y='420'>n</text>
<text x='888' y='420'>e</text>
<text x='904' y='420'>p</text>
<text x='912' y='420'>r</text>
<text x='920' y='420'>o</text>
<text x='928' y='420'>f</text>
<text x='936' y='420'>i</text>
<text x='944' y='420'>l</text>
<text x='952' y='420'>e</text>
<text x='960' y='420'>)</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 20 KiB

View file

@ -3,9 +3,10 @@ Type=Application
Icon=harbour-seaprint
X-Nemo-Application-Type=silica-qt5
Exec=harbour-seaprint
X-DBusActivatable=true
Name=SeaPrint
[X-Sailjail]
Permissions=Internet;Pictures;Documents;Downloads;RemovableMedia;MediaIndexing;Compatibility
OrganizationName=net.attah
ApplicationName=seaprint
ExecDBus=harbour-seaprint --prestart

View file

@ -26,14 +26,18 @@ INSTALLS += i18n
system(lrelease $$PWD/translations/*.ts)
CONFIG += sailfishapp
QT += svg
PKGCONFIG += mlite5 libcurl poppler glib-2.0 cairo libjpeg
QT += svg dbus
PKGCONFIG += mlite5 libcurl glib-2.0
INCLUDEPATH += $$system(pkg-config --cflags-only-I poppler-glib | sed 's/-I//g')
LIBS += -lcurl -lglib-2.0 -lgobject-2.0 -ldl
DEFINES += MADNESS=1
DEFINES += PDF_CREATOR='\\"SeaPrint\ $$VERSION\\"'
DEFINES += SEAPRINT_VERSION='\\"$$VERSION\\"'
SOURCES += src/harbour-seaprint.cpp \
src/dbusadaptorbase.cpp \
src/freedesktopdbusadaptor.cpp \
src/rangelistchecker.cpp \
src/convertchecker.cpp \
src/curlrequester.cpp \
src/imageitem.cpp \
@ -41,16 +45,17 @@ SOURCES += src/harbour-seaprint.cpp \
src/ippmsg.cpp \
src/ippprinter.cpp \
src/mimer.cpp \
ppm2pwg/printparameters.cpp \
ppm2pwg/ppm2pwg.cpp \
ppm2pwg/pdf2printable.cpp \
ppm2pwg/baselinify.cpp \
ppm2pwg/bytestream/bytestream.cpp \
src/overrider.cpp \
src/printerworker.cpp \
src/seaprintdbusadaptor.cpp \
src/settings.cpp
DISTFILES += qml/harbour-seaprint.qml \
qml/components/DependentOn.qml \
qml/cover/CoverPage.qml \
qml/components/*qml \
qml/pages/*.qml \
@ -81,6 +86,9 @@ TRANSLATIONS += translations/harbour-seaprint-de.ts \
translations/harbour-seaprint-pl.ts
HEADERS += \
src/dbusadaptorbase.h \
src/freedesktopdbusadaptor.h \
src/rangelistchecker.h \
src/convertchecker.h \
src/curlrequester.h \
src/imageitem.h \
@ -99,9 +107,11 @@ HEADERS += \
ppm2pwg/UrfPgHdr.codable \
ppm2pwg/bytestream/bytestream.h \
ppm2pwg/bytestream/codable.h \
ppm2pwg/argget.h \
src/overrider.h \
src/papersizes.h \
src/printerworker.h \
src/seaprintdbusadaptor.h \
src/settings.h
INCLUDEPATH += ppm2pwg \

@ -1 +1 @@
Subproject commit ba8d015e911991d20dc1433292d7188e5e7ab8f9
Subproject commit acc32f3769c3b18bd6b94c55b882c7b7b778854c

View file

@ -7,7 +7,7 @@ Setting {
property var preferred_choices: []
property string preferred_choice_suffix: ""
property var actual_choices: Utils.fixupChoices(name, choices, parent.selectedFileType)
property var actual_choices: Utils.fixupChoices(name, choices, parent.selectedFileType, parent.printer)
property int num_large_choices: 8

View file

@ -20,10 +20,9 @@ Dialog {
id: valueField
validator: IntValidator{bottom: min; top: max;}
width: parent.width
placeholderText: ""+min+"-"+max
placeholderText: ""+min+"-"+(max == 65535 ? "..." : max)
label: title
focus: true
labelVisible: true
inputMethodHints: Qt.ImhDigitsOnly
}

View file

@ -2,8 +2,21 @@ import QtQuick 2.6
import Sailfish.Silica 1.0
Setting {
property int low: valid ? parent.printer.attrs[name+"-supported"].value.low : 0
property int high: valid ? parent.printer.attrs[name+"-supported"].value.high : 0
property int minimum_high: 0
property int low: _valid ? parent.printer.attrs[name+"-supported"].value.low : (minimum_high != 0) ? 1 : 0
property int high: _valid ? ensure_minimum(parent.printer.attrs[name+"-supported"].value.high) : minimum_high
function ensure_minimum(orig)
{
if(orig < minimum_high)
{
return minimum_high;
}
else
{
return orig;
}
}
property bool suppressChange: false
@ -40,7 +53,7 @@ Setting {
anchors.right: parent.right
icon.source: "image://theme/icon-s-edit"
onClicked: {var dialog = pageStack.push(Qt.resolvedUrl("IntegerInputDialog.qml"),
{value: choice, title: prettyName,
{title: prettyName,
min: low, max: high});
dialog.accepted.connect(function() {
choice = dialog.value;

View file

@ -0,0 +1,30 @@
import QtQuick 2.6
import Sailfish.Silica 1.0
import seaprint.rangelistchecker 1.0
Dialog {
id: dialog
allowedOrientations: Orientation.All
property string title
property var value
canAccept: valueField.acceptableInput
Column {
width: parent.width
DialogHeader { }
TextField {
id: valueField
acceptableInput: Object.keys(value).length !== 0
width: parent.width
placeholderText: "1,2,17-42"
label: title
focus: true
labelVisible: true
onTextChanged: { dialog.value = RangeListChecker.parse(text) }
}
}
}

View file

@ -5,6 +5,7 @@ Setting {
property int high
property int choice_low: 1
property int choice_high: 0
property bool acceptRangeList: false
property bool suppressChange: false
@ -41,7 +42,7 @@ Setting {
}
onChoiceChanged: {
if(choice == undefined)
if(choice == undefined || choice.constructor.name !== "Object")
{
suppressChange = true;
low_slider.value = low_slider.minimumValue;
@ -50,7 +51,39 @@ Setting {
}
}
displayValue: choice == undefined ? qsTr("all") : ""+choice.low+" - "+choice.high
displayValue: prettify(choice)
function prettify(choice)
{
if(choice == undefined)
{
return qsTr("all");
}
else if(choice.constructor.name === "Object")
{
return (""+choice.low+" - "+choice.high)
}
else
{
var ret = "";
for(var i = 0; i < choice.length; i++)
{
if(i!=0)
{
ret = ret+","
}
if(choice[i].low == choice[i].high)
{
ret=ret+choice[i].low
}
else
{
ret=ret+choice[i].low+"-"+choice[i].high
}
}
return ret
}
}
menu: ContextMenu {
MenuItem {
@ -71,7 +104,7 @@ Setting {
anchors.right: parent.right
icon.source: "image://theme/icon-s-edit"
onClicked: {var dialog = pageStack.push(Qt.resolvedUrl("IntegerInputDialog.qml"),
{value: choice, title: prettyName,
{title: prettyName + " (" + qsTr("Low") + ")",
min: 1, max: high});
dialog.accepted.connect(function() {
choice_low = dialog.value;
@ -99,7 +132,7 @@ Setting {
anchors.right: parent.right
icon.source: "image://theme/icon-s-edit"
onClicked: {var dialog = pageStack.push(Qt.resolvedUrl("IntegerInputDialog.qml"),
{value: choice, title: prettyName,
{title: prettyName + " (" + qsTr("High") + ")",
min: 1, max: high});
dialog.accepted.connect(function() {
choice_high = dialog.value;
@ -109,6 +142,17 @@ Setting {
}
MenuItem {
visible: acceptRangeList
text: qsTr("Advanced")
onClicked: {var dialog = pageStack.push(Qt.resolvedUrl("RangeListInputDialog.qml"),
{title: prettyName});
dialog.accepted.connect(function() {
choice = dialog.value;
})
}
}
}

View file

@ -13,9 +13,37 @@ ApplicationWindow
{
id: appWin
property Page _mainPage
property bool expectCalligra: true
initialPage: Component { FirstPage { selectedFile: Qt.application.arguments[1] ? Qt.application.arguments[1] : "" } }
function openFile(file) {
selectedFile = file
selectedFileType = Mimer.get_type(selectedFile);
if(selectedFileType == "")
{
selectedFile = ""
notifier.notify(qsTr("Unsupported document format"))
}
if(pageStack.currentPage.busyPage)
{
notifier.notify(qsTr("New file selected"))
}
else
{
pageStack.pop(appWin._mainPage, PageStackAction.Immediate)
}
}
property string selectedFile: ""
property string selectedFileType
initialPage: Component {
FirstPage {
Component.onCompleted: appWin._mainPage = this
}
}
cover: Qt.resolvedUrl("cover/CoverPage.qml")
allowedOrientations: Orientation.All

View file

@ -62,7 +62,7 @@ Page {
AboutLabel {
font.pixelSize: Theme.fontSizeSmall
color: Theme.primaryColor
text: "© 2019-2022 Anton Thomasson et al."
text: "© 2019-2023 Anton Thomasson et al."
}
@ -101,7 +101,7 @@ Page {
qsTr("Dutch")+" - JSEHV, Rudi Timmermans\n"+
qsTr("French")+" - ensag-dev, pherjung, phklrz, Quentí\n"+
qsTr("German")+" - black-sheep-dev, cnlpete, wheelseal\n"+
qsTr("Polish")+" - atlochowski\n"+
qsTr("Polish")+" - atlochowski, karolkurek\n"+
qsTr("Spanish")+" - carmenfdezb, JSEHV"
}

View file

@ -3,6 +3,8 @@ import Sailfish.Silica 1.0
import "utils.js" as Utils
Page {
property bool busyPage: true
allowedOrientations: Orientation.All
Component.onCompleted: {

View file

@ -13,6 +13,7 @@ Page {
contentHeight: col.height
PullDownMenu {
visible: identifyLabel.visible
MenuItem {
id: identifyLabel

View file

@ -12,9 +12,6 @@ Page {
id: page
allowedOrientations: Orientation.All
property string selectedFile: ""
property string selectedFileType
Connections {
target: wifi
onConnectedChanged: {
@ -60,11 +57,6 @@ Page {
Component.onCompleted: {
IppDiscovery.discover();
if(selectedFile != "")
{
var type = Mimer.get_type(selectedFile);
selectedFileType = type;
}
}
property bool nagged: false
@ -143,7 +135,7 @@ Page {
property string name: Utils.unknownForEmptyString(printer.attrs["printer-name"].value)
property var supported_formats: Utils.supported_formats(printer, considerAdditionalFormatsSetting.value)
property bool canPrint: supported_formats.mimetypes.indexOf(selectedFileType) != -1
property bool canPrint: supported_formats.mimetypes.indexOf(appWin.selectedFileType) != -1
Connections {
target: printer
@ -182,7 +174,7 @@ Page {
{
if(printer.attrs.hasOwnProperty("printer-uuid"))
{
return JSON.parse(db.getJobSettings(printer.attrs["printer-uuid"].value, selectedFileType));
return JSON.parse(db.getJobSettings(printer.attrs["printer-uuid"].value, appWin.selectedFileType));
}
else
{
@ -199,7 +191,7 @@ Page {
return;
}
debugCountReset.restart();
if(selectedFile == "")
if(appWin.selectedFile == "")
{
noFileSelected();
}
@ -209,7 +201,7 @@ Page {
}
else
{
pageStack.push(Qt.resolvedUrl("PrinterPage.qml"), {printer: printer, selectedFile: selectedFile, jobParams: maybeGetParams()})
pageStack.push(Qt.resolvedUrl("PrinterPage.qml"), {printer: printer, selectedFile: appWin.selectedFile, jobParams: maybeGetParams()})
}
}
@ -250,13 +242,13 @@ Page {
Label {
id: name_label
color: canPrint || selectedFile == "" ? Theme.primaryColor : Theme.secondaryColor
color: canPrint || appWin.selectedFile == "" ? Theme.primaryColor : Theme.secondaryColor
text: name
}
Label {
id: mm_label
color: canPrint || selectedFile == "" ? Theme.primaryColor : Theme.secondaryColor
color: canPrint || appWin.selectedFile == "" ? Theme.primaryColor : Theme.secondaryColor
font.pixelSize: Theme.fontSizeExtraSmall
text: Utils.unknownForEmptyString(printer.attrs["printer-make-and-model"].value)
+ (Utils.existsAndNotEmpty("printer-location", printer) ? " • "+printer.attrs["printer-location"].value : "")
@ -264,7 +256,7 @@ Page {
Label {
id: uri_label
color: canPrint || selectedFile == "" ? Theme.highlightColor : Theme.secondaryColor
color: canPrint || appWin.selectedFile == "" ? Theme.highlightColor : Theme.secondaryColor
font.pixelSize: Theme.fontSizeTiny
text: printer.url
}
@ -285,7 +277,7 @@ Page {
width: Theme.itemSizeExtraSmall/2
visible: supported_formats.pdf
highlightColor: "red"
highlighted: !(selectedFile == "" || canPrint)
highlighted: !(appWin.selectedFile == "" || canPrint)
source: "image://theme/icon-m-file-pdf"
}
HighlightImage {
@ -293,7 +285,7 @@ Page {
width: Theme.itemSizeExtraSmall/2
visible: supported_formats.postscript
highlightColor: "red"
highlighted: !(selectedFile == "" || canPrint)
highlighted: !(appWin.selectedFile == "" || canPrint)
source: "image://theme/icon-m-file-other"
}
@ -302,7 +294,7 @@ Page {
width: Theme.itemSizeExtraSmall/2
visible: supported_formats.plaintext
highlightColor: "red"
highlighted: !(selectedFile == "" || canPrint)
highlighted: !(appWin.selectedFile == "" || canPrint)
source: "image://theme/icon-m-file-document"
}
HighlightImage {
@ -310,7 +302,7 @@ Page {
width: Theme.itemSizeExtraSmall/2
visible: supported_formats.office
highlightColor: "red"
highlighted: !(selectedFile == "" || canPrint)
highlighted: !(appWin.selectedFile == "" || canPrint)
source: "image://theme/icon-m-file-formatted"
}
HighlightImage {
@ -318,7 +310,7 @@ Page {
width: Theme.itemSizeExtraSmall/2
visible: supported_formats.office
highlightColor: "red"
highlighted: !(selectedFile == "" || canPrint)
highlighted: !(appWin.selectedFile == "" || canPrint)
source: "image://theme/icon-m-file-presentation"
}
HighlightImage {
@ -326,7 +318,7 @@ Page {
width: Theme.itemSizeExtraSmall/2
visible: supported_formats.images
highlightColor: "red"
highlighted: !(selectedFile == "" || canPrint)
highlighted: !(appWin.selectedFile == "" || canPrint)
source: "image://theme/icon-m-file-image"
}
}
@ -381,7 +373,7 @@ Page {
Row {
id: warningRow
anchors.horizontalCenter: parent.horizontalCenter
visible: Mimer.isOffice(page.selectedFileType)
visible: Mimer.isOffice(appWin.selectedFileType)
HighlightImage {
source: "image://theme/icon-s-warning"
@ -404,7 +396,7 @@ Page {
horizontalAlignment: contentWidth > width ? Text.AlignRight : Text.AlignHCenter
truncationMode: TruncationMode.Fade
text: selectedFile != "" ? selectedFile : qsTr("No file selected")
text: appWin.selectedFile != "" ? appWin.selectedFile : qsTr("No file selected")
SequentialAnimation {
id: noFileSelectedAnimation
@ -457,18 +449,7 @@ Page {
title: qsTr("Choose file")
onSelectedContentPropertiesChanged: {
var mimeType = Mimer.get_type(selectedContentProperties.filePath)
if(mimeType == Mimer.PDF || mimeType == Mimer.Postscript || mimeType == Mimer.Plaintext || Mimer.isOffice(mimeType))
{
page.selectedFile = selectedContentProperties.filePath
page.selectedFileType = mimeType
}
else
{
notifier.notify(qsTr("Unsupported document format"))
page.selectedFile = ""
page.selectedFileType = ""
}
appWin.openFile(selectedContentProperties.filePath);
}
}
}
@ -478,8 +459,7 @@ Page {
allowedOrientations: Orientation.All
onSelectedContentPropertiesChanged: {
page.selectedFile = selectedContentProperties.filePath
page.selectedFileType = Mimer.get_type(selectedContentProperties.filePath)
appWin.openFile(selectedContentProperties.filePath);
}
}
}

View file

@ -104,6 +104,8 @@ Page {
tag: IppMsg.Integer
name: "copies"
prettyName: qsTr("Copies")
valid: _valid || Utils.supports_raster(printer)
minimum_high: 99
}
ChoiceSetting {
tag: IppMsg.Keyword
@ -118,6 +120,7 @@ Page {
property var pdfpages: ConvertChecker.pdfPages(selectedFile)
high: pdfpages == 0 ? 65535 : pdfpages
acceptRangeList: true
}
ChoiceSetting {
tag: IppMsg.Integer

View file

@ -63,6 +63,16 @@ function supported_formats(printer, considerAdditionalFormats)
return {pdf: pdf, postscript: postscript, plaintext: plaintext, office: office, images: images, mimetypes: mimetypes};
}
function supports_raster(printer)
{
var formats = printer.attrs["document-format-supported"].value;
if(considerAdditionalFormats)
{
formats=formats+printer.additionalDocumentFormats;
}
return (has(formats, Mimer.Mimer.PWG) || has(formats, Mimer.Mimer.URF));
}
function has(arrayish, what)
{
return arrayish.indexOf(what) != -1;
@ -435,7 +445,7 @@ function knownPaperSize(mediaName)
}
function fixupChoices(name, choices, mimeType)
function fixupChoices(name, choices, mimeType, printer)
{
switch(name) {
case "document-format":
@ -487,7 +497,18 @@ function fixupChoices(name, choices, mimeType)
return choices;
}
case "media":
return choices.filter(knownPaperSize);
if(printer.attrs.hasOwnProperty("media-ready"))
{
for(var m in printer.attrs["media-ready"].value)
{
var value = printer.attrs["media-ready"].value[m];
if(!has(choices, value))
{
choices.push(value);
}
}
}
return choices;
default:
return choices;
}

View file

@ -4,8 +4,8 @@ Summary: SeaPrint
Version: 0
Release: 1
Group: Qt/Qt
License: LICENSE
URL: http://example.org/
License: GPLv3
URL: https://github.com/attah/harbour-seaprint
Source0: %{name}-%{version}.tar.bz2
Requires: sailfishsilica-qt5 >= 0.10.9
BuildRequires: pkgconfig(sailfishapp) >= 1.0.2
@ -21,6 +21,9 @@ BuildRequires: pkgconfig(glib-2.0)
BuildRequires: pkgconfig(cairo)
BuildRequires: pkgconfig(libjpeg)
%define _source_payload w6T.xzdio
%define _binary_payload w6T.xzdio
%description
Network printing for Sailfish OS
@ -44,7 +47,7 @@ desktop-file-install --delete-original \
%files
%defattr(-,root,root,-)
%{_bindir}
%{_bindir}/%{name}
%{_datadir}/%{name}
%{_datadir}/applications/%{name}.desktop
%{_datadir}/icons/hicolor/*/apps/%{name}.png

View file

@ -8,7 +8,7 @@ static size_t trampoline(char* dest, size_t size, size_t nmemb, void* userp)
return cid->requestWrite(dest, size*nmemb);
}
CurlRequester::CurlRequester(QUrl addr, Role role)
CurlRequester::CurlRequester(QUrl addr, Role role, Bytestream* singleData)
: _addr(addr), _canWrite(1), _canRead(), _reading(false), _done(false), _dest(nullptr), _size(0), _offset(0), _curl(curl_easy_init())
{
@ -36,7 +36,15 @@ CurlRequester::CurlRequester(QUrl addr, Role role)
curl_easy_setopt(_curl, CURLOPT_READDATA, this);
_opts = curl_slist_append(_opts, "Expect:");
_opts = curl_slist_append(_opts, "Transfer-Encoding: chunked");
if(singleData != nullptr)
{
curl_easy_setopt(_curl, CURLOPT_POSTFIELDSIZE, singleData->size());
write((char*)(singleData->raw()), singleData->size());
}
else
{
_opts = curl_slist_append(_opts, "Transfer-Encoding: chunked");
}
_opts = curl_slist_append(_opts, "Content-Type: application/ipp");
_opts = curl_slist_append(_opts, "Accept-Encoding: identity");
break;
@ -121,7 +129,7 @@ size_t CurlRequester::requestWrite(char* dest, size_t size)
if(!_reading)
{
_canRead.acquire();
if(_done) // Can only have been set by write() - only relevant to check if strating to write
if(_done) // Can only have been set by await() - only relevant to check if strating to write
{
return 0;
}

View file

@ -19,7 +19,7 @@ public:
HttpGetRequest
};
CurlRequester(QUrl addr, Role role = IppRequest);
CurlRequester(QUrl addr, Role role = IppRequest, Bytestream* = nullptr);
~CurlRequester();
CURLcode await(Bytestream* = nullptr);

25
src/dbusadaptorbase.cpp Normal file
View file

@ -0,0 +1,25 @@
#include "dbusadaptorbase.h"
#include <QtQuick>
void DBusAdaptorBase::doActivate()
{
QMetaObject::invokeMethod(_view->rootObject(), "activate");
}
void DBusAdaptorBase::doOpen(const QString& fileName)
{
QMetaObject::invokeMethod(_view->rootObject(), "openFile", Q_ARG(QVariant, fileName));
doActivate();
}
void DBusAdaptorBase::doCreateFileAndOpen(const QString& fileContents, const QString& name)
{
QTemporaryFile tmpfile(QDir::tempPath() + "/" + name);
tmpfile.setAutoRemove(false);
tmpfile.open();
tmpfile.write(fileContents.toUtf8());
tmpfile.close();
QMetaObject::invokeMethod(_view->rootObject(), "openFile", Q_ARG(QVariant, tmpfile.fileName()));
doActivate();
}

24
src/dbusadaptorbase.h Normal file
View file

@ -0,0 +1,24 @@
#ifndef DBUSADAPTORBASE_H
#define DBUSADAPTORBASE_H
#include <QObject>
#include <QtDBus/QDBusAbstractAdaptor>
#include <QQuickView>
class DBusAdaptorBase
{
public:
DBusAdaptorBase(QQuickView* view)
: _view(view)
{}
void doActivate();
void doOpen(const QString& fileName);
void doCreateFileAndOpen(const QString& fileContents, const QString& name);
protected:
QQuickView* _view;
};
#endif // DBUSADAPTORBASE_H

View file

@ -0,0 +1,31 @@
#include "freedesktopdbusadaptor.h"
#include <QtQuick>
FreedesktopDBusAdaptor::FreedesktopDBusAdaptor(QQuickView *view)
: QDBusAbstractAdaptor(view)
, DBusAdaptorBase(view)
{
}
FreedesktopDBusAdaptor::~FreedesktopDBusAdaptor()
{
}
void FreedesktopDBusAdaptor::Open(const QStringList& uris, const QVariantMap& platformData)
{
qDebug() << platformData;
if (!uris.isEmpty() && uris[0] != "") {
doOpen(uris.at(0));
}
else if(platformData.contains("data"))
{
doCreateFileAndOpen(platformData["data"].toString(),
(platformData.contains("name") ? platformData["name"].toString() : "seaprint"));
}
}
void FreedesktopDBusAdaptor::Activate(const QVariantMap&)
{
QMetaObject::invokeMethod(_view->rootObject(), "activate");
}

View file

@ -0,0 +1,21 @@
#ifndef FREEDESKTOPDBUSADAPTOR_H
#define FREEDESKTOPDBUSADAPTOR_H
#include "dbusadaptorbase.h"
class FreedesktopDBusAdaptor : public QDBusAbstractAdaptor, public DBusAdaptorBase
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.freedesktop.Application")
public:
FreedesktopDBusAdaptor(QQuickView *view);
~FreedesktopDBusAdaptor();
public Q_SLOTS:
Q_NOREPLY void Open(const QStringList& uris, const QVariantMap& platformData);
Q_NOREPLY void Activate(const QVariantMap& platformData);
};
#endif // FREEDESKTOPDBUSADAPTOR_H

View file

@ -1,4 +1,6 @@
#include <QtQuick>
#include <QVariant>
#include <QDBusConnection>
#include <sailfishapp.h>
#include <src/ippdiscovery.h>
@ -7,6 +9,11 @@
#include <src/mimer.h>
#include <src/convertchecker.h>
#include <src/settings.h>
#include <src/rangelistchecker.h>
#include <src/freedesktopdbusadaptor.h>
#include <src/seaprintdbusadaptor.h>
#include "argget.h"
#include <iostream>
Q_DECLARE_METATYPE(CURLcode)
Q_DECLARE_METATYPE(Bytestream)
@ -25,6 +32,17 @@ static QObject* singletontype_provider(QQmlEngine *engine, QJSEngine *scriptEngi
int main(int argc, char *argv[])
{
bool prestart = false;
std::string FileName;
SwitchArg<bool> pretsartOpt(prestart, {"--prestart"}, "Run prestart");
PosArg fileArg(FileName, "File to print", true);
ArgGet args({&pretsartOpt}, {&fileArg});
if(!args.get_args(argc, argv))
{
return 1;
}
qRegisterMetaType<CURLcode>();
qRegisterMetaType<Bytestream>();
qRegisterMetaType<PrintParameters>();
@ -41,7 +59,9 @@ int main(int argc, char *argv[])
qmlRegisterSingletonType<IppDiscovery>("seaprint.ippdiscovery", 1, 0, "IppDiscovery", singletontype_provider<IppDiscovery>);
qmlRegisterSingletonType<Mimer>("seaprint.mimer", 1, 0, "Mimer", singletontype_provider<Mimer>);
qmlRegisterSingletonType<ConvertChecker>("seaprint.convertchecker", 1, 0, "ConvertChecker", singletontype_provider<ConvertChecker>);
qmlRegisterSingletonType<ConvertChecker>("seaprint.settings", 1, 0, "SeaPrintSettings", singletontype_provider<Settings>);
qmlRegisterSingletonType<Settings>("seaprint.settings", 1, 0, "SeaPrintSettings", singletontype_provider<Settings>);
qmlRegisterSingletonType<RangeListChecker>("seaprint.rangelistchecker", 1, 0, "RangeListChecker", singletontype_provider<RangeListChecker>);
qmlRegisterType<IppPrinter>("seaprint.ippprinter", 1, 0, "IppPrinter");
qmlRegisterType<ImageItem>("seaprint.imageitem", 1, 0, "ImageItem");
qmlRegisterUncreatableType<IppMsg>("seaprint.ippmsg", 1, 0, "IppMsg", "Only used to supply an enum type");
@ -49,8 +69,26 @@ int main(int argc, char *argv[])
QQuickView* view = SailfishApp::createView();
view->engine()->addImportPath(SailfishApp::pathTo("qml/pages").toString());
view->setSource(SailfishApp::pathToMainQml());
view->show();
FreedesktopDBusAdaptor freedesktopDbus(view);
SeaPrintDBusAdaptor seaprintDbus(view);
if (!QDBusConnection::sessionBus().registerObject("/net/attah/seaprint", view))
qWarning() << "Could not register /net/attah/seaprint D-Bus object.";
if (!QDBusConnection::sessionBus().registerService("net.attah.seaprint"))
qWarning() << "Could not register net.attah.seaprint D-Bus service.";
if(!FileName.empty())
{
qDebug() << "Opening" << FileName.c_str();
QVariant fileNameVariant(FileName.c_str());
QMetaObject::invokeMethod(view->rootObject(), "openFile", Q_ARG(QVariant, fileNameVariant));
}
if(!prestart)
{
view->show();
}
return app->exec();
}

View file

@ -288,6 +288,7 @@ QString IppMsg::consume_attribute(QJsonObject& attrs, Bytestream& data)
|| name.startsWith("printer-firmware")
|| name.endsWith("-supported")
|| name == "printer-icons"
|| name == "media-ready"
|| name.endsWith("-reasons")));
if(!unnamed.empty() || forceArray)
@ -319,11 +320,15 @@ Bytestream IppMsg::encode()
QStringList InitialAttrs = {"attributes-charset",
"attributes-natural-language",
"printer-uri",
"job-id",
"requesting-user-name"};
for(QString key : InitialAttrs)
{
QJsonObject val = _opAttrs.take(key).toObject();
encode_attr(ipp, val["tag"].toInt(), key, val["value"]);
if(_opAttrs.find(key) != _opAttrs.end())
{
QJsonObject val = _opAttrs.take(key).toObject();
encode_attr(ipp, val["tag"].toInt(), key, val["value"]);
}
}
for(QJsonObject::iterator it = _opAttrs.begin(); it != _opAttrs.end(); it++)
{ // encode any remaining op-attrs
@ -357,7 +362,25 @@ void IppMsg::encode_attr(Bytestream& msg, quint8 tag, QString name, QJsonValue v
name = "";
}
msg << tag << quint16(name.length()) << name.toStdString();
if(value.isArray())
{
QJsonArray array = value.toArray();
value = array.takeAt(0);
encode_value(msg, tag, value);
for(QJsonValue v : array)
{
msg << tag << quint16(0);
encode_value(msg, tag, v);
}
}
else
{
encode_value(msg, tag, value);
}
}
void IppMsg::encode_value(Bytestream& msg, quint8 tag, QJsonValue value)
{
switch (tag) {
case OpAttrs:
@ -401,19 +424,11 @@ void IppMsg::encode_attr(Bytestream& msg, quint8 tag, QString name, QJsonValue v
case BeginCollection:
{
msg << (quint16)0; // length of value
if(value.isObject())
QJsonObject collection = value.toObject();
for(QString key : collection.keys())
{
QJsonObject collection = value.toObject();
for(QString key : collection.keys())
{
encode_attr(msg, collection[key].toObject()["tag"].toInt(), key,
collection[key].toObject()["value"], true);
}
}
else
{
// TODO add support for 1-setOf in collections
Q_ASSERT("FIXME-array");
encode_attr(msg, collection[key].toObject()["tag"].toInt(), key,
collection[key].toObject()["value"], true);
}
msg << (quint8)EndCollection << (quint16)0 << (quint16)0;
break;
@ -441,3 +456,8 @@ void IppMsg::encode_attr(Bytestream& msg, quint8 tag, QString name, QJsonValue v
break;
}
}
void IppMsg::setOpAttr(QString name, IppMsg::IppTag type, QJsonValue value)
{
_opAttrs.insert(name, QJsonObject {{"tag", type}, {"value", value}});
}

View file

@ -76,6 +76,8 @@ public:
QJsonArray getJobAttrs() {return _jobAttrs;}
QJsonObject getOpAttrs() {return _opAttrs;}
void setOpAttr(QString name, IppMsg::IppTag type, QJsonValue value);
quint16 getStatus() {return _status;}
@ -86,6 +88,7 @@ private:
QJsonValue collect_attributes(QJsonArray& attrs);
QString consume_attribute(QJsonObject& attrs, Bytestream& data);
void encode_attr(Bytestream& msg, quint8 tag, QString name, QJsonValue value, bool subCollection=false);
void encode_value(Bytestream& msg, quint8 tag, QJsonValue value);
Operation _operation;

View file

@ -1,6 +1,7 @@
#include "ippprinter.h"
#include "ippdiscovery.h"
#include "mimer.h"
#include "convertchecker.h"
#include "papersizes.h"
#include "overrider.h"
#include "settings.h"
@ -9,34 +10,32 @@
Q_DECLARE_METATYPE(QMargins)
Q_DECLARE_METATYPE(IppMsg)
IppPrinter::IppPrinter() : _worker(this)
IppPrinter::IppPrinter()
{
_worker = new PrinterWorker(this);
QObject::connect(this, &IppPrinter::urlChanged, this, &IppPrinter::onUrlChanged);
qRegisterMetaType<QTemporaryFile*>("QTemporaryFile*");
_worker.moveToThread(&_workerThread);
connect(this, &IppPrinter::doDoGetPrinterAttributes, _worker, &PrinterWorker::getPrinterAttributes);
connect(this, &IppPrinter::doGetJobs, _worker, &PrinterWorker::getJobs);
connect(this, &IppPrinter::doCancelJob, _worker, &PrinterWorker::cancelJob);
connect(this, &IppPrinter::doIdentify, _worker, &PrinterWorker::identify);
connect(this, &IppPrinter::doPrint, _worker, &PrinterWorker::print);
connect(this, &IppPrinter::doPrint2, _worker, &PrinterWorker::print2);
connect(this, &IppPrinter::doDoGetPrinterAttributes, &_worker, &PrinterWorker::getPrinterAttributes);
connect(this, &IppPrinter::doGetJobs, &_worker, &PrinterWorker::getJobs);
connect(this, &IppPrinter::doCancelJob, &_worker, &PrinterWorker::cancelJob);
connect(this, &IppPrinter::doIdentify, &_worker, &PrinterWorker::identify);
connect(this, &IppPrinter::doPrint, &_worker, &PrinterWorker::print);
connect(this, &IppPrinter::doGetStrings, _worker, &PrinterWorker::getStrings);
connect(this, &IppPrinter::doGetImage, _worker, &PrinterWorker::getImage);
connect(this, &IppPrinter::doGetStrings, &_worker, &PrinterWorker::getStrings);
connect(this, &IppPrinter::doGetImage, &_worker, &PrinterWorker::getImage);
connect(&_worker, &PrinterWorker::progress, this, &IppPrinter::setProgress);
connect(&_worker, &PrinterWorker::busyMessage, this, &IppPrinter::setBusyMessage);
connect(&_worker, &PrinterWorker::failed, this, &IppPrinter::convertFailed);
connect(_worker, &PrinterWorker::progress, this, &IppPrinter::setProgress);
connect(_worker, &PrinterWorker::busyMessage, this, &IppPrinter::setBusyMessage);
connect(_worker, &PrinterWorker::failed, this, &IppPrinter::convertFailed);
qRegisterMetaType<QMargins>();
qRegisterMetaType<IppMsg>();
_workerThread.start();
}
IppPrinter::~IppPrinter() {
}
QJsonObject IppPrinter::opAttrs() {
@ -84,6 +83,7 @@ void IppPrinter::setUrl(QString url_s)
void IppPrinter::onUrlChanged()
{
QMetaObject::invokeMethod(_worker, "urlChanged", Q_ARG(QUrl, httpUrl()));
refresh();
}
@ -419,16 +419,16 @@ QString targetFormatIfAuto(QString documentFormat, QString mimeType, QJsonArray
return documentFormat;
}
void IppPrinter::adjustRasterSettings(QString documentFormat, QJsonObject& jobAttrs, PrintParameters& Params)
void IppPrinter::adjustRasterSettings(QString filename, QString mimeType, QJsonObject& jobAttrs, PrintParameters& Params)
{
if(documentFormat != Mimer::PWG && documentFormat != Mimer::URF)
if(Params.format != PrintParameters::PWG && Params.format != PrintParameters::URF)
{
return;
}
//TODO? jobAttrs.remove("printer-resolution");
jobAttrs.remove("printer-resolution");
if(documentFormat == Mimer::PWG)
if(Params.format == PrintParameters::PWG)
{
quint32 diff = std::numeric_limits<quint32>::max();
quint32 AdjustedHwResX = Params.hwResW;
@ -451,9 +451,8 @@ void IppPrinter::adjustRasterSettings(QString documentFormat, QJsonObject& jobAt
Params.hwResW = AdjustedHwResX;
Params.hwResH = AdjustedHwResY;
}
if(documentFormat == Mimer::URF)
{ // Ensure symmetric resolution for URF
else if(Params.format == PrintParameters::URF)
{ // Ensure Params.format resolution for URF
Params.hwResW = Params.hwResH = std::min(Params.hwResW, Params.hwResH);
quint32 diff = std::numeric_limits<quint32>::max();
@ -486,7 +485,7 @@ void IppPrinter::adjustRasterSettings(QString documentFormat, QJsonObject& jobAt
if(Sides != "" && Sides != "one-sided")
{
if(documentFormat == Mimer::PWG)
if(Params.format == PrintParameters::PWG)
{
QString DocumentSheetBack = _attrs["pwg-raster-document-sheet-back"].toObject()["value"].toString();
if(Sides=="two-sided-long-edge")
@ -514,7 +513,7 @@ void IppPrinter::adjustRasterSettings(QString documentFormat, QJsonObject& jobAt
}
}
}
else if(documentFormat == Mimer::URF)
else if(Params.format == PrintParameters::URF)
{
QJsonArray URfSupported = _attrs["urf-supported"].toObject()["value"].toArray();
if(Sides=="two-sided-long-edge")
@ -544,6 +543,47 @@ void IppPrinter::adjustRasterSettings(QString documentFormat, QJsonObject& jobAt
}
}
int copies_requested = getAttrOrDefault(jobAttrs, "copies").toInt(1);
QJsonArray varying_attributes = _attrs["document-format-varying-attributes"].toObject()["value"].toArray();
bool supports_copies = _attrs.contains("copies-supported")
&& _attrs["copies-supported"].toObject()["value"].toObject()["high"].toInt(1) != 1
// assume raster formats causes the variation in supported copies
&& !(varying_attributes.contains("copies-supported") || varying_attributes.contains("copies"));
if(copies_requested > 1 && !supports_copies)
{
QString copyMode = getAttrOrDefault(jobAttrs, "multiple-document-handling").toString();
qDebug() << "Doing local copies" << copyMode << copies_requested;
if(copyMode == "separate-documents-uncollated-copies")
{ // Only do silly copies if explicitly requested
Params.pageCopies = copies_requested;
}
else
{
Params.documentCopies = copies_requested;
}
jobAttrs.remove("copies");
if(Sides != "one-sided")
{
bool singlePageRange = false;
if(Params.pageRangeList.size() == 1)
{
size_t fromPage = Params.pageRangeList.begin()->first;
size_t toPage = Params.pageRangeList.begin()->second;
singlePageRange = fromPage != 0 && fromPage == toPage;
}
bool singlePageDocument = (Mimer::instance()->isImage(mimeType) ||
(mimeType == Mimer::PDF && ConvertChecker::instance()->pdfPages(filename) == 1));
if(singlePageDocument || singlePageRange)
{
jobAttrs.insert("sides", QJsonObject {{"tag", IppMsg::Keyword}, {"value", "one-sided"}});
qDebug() << "Optimizing one-page document to one-sided";
}
}
}
}
void IppPrinter::print(QJsonObject jobAttrs, QString filename)
@ -574,10 +614,11 @@ void IppPrinter::print(QJsonObject jobAttrs, QString filename)
qDebug() << supportedMimeTypes << supportedMimeTypes.contains(mimeType);
QJsonObject o = opAttrs();
o.insert("job-name", QJsonObject {{"tag", IppMsg::NameWithoutLanguage}, {"value", fileinfo.fileName()}});
Params.paperSizeName = getAttrOrDefault(jobAttrs, "media").toString(Params.paperSizeName.c_str()).toStdString();
if(!Params.setPaperSize(getAttrOrDefault(jobAttrs, "media").toString(Params.paperSizeName.c_str()).toStdString()))
{
emit convertFailed(tr("Unsupported paper size"));
return;
}
QString targetFormat = getAttrOrDefault(jobAttrs, "document-format").toString();
qDebug() << "target format:" << targetFormat;
@ -612,14 +653,9 @@ void IppPrinter::print(QJsonObject jobAttrs, QString filename)
if(jobAttrs.contains("media-col") && jobAttrs.contains("media"))
{
qDebug() << "moving media to media-col" << Params.paperSizeName.c_str();
if(!PaperSizes.contains(Params.paperSizeName.c_str()))
{
emit convertFailed(tr("Unsupported paper size"));
return;
}
int x = PaperSizes[Params.paperSizeName.c_str()].width()*100;
int y = PaperSizes[Params.paperSizeName.c_str()].height()*100;
int x = Params.getPaperSizeWInMillimeters()*100;
int y = Params.getPaperSizeHInMillimeters()*100;
QJsonObject Dimensions =
{{"tag", IppMsg::BeginCollection},
@ -638,8 +674,9 @@ void IppPrinter::print(QJsonObject jobAttrs, QString filename)
jobAttrs.remove("media");
}
QJsonObject jobOpAttrs = opAttrs();
// document-format goes in the op-attrs and not the job-attrs
o.insert("document-format", QJsonObject {{"tag", IppMsg::MimeMediaType}, {"value", targetFormat}});
jobOpAttrs.insert("document-format", QJsonObject {{"tag", IppMsg::MimeMediaType}, {"value", targetFormat}});
jobAttrs.remove("document-format");
targetFormat = targetFormatIfAuto(targetFormat, mimeType, supportedMimeTypes);
@ -672,39 +709,33 @@ void IppPrinter::print(QJsonObject jobAttrs, QString filename)
Params.format = PrintParameters::Invalid;
}
QSizeF size = PaperSizes[Params.paperSizeName.c_str()];
Params.paperSizeUnits = PrintParameters::Millimeters;
Params.paperSizeW = size.width();
Params.paperSizeH = size.height();
qDebug() << "Printing job" << o << jobAttrs;
qDebug() << "Printing job" << jobOpAttrs << jobAttrs;
QJsonValue PrinterResolutionRef = getAttrOrDefault(jobAttrs, "printer-resolution");
Params.hwResW = PrinterResolutionRef.toObject()["x"].toInt(Params.hwResW);
Params.hwResH = PrinterResolutionRef.toObject()["y"].toInt(Params.hwResH);
adjustRasterSettings(targetFormat, jobAttrs, Params);
Params.quality = getAttrOrDefault(jobAttrs, "print-quality").toInt();
QString PrintColorMode = getAttrOrDefault(jobAttrs, "print-color-mode").toString();
Params.colors = PrintColorMode.contains("color") ? 3 : PrintColorMode.contains("monochrome") ? 1 : Params.colors;
if(jobAttrs.contains("page-ranges"))
// Effected locally, unless it is Postscript which we cant't render
if(jobAttrs.contains("page-ranges") && mimeType != Mimer::Postscript)
{
QJsonObject PageRanges = getAttrOrDefault(jobAttrs, "page-ranges").toObject();
Params.fromPage = PageRanges["low"].toInt();
Params.toPage = PageRanges["high"].toInt();
// Effected locally, unless it is Postscript which we cant't render
if(targetFormat != Mimer::Postscript)
QJsonArray tmp;
QJsonValue pageRanges = getAttrOrDefault(jobAttrs, "page-ranges");
if(pageRanges.isArray())
{
jobAttrs.remove("page-ranges");
tmp = pageRanges.toArray();
}
else if(pageRanges.isObject())
{
tmp = {pageRanges.toObject()};
}
for(QJsonValueRef ref : tmp)
{
Params.pageRangeList.push_back({ref.toObject()["low"].toInt(), ref.toObject()["high"].toInt()});
}
jobAttrs.remove("page-ranges");
}
qDebug() << "Final op attributes:" << o;
qDebug() << "Final job attributes:" << jobAttrs;
adjustRasterSettings(filename, mimeType, jobAttrs, Params);
QString Sides = getAttrOrDefault(jobAttrs, "sides").toString();
@ -718,8 +749,39 @@ void IppPrinter::print(QJsonObject jobAttrs, QString filename)
Params.tumble = true;
}
IppMsg job = mk_msg(IppMsg::PrintJob, o, jobAttrs);
emit doPrint(filename, mimeType, targetFormat, job, Params, margins);
Params.quality = getAttrOrDefault(jobAttrs, "print-quality").toInt();
QString PrintColorMode = getAttrOrDefault(jobAttrs, "print-color-mode").toString();
Params.colors = PrintColorMode.contains("color") ? 3 : PrintColorMode.contains("monochrome") ? 1 : Params.colors;
QJsonArray supportedOperations = _attrs["operations-supported"].toObject()["value"].toArray();
if(supportedOperations.contains(IppMsg::CreateJob) && supportedOperations.contains(IppMsg::SendDocument))
{
QJsonObject createJobOpAttrs = opAttrs();
createJobOpAttrs.insert("job-name", QJsonObject {{"tag", IppMsg::NameWithoutLanguage}, {"value", fileinfo.fileName()}});
qDebug() << "Final create op attributes:" << createJobOpAttrs;
qDebug() << "Final job attributes:" << jobAttrs;
IppMsg createJob = mk_msg(IppMsg::CreateJob, createJobOpAttrs, jobAttrs);
qDebug() << "Final job op attributes:" << jobOpAttrs;
IppMsg sendDoc = mk_msg(IppMsg::SendDocument, jobOpAttrs);
emit doPrint2(filename, mimeType, targetFormat, createJob, sendDoc, Params, margins);
}
else
{
jobOpAttrs.insert("job-name", QJsonObject {{"tag", IppMsg::NameWithoutLanguage}, {"value", fileinfo.fileName()}});
qDebug() << "Final op attributes:" << jobOpAttrs;
qDebug() << "Final job attributes:" << jobAttrs;
IppMsg job = mk_msg(IppMsg::PrintJob, jobOpAttrs, jobAttrs);
emit doPrint(filename, mimeType, targetFormat, job, Params, margins);
}
}
bool IppPrinter::getJobs() {

View file

@ -73,6 +73,7 @@ signals:
void doConvertPlaintext(QString filename, Bytestream header, PrintParameters Params);
void doPrint(QString filename, QString mimeType, QString targetFormat, IppMsg job, PrintParameters Params, QMargins margins);
void doPrint2(QString filename, QString mimeType, QString targetFormat, IppMsg createJob, IppMsg sendDocument, PrintParameters Params, QMargins margins);
void doGetStrings(QUrl url);
void doGetImage(QUrl url);
@ -84,7 +85,6 @@ signals:
public slots:
void print(QJsonObject attrs, QString file);
void onUrlChanged();
void MaybeGetStrings();
void MaybeGetIcon(bool retry=false);
@ -107,7 +107,7 @@ private:
QJsonObject opAttrs();
void adjustRasterSettings(QString documentFormat, QJsonObject& jobAttrs, PrintParameters& Params);
void adjustRasterSettings(QString filename, QString mimeType, QJsonObject& jobAttrs, PrintParameters& Params);
void setBusyMessage(QString msg);
void setProgress(qint64 sent, qint64 total);
@ -130,8 +130,7 @@ private:
QString _busyMessage;
QString _progress;
QThread _workerThread;
PrinterWorker _worker;
PrinterWorker* _worker;
bool _iconRetried = false;
};

View file

@ -55,5 +55,12 @@ Mimer* Mimer::instance()
QString Mimer::get_type(QString filename) {
QString type = _db.mimeTypeForFile(filename).name();
qDebug() << "MimeType:" << type;
return type;
if(type == PDF || type == Postscript || type == Plaintext || isImage(type) || isOffice(type))
{
return type;
}
else
{
return "";
}
}

View file

@ -3,208 +3,6 @@
#include <QMap>
#include <QSizeF>
static QMap<QString, QSizeF> PaperSizes =
{{"asme_f_28x40in", {711.20, 1016.00}},
{"iso_2a0_1189x1682mm", {1189.00, 1682.00}},
{"iso_a0_841x1189mm", {841.00, 1189.00}},
{"iso_a0x3_1189x2523mm", {1189.00, 2523.00}},
{"iso_a10_26x37mm", {26.00, 37.00}},
{"iso_a1_594x841mm", {594.00, 841.00}},
{"iso_a1x3_841x1783mm", {841.00, 1783.00}},
{"iso_a1x4_841x2378mm", {841.00, 2378.00}},
{"iso_a2_420x594mm", {420.00, 594.00}},
{"iso_a2x3_594x1261mm", {594.00, 1261.00}},
{"iso_a2x4_594x1682mm", {594.00, 1682.00}},
{"iso_a2x5_594x2102mm", {594.00, 2102.00}},
{"iso_a3-extra_322x445mm", {322.00, 445.00}},
{"iso_a3_297x420mm", {297.00, 420.00}},
{"iso_a3x3_420x891mm", {420.00, 891.00}},
{"iso_a3x4_420x1189mm", {420.00, 1189.00}},
{"iso_a3x5_420x1486mm", {420.00, 1486.00}},
{"iso_a3x6_420x1783mm", {420.00, 1783.00}},
{"iso_a3x7_420x2080mm", {420.00, 2080.00}},
{"iso_a4-extra_235.5x322.3m", {235.50, 322.30}},
{"iso_a4-tab_225x297mm", {225.00, 297.00}},
{"iso_a4_210x297mm", {210.00, 297.00}},
{"iso_a4x3_297x630mm", {297.00, 630.00}},
{"iso_a4x4_297x841mm", {297.00, 841.00}},
{"iso_a4x5_297x1051mm", {297.00, 1051.00}},
{"iso_a4x6_297x1261mm", {297.00, 1261.00}},
{"iso_a4x7_297x1471mm", {297.00, 1471.00}},
{"iso_a4x8_297x1682mm", {297.00, 1682.00}},
{"iso_a4x9_297x1892mm", {297.00, 1892.00}},
{"iso_a5-extra_174x235mm", {174.00, 235.00}},
{"iso_a5_148x210mm", {148.00, 210.00}},
{"iso_a6_105x148mm", {105.00, 148.00}},
{"iso_a7_74x105mm", {74.00, 105.00}},
{"iso_a8_52x74mm", {52.00, 74.00}},
{"iso_a9_37x52mm", {37.00, 52.00}},
{"iso_b0_1000x1414mm", {1000.00, 1414.00}},
{"iso_b10_31x44mm", {31.00, 44.00}},
{"iso_b1_707x1000mm", {707.00, 1000.00}},
{"iso_b2_500x707mm", {500.00, 707.00}},
{"iso_b3_353x500mm", {353.00, 500.00}},
{"iso_b4_250x353mm", {250.00, 353.00}},
{"iso_b5-extra_201x276mm", {201.00, 276.00}},
{"iso_b5_176x250mm", {176.00, 250.00}},
{"iso_b6_125x176mm", {125.00, 176.00}},
{"iso_b6c4_125x324mm", {125.00, 324.00}},
{"iso_b7_88x125mm", {88.00, 125.00}},
{"iso_b8_62x88mm", {62.00, 88.00}},
{"iso_b9_44x62mm", {44.00, 62.00}},
{"iso_c0_917x1297mm", {917.00, 1297.00}},
{"iso_c10_28x40mm", {28.00, 40.00}},
{"iso_c1_648x917mm", {648.00, 917.00}},
{"iso_c2_458x648mm", {458.00, 648.00}},
{"iso_c3_324x458mm", {324.00, 458.00}},
{"iso_c4_229x324mm", {229.00, 324.00}},
{"iso_c5_162x229mm", {162.00, 229.00}},
{"iso_c6_114x162mm", {114.00, 162.00}},
{"iso_c6c5_114x229mm", {114.00, 229.00}},
{"iso_c7_81x114mm", {81.00, 114.00}},
{"iso_c7c6_81x162mm", {81.00, 162.00}},
{"iso_c8_57x81mm", {57.00, 81.00}},
{"iso_c9_40x57mm", {40.00, 57.00}},
{"iso_dl_110x220mm", {110.00, 220.00}},
{"iso_id-1_53.98x85.6mm", {53.98, 85.60}},
{"iso_id-3_88x125mm", {88.00, 125.00}},
{"iso_ra0_860x1220mm", {860.00, 1220.00}},
{"iso_ra1_610x860mm", {610.00, 860.00}},
{"iso_ra2_430x610mm", {430.00, 610.00}},
{"iso_ra3_305x430mm", {305.00, 430.00}},
{"iso_ra4_215x305mm", {215.00, 305.00}},
{"iso_sra0_900x1280mm", {900.00, 1280.00}},
{"iso_sra1_640x900mm", {640.00, 900.00}},
{"iso_sra2_450x640mm", {450.00, 640.00}},
{"iso_sra3_320x450mm", {320.00, 450.00}},
{"iso_sra4_225x320mm", {225.00, 320.00}},
{"jis_b0_1030x1456mm", {1030.00, 1456.00}},
{"jis_b10_32x45mm", {32.00, 45.00}},
{"jis_b1_728x1030mm", {728.00, 1030.00}},
{"jis_b2_515x728mm", {515.00, 728.00}},
{"jis_b3_364x515mm", {364.00, 515.00}},
{"jis_b4_257x364mm", {257.00, 364.00}},
{"jis_b5_182x257mm", {182.00, 257.00}},
{"jis_b6_128x182mm", {128.00, 182.00}},
{"jis_b7_91x128mm", {91.00, 128.00}},
{"jis_b8_64x91mm", {64.00, 91.00}},
{"jis_b9_45x64mm", {45.00, 64.00}},
{"jis_exec_216x330mm", {216.00, 330.00}},
{"jpn_chou2_111.1x146mm", {111.10, 146.00}},
{"jpn_chou3_120x235mm", {120.00, 235.00}},
{"jpn_chou40_90x225mm", {90.00, 225.00}},
{"jpn_chou4_90x205mm", {90.00, 205.00}},
{"jpn_hagaki_100x148mm", {100.00, 148.00}},
{"jpn_kahu_240x322.1mm", {240.00, 322.10}},
{"jpn_kaku1_270x382mm", {270.00, 382.00}},
{"jpn_kaku2_240x332mm", {240.00, 332.00}},
{"jpn_kaku3_216x277mm", {216.00, 277.00}},
{"jpn_kaku4_197x267mm", {197.00, 267.00}},
{"jpn_kaku5_190x240mm", {190.00, 240.00}},
{"jpn_kaku7_142x205mm", {142.00, 205.00}},
{"jpn_kaku8_119x197mm", {119.00, 197.00}},
{"jpn_oufuku_148x200mm", {148.00, 200.00}},
{"jpn_you4_105x235mm", {105.00, 235.00}},
{"na_10x11_10x11in", {254.00, 279.40}},
{"na_10x13_10x13in", {254.00, 330.20}},
{"na_10x14_10x14in", {254.00, 355.60}},
{"na_10x15_10x15in", {254.00, 381.00}},
{"na_11x12_11x12in", {279.40, 304.80}},
{"na_11x15_11x15in", {279.40, 381.00}},
{"na_12x19_12x19in", {304.80, 482.60}},
{"na_5x7_5x7in", {127.00, 177.80}},
{"na_6x9_6x9in", {152.40, 228.60}},
{"na_7x9_7x9in", {177.80, 228.60}},
{"na_9x11_9x11in", {228.60, 279.40}},
{"na_a2_4.375x5.75in", {111.12, 146.05}},
{"na_arch-a_9x12in", {228.60, 304.80}},
{"na_arch-b_12x18in", {304.80, 457.20}},
{"na_arch-c_18x24in", {457.20, 609.60}},
{"na_arch-d_24x36in", {609.60, 914.40}},
{"na_arch-e2_26x38in", {660.40, 965.20}},
{"na_arch-e3_27x39in", {685.80, 990.60}},
{"na_arch-e_36x48in", {914.40, 1219.20}},
{"na_b-plus_12x19.17in", {304.80, 486.92}},
{"na_c5_6.5x9.5in", {165.10, 241.30}},
{"na_c_17x22in", {431.80, 558.80}},
{"na_d_22x34in", {558.80, 863.60}},
{"na_e_34x44in", {863.60, 1117.60}},
{"na_edp_11x14in", {279.40, 355.60}},
{"na_eur-edp_12x14in", {304.80, 355.60}},
{"na_executive_7.25x10.5in", {184.15, 266.70}},
{"na_f_44x68in", {1117.60, 1727.20}},
{"na_fanfold-eur_8.5x12in", {215.90, 304.80}},
{"na_fanfold-us_11x14.875in", {279.40, 377.82}},
{"na_foolscap_8.5x13in", {215.90, 330.20}},
{"na_govt-legal_8x13in", {203.20, 330.20}},
{"na_govt-letter_8x10in", {203.20, 254.00}},
{"na_index-3x5_3x5in", {76.20, 127.00}},
{"na_index-4x6-ext_6x8in", {152.40, 203.20}},
{"na_index-4x6_4x6in", {101.60, 152.40}},
{"na_index-5x8_5x8in", {127.00, 203.20}},
{"na_invoice_5.5x8.5in", {139.70, 215.90}},
{"na_ledger_11x17in", {279.40, 431.80}},
{"na_legal-extra_9.5x15in", {241.30, 381.00}},
{"na_legal_8.5x14in", {215.90, 355.60}},
{"na_letter-extra_9.5x12in", {241.30, 304.80}},
{"na_letter-plus_8.5x12.69in", {215.90, 322.33}},
{"na_letter_8.5x11in", {215.90, 279.40}},
{"na_monarch_3.875x7.5in", {98.42, 190.50}},
{"na_number-10_4.125x9.5in", {104.77, 241.30}},
{"na_number-11_4.5x10.375in", {114.30, 263.52}},
{"na_number-12_4.75x11in", {120.65, 279.40}},
{"na_number-14_5x11.5in", {127.00, 292.10}},
{"na_number-9_3.875x8.875in", {98.42, 225.42}},
{"na_oficio_8.5x13.4in", {215.90, 340.36}},
{"na_personal_3.625x6.5in", {92.07, 165.10}},
{"na_quarto_8.5x10.83in", {215.90, 275.08}},
{"na_super-a_8.94x14in", {227.08, 355.60}},
{"na_super-b_13x19in", {330.20, 482.60}},
{"na_wide-format_30x42in", {762.00, 1066.80}},
{"oe_12x16_12x16in", {304.80, 406.40}},
{"oe_14x17_14x17in", {355.60, 431.80}},
{"oe_18x22_18x22in", {457.20, 558.80}},
{"oe_a2plus_17x24in", {431.80, 609.60}},
{"oe_business-card_2x3.5in", {50.80, 88.90}},
{"oe_photo-10r_10x12in", {254.00, 304.80}},
{"oe_photo-20r_20x24in", {508.00, 609.60}},
{"oe_photo-l_3.5x5in", {88.90, 127.00}},
{"oe_photo-s10r_10x15in", {254.00, 381.00}},
{"oe_square-photo_4x4in", {101.60, 101.60}},
{"oe_square-photo_5x5in", {127.00, 127.00}},
{"om_16k_184x260mm", {184.00, 260.00}},
{"om_16k_195x270mm", {195.00, 270.00}},
{"om_business-card_55x85mm", {55.00, 85.00}},
{"om_business-card_55x91mm", {55.00, 91.00}},
{"om_card_54x86mm", {54.00, 86.00}},
{"om_dai-pa-kai_275x395mm", {275.00, 395.00}},
{"om_dsc-photo_89x119mm", {89.00, 119.00}},
{"om_folio-sp_215x315mm", {215.00, 315.00}},
{"om_folio_210x330mm", {210.00, 330.00}},
{"om_invite_220x220mm", {220.00, 220.00}},
{"om_italian_110x230mm", {110.00, 230.00}},
{"om_juuro-ku-kai_198x275mm", {198.00, 275.00}},
{"om_large-photo_200x300", {200.00, 300.00}},
{"om_medium-photo_130x180mm", {130.00, 180.00}},
{"om_pa-kai_267x389mm", {267.00, 389.00}},
{"om_postfix_114x229mm", {114.00, 229.00}},
{"om_small-photo_100x150mm", {100.00, 150.00}},
{"om_square-photo_89x89mm", {89.00, 89.00}},
{"om_wide-photo_100x200mm", {100.00, 200.00}},
{"prc_10_324x458mm", {324.00, 458.00}},
{"prc_16k_146x215mm", {146.00, 215.00}},
{"prc_1_102x165mm", {102.00, 165.00}},
{"prc_2_102x176mm", {102.00, 176.00}},
{"prc_32k_97x151mm", {97.00, 151.00}},
{"prc_3_125x176mm", {125.00, 176.00}},
{"prc_4_110x208mm", {110.00, 208.00}},
{"prc_5_110x220mm", {110.00, 220.00}},
{"prc_6_120x320mm", {120.00, 320.00}},
{"prc_7_160x230mm", {160.00, 230.00}},
{"prc_8_120x309mm", {120.00, 309.00}},
{"roc_16k_7.75x10.75in", {196.85, 273.05}},
{"roc_8k_10.75x15.5in", {273.05, 393.70}}};
static QMap<QString, QString> CalligraPaperSizes =
{{"iso_a0_841x1189mm", "A0"},
{"iso_a1_594x841mm", "A1"},

View file

@ -21,6 +21,26 @@
PrinterWorker::PrinterWorker(IppPrinter* parent)
{
_printer = parent;
_url = parent->httpUrl();
_thread.reset(new QThread);
moveToThread(_thread.get());
_thread->start();
}
PrinterWorker::~PrinterWorker()
{
QMetaObject::invokeMethod(this, "cleanup");
_thread->wait();
}
void PrinterWorker::cleanup()
{
_thread->quit();
}
void PrinterWorker::urlChanged(QUrl url)
{
_url = url;
}
void PrinterWorker::getStrings(QUrl url)
@ -38,42 +58,78 @@ void PrinterWorker::getImage(QUrl url)
void PrinterWorker::getPrinterAttributes(Bytestream msg)
{
CurlRequester cr(_printer->httpUrl());
cr.write((char*)msg.raw(), msg.size());
CurlRequester cr(_url, CurlRequester::IppRequest, &msg);
awaitResult(cr, "getPrinterAttributesFinished");
}
void PrinterWorker::getJobs(Bytestream msg)
{
CurlRequester cr(_printer->httpUrl());
cr.write((char*)msg.raw(), msg.size());
CurlRequester cr(_url, CurlRequester::IppRequest, &msg);
awaitResult(cr, "getJobsRequestFinished");
}
void PrinterWorker::cancelJob(Bytestream msg)
{
CurlRequester cr(_printer->httpUrl());
cr.write((char*)msg.raw(), msg.size());
CurlRequester cr(_url, CurlRequester::IppRequest, &msg);
awaitResult(cr, "cancelJobFinished");
}
void PrinterWorker::identify(Bytestream msg)
{
CurlRequester cr(_printer->httpUrl());
cr.write((char*)msg.raw(), msg.size());
CurlRequester cr(_url, CurlRequester::IppRequest, &msg);
awaitResult(cr, "identifyFinished");
}
void PrinterWorker::print2(QString filename, QString mimeType, QString targetFormat, IppMsg createJob, IppMsg sendDocument, PrintParameters Params, QMargins margins)
{
emit busyMessage(tr("Preparing"));
Bytestream header = createJob.encode();
CurlRequester cr(_url, CurlRequester::IppRequest, &header);
Bytestream resData;
CURLcode res = cr.await(&resData);
if(res == CURLE_OK)
{
IppMsg resMsg(resData);
qDebug() << resMsg.getOpAttrs() << resMsg.getJobAttrs();
QJsonObject resJobAttrs = resMsg.getJobAttrs()[0].toObject();
if(resMsg.getStatus() <= 0xff && resJobAttrs.contains("job-id"))
{
int jobId = resJobAttrs["job-id"].toObject()["value"].toInt();
sendDocument.setOpAttr("job-id", IppMsg::Integer, jobId);
sendDocument.setOpAttr("last-document", IppMsg::Boolean, true);
print(filename, mimeType, targetFormat, sendDocument, Params, margins);
}
else
{
resData.setPos(0);
QMetaObject::invokeMethod(_printer, "printRequestFinished", Qt::QueuedConnection,
Q_ARG(CURLcode, res),
Q_ARG(Bytestream, resData));
}
}
else
{
QMetaObject::invokeMethod(_printer, "printRequestFinished", Qt::QueuedConnection,
Q_ARG(CURLcode, res),
Q_ARG(Bytestream, resData));
}
}
void PrinterWorker::print(QString filename, QString mimeType, QString targetFormat, IppMsg job, PrintParameters Params, QMargins margins)
{
try {
try
{
Mimer* mimer = Mimer::instance();
Bytestream contents = job.encode();
emit busyMessage(tr("Preparing"));
if((mimeType == targetFormat) && (targetFormat == Mimer::Postscript))
{ // Can't process Postscript
justUpload(filename, contents);
@ -94,7 +150,14 @@ void PrinterWorker::print(QString filename, QString mimeType, QString targetForm
}
else if(mimeType == Mimer::Plaintext)
{
convertPlaintext(filename, contents, Params);
if(Params.paperSizeH == 0 && Params.getPaperSizeWInMillimeters() < 26)
{
convertPlaintextLabel(filename, contents, Params);
}
else
{
convertPlaintext(filename, contents, Params);
}
}
else if(Mimer::isImage(mimeType))
{
@ -126,7 +189,7 @@ void PrinterWorker::justUpload(QString filename, Bytestream header)
{
emit busyMessage(tr("Printing"));
CurlRequester cr(_printer->httpUrl());
CurlRequester cr(_url);
QFile file(filename);
file.open(QFile::ReadOnly);
@ -145,8 +208,6 @@ void PrinterWorker::printImageAsImage(QString filename, Bytestream header, QStri
QStringList supportedImageFormats = {Mimer::JPEG, Mimer::PNG};
qDebug() << ((IppPrinter*)parent())->_attrs;
if(targetFormat == Mimer::RBMP)
{
// ok
@ -163,7 +224,7 @@ void PrinterWorker::printImageAsImage(QString filename, Bytestream header, QStri
QString mimeType = Mimer::instance()->get_type(filename);
Bytestream OutBts;
CurlRequester cr(_printer->httpUrl());
CurlRequester cr(_url);
if(mimeType == Mimer::JPEG && targetFormat == Mimer::JPEG)
{
@ -233,7 +294,7 @@ void PrinterWorker::printImageAsImage(QString filename, Bytestream header, QStri
void PrinterWorker::fixupPlaintext(QString filename, Bytestream header)
{
CurlRequester cr(_printer->httpUrl());
CurlRequester cr(_url);
QFile inFile(filename);
if(!inFile.open(QIODevice::ReadOnly))
@ -275,7 +336,7 @@ void PrinterWorker::convertPdf(QString filename, Bytestream header, PrintParamet
{
emit busyMessage(tr("Printing"));
CurlRequester cr(_printer->httpUrl());
CurlRequester cr(_url);
OK(cr.write((char*)header.raw(), header.size()));
@ -400,6 +461,14 @@ void PrinterWorker::convertImage(QString filename, Bytestream header, PrintParam
}
else
{
size_t total_pages = Params.documentCopies*Params.pageCopies;
if(total_pages > 1 && Params.duplex)
{ // Images are one page by definition - if we need to do client-side copies, they must be one-sided or we'd have to insert backsides
qDebug() << "Inconsistent duplex setting";
throw ConvertFailedException(tr("Inconsistent duplex setting"));
}
QImage outImage = QImage(Params.getPaperSizeWInPixels(), Params.getPaperSizeHInPixels(), inImage.format());
outImage.fill(Qt::white);
QPainter painter(&outImage);
@ -410,7 +479,7 @@ void PrinterWorker::convertImage(QString filename, Bytestream header, PrintParam
QBuffer buf;
buf.open(QIODevice::ReadWrite);
Bytestream outBts;
Bytestream fileHdr, outBts;
if(inImage.allGray())
@ -435,18 +504,23 @@ void PrinterWorker::convertImage(QString filename, Bytestream header, PrintParam
buf.read((char*)(inBts.raw()), inBts.size());
outBts << (Params.format == PrintParameters::URF ? make_urf_file_hdr(1) : make_pwg_file_hdr());
fileHdr << (Params.format == PrintParameters::URF ? make_urf_file_hdr(1) : make_pwg_file_hdr());
bool verbose = QLoggingCategory::defaultCategory()->isDebugEnabled();
bmp_to_pwg(inBts, outBts, 1, Params, verbose);
CurlRequester cr(_printer->httpUrl());
CurlRequester cr(_url);
emit busyMessage(tr("Printing"));
OK(cr.write((char*)header.raw(), header.size()));
OK(cr.write((char*)(outBts.raw()), outBts.size()));
OK(cr.write((char*)fileHdr.raw(), fileHdr.size()));
for(size_t c = 0; c < total_pages; c++)
{
OK(cr.write((char*)(outBts.raw()), outBts.size()));
emit progress(c+1, total_pages);
}
awaitResult(cr, "printRequestFinished");
}
@ -513,12 +587,22 @@ void PrinterWorker::convertOfficeDocument(QString filename, Bytestream header, P
void PrinterWorker::convertPlaintext(QString filename, Bytestream header, PrintParameters Params)
{
if(!PaperSizes.contains(Params.paperSizeName.c_str()))
QPageSize pageSize;
if(Params.paperSizeUnits == PrintParameters::Millimeters)
{
pageSize = QPageSize(QSizeF {Params.paperSizeW, Params.paperSizeH}, QPageSize::Millimeter);
}
else if(Params.paperSizeUnits == PrintParameters::Inches)
{
pageSize = QPageSize(QSizeF {Params.paperSizeW, Params.paperSizeH}, QPageSize::Inch);
}
else
{
qDebug() << "Unsupported paper size" << Params.paperSizeName.c_str();
throw ConvertFailedException(tr("Unsupported paper size"));
}
QSizeF size = PaperSizes[Params.paperSizeName.c_str()];
QFile inFile(filename);
if(!inFile.open(QIODevice::ReadOnly))
@ -533,7 +617,7 @@ void PrinterWorker::convertPlaintext(QString filename, Bytestream header, PrintP
QPdfWriter pdfWriter(tmpPdfFile.fileName());
pdfWriter.setCreator("SeaPrint " SEAPRINT_VERSION);
QPageSize pageSize(size, QPageSize::Millimeter);
pdfWriter.setPageSize(pageSize);
pdfWriter.setResolution(resolution);
@ -572,7 +656,6 @@ void PrinterWorker::convertPlaintext(QString filename, Bytestream header, PrintP
doc.setDefaultFont(font);
(void)doc.documentLayout(); // wat
// Needs to be before painter
pdfWriter.setMargins({mmMargin, mmMargin, mmMargin, mmMargin});
@ -655,6 +738,70 @@ void PrinterWorker::convertPlaintext(QString filename, Bytestream header, PrintP
qDebug() << "posted";
}
void PrinterWorker::convertPlaintextLabel(QString filename, Bytestream header, PrintParameters Params)
{
QFile inFile(filename);
if(!inFile.open(QIODevice::ReadOnly))
{
throw ConvertFailedException(tr("Failed to open file"));
}
QString allText = inFile.readAll();
while(allText.endsWith('\n'))
{
allText.chop(1);
}
if(allText.contains('\n') || allText.contains('\f'))
{
throw ConvertFailedException(tr("Multiline label not supported"));
}
QTemporaryFile tmpPdfFile;
tmpPdfFile.open();
// NB: running with rotated format - pdf2printable will sort that out
int pixelHeight = Params.getPaperSizeWInPixels();
QFont font = QFont("Arial");
font.setPixelSize(pixelHeight);
QFontMetrics fm(font);
QString bigText = "AXgjqÈÅÄÖþ";
QRect rect = fm.boundingRect(bigText);
while(rect.height() > pixelHeight*(8.0/10.0))
{
font.setPixelSize(font.pixelSize()-1);
fm = QFontMetrics(font);
rect = fm.boundingRect(bigText);
}
rect = fm.boundingRect(allText);
int pixelWidth = rect.width() + pixelHeight/2;
float ratio = pixelWidth*1.0/pixelHeight;
Params.paperSizeH = Params.paperSizeW * ratio;
QPdfWriter pdfWriter(tmpPdfFile.fileName());
pdfWriter.setCreator("SeaPrint " SEAPRINT_VERSION);
QPageSize pageSize({Params.getPaperSizeHInPoints(), Params.getPaperSizeWInPoints()}, QPageSize::Point);
pdfWriter.setPageSize(pageSize);
pdfWriter.setMargins({0,0,0,0});
pdfWriter.setResolution(Params.hwResH);
QPainter painter(&pdfWriter);
int xOffset = -rect.x() + pixelHeight/4;
int yOffset = -rect.y() + pixelHeight/10;
painter.setFont(font);
painter.drawText(xOffset, yOffset, allText);
painter.end();
convertPdf(tmpPdfFile.fileName(), header, Params);
qDebug() << "Finished";
qDebug() << "posted";
}
void PrinterWorker::awaitResult(CurlRequester& cr, QString callback)
{
Bytestream resMsg;

View file

@ -1,6 +1,7 @@
#ifndef PRINTERWORKER_H
#define PRINTERWORKER_H
#include <QObject>
#include <memory>
#include "curlrequester.h"
#include "ippmsg.h"
#include "ppm2pwg/printparameters.h"
@ -27,11 +28,13 @@ class PrinterWorker : public QObject
public:
PrinterWorker(IppPrinter* parent);
~PrinterWorker();
private:
PrinterWorker();
public slots:
void urlChanged(QUrl url);
void getStrings(QUrl url);
void getImage(QUrl url);
void getPrinterAttributes(Bytestream msg);
@ -39,6 +42,10 @@ public slots:
void cancelJob(Bytestream msg);
void identify(Bytestream msg);
void print(QString filename, QString mimeType, QString targetFormat, IppMsg job, PrintParameters Params, QMargins margins);
void print2(QString filename, QString mimeType, QString targetFormat, IppMsg createJob, IppMsg sendDocument, PrintParameters Params, QMargins margins);
private slots:
void cleanup();
signals:
void progress(qint64 done, qint64 pages);
@ -53,11 +60,13 @@ private:
void convertImage(QString filename, Bytestream header, PrintParameters Params, QMargins margins);
void convertOfficeDocument(QString filename, Bytestream header, PrintParameters Params);
void convertPlaintext(QString filename, Bytestream header, PrintParameters Params);
void convertPlaintextLabel(QString filename, Bytestream header, PrintParameters Params);
void awaitResult(CurlRequester& cr, QString callback);
IppPrinter* _printer;
std::unique_ptr<QThread> _thread;
QPointer<IppPrinter> _printer;
QUrl _url;
};
#endif // PRINTERWORKER_H

47
src/rangelistchecker.cpp Normal file
View file

@ -0,0 +1,47 @@
#include "rangelistchecker.h"
RangeListChecker::RangeListChecker()
{
}
RangeListChecker::~RangeListChecker()
{
}
RangeListChecker* RangeListChecker::m_Instance = 0;
RangeListChecker* RangeListChecker::instance()
{
static QMutex mutex;
if (!m_Instance)
{
mutex.lock();
if (!m_Instance)
m_Instance = new RangeListChecker;
mutex.unlock();
}
return m_Instance;
}
QJsonArray RangeListChecker::parse(QString str) const
{
PrintParameters params;
params.setPageRange(str.toStdString());
QJsonArray ret;
size_t previous = 0;
for(const std::pair<size_t, size_t>& p : params.pageRangeList)
{
if(p.first <= previous)
{
return {};
}
ret.append(QJsonObject {{"low", int(p.first)}, {"high", int(p.second)}});
previous = p.second;
}
return ret;
}

29
src/rangelistchecker.h Normal file
View file

@ -0,0 +1,29 @@
#ifndef RANGELISTCHECKER_H
#define RANGELISTCHECKER_H
#include <QValidator>
#include <QMutex>
#include <QJsonArray>
#include <QJsonObject>
#include "printparameters.h"
class RangeListChecker : public QObject
{
Q_OBJECT
public:
static RangeListChecker* instance();
Q_INVOKABLE QJsonArray parse(QString str) const;
private:
static RangeListChecker* m_Instance;
RangeListChecker();
~RangeListChecker();
RangeListChecker(const RangeListChecker &);
RangeListChecker& operator=(const RangeListChecker &);
};
#endif // RANGELISTCHECKER_H

View file

@ -0,0 +1,21 @@
#include "seaprintdbusadaptor.h"
#include <QtQuick>
SeaPrintDBusAdaptor::SeaPrintDBusAdaptor(QQuickView *view)
: QDBusAbstractAdaptor(view)
, DBusAdaptorBase(view)
{
}
SeaPrintDBusAdaptor::~SeaPrintDBusAdaptor()
{
}
void SeaPrintDBusAdaptor::Open(const QString& fileName)
{
doOpen(fileName);
}
void SeaPrintDBusAdaptor::OpenPlaintext(const QString& fileContents, const QString& name)
{
doCreateFileAndOpen(fileContents, name);
}

21
src/seaprintdbusadaptor.h Normal file
View file

@ -0,0 +1,21 @@
#ifndef SEAPRINTDBUSADAPTOR_H
#define SEAPRINTDBUSADAPTOR_H
#include "dbusadaptorbase.h"
class SeaPrintDBusAdaptor : public QDBusAbstractAdaptor, public DBusAdaptorBase
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "net.attah.seaprint")
public:
SeaPrintDBusAdaptor(QQuickView *view);
~SeaPrintDBusAdaptor();
public Q_SLOTS:
Q_NOREPLY void Open(const QString& fileName);
Q_NOREPLY void OpenPlaintext(const QString& fileContents, const QString& name);
};
#endif // SEAPRINTDBUSADAPTOR_H

File diff suppressed because it is too large Load diff

View file

@ -276,10 +276,6 @@
<source>Not on WiFi</source>
<translation>No hay WiFi</translation>
</message>
<message>
<source>Unsupported document format</source>
<translation>Formato de documento no soportado</translation>
</message>
<message>
<source>This format may not render correctly</source>
<translation>Este formato puede no renderizarse correctamente</translation>
@ -519,6 +515,14 @@
<source>Print error</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Inconsistent duplex setting</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Multiline label not supported</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RangeSetting</name>
@ -526,6 +530,18 @@
<source>all</source>
<translation>todos</translation>
</message>
<message>
<source>Advanced</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Low</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>High</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Setting</name>
@ -610,6 +626,14 @@
<source>SVGs</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unsupported document format</source>
<translation>Formato de documento no soportado</translation>
</message>
<message>
<source>New file selected</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>strings</name>
@ -5168,10 +5192,6 @@
</context>
<context>
<name>utils</name>
<message>
<source></source>
<translation></translation>
</message>
<message>
<source>pending</source>
<translation type="unfinished"></translation>

View file

@ -276,10 +276,6 @@
<source>Not on WiFi</source>
<translation>Pas en WiFi</translation>
</message>
<message>
<source>Unsupported document format</source>
<translation>Format de document non supporté</translation>
</message>
<message>
<source>This format may not render correctly</source>
<translation>Ce format peut ne pas être rendu correctement</translation>
@ -506,7 +502,7 @@ sur cette imprimante</translation>
</message>
<message>
<source>Unknown target format</source>
<translation></translation>
<translation type="unfinished"></translation>
</message>
<message>
<source>Preparing</source>
@ -520,6 +516,14 @@ sur cette imprimante</translation>
<source>Print error</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Inconsistent duplex setting</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Multiline label not supported</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RangeSetting</name>
@ -527,6 +531,18 @@ sur cette imprimante</translation>
<source>all</source>
<translation>tout</translation>
</message>
<message>
<source>Advanced</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Low</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>High</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Setting</name>
@ -611,6 +627,14 @@ sur cette imprimante</translation>
<source>SVGs</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unsupported document format</source>
<translation>Format de document non supporté</translation>
</message>
<message>
<source>New file selected</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>strings</name>
@ -5169,10 +5193,6 @@ sur cette imprimante</translation>
</context>
<context>
<name>utils</name>
<message>
<source></source>
<translation></translation>
</message>
<message>
<source>pending</source>
<translation type="unfinished"></translation>

View file

@ -276,10 +276,6 @@
<source>Not on WiFi</source>
<translation>Niet met WiFi netwerk verbonden</translation>
</message>
<message>
<source>Unsupported document format</source>
<translation>Niet-ondersteunde documentindeling</translation>
</message>
<message>
<source>This format may not render correctly</source>
<translation>Dit formaat wordt mogelijk niet correct weergegeven</translation>
@ -519,6 +515,14 @@
<source>Print error</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Inconsistent duplex setting</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Multiline label not supported</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RangeSetting</name>
@ -526,6 +530,18 @@
<source>all</source>
<translation>alles</translation>
</message>
<message>
<source>Advanced</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Low</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>High</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Setting</name>
@ -610,6 +626,14 @@
<source>SVGs</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unsupported document format</source>
<translation>Niet-ondersteunde documentindeling</translation>
</message>
<message>
<source>New file selected</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>strings</name>
@ -5168,10 +5192,6 @@
</context>
<context>
<name>utils</name>
<message>
<source></source>
<translation></translation>
</message>
<message>
<source>pending</source>
<translation type="unfinished"></translation>

View file

@ -5,91 +5,91 @@
<name>AboutPage</name>
<message>
<source>GitHub repository</source>
<translation type="unfinished"></translation>
<translation>Repozytorium GitHub</translation>
</message>
<message>
<source>Report an Issue</source>
<translation type="unfinished"></translation>
<translation>Zgłoś problem</translation>
</message>
<message>
<source>About</source>
<translation type="unfinished"></translation>
<translation>O Seaprint</translation>
</message>
<message>
<source>Network printing for Sailfish OS.</source>
<translation type="unfinished"></translation>
<translation>Drukowanie sieciowe dla Sailfish OS.</translation>
</message>
<message>
<source>Icons</source>
<translation type="unfinished"></translation>
<translation>Ikony</translation>
</message>
<message>
<source>Icon made by Gregguh.</source>
<translation type="unfinished"></translation>
<translation>Ikona wykonana przez Gregguh.</translation>
</message>
<message>
<source>General contributions</source>
<translation type="unfinished"></translation>
<translation>Autorzy</translation>
</message>
<message>
<source>Translations</source>
<translation type="unfinished"></translation>
<translation>Tłumaczenia</translation>
</message>
<message>
<source>Chinese</source>
<translation type="unfinished"></translation>
<translation>Chiński</translation>
</message>
<message>
<source>Dutch</source>
<translation type="unfinished"></translation>
<translation>Duński</translation>
</message>
<message>
<source>French</source>
<translation type="unfinished"></translation>
<translation>Francuski</translation>
</message>
<message>
<source>German</source>
<translation type="unfinished"></translation>
<translation>Niemiecki</translation>
</message>
<message>
<source>Polish</source>
<translation type="unfinished"></translation>
<translation>Polski</translation>
</message>
<message>
<source>Spanish</source>
<translation type="unfinished"></translation>
<translation>Hiszpański</translation>
</message>
<message>
<source>Optional dependencies</source>
<translation type="unfinished"></translation>
<translation>Opcjonalne zależności</translation>
</message>
<message>
<source>Installed</source>
<translation type="unfinished"></translation>
<translation>Zainstalowano</translation>
</message>
<message>
<source>Not installed</source>
<translation type="unfinished"></translation>
<translation>Nie zainstalowano</translation>
</message>
<message>
<source>Donations</source>
<translation type="unfinished"></translation>
<translation>Darowizny</translation>
</message>
<message>
<source>Licensing</source>
<translation type="unfinished"></translation>
<translation>Licencja</translation>
</message>
<message>
<source>Source code is available at GitHub. Translations, bug reports and other contributions are welcome!</source>
<translation type="unfinished"></translation>
<translation>Kod źródłowy dostępny w GitHub. Tłumaczenia, zgłoszenia błędów i inna pomoc mile widziane!</translation>
</message>
<message>
<source>Special thanks to</source>
<translation type="unfinished"></translation>
<translation>Specjalne podziękowania dla</translation>
</message>
<message>
<source>SeaPrint is free software released under the GNU General Public License (GPL), version 3 or later.</source>
<translation type="unfinished"></translation>
<translation>Seaprint jest wolnym oprogramowaniem udostępnianym na licencji GNU General Public License (GPL), wersja 3 lub późniejsze.</translation>
</message>
</context>
<context>
@ -116,45 +116,45 @@
</message>
<message>
<source>Port 9100 is not used for IPP.</source>
<translation type="unfinished"></translation>
<translation>Port 9100 nie jest wykorzystywany dla IPP.</translation>
</message>
<message>
<source>The uri suffix is not in the printer&apos;s supported list.</source>
<translation type="unfinished"></translation>
<translation>Końcówka adresu uri nie znajduje się na wspieranej przez drukarkę liście.</translation>
</message>
<message>
<source>It might not accept print jobs on this address.</source>
<translation type="unfinished"></translation>
<translation>Może nieakceptować zadań drukowania pod tym adresem.</translation>
</message>
<message>
<source>Consider using a suffix like &quot;/ipp/print&quot;.</source>
<translation type="unfinished"></translation>
<translation>Użyj końcówki adresu &quot;/ipp/print&quot;.</translation>
</message>
<message>
<source>The printer/server lists these suffixes:</source>
<translation type="unfinished"></translation>
<translation>Drukarka/serwer zgłasza końcówki adresu:</translation>
</message>
</context>
<context>
<name>BusyPage</name>
<message>
<source>Unknown</source>
<translation type="unfinished">Nieznana drukarka</translation>
<translation>Nieznane</translation>
</message>
<message>
<source>Print success: </source>
<translation type="unfinished">Drukowanie udane: </translation>
<translation>Drukowanie udane: </translation>
</message>
<message>
<source>Print failed: </source>
<translation type="unfinished">Nieudane drukowanie: </translation>
<translation>Drukowanie nieudane: </translation>
</message>
</context>
<context>
<name>Clipper</name>
<message>
<source>Copied to clipboard</source>
<translation type="unfinished"></translation>
<translation>Skopiowano do schowka</translation>
</message>
</context>
<context>
@ -168,58 +168,58 @@
<name>DebugPage</name>
<message>
<source>Copied to clipboard</source>
<translation type="unfinished"></translation>
<translation>Skopiowano do schowka</translation>
</message>
</context>
<context>
<name>DetailsPage</name>
<message>
<source>Details</source>
<translation type="unfinished"></translation>
<translation>Szczegóły</translation>
</message>
<message>
<source>Make and model</source>
<translation type="unfinished"></translation>
<translation>Producent i model</translation>
</message>
<message>
<source>Printer status</source>
<translation type="unfinished"></translation>
<translation>Stan drukarki</translation>
</message>
<message>
<source>IPP versions</source>
<translation type="unfinished"></translation>
<translation>Wersje IPP</translation>
</message>
<message>
<source>IPP features</source>
<translation type="unfinished"></translation>
<translation>Właściwości IPP</translation>
</message>
<message>
<source>Firmware</source>
<translation type="unfinished"></translation>
<translation>Oprogramowanie wewnętrzne</translation>
</message>
<message>
<source>Supply status</source>
<translation type="unfinished"></translation>
<translation>Poziom tuszu/tonera</translation>
</message>
<message>
<source>Location</source>
<translation type="unfinished"></translation>
<translation>Lokalizacja</translation>
</message>
<message>
<source>Performance</source>
<translation type="unfinished"></translation>
<translation>Wydajność</translation>
</message>
<message>
<source>pages/min</source>
<translation type="unfinished"></translation>
<translation>stron/min</translation>
</message>
<message>
<source>pages/min (color)</source>
<translation type="unfinished"></translation>
<translation>stron/min (kolor)</translation>
</message>
<message>
<source>Identify printer</source>
<translation type="unfinished"></translation>
<translation>Identyfikuj drukarkę</translation>
</message>
</context>
<context>
@ -262,42 +262,38 @@
</message>
<message>
<source>Settings</source>
<translation type="unfinished"></translation>
<translation>Ustawienia</translation>
</message>
<message>
<source>Available printers</source>
<translation type="unfinished"></translation>
<translation>Dostępne drukarki</translation>
</message>
<message>
<source>Printer details</source>
<translation type="unfinished"></translation>
<translation>Szczegóły drukarki</translation>
</message>
<message>
<source>Not on WiFi</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unsupported document format</source>
<translation type="unfinished"></translation>
<translation>Brak połączenia WiFi</translation>
</message>
<message>
<source>This format may not render correctly</source>
<translation type="unfinished"></translation>
<translation>Ten format może zostać przetworzony niepoprawnie</translation>
</message>
</context>
<context>
<name>IppPrinter</name>
<message>
<source>Failed to open file</source>
<translation type="unfinished"></translation>
<translation>Otwarcie pliku nie powiodło się</translation>
</message>
<message>
<source>Unknown document format</source>
<translation type="unfinished"></translation>
<translation>Nieznany rodzaj dokumentu</translation>
</message>
<message>
<source>Unsupported paper size</source>
<translation type="unfinished"></translation>
<translation>Niewspierany rozmiar papieru</translation>
</message>
</context>
<context>
@ -335,39 +331,39 @@
<name>NagScreen</name>
<message>
<source>Optional dependencies are not installed!</source>
<translation type="unfinished"></translation>
<translation>Opcjonalne zależności nie zostały zainstalowane!</translation>
</message>
<message>
<source>To install, enable developer mode, and open a terminal.</source>
<translation type="unfinished"></translation>
<translation>W celu zainstalowania, włącz tryb dewelopera i otwórz terminal.</translation>
</message>
<message>
<source>Become root:</source>
<translation type="unfinished"></translation>
<translation>Przejdź na konto root:</translation>
</message>
<message>
<source>Dismiss</source>
<translation type="unfinished"></translation>
<translation>Odrzuć</translation>
</message>
<message>
<source>Don&apos;t show again</source>
<translation type="unfinished"></translation>
<translation>Nie pokazuj ponownie</translation>
</message>
<message>
<source>Install Calligra:</source>
<translation type="unfinished"></translation>
<translation>Zainstaluj pakiet Calligra:</translation>
</message>
<message>
<source>(done)</source>
<translation type="unfinished"></translation>
<translation>(wykonano)</translation>
</message>
<message>
<source>In order to print &quot;office&quot; documents like odt and doc(x) you need &quot;calligraconverter&quot; from the &quot;calligra&quot; package (version 3.2.1+, Sailfish OS 4.2).</source>
<translation type="unfinished"></translation>
<translation>W celu drukowania dokumentów tekstowych o rozszerzeniach odt i doc(x) potrzebujesz &quot;calligraconverter&quot; z pakietu &quot;calligra&quot; (wersja 3.2.1+, Sailfish OS 4.2).</translation>
</message>
<message>
<source>If you are still seeing this message despite installing Calligra, that can be because of SailJail in Sailfish OS 4.x before the compatibility permission in 4.4. You can either upgrade to 4.4 or edit out the SailJail section in /usr/share/applications/harbour-seaprint.desktop</source>
<translation type="unfinished"></translation>
<translation>Jeśli wciąż widzisz wiadomość, pomimo zainstalowania pakietu Calligra, może to być spowodowane &apos;SailJail&apos; w wersji Sailfish OS 4.x przed wprowadzeniem uprawnienia &apos;compatibility&apos; w wersji 4.4. Należy dokonac aktualizacji do wersji 4.4 lub wyedytować sekcję SailJail w /usr/share/applications/harbour-seaprint.desktop</translation>
</message>
</context>
<context>
@ -398,125 +394,133 @@
</message>
<message>
<source>Print media</source>
<translation>Drukuj multimedia</translation>
<translation>Rozmiar nośnika</translation>
</message>
<message>
<source>Page range</source>
<translation type="unfinished"></translation>
<translation>Zakres stron</translation>
</message>
<message>
<source>Transfer format</source>
<translation type="unfinished"></translation>
<translation>Format transferu</translation>
</message>
<message>
<source>Media source</source>
<translation type="unfinished"></translation>
<translation>Źródło nośnika</translation>
</message>
<message>
<source>Collated copies</source>
<translation type="unfinished"></translation>
<translation>Posortowane kopie</translation>
</message>
<message>
<source>Default settings for %1 on this printer</source>
<translation type="unfinished"></translation>
<translation>Ustawienia domyślne dla &apos;%1&apos; wybranej drukarki</translation>
</message>
<message>
<source>(loaded)</source>
<translation type="unfinished"></translation>
<translation>(załadowano)</translation>
</message>
<message>
<source>Output bin</source>
<translation type="unfinished"></translation>
<translation>Odbiornik</translation>
</message>
<message>
<source>Media type</source>
<translation type="unfinished"></translation>
<translation>Typ nośnika</translation>
</message>
<message>
<source>Top</source>
<translation type="unfinished"></translation>
<translation>Góra</translation>
</message>
<message>
<source>Bottom</source>
<translation type="unfinished"></translation>
<translation>Dół</translation>
</message>
<message>
<source>Left</source>
<translation type="unfinished"></translation>
<translation>Lewy</translation>
</message>
<message>
<source>Right</source>
<translation type="unfinished"></translation>
<translation>Prawo</translation>
</message>
<message>
<source>Margins</source>
<translation type="unfinished"></translation>
<translation>Marginesy</translation>
</message>
<message>
<source>Pages per page</source>
<translation type="unfinished"></translation>
<translation>Stron na kartkę</translation>
</message>
<message>
<source>Scaling</source>
<translation type="unfinished"></translation>
<translation>Skalowanie</translation>
</message>
<message>
<source>Media handling</source>
<translation type="unfinished"></translation>
<translation>Obsługa nośnika</translation>
</message>
<message>
<source>Reset default settings</source>
<translation type="unfinished"></translation>
<translation>Przywróć domyślne ustawienia</translation>
</message>
<message>
<source>Save as default settings</source>
<translation type="unfinished"></translation>
<translation>Zapisz jako domyślne ustawienia</translation>
</message>
</context>
<context>
<name>PrinterWorker</name>
<message>
<source>Unsupported resolution (dpi)</source>
<translation type="unfinished"></translation>
<translation>Niewspierana rozdzielczość (dpi)</translation>
</message>
<message>
<source>Unsupported PDF paper size</source>
<translation type="unfinished"></translation>
<translation>Niewspierany rozmiar strony PDF</translation>
</message>
<message>
<source>Unsupported paper size</source>
<translation type="unfinished"></translation>
<translation>Niewspierany rozmiar papieru</translation>
</message>
<message>
<source>Failed to load image</source>
<translation type="unfinished"></translation>
<translation>Wczytywanie obrazu nie powiodło się</translation>
</message>
<message>
<source>Failed to open file</source>
<translation type="unfinished"></translation>
<translation>Wczytywanie pliku nie powiodło się</translation>
</message>
<message>
<source>Printing</source>
<translation type="unfinished"></translation>
<translation>Drukowanie</translation>
</message>
<message>
<source>Conversion failed</source>
<translation type="unfinished"></translation>
<translation>Konwersja nie powiodła się</translation>
</message>
<message>
<source>Unknown target format</source>
<translation type="unfinished"></translation>
<translation>Nieznany format docelowy</translation>
</message>
<message>
<source>Preparing</source>
<translation type="unfinished"></translation>
<translation>Przygotowywanie</translation>
</message>
<message>
<source>Cannot convert this file format</source>
<translation type="unfinished"></translation>
<translation>Konwersja dla typu pliku nie możliwa</translation>
</message>
<message>
<source>Print error</source>
<translation>Błąd drukowania</translation>
</message>
<message>
<source>Inconsistent duplex setting</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Multiline label not supported</source>
<translation type="unfinished"></translation>
</message>
</context>
@ -524,6 +528,18 @@
<name>RangeSetting</name>
<message>
<source>all</source>
<translation>wszystkie</translation>
</message>
<message>
<source>Advanced</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Low</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>High</source>
<translation type="unfinished"></translation>
</message>
</context>
@ -531,83 +547,91 @@
<name>Setting</name>
<message>
<source>Reset</source>
<translation type="unfinished"></translation>
<translation>Reset</translation>
</message>
</context>
<context>
<name>SettingsPage</name>
<message>
<source>Settings</source>
<translation type="unfinished"></translation>
<translation>Ustawienia</translation>
</message>
<message>
<source>Show nag-screen</source>
<translation type="unfinished"></translation>
<translation>Pokaż ekran ostrzeżenia</translation>
</message>
<message>
<source>Display the warning page about optional dependencies not being installed, if they are not installed.</source>
<translation type="unfinished"></translation>
<translation>Wyświetlaj ekran ostrzeżenia dotyczący niezainstalowanych opcjonalnych zależności, jeśli nie zainstalowane.</translation>
</message>
<message>
<source>Consider additional formats</source>
<translation type="unfinished"></translation>
<translation>Spróbuj wykorzystać dodatkowe formaty</translation>
</message>
<message>
<source>Some printers support more formats than they advertise correctly. However, additional formats can be inferred from other attributes. Mainly relevant for Postscript-compatible printers that also support PDF.</source>
<translation type="unfinished"></translation>
<translation>Niektóre drukarki wspierają dodatkowe formaty w stosunku do zgłaszanych. Dodatkowe formaty mogą zostać ustalone na podstawie innych atrybutów. Dotyczy głównie drukarek zgodnych z Postscriptem, które obsługują również PDF.</translation>
</message>
<message>
<source>Ignore SSL errors</source>
<translation type="unfinished"></translation>
<translation>Ignoruj błędy SSL</translation>
</message>
<message>
<source>In order to work with self-signed certificates of printers and CUPS instances, SSL errors needs to be ignored.</source>
<translation type="unfinished"></translation>
<translation>Dla poprawnej współpracy z samopodpisanymi certyfikatami drukarek i instancji CUPS, błędy SSL powinny być ignorowane.</translation>
</message>
<message>
<source>Enable debug log</source>
<translation type="unfinished"></translation>
<translation>Włącz logowanie do celów debugowania</translation>
</message>
<message>
<source>Print debug log messages to console (if launched from there) or journal if launched normally. Takes effect on app (re-)start.</source>
<translation type="unfinished"></translation>
<translation>Wyświetl informacje debugowania w konsoli (jeśli uruchomiono z konsoli) lub do dziennika systemowego jeśli uruchomiono normalnie. Wymaga restartu aplikacji.</translation>
</message>
<message>
<source>Allow external connections</source>
<translation type="unfinished"></translation>
<translation>Zezwalaj na zewnętrzne połączenia</translation>
</message>
<message>
<source>Allow SeaPrint to fetch recources like icons and option name dictionaries from addresses that are not the printer itself. Some printer makers store icons on their website as opposed to locally on the printer.</source>
<translation type="unfinished"></translation>
<translation>Pozwól SeaPrint na pobieranie zasobów takich jak ikony i słowniki nazw z adresów, które nie należą do drukarki. Niektórzy producenci drukarek nie przechowują ikon lokalnie, ale umieszczają je na własnych stronach internetowych.</translation>
</message>
</context>
<context>
<name>SupplyItem</name>
<message>
<source>Unknown type</source>
<translation type="unfinished"></translation>
<translation>Nieznany typ</translation>
</message>
<message>
<source>Unnamed supply</source>
<translation type="unfinished"></translation>
<translation>Tusz/toner bez nazwy</translation>
</message>
</context>
<context>
<name>harbour-seaprint</name>
<message>
<source>images</source>
<translation type="unfinished"></translation>
<translation>obrazy</translation>
</message>
<message>
<source>documents</source>
<translation type="unfinished"></translation>
<translation>dokumenty</translation>
</message>
<message>
<source>plaintext</source>
<translation type="unfinished"></translation>
<translation>czystytekst</translation>
</message>
<message>
<source>SVGs</source>
<translation>SVG</translation>
</message>
<message>
<source>Unsupported document format</source>
<translation>Nieobsługiwany rodzaj dokumentu</translation>
</message>
<message>
<source>New file selected</source>
<translation type="unfinished"></translation>
</message>
</context>
@ -5168,149 +5192,145 @@
</context>
<context>
<name>utils</name>
<message>
<source></source>
<translation></translation>
</message>
<message>
<source>pending</source>
<translation type="unfinished"></translation>
<translation>oczekujące</translation>
</message>
<message>
<source>pending-held</source>
<translation type="unfinished"></translation>
<translation>w toku</translation>
</message>
<message>
<source>processing</source>
<translation type="unfinished"></translation>
<translation>przetwarzanie</translation>
</message>
<message>
<source>processing-stopped</source>
<translation type="unfinished"></translation>
<translation>przetwarzanie zatrzymane</translation>
</message>
<message>
<source>canceled</source>
<translation type="unfinished"></translation>
<translation>anulowano</translation>
</message>
<message>
<source>aborted</source>
<translation type="unfinished"></translation>
<translation>przerwano</translation>
</message>
<message>
<source>completed</source>
<translation type="unfinished"></translation>
<translation>ukończono</translation>
</message>
<message>
<source>unknown state </source>
<translation type="unfinished"></translation>
<translation>nieznany stan </translation>
</message>
<message>
<source>Idle</source>
<translation type="unfinished"></translation>
<translation>Bezczynny</translation>
</message>
<message>
<source>Processing</source>
<translation type="unfinished"></translation>
<translation>Przetwarzanie</translation>
</message>
<message>
<source>Stopped</source>
<translation type="unfinished"></translation>
<translation>Zatrzymano</translation>
</message>
<message>
<source>Unknown State </source>
<translation type="unfinished"></translation>
<translation>Nieznany Stan </translation>
</message>
<message>
<source>draft</source>
<translation type="unfinished"></translation>
<translation>szkic</translation>
</message>
<message>
<source>normal</source>
<translation type="unfinished"></translation>
<translation>normalny</translation>
</message>
<message>
<source>high</source>
<translation type="unfinished"></translation>
<translation>wysoki</translation>
</message>
<message>
<source>unknown quality </source>
<translation type="unfinished"></translation>
<translation>nieznana jakość </translation>
</message>
<message>
<source>portrait</source>
<translation type="unfinished"></translation>
<translation>pionowa</translation>
</message>
<message>
<source>landscape</source>
<translation type="unfinished"></translation>
<translation>pozioma</translation>
</message>
<message>
<source>reverse landscape</source>
<translation type="unfinished"></translation>
<translation>odwrócona pozioma</translation>
</message>
<message>
<source>reverse portrait</source>
<translation type="unfinished"></translation>
<translation>odwrócona pionowa</translation>
</message>
<message>
<source>unknown orientation </source>
<translation type="unfinished"></translation>
<translation>nieznana orientacja </translation>
</message>
<message>
<source>dpi</source>
<translation type="unfinished"></translation>
<translation>dpi</translation>
</message>
<message>
<source>dots/cm</source>
<translation type="unfinished"></translation>
<translation>punktów/cm</translation>
</message>
<message>
<source>Report</source>
<translation type="unfinished"></translation>
<translation>Raport</translation>
</message>
<message>
<source>Warning</source>
<translation type="unfinished"></translation>
<translation>Ostrzeżenie</translation>
</message>
<message>
<source>Error</source>
<translation type="unfinished"></translation>
<translation>Błąd</translation>
</message>
<message>
<source>one-sided</source>
<translation type="unfinished"></translation>
<translation>jednostronnie</translation>
</message>
<message>
<source>two-sided</source>
<translation type="unfinished"></translation>
<translation>dwustronnie</translation>
</message>
<message>
<source>two-sided flipped</source>
<translation type="unfinished"></translation>
<translation>dwustronnie odwrócony</translation>
</message>
<message>
<source>single document</source>
<translation type="unfinished"></translation>
<translation>pojedynczy dokument</translation>
</message>
<message>
<source>uncollated</source>
<translation type="unfinished"></translation>
<translation>nieposortowane</translation>
</message>
<message>
<source>collated</source>
<translation type="unfinished"></translation>
<translation>posortowane</translation>
</message>
<message>
<source>single document (new sheet)</source>
<translation type="unfinished"></translation>
<translation>pojedynczy dokument (nowa kartka)</translation>
</message>
<message>
<source>automatic</source>
<translation type="unfinished"></translation>
<translation>automatycznie</translation>
</message>
<message>
<source>auto monochrome</source>
<translation type="unfinished"></translation>
<translation>auto czarno-biały</translation>
</message>
<message>
<source>bi-level</source>
@ -5318,47 +5338,47 @@
</message>
<message>
<source>color</source>
<translation type="unfinished"></translation>
<translation>kolor</translation>
</message>
<message>
<source>highlight</source>
<translation type="unfinished"></translation>
<translation>wyróżnienie</translation>
</message>
<message>
<source>monochrome</source>
<translation type="unfinished"></translation>
<translation>czarno-biały</translation>
</message>
<message>
<source>process bi-level</source>
<translation type="unfinished"></translation>
<translation>przetwarzanie bi-level</translation>
</message>
<message>
<source>process monochrome</source>
<translation type="unfinished"></translation>
<translation>przetwarzanie czarno-biały</translation>
</message>
<message>
<source>auto</source>
<translation type="unfinished"></translation>
<translation>automatycznie</translation>
</message>
<message>
<source>auto (fit)</source>
<translation type="unfinished"></translation>
<translation>automatycznie (dopasuj)</translation>
</message>
<message>
<source>fill</source>
<translation type="unfinished"></translation>
<translation>wypełnienie</translation>
</message>
<message>
<source>fit</source>
<translation type="unfinished"></translation>
<translation>dopasowanie</translation>
</message>
<message>
<source>none</source>
<translation type="unfinished"></translation>
<translation>brak</translation>
</message>
<message>
<source>auto-sense</source>
<translation type="unfinished"></translation>
<translation>automatyczne wykrywanie</translation>
</message>
<message>
<source>PDF</source>
@ -5390,7 +5410,7 @@
</message>
<message>
<source>tray</source>
<translation type="unfinished"></translation>
<translation>podajnik</translation>
</message>
<message>
<source>roll</source>
@ -5406,23 +5426,23 @@
</message>
<message>
<source>bottom</source>
<translation type="unfinished"></translation>
<translation>dół</translation>
</message>
<message>
<source>by-pass tray</source>
<translation type="unfinished"></translation>
<translation>podajnik obejściowy</translation>
</message>
<message>
<source>center</source>
<translation type="unfinished"></translation>
<translation>centrowanie</translation>
</message>
<message>
<source>disc</source>
<translation type="unfinished"></translation>
<translation>płyta</translation>
</message>
<message>
<source>envelope</source>
<translation type="unfinished"></translation>
<translation>koperta</translation>
</message>
<message>
<source>hagaki</source>
@ -5430,15 +5450,15 @@
</message>
<message>
<source>large capacity</source>
<translation type="unfinished"></translation>
<translation>wysoka pojemność</translation>
</message>
<message>
<source>left</source>
<translation type="unfinished"></translation>
<translation>lewo</translation>
</message>
<message>
<source>main</source>
<translation type="unfinished"></translation>
<translation>główny</translation>
</message>
<message>
<source>main roll</source>
@ -5446,59 +5466,59 @@
</message>
<message>
<source>manual</source>
<translation type="unfinished"></translation>
<translation>ręcznie</translation>
</message>
<message>
<source>middle</source>
<translation type="unfinished"></translation>
<translation>środek</translation>
</message>
<message>
<source>photo</source>
<translation type="unfinished"></translation>
<translation>zdjęcie</translation>
</message>
<message>
<source>rear</source>
<translation type="unfinished"></translation>
<translation>tył</translation>
</message>
<message>
<source>right</source>
<translation type="unfinished"></translation>
<translation>prawo</translation>
</message>
<message>
<source>side</source>
<translation type="unfinished"></translation>
<translation>strona</translation>
</message>
<message>
<source>top</source>
<translation type="unfinished"></translation>
<translation>góra</translation>
</message>
<message>
<source>stacker</source>
<translation type="unfinished"></translation>
<translation>układarka</translation>
</message>
<message>
<source>mailbox</source>
<translation type="unfinished"></translation>
<translation>skrzynka na pocztę</translation>
</message>
<message>
<source>face-up</source>
<translation type="unfinished"></translation>
<translation>wierzchem do góry</translation>
</message>
<message>
<source>face-down</source>
<translation type="unfinished"></translation>
<translation>wierzchem do dołu</translation>
</message>
<message>
<source>my mailbox</source>
<translation type="unfinished"></translation>
<translation>moja skrzynka na pocztę</translation>
</message>
<message>
<source>Unknown</source>
<translation type="unfinished">Nieznana drukarka</translation>
<translation>Nieznane</translation>
</message>
<message>
<source>Plaintext</source>
<translation type="unfinished"></translation>
<translation>Czysty tekst</translation>
</message>
<message>
<source>Reverse BMP</source>

View file

@ -276,10 +276,6 @@
<source>Not on WiFi</source>
<translation>WiFi</translation>
</message>
<message>
<source>Unsupported document format</source>
<translation></translation>
</message>
<message>
<source>This format may not render correctly</source>
<translation></translation>
@ -519,6 +515,14 @@
<source>Print error</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Inconsistent duplex setting</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Multiline label not supported</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RangeSetting</name>
@ -526,6 +530,18 @@
<source>all</source>
<translation></translation>
</message>
<message>
<source>Advanced</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Low</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>High</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Setting</name>
@ -610,6 +626,14 @@
<source>SVGs</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unsupported document format</source>
<translation></translation>
</message>
<message>
<source>New file selected</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>strings</name>
@ -5168,10 +5192,6 @@
</context>
<context>
<name>utils</name>
<message>
<source></source>
<translation></translation>
</message>
<message>
<source>pending</source>
<translation type="unfinished"></translation>

View file

@ -276,10 +276,6 @@
<source>Not on WiFi</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unsupported document format</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>This format may not render correctly</source>
<translation type="unfinished"></translation>
@ -519,6 +515,14 @@
<source>Unknown target format</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Inconsistent duplex setting</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Multiline label not supported</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RangeSetting</name>
@ -526,6 +530,18 @@
<source>all</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Advanced</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Low</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>High</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Setting</name>
@ -610,6 +626,14 @@
<source>plaintext</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unsupported document format</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>New file selected</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>strings</name>