Add page range support
This commit is contained in:
parent
eb58606250
commit
e1d34a4d1d
13 changed files with 221 additions and 36 deletions
|
@ -3,25 +3,103 @@ import Sailfish.Silica 1.0
|
||||||
|
|
||||||
Setting {
|
Setting {
|
||||||
|
|
||||||
//TODO
|
|
||||||
|
|
||||||
property int low
|
|
||||||
property int high
|
property int high
|
||||||
property int choice_low
|
property int choice_low: 1
|
||||||
property int choice_high
|
property int choice_high: 0
|
||||||
|
|
||||||
|
|
||||||
|
function update_choice() {
|
||||||
|
choice = new Object({low: choice_low, high: choice_high});
|
||||||
|
}
|
||||||
|
|
||||||
|
onChoice_highChanged: {
|
||||||
|
if(choice_high < choice_low)
|
||||||
|
{
|
||||||
|
low_slider.value = choice_high > 0 ? choice_high : 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
update_choice()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onChoice_lowChanged: {
|
||||||
|
if(choice_low > choice_high)
|
||||||
|
{
|
||||||
|
high_slider.value = choice_low
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
update_choice()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ValueButton {
|
ValueButton {
|
||||||
enabled: valid
|
enabled: valid
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
label: prettyName
|
label: prettyName
|
||||||
value: choice ? choice : default_choice
|
value: choice_high==0 ? qsTr("all") : ""+choice_low+" - "+choice_high
|
||||||
onClicked: parent.clicked()
|
onClicked: parent.clicked()
|
||||||
}
|
}
|
||||||
|
|
||||||
property var menu: ContextMenu {
|
property var menu: ContextMenu {
|
||||||
id: menu
|
id: menu
|
||||||
enabled: valid
|
enabled: valid
|
||||||
|
|
||||||
MenuItem {
|
MenuItem {
|
||||||
|
Slider
|
||||||
|
{
|
||||||
|
id: low_slider
|
||||||
|
minimumValue: 1
|
||||||
|
maximumValue: high
|
||||||
|
width: parent.width
|
||||||
|
stepSize: 1
|
||||||
|
value: choice_low
|
||||||
|
onValueChanged:
|
||||||
|
{
|
||||||
|
choice_low = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IconButton
|
||||||
|
{
|
||||||
|
anchors.right: parent.right
|
||||||
|
icon.source: "image://theme/icon-s-edit"
|
||||||
|
onClicked: {var dialog = pageStack.push(Qt.resolvedUrl("IntegerInputDialog.qml"),
|
||||||
|
{value: choice, title: prettyName,
|
||||||
|
min: 1, max: high});
|
||||||
|
dialog.accepted.connect(function() {
|
||||||
|
choice_low = dialog.value;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
MenuItem {
|
||||||
|
Slider
|
||||||
|
{
|
||||||
|
id: high_slider
|
||||||
|
minimumValue: 0
|
||||||
|
maximumValue: high
|
||||||
|
width: parent.width
|
||||||
|
stepSize: 1
|
||||||
|
value: choice_high
|
||||||
|
onValueChanged:
|
||||||
|
{
|
||||||
|
choice_high = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IconButton
|
||||||
|
{
|
||||||
|
anchors.right: parent.right
|
||||||
|
icon.source: "image://theme/icon-s-edit"
|
||||||
|
onClicked: {var dialog = pageStack.push(Qt.resolvedUrl("IntegerInputDialog.qml"),
|
||||||
|
{value: choice, title: prettyName,
|
||||||
|
min: 1, max: high});
|
||||||
|
dialog.accepted.connect(function() {
|
||||||
|
choice_high = dialog.value;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ import QtQuick 2.0
|
||||||
import Sailfish.Silica 1.0
|
import Sailfish.Silica 1.0
|
||||||
import seaprint.mimer 1.0
|
import seaprint.mimer 1.0
|
||||||
import seaprint.ippmsg 1.0
|
import seaprint.ippmsg 1.0
|
||||||
|
import seaprint.convertchecker 1.0
|
||||||
import "utils.js" as Utils
|
import "utils.js" as Utils
|
||||||
|
|
||||||
Page {
|
Page {
|
||||||
|
@ -39,7 +40,7 @@ Page {
|
||||||
ListElement {name: "sides"; prettyName: qsTr("Sides"); tag: IppMsg.Enum}
|
ListElement {name: "sides"; prettyName: qsTr("Sides"); tag: IppMsg.Enum}
|
||||||
ListElement {name: "media"; prettyName: qsTr("Print media"); tag: IppMsg.Keyword}
|
ListElement {name: "media"; prettyName: qsTr("Print media"); tag: IppMsg.Keyword}
|
||||||
ListElement {name: "copies"; prettyName: qsTr("Copies"); tag: IppMsg.Integer}
|
ListElement {name: "copies"; prettyName: qsTr("Copies"); tag: IppMsg.Integer}
|
||||||
// ListElement {name: "page-ranges"; prettyName: qsTr("Page range"); tag: IppMsg.IntegerRange}
|
ListElement {name: "page-ranges"; prettyName: qsTr("Page range"); tag: IppMsg.IntegerRange}
|
||||||
ListElement {name: "print-color-mode"; prettyName: qsTr("Color mode"); tag: IppMsg.Enum}
|
ListElement {name: "print-color-mode"; prettyName: qsTr("Color mode"); tag: IppMsg.Enum}
|
||||||
// ListElement {name: "orientation-requested"; prettyName: qsTr("Orientation"); tag: IppMsg.Enum}
|
// ListElement {name: "orientation-requested"; prettyName: qsTr("Orientation"); tag: IppMsg.Enum}
|
||||||
ListElement {name: "print-quality"; prettyName: qsTr("Quality"); tag: IppMsg.Enum}
|
ListElement {name: "print-quality"; prettyName: qsTr("Quality"); tag: IppMsg.Enum}
|
||||||
|
@ -111,11 +112,14 @@ Page {
|
||||||
})
|
})
|
||||||
break
|
break
|
||||||
case IppMsg.IntegerRange:
|
case IppMsg.IntegerRange:
|
||||||
|
var valid = printer.attrs.hasOwnProperty(name+"-supported") &&
|
||||||
|
name=="page-ranges" && Mimer.get_type(selectedFile) == "application/pdf";
|
||||||
loader.setSource("../components/RangeSetting.qml",
|
loader.setSource("../components/RangeSetting.qml",
|
||||||
{name: name,
|
{name: name,
|
||||||
prettyName: prettyName,
|
prettyName: prettyName,
|
||||||
tag: tag,
|
tag: tag,
|
||||||
valid: false //TODO printer.attrs.hasOwnProperty(name+"-supported"),
|
valid: valid,
|
||||||
|
high: name=="page-ranges" ? ConvertChecker.pdfPages(selectedFile) : 0
|
||||||
})
|
})
|
||||||
break
|
break
|
||||||
case IppMsg.Resolution:
|
case IppMsg.Resolution:
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "convertchecker.h"
|
#include "convertchecker.h"
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
|
#include <QtDebug>
|
||||||
|
|
||||||
ConvertChecker::ConvertChecker()
|
ConvertChecker::ConvertChecker()
|
||||||
{
|
{
|
||||||
|
@ -38,3 +39,36 @@ ConvertChecker* ConvertChecker::instance()
|
||||||
|
|
||||||
return m_Instance;
|
return m_Instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
quint32 ConvertChecker::pdfPages(QString filename)
|
||||||
|
{
|
||||||
|
quint32 pages = 0;
|
||||||
|
if(!_pdf)
|
||||||
|
{
|
||||||
|
return pages;
|
||||||
|
}
|
||||||
|
|
||||||
|
QProcess* pdfinfo = new QProcess(this);
|
||||||
|
pdfinfo->setProgram("pdfinfo");
|
||||||
|
pdfinfo->setArguments({filename});
|
||||||
|
pdfinfo->start();
|
||||||
|
|
||||||
|
if(!pdfinfo->waitForStarted(1000) || !pdfinfo->waitForFinished(1000))
|
||||||
|
{
|
||||||
|
pdfinfo->deleteLater();
|
||||||
|
return pages;
|
||||||
|
}
|
||||||
|
QByteArray pdfInfoOutput = pdfinfo->readAllStandardOutput();
|
||||||
|
pdfinfo->deleteLater();
|
||||||
|
qDebug() << pdfInfoOutput;
|
||||||
|
QList<QByteArray> pdfInfoOutputLines = pdfInfoOutput.split('\n');
|
||||||
|
for(QList<QByteArray>::iterator it = pdfInfoOutputLines.begin(); it != pdfInfoOutputLines.end(); it++)
|
||||||
|
{
|
||||||
|
if(it->startsWith("Pages"))
|
||||||
|
{
|
||||||
|
QList<QByteArray> pagesTokens = it->split(' ');
|
||||||
|
pages = pagesTokens.last().toInt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pages;
|
||||||
|
}
|
||||||
|
|
|
@ -10,6 +10,8 @@ public:
|
||||||
static ConvertChecker* instance();
|
static ConvertChecker* instance();
|
||||||
Q_PROPERTY(bool pdf MEMBER _pdf)
|
Q_PROPERTY(bool pdf MEMBER _pdf)
|
||||||
|
|
||||||
|
Q_INVOKABLE quint32 pdfPages(QString pdf);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
protected:
|
protected:
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "convertworker.h"
|
#include "convertworker.h"
|
||||||
#include <sailfishapp.h>
|
#include <sailfishapp.h>
|
||||||
#include "papersizes.h"
|
#include "papersizes.h"
|
||||||
|
#include "convertchecker.h"
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QMatrix>
|
#include <QMatrix>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
@ -44,34 +45,20 @@ void ppm2PwgEnv(QStringList& env, bool urf, quint32 Quality, QString PaperSize,
|
||||||
|
|
||||||
void ConvertWorker::convertPdf(QNetworkRequest request, QString filename, QTemporaryFile* tempfile,
|
void ConvertWorker::convertPdf(QNetworkRequest request, QString filename, QTemporaryFile* tempfile,
|
||||||
QString targetFormat, quint32 Colors, quint32 Quality, QString PaperSize,
|
QString targetFormat, quint32 Colors, quint32 Quality, QString PaperSize,
|
||||||
quint32 HwResX, quint32 HwResY, bool TwoSided, bool Tumble)
|
quint32 HwResX, quint32 HwResY, bool TwoSided, bool Tumble,
|
||||||
|
quint32 PageRangeLow, quint32 PageRangeHigh)
|
||||||
{
|
{
|
||||||
|
quint32 pages = ConvertChecker::instance()->pdfPages(filename);
|
||||||
QProcess* pdfinfo = new QProcess(this);
|
if (!pages)
|
||||||
pdfinfo->setProgram("pdfinfo");
|
|
||||||
pdfinfo->setArguments({filename});
|
|
||||||
pdfinfo->start();
|
|
||||||
|
|
||||||
if(!pdfinfo->waitForStarted() || !pdfinfo->waitForFinished())
|
|
||||||
{
|
{
|
||||||
qDebug() << "pdfinfo died";
|
qDebug() << "pdfinfo returned 0 pages";
|
||||||
pdfinfo->deleteLater();
|
|
||||||
tempfile->deleteLater();
|
tempfile->deleteLater();
|
||||||
emit failed(tr("Failed to get info about PDF file"));
|
emit failed(tr("Failed to get info about PDF file"));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
QByteArray pdfInfoOutput = pdfinfo->readAllStandardOutput();
|
|
||||||
pdfinfo->deleteLater();
|
if(PageRangeHigh==0)
|
||||||
qDebug() << pdfInfoOutput;
|
|
||||||
QList<QByteArray> pdfInfoOutputLines = pdfInfoOutput.split('\n');
|
|
||||||
quint32 pages = 0;
|
|
||||||
for(QList<QByteArray>::iterator it = pdfInfoOutputLines.begin(); it != pdfInfoOutputLines.end(); it++)
|
|
||||||
{
|
{
|
||||||
if(it->startsWith("Pages"))
|
PageRangeHigh=pages;
|
||||||
{
|
|
||||||
QList<QByteArray> pagesTokens = it->split(' ');
|
|
||||||
pages = pagesTokens.last().toInt();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool urf = false;
|
bool urf = false;
|
||||||
|
@ -132,11 +119,17 @@ void ConvertWorker::convertPdf(QNetworkRequest request, QString filename, QTempo
|
||||||
{
|
{
|
||||||
QProcess* pdftops = new QProcess(this);
|
QProcess* pdftops = new QProcess(this);
|
||||||
pdftops->setProgram("pdftops");
|
pdftops->setProgram("pdftops");
|
||||||
QStringList PdfToPsArgs = {"-paper", ShortPaperSize, filename, "-"};
|
QStringList PdfToPsArgs;
|
||||||
if(TwoSided)
|
if(TwoSided)
|
||||||
{
|
{
|
||||||
PdfToPsArgs.prepend("-duplex");
|
PdfToPsArgs.append("-duplex");
|
||||||
}
|
}
|
||||||
|
if(PageRangeLow != 0)
|
||||||
|
{
|
||||||
|
PdfToPsArgs << QStringList {"-f", QString::number(PageRangeLow), "-l", QString::number(PageRangeHigh)};
|
||||||
|
}
|
||||||
|
PdfToPsArgs << QStringList {"-paper", ShortPaperSize, filename, "-"};
|
||||||
|
|
||||||
pdftops->setArguments(PdfToPsArgs);
|
pdftops->setArguments(PdfToPsArgs);
|
||||||
|
|
||||||
pdftops->setStandardOutputFile(tempfile->fileName(), QIODevice::Append);
|
pdftops->setStandardOutputFile(tempfile->fileName(), QIODevice::Append);
|
||||||
|
@ -169,7 +162,13 @@ void ConvertWorker::convertPdf(QNetworkRequest request, QString filename, QTempo
|
||||||
|
|
||||||
QProcess* pdftocairo = new QProcess(this);
|
QProcess* pdftocairo = new QProcess(this);
|
||||||
pdftocairo->setProgram("pdftocairo");
|
pdftocairo->setProgram("pdftocairo");
|
||||||
pdftocairo->setArguments({"-pdf", "-paper", ShortPaperSize, filename, "-"});
|
QStringList PdfToCairoArgs;
|
||||||
|
if(PageRangeLow != 0)
|
||||||
|
{
|
||||||
|
PdfToCairoArgs << QStringList {"-f", QString::number(PageRangeLow), "-l", QString::number(PageRangeHigh)};
|
||||||
|
}
|
||||||
|
PdfToCairoArgs << QStringList {"-pdf", "-paper", ShortPaperSize, filename, "-"};
|
||||||
|
pdftocairo->setArguments(PdfToCairoArgs);
|
||||||
|
|
||||||
QProcess* pdftoppm = new QProcess(this);
|
QProcess* pdftoppm = new QProcess(this);
|
||||||
pdftoppm->setProgram("pdftoppm");
|
pdftoppm->setProgram("pdftoppm");
|
||||||
|
|
|
@ -10,7 +10,8 @@ class ConvertWorker : public QObject
|
||||||
public slots:
|
public slots:
|
||||||
void convertPdf(QNetworkRequest request, QString filename, QTemporaryFile* tempfile,
|
void convertPdf(QNetworkRequest request, QString filename, QTemporaryFile* tempfile,
|
||||||
QString targetFormat, quint32 Colors, quint32 Quality, QString PaperSize,
|
QString targetFormat, quint32 Colors, quint32 Quality, QString PaperSize,
|
||||||
quint32 HwResX, quint32 HwResY, bool TwoSided, bool Tumble);
|
quint32 HwResX, quint32 HwResY, bool TwoSided, bool Tumble,
|
||||||
|
quint32 PageRangeLow, quint32 PageRangeHigh);
|
||||||
|
|
||||||
void convertImage(QNetworkRequest request, QString filename, QTemporaryFile* tempfile,
|
void convertImage(QNetworkRequest request, QString filename, QTemporaryFile* tempfile,
|
||||||
QString targetFormat, quint32 Colors, quint32 Quality, QString PaperSize,
|
QString targetFormat, quint32 Colors, quint32 Quality, QString PaperSize,
|
||||||
|
|
|
@ -432,6 +432,17 @@ void IppPrinter::print(QJsonObject attrs, QString filename,
|
||||||
{
|
{
|
||||||
attrs.remove("sides");
|
attrs.remove("sides");
|
||||||
}
|
}
|
||||||
|
quint32 PageRangeLow = 0;
|
||||||
|
quint32 PageRangeHigh = 0;
|
||||||
|
if(mimeType == "application/pdf" && documentFormat != "application/pdf")
|
||||||
|
{
|
||||||
|
if(attrs.contains("page-ranges"))
|
||||||
|
{
|
||||||
|
QJsonObject PageRanges = getAttrOrDefault(attrs, "page-ranges").toObject();
|
||||||
|
PageRangeLow = PageRanges["low"].toInt();
|
||||||
|
PageRangeHigh = PageRanges["high"].toInt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
qDebug() << "Final op attributes:" << o;
|
qDebug() << "Final op attributes:" << o;
|
||||||
qDebug() << "Final job attributes:" << attrs;
|
qDebug() << "Final job attributes:" << attrs;
|
||||||
|
@ -476,7 +487,7 @@ void IppPrinter::print(QJsonObject attrs, QString filename,
|
||||||
}
|
}
|
||||||
|
|
||||||
emit doConvertPdf(request, filename, tempfile, documentFormat, Colors, Quality,
|
emit doConvertPdf(request, filename, tempfile, documentFormat, Colors, Quality,
|
||||||
PaperSize, HwResX, HwResY, TwoSided, Tumble);
|
PaperSize, HwResX, HwResY, TwoSided, Tumble, PageRangeLow, PageRangeHigh);
|
||||||
}
|
}
|
||||||
else if (mimeType.contains("image"))
|
else if (mimeType.contains("image"))
|
||||||
{
|
{
|
||||||
|
|
|
@ -42,7 +42,8 @@ signals:
|
||||||
|
|
||||||
void doConvertPdf(QNetworkRequest request, QString filename, QTemporaryFile* tempfile,
|
void doConvertPdf(QNetworkRequest request, QString filename, QTemporaryFile* tempfile,
|
||||||
QString targetFormat, quint32 Colors, quint32 Quality, QString PaperSize,
|
QString targetFormat, quint32 Colors, quint32 Quality, QString PaperSize,
|
||||||
quint32 HwResX, quint32 HwResY, bool TwoSided, bool Tumble);
|
quint32 HwResX, quint32 HwResY, bool TwoSided, bool Tumble,
|
||||||
|
quint32 PageRangeLow, quint32 PageRangeHigh);
|
||||||
|
|
||||||
void doConvertImage(QNetworkRequest request, QString filename, QTemporaryFile* tempfile,
|
void doConvertImage(QNetworkRequest request, QString filename, QTemporaryFile* tempfile,
|
||||||
QString targetFormat, quint32 Colors, quint32 Quality, QString PaperSize,
|
QString targetFormat, quint32 Colors, quint32 Quality, QString PaperSize,
|
||||||
|
|
|
@ -349,6 +349,17 @@
|
||||||
<source>Zero margins</source>
|
<source>Zero margins</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Page range</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>RangeSetting</name>
|
||||||
|
<message>
|
||||||
|
<source>all</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsPage</name>
|
<name>SettingsPage</name>
|
||||||
|
|
|
@ -349,6 +349,17 @@
|
||||||
<source>Zero margins</source>
|
<source>Zero margins</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Page range</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>RangeSetting</name>
|
||||||
|
<message>
|
||||||
|
<source>all</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsPage</name>
|
<name>SettingsPage</name>
|
||||||
|
|
|
@ -349,6 +349,17 @@
|
||||||
<source>Zero margins</source>
|
<source>Zero margins</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Page range</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>RangeSetting</name>
|
||||||
|
<message>
|
||||||
|
<source>all</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsPage</name>
|
<name>SettingsPage</name>
|
||||||
|
|
|
@ -349,6 +349,17 @@
|
||||||
<source>Zero margins</source>
|
<source>Zero margins</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Page range</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>RangeSetting</name>
|
||||||
|
<message>
|
||||||
|
<source>all</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsPage</name>
|
<name>SettingsPage</name>
|
||||||
|
|
|
@ -349,6 +349,17 @@
|
||||||
<source>Zero margins</source>
|
<source>Zero margins</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Page range</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>RangeSetting</name>
|
||||||
|
<message>
|
||||||
|
<source>all</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsPage</name>
|
<name>SettingsPage</name>
|
||||||
|
|
Loading…
Reference in a new issue