[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [plasma-desktop/andriy/keyboard] kcms/keyboard: Take keyboard geometry into account when showing lay
From: Andriy Rysin <arysin () gmail ! com>
Date: 2014-10-01 2:59:36
Message-ID: E1XZA8e-00038f-GB () scm ! kde ! org
[Download RAW message or body]
Git commit e7444cac60085e6db4f5cfe050ceeaf413b1c97a by Andriy Rysin.
Committed on 01/10/2014 at 02:54.
Pushed by rysin into branch 'andriy/keyboard'.
Take keyboard geometry into account when showing layout preview
GSoC 2013 project by Shivam Makkar (amourphious1992@gmail.com)
REVIEW: 113413
A +242 -0 kcms/keyboard/preview/geometry_components.cpp [License: GPL (v2+)]
A +358 -0 kcms/keyboard/preview/geometry_components.h [License: GPL (v2+)]
A +535 -0 kcms/keyboard/preview/geometry_parser.cpp [License: GPL (v2+)]
A +158 -0 kcms/keyboard/preview/geometry_parser.h [License: GPL (v2+)]
A +287 -0 kcms/keyboard/preview/symbol_parser.cpp [License: GPL (v2+)]
A +93 -0 kcms/keyboard/preview/symbol_parser.h [License: GPL (v2+)]
A +104 -0 kcms/keyboard/tests/geometry_parser_test.cpp [License: GPL (v2+)]
http://commits.kde.org/plasma-desktop/e7444cac60085e6db4f5cfe050ceeaf413b1c97a
diff --git a/kcms/keyboard/preview/geometry_components.cpp \
b/kcms/keyboard/preview/geometry_components.cpp new file mode 100644
index 0000000..7addcb5
--- /dev/null
+++ b/kcms/keyboard/preview/geometry_components.cpp
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#include "geometry_components.h"
+
+#include <QString>
+#include <QDebug>
+#include <QPoint>
+
+
+GShape::GShape()
+{
+ cordi_count = 0;
+}
+
+void GShape::setCordinate(double a, double b)
+{
+ cordii << QPoint(a, b);
+ cordi_count++;
+}
+
+void GShape::setApprox(double a, double b)
+{
+ a -= approx.x();
+ b -= approx.y();
+ approx = QPoint(a, b);
+}
+
+QPoint GShape :: getCordii(int i) const
+{
+ if (i < cordi_count) {
+ return cordii[i];
+ }
+
+ return QPoint();
+}
+
+void GShape::display()
+{
+ qDebug() << "shape: " << sname << "\n";
+ qDebug() << "(" << approx.x() << "," << approx.y() << ");";
+
+ for (int i = 0; i < cordi_count; i++) {
+ qDebug() << cordii[i];
+ }
+}
+
+double GShape::size(int vertical) const
+{
+ if (!cordii.isEmpty()) {
+ if (vertical == 0) {
+ if (approx.x() == 0 && approx.y() == 0) {
+ int max = 0;
+ for (int i = 0; i < cordi_count; i++) {
+ if (max < cordii[i].x()) {
+ max = cordii[i].x();
+ }
+ }
+ return max;
+ } else {
+ return approx.x();
+ }
+ } else {
+ if (approx.x() == 0 && approx.y() == 0) {
+ int max = 0;
+ for (int i = 0; i < cordi_count; i++) {
+ if (max < cordii[i].y()) {
+ max = cordii[i].y();
+ }
+ }
+ return max;
+ }
+
+ return approx.y();
+ }
+ }
+
+ return 0;
+}
+
+
+Key::Key()
+{
+ offset = 0;
+}
+
+void Key::setKeyPosition(double x, double y)
+{
+ position = QPoint(x, y);
+}
+
+void Key::showKey()
+{
+ qDebug() << "\n\tKey: " << name << "\tshape: " << shapeName << "\toffset: " << offset;
+ qDebug() << "\tposition" << position;
+}
+
+
+Row::Row()
+{
+ top = 0;
+ left = 0;
+ keyCount = 0;
+ vertical = 0;
+ keyList << Key();
+}
+
+void Row::addKey()
+{
+ //qDebug() << "keyCount: " << keyCount;
+ keyCount++;
+ keyList << Key();
+}
+
+void Row::displayRow()
+{
+ qDebug() << "\nRow: (" << left << "," << top << ")\n";
+ qDebug() << "vertical: " << vertical;
+ for (int i = 0; i < keyCount; i++) {
+ keyList[i].showKey();
+ }
+}
+
+
+Section::Section()
+{
+ top = 0;
+ left = 0;
+ angle = 0;
+ rowCount = 0;
+ vertical = 0;
+ rowList << Row();
+}
+
+void Section::addRow()
+{
+ //qDebug() << "\nrowCount: " << rowCount;
+ rowCount++;
+ rowList << Row();
+}
+
+void Section::displaySection()
+{
+ //qDebug() << "\nSection: " << name << "\n\tposition: (" << left << "," << top << ");" << angle << \
"\n"; + //qDebug() << "vertical: " << vertical;
+ for (int i = 0; i < rowCount; i++) {
+ qDebug() << "\n\t";
+ rowList[i].displayRow();
+ }
+}
+
+
+Geometry::Geometry()
+{
+ sectionTop = 0;
+ sectionLeft = 0;
+ rowTop = 0;
+ rowLeft = 0;
+ keyGap = 0;
+ shape_count = 0;
+ width = 0;
+ height = 0;
+ sectionCount = 0;
+ vertical = 0;
+ sectionList << Section();
+ shapes << GShape();
+ keyShape = QString("NORM");
+ parsedGeometry = true;
+}
+
+void Geometry::setShapeName(const QString &n)
+{
+ shapes[shape_count].setShapeName(n);
+}
+
+void Geometry::setShapeCord(double a, double b)
+{
+ shapes[shape_count].setCordinate(a, b);
+}
+
+void Geometry::setShapeApprox(double a, double b)
+{
+ shapes[shape_count].setApprox(a, b);
+}
+
+void Geometry::addShape()
+{
+ shape_count++;
+ shapes << GShape();
+}
+
+void Geometry::display()
+{
+ qDebug() << name << "\n" << description << "\nwidth:" << width
+ << "\nheight:" << height << "\n" << "sectionTop:" << sectionTop;
+ qDebug() << "\nsectionLeft:" << sectionLeft << "\nrowTop:" << rowTop << "\nrowLeft:"
+ << rowLeft << "\nkeyGap: " << keyGap << "\nkeyShape:" << keyShape << "\n";
+ qDebug() << "vertical:" << vertical;
+
+ for (int i = 0; i < shape_count; i++) {
+ shapes[i].display();
+ }
+
+ for (int j = 0; j < sectionCount; j++) {
+ sectionList[j].displaySection();
+ }
+}
+
+void Geometry::addSection()
+{
+ //qDebug() << "\nsectionCount: " << sectionCount;
+ sectionCount++;
+ sectionList << Section();
+}
+
+GShape Geometry::findShape(const QString &name)
+{
+ GShape l;
+
+ for (int i = 0; i < shape_count; i++) {
+ if (shapes[i].getShapeName() == name) {
+ return shapes[i];
+ }
+ }
+ return l;
+}
diff --git a/kcms/keyboard/preview/geometry_components.h b/kcms/keyboard/preview/geometry_components.h
new file mode 100644
index 0000000..65d3d67
--- /dev/null
+++ b/kcms/keyboard/preview/geometry_components.h
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef GEOMETRY_COMPONENTS_H
+#define GEOMETRY_COMPONENTS_H
+
+#include <QString>
+#include <QPoint>
+#include <QList>
+
+
+class GShape
+{
+private:
+ QString sname;
+ QPoint approx;
+ QList <QPoint> cordii;
+ int cordi_count;
+
+public:
+ GShape();
+ void setCordinate(double a, double b);
+ void setApprox(double a, double b);
+ QPoint getCordii(int i) const;
+ void display();
+ double size(int vertical) const;
+
+ void setShapeName(const QString &n)
+ {
+ sname = n;
+ }
+
+ QPoint getApprox() const
+ {
+ return approx;
+ }
+
+ QString getShapeName()
+ {
+ return sname;
+ }
+
+ int getCordi_count() const
+ {
+ return cordi_count;
+ }
+};
+
+class Key
+{
+private:
+ QString name, shapeName;
+ double offset;
+ QPoint position;
+
+public:
+ Key();
+ void setKeyPosition(double x, double y);
+
+ void setOffset(double o)
+ {
+ offset = o;
+ }
+
+ void setKeyName(const QString &n)
+ {
+ name = n;
+ }
+
+ void setShapeName(const QString &n)
+ {
+ shapeName = n;
+ }
+
+ QString getName()
+ {
+ return name;
+ }
+
+ QString getShapeName()
+ {
+ return shapeName;
+ }
+
+ double getOffset()
+ {
+ return offset;
+ }
+
+ QPoint getPosition()
+ {
+ return position;
+ }
+
+ void showKey();
+};
+
+class Row
+{
+private:
+ double top, left;
+ int keyCount, vertical;
+ QString shapeName;
+
+public :
+ QList <Key> keyList;
+
+ Row();
+ void addKey();
+
+ void setTop(double t)
+ {
+ top = t;
+ }
+
+ void setLeft(double l)
+ {
+ left = l;
+ }
+
+ void setVertical(int v)
+ {
+ vertical = v;
+ }
+
+ void setShapeName(const QString &n)
+ {
+ shapeName = n;
+ }
+
+ double getTop()
+ {
+ return top;
+ }
+
+ double getLeft()
+ {
+ return left;
+ }
+
+ int getKeyCount()
+ {
+ return keyCount;
+ }
+
+ int getVertical()
+ {
+ return vertical;
+ }
+
+ QString getShapeName()
+ {
+ return shapeName;
+ }
+
+ void displayRow();
+};
+
+class Section
+{
+private:
+ QString name, shapeName;
+ double top, left, angle;
+ int rowCount, vertical;
+
+public:
+ QList <Row> rowList;
+
+ Section();
+ void addRow();
+
+ void setName(const QString &n)
+ {
+ name = n;
+ }
+
+ void setShapeName(const QString &n)
+ {
+ shapeName = n;
+ }
+
+ void setTop(double t)
+ {
+ top = t;
+ }
+
+ void setLeft(double l)
+ {
+ left = l;
+ }
+
+ void setAngle(double a)
+ {
+ angle = a;
+ }
+
+ void setVertical(int v)
+ {
+ vertical = v;
+ }
+
+ QString getName()
+ {
+ return name;
+ }
+
+ QString getShapeName()
+ {
+ return shapeName;
+ }
+
+ double getTop()
+ {
+ return top;
+ }
+
+ double getLeft()
+ {
+ return left;
+ }
+
+ double getAngle()
+ {
+ return angle;
+ }
+
+ int getVertical()
+ {
+ return vertical;
+ }
+
+ int getRowCount()
+ {
+ return rowCount;
+ }
+
+ void displaySection();
+};
+
+class Geometry
+{
+private:
+ QString name, description, keyShape;
+ int shape_count, vertical;
+ int sectionCount;
+
+public:
+ QList <GShape> shapes;
+ QList <Section> sectionList;
+ double width, height, sectionTop, sectionLeft, rowTop, rowLeft, keyGap;
+ bool parsedGeometry;
+ Geometry();
+
+ void setWidth(double a)
+ {
+ width = a;
+ }
+
+ void setParsing(bool state)
+ {
+ parsedGeometry = state;
+ }
+
+ void setHeight(double a)
+ {
+ height = a;
+ }
+
+ void setName(const QString &n)
+ {
+ name = n;
+ }
+
+ void setDescription(const QString &d)
+ {
+ description = d;
+ }
+
+ void setKeyShape(const QString &s)
+ {
+ keyShape = s;
+ }
+
+ void setVertical(int v)
+ {
+ vertical = v;
+ }
+
+ double getWidth()
+ {
+ return width;
+ }
+
+ double getHeight()
+ {
+ return height;
+ }
+
+ QString getName()
+ {
+ return name;
+ }
+
+ QString getDescription()
+ {
+ return description;
+ }
+
+ QString getKeyShape()
+ {
+ return keyShape;
+ }
+
+ int getVertical()
+ {
+ return vertical;
+ }
+
+ int getShapeCount()
+ {
+ return shape_count;
+ }
+
+ int getSectionCount()
+ {
+ return sectionCount;
+ }
+
+ bool getParsing()
+ {
+ return parsedGeometry;
+ }
+
+ void setShapeName(const QString &n);
+ void setShapeCord(double a, double b);
+ void setShapeApprox(double a, double b);
+ void addShape();
+ void display();
+ void addSection();
+ GShape findShape(const QString &name);
+};
+
+#endif //geometry_componets.h
diff --git a/kcms/keyboard/preview/geometry_parser.cpp b/kcms/keyboard/preview/geometry_parser.cpp
new file mode 100644
index 0000000..0b8ed92
--- /dev/null
+++ b/kcms/keyboard/preview/geometry_parser.cpp
@@ -0,0 +1,535 @@
+/*
+* Copyright (C) 2013 Shivam Makkar (amourphious1992@gmail.com)
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include "geometry_parser.h"
+#include "geometry_components.h"
+#include "xkb_rules.h"
+
+#include <QString>
+#include <QDebug>
+#include <QFileDialog>
+#include <QFile>
+#include <QPair>
+
+
+#include <fixx11h.h>
+#include <config-workspace.h>
+
+namespace grammar
+{
+keywords::keywords()
+{
+ add
+ ("shape", 1)
+ ("height", 2)
+ ("width", 3)
+ ("description", 4)
+ ("keys", 5)
+ ("row", 6)
+ ("section", 7)
+ ("key", 8)
+ ("//", 9)
+ ("/*", 10)
+ ;
+}
+
+
+template<typename Iterator>
+Geometry_parser<Iterator>::Geometry_parser(): Geometry_parser::base_type(start)
+{
+
+ using qi::lexeme;
+ using qi::char_;
+ using qi::lit;
+ using qi::_1;
+ using qi::_val;
+ using qi::int_;
+ using qi::double_;
+ using qi::eol;
+
+
+ name = '"' >> +(char_ - '"') >> '"';
+
+ ignore = (lit("outline") || lit("overlay") || lit("text")) >> *(char_ - lit("};")) >> lit("};")
+ || lit("solid") >> *(char_ - lit("};")) >> lit("};")
+ || lit("indicator") >> *(char_ - ';' - '{') >> ';' || '{' >> *(char_ - lit("};")) >> \
lit("};") + || lit("indicator") >> '.' >> lit("shape") >> '=' >> name >> ';';
+
+ comments = lexeme[ lit("//") >> *(char_ - eol || keyword - eol) >> eol || lit("/*") >> *(char_ - \
lit("*/") || keyword - lit("*/")) >> lit("*/") ]; +
+ cordinates = ('['
+ >> double_[phx::ref(shapeLenX) = _1]
+ >> ','
+ >> double_[phx::ref(shapeLenY) = _1]
+ >> ']')
+ || '[' >> double_ >> "," >> double_ >> ']'
+ ;
+
+ cordinatea = '[' >> double_[phx::ref(approxLenX) = _1] >> "," >> double_[phx::ref(approxLenY) = _1] \
>> ']'; +
+ set = '{' >> cordinates >> *(',' >> cordinates) >> '}';
+
+ setap = '{' >> cordinatea >> *(',' >> cordinatea) >> '}';
+
+ seta = '{'
+ >> cordinates[phx::bind(&Geometry_parser::setCord, this)]
+ >> *(',' >> cordinates[phx::bind(&Geometry_parser::setCord, this)])
+ >> '}'
+ ;
+
+ description = lit("description") >> '=' >> name[phx::bind(&Geometry_parser::getDescription, this, \
_1)] >> ';'; +
+ cornerRadius = (lit("cornerRadius") || lit("corner")) >> '=' >> double_;
+
+ shapeDef = lit("shape")
+ >> name[phx::bind(&Geometry_parser::getShapeName, this, _1)]
+ >> '{'
+ >> *(lit("approx") >> '=' >> setap[phx::bind(&Geometry_parser::setApprox, this)] >> ',' \
|| cornerRadius >> ',' || comments) + >> seta
+ >> *((',' >> (set || lit("approx") >> '=' >> setap[phx::bind(&Geometry_parser::setApprox, \
this)] || cornerRadius) || comments)) + >> lit("};")
+ ;
+
+ keyName = '<' >> +(char_ - '>') >> '>';
+
+ keyShape = *(lit("key.")) >> lit("shape") >> '=' >> name[phx::bind(&Geometry_parser::setKeyShape, \
this, _1)] + || name[phx::bind(&Geometry_parser::setKeyShape, this, _1)];
+
+ keyColor = lit("color") >> '=' >> name;
+
+ keygap = lit("gap") >> '=' >> double_[phx::ref(KeyOffset) = _1] || double_[phx::ref(KeyOffset) = \
_1]; +
+ keyDesc = keyName[phx::bind(&Geometry_parser::setKeyNameandShape, this, _1)]
+ || '{' >> (keyName[phx::bind(&Geometry_parser::setKeyNameandShape, this, _1)] || keyShape
+ || keygap[phx::bind(&Geometry_parser::setKeyOffset, this)]
+ || keyColor)
+ >> *((','
+ >> (keyName
+ || keyShape
+ || keygap[phx::bind(&Geometry_parser::setKeyOffset, this)]
+ || keyColor))
+ || comments)
+ >> '}';
+
+ keys = lit("keys")
+ >> '{'
+ >> keyDesc[phx::bind(&Geometry_parser::setKeyCordi, this)]
+ >> *((*lit(',') >> keyDesc[phx::bind(&Geometry_parser::setKeyCordi, this)] >> *lit(',')) || \
comments) + >> lit("};");
+
+ geomShape = ((lit("key.shape") >> '=' >> name[phx::bind(&Geometry_parser::setGeomShape, this, _1)]) \
|| (lit("key.color") >> '=' >> name)) >> ';'; + geomLeft = lit("section.left") >> '=' >> \
double_[phx::ref(geom.sectionLeft) = _1] >> ';'; + geomTop = lit("section.top") >> '=' >> \
double_[phx::ref(geom.sectionTop) = _1] >> ';'; + geomRowTop = lit("row.top") >> '=' >> \
double_[phx::ref(geom.rowTop) = _1] >> ';'; + geomRowLeft = lit("row.left") >> '=' >> \
double_[phx::ref(geom.rowLeft) = _1] >> ';'; + geomGap = lit("key.gap") >> '=' >> \
double_[phx::ref(geom.keyGap) = _1] >> ';'; + geomVertical = *lit("row.") >> lit("vertical") >> '=' >> \
(lit("True") || lit("true")) >> ';'; + geomAtt = geomLeft || geomTop || geomRowTop || geomRowLeft || \
geomGap; +
+ top = lit("top") >> '=' >> double_ >> ';';
+ left = lit("left") >> '=' >> double_ >> ';';
+
+ row = lit("row")[phx::bind(&Geometry_parser::rowinit, this)]
+ >> '{'
+ >> *(top[phx::bind(&Geometry_parser::setRowTop, this, _1)]
+ || left[phx::bind(&Geometry_parser::setRowLeft, this, _1)]
+ || localShape[phx::bind(&Geometry_parser::setRowShape, this, _1)]
+ || localColor
+ || comments
+ || geomVertical[phx::bind(&Geometry_parser::setVerticalRow, this)]
+ || keys
+ )
+ >> lit("};") || ignore || geomVertical[phx::bind(&Geometry_parser::setVerticalSection, this)];
+
+ angle = lit("angle") >> '=' >> double_ >> ';';
+
+ localShape = lit("key.shape") >> '=' >> name[_val = _1] >> ';';
+ localColor = lit("key.color") >> '=' >> name >> ';';
+ localDimension = (lit("height") || lit("width")) >> '=' >> double_ >> ';';
+ priority = lit("priority") >> '=' >> double_ >> ';';
+
+ section = lit("section")[phx::bind(&Geometry_parser::sectioninit, this)]
+ >> name[phx::bind(&Geometry_parser::sectionName, this, _1)]
+ >> '{'
+ >> *(top[phx::bind(&Geometry_parser::setSectionTop, this, _1)]
+ || left[phx::bind(&Geometry_parser::setSectionLeft, this, _1)]
+ || angle[phx::bind(&Geometry_parser::setSectionAngle, this, _1)]
+ || row[phx::bind(&Geometry_parser::addRow, this)]
+ || localShape[phx::bind(&Geometry_parser::setSectionShape, this, _1)]
+ || geomAtt
+ || localColor
+ || localDimension
+ || priority
+ || comments)
+ >> lit("};") || geomVertical[phx::bind(&Geometry_parser::setVerticalGeometry, this)];
+
+ shapeC = lit("shape") >> '.' >> cornerRadius >> ';';
+
+ shape = shapeDef || shapeC;
+
+
+ input = '{'
+ >> +(width
+ || height
+ || comments
+ || ignore
+ || description
+ || (char_ - keyword - '}'
+ || shape[phx::bind(&Geometry::addShape, &geom)]
+ || section[phx::bind(&Geometry::addSection, &geom)]
+ || geomAtt
+ || geomShape
+ ))
+ >> '}';
+
+ width = lit("width") >> '=' >> double_[phx::bind(&Geometry::setWidth, &geom, _1)] >> ";";
+ height = lit("height") >> '=' >> double_[phx::bind(&Geometry::setHeight, &geom, _1)] >> ";";
+
+ start %= *(lit("default"))
+ >> lit("xkb_geometry")
+ >> name[phx::bind(&Geometry_parser::getName, this, _1)]
+ >> input
+ >> ';' >> *(comments || char_ - lit("xkb_geometry"));
+}
+
+template<typename Iterator>
+void Geometry_parser<Iterator>::setCord()
+{
+ geom.setShapeCord(shapeLenX, shapeLenY);
+}
+
+
+template<typename Iterator>
+void Geometry_parser<Iterator>::setSectionShape(std::string n)
+{
+ geom.sectionList[geom.getSectionCount()].setShapeName(QString::fromUtf8(n.data(), n.size()));
+}
+
+
+template<typename Iterator>
+void Geometry_parser<Iterator>::getName(std::string n)
+{
+ geom.setName(QString::fromUtf8(n.data(), n.size()));
+}
+
+
+template<typename Iterator>
+void Geometry_parser<Iterator>::getDescription(std::string n)
+{
+ geom.setDescription(QString::fromUtf8(n.data(), n.size()));
+}
+
+
+template<typename Iterator>
+void Geometry_parser<Iterator>::getShapeName(std::string n)
+{
+ geom.setShapeName(QString::fromUtf8(n.data(), n.size()));
+}
+
+
+template<typename Iterator>
+void Geometry_parser<Iterator>::setGeomShape(std::string n)
+{
+ geom.setKeyShape(QString::fromUtf8(n.data(), n.size()));
+}
+
+
+template<typename Iterator>
+void Geometry_parser<Iterator>::setRowShape(std::string n)
+{
+ int secn = geom.getSectionCount();
+ int rown = geom.sectionList[secn].getRowCount();
+ geom.sectionList[secn].rowList[rown].setShapeName(QString::fromUtf8(n.data(), n.size()));
+}
+
+
+template<typename Iterator>
+void Geometry_parser<Iterator>::setApprox()
+{
+ geom.setShapeApprox(approxLenX, approxLenY);
+}
+
+
+template<typename Iterator>
+void Geometry_parser<Iterator>::addRow()
+{
+ geom.sectionList[geom.getSectionCount()].addRow();
+}
+
+
+template<typename Iterator>
+void Geometry_parser<Iterator>::sectionName(std::string n)
+{
+ geom.sectionList[geom.getSectionCount()].setName(QString::fromUtf8(n.data(), n.size()));
+}
+
+
+template<typename Iterator>
+void Geometry_parser<Iterator>::rowinit()
+{
+ int secn = geom.getSectionCount();
+ int rown = geom.sectionList[secn].getRowCount();
+ double tempTop = geom.sectionList[secn].getTop();
+ QString tempShape = geom.sectionList[secn].getShapeName();
+ geom.sectionList[secn].rowList[rown].setTop(tempTop);
+ geom.sectionList[secn].rowList[rown].setLeft(geom.sectionList[secn].getLeft());
+ geom.sectionList[secn].rowList[rown].setShapeName(tempShape);
+ keyCordiX = geom.sectionList[secn].rowList[rown].getLeft();
+ keyCordiY = geom.sectionList[secn].rowList[rown].getTop();
+ tempTop = geom.sectionList[secn].getVertical();
+ geom.sectionList[secn].rowList[rown].setVertical(tempTop);
+}
+
+
+template<typename Iterator>
+void Geometry_parser<Iterator>::sectioninit()
+{
+ int secn = geom.getSectionCount();
+ geom.sectionList[secn].setTop(geom.sectionTop);
+ geom.sectionList[secn].setLeft(geom.sectionLeft);
+ keyCordiX = geom.sectionList[secn].getLeft();
+ keyCordiY = geom.sectionList[secn].getTop();
+ geom.sectionList[secn].setShapeName(geom.getKeyShape());
+ geom.sectionList[secn].setVertical(geom.getVertical());
+}
+
+
+template<typename Iterator>
+void Geometry_parser<Iterator>::setRowTop(double a)
+{
+ int secn = geom.getSectionCount();
+ int rown = geom.sectionList[secn].getRowCount();
+ double tempTop = geom.sectionList[secn].getTop();
+ geom.sectionList[secn].rowList[rown].setTop(a + tempTop);
+ keyCordiY = geom.sectionList[secn].rowList[rown].getTop();
+}
+
+
+template<typename Iterator>
+void Geometry_parser<Iterator>::setRowLeft(double a)
+{
+ int secn = geom.getSectionCount();
+ int rown = geom.sectionList[secn].getRowCount();
+ double tempLeft = geom.sectionList[secn].getLeft();
+ geom.sectionList[secn].rowList[rown].setLeft(a + tempLeft);
+ keyCordiX = geom.sectionList[secn].rowList[rown].getLeft();
+}
+
+
+template<typename Iterator>
+void Geometry_parser<Iterator>::setSectionTop(double a)
+{
+ //qDebug() << "\nsectionCount" << geom.sectionCount;
+ int secn = geom.getSectionCount();
+ geom.sectionList[secn].setTop(a + geom.sectionTop);
+ keyCordiY = geom.sectionList[secn].getTop();
+}
+
+
+template<typename Iterator>
+void Geometry_parser<Iterator>::setSectionLeft(double a)
+{
+ //qDebug() << "\nsectionCount" << geom.sectionCount;
+ int secn = geom.getSectionCount();
+ geom.sectionList[secn].setLeft(a + geom.sectionLeft);
+ keyCordiX = geom.sectionList[secn].getLeft();
+
+}
+
+
+template<typename Iterator>
+void Geometry_parser<Iterator>::setSectionAngle(double a)
+{
+ //qDebug() << "\nsectionCount" << geom.sectionCount;
+ int secn = geom.getSectionCount();
+ geom.sectionList[secn].setAngle(a);
+}
+
+
+template<typename Iterator>
+void Geometry_parser<Iterator>::setVerticalRow()
+{
+ int secn = geom.getSectionCount();
+ int rown = geom.sectionList[secn].getRowCount();
+ geom.sectionList[secn].rowList[rown].setVertical(1);
+}
+
+
+template<typename Iterator>
+void Geometry_parser<Iterator>::setVerticalSection()
+{
+ int secn = geom.getSectionCount();
+ geom.sectionList[secn].setVertical(1);
+}
+
+
+template<typename Iterator>
+void Geometry_parser<Iterator>::setVerticalGeometry()
+{
+ geom.setVertical(1);
+}
+
+
+template<typename Iterator>
+void Geometry_parser<Iterator>::setKeyName(std::string n)
+{
+ int secn = geom.getSectionCount();
+ int rown = geom.sectionList[secn].getRowCount();
+ int keyn = geom.sectionList[secn].rowList[rown].getKeyCount();
+ //qDebug() << "\nsC: " << secn << "\trC: " << rown << "\tkn: " << keyn;
+ geom.sectionList[secn].rowList[rown].keyList[keyn].setKeyName(QString::fromUtf8(n.data(), \
n.size())); +}
+
+
+template<typename Iterator>
+void Geometry_parser<Iterator>::setKeyShape(std::string n)
+{
+ int secn = geom.getSectionCount();
+ int rown = geom.sectionList[secn].getRowCount();
+ int keyn = geom.sectionList[secn].rowList[rown].getKeyCount();
+ //qDebug() << "\nsC: " << secn << "\trC: " << rown << "\tkn: " << keyn;
+ geom.sectionList[secn].rowList[rown].keyList[keyn].setShapeName(QString::fromUtf8(n.data(), \
n.size())); +}
+
+
+template<typename Iterator>
+void Geometry_parser<Iterator>::setKeyNameandShape(std::string n)
+{
+ int secn = geom.getSectionCount();
+ int rown = geom.sectionList[secn].getRowCount();
+ setKeyName(n);
+ setKeyShape(geom.sectionList[secn].rowList[rown].getShapeName().toUtf8().constData());
+}
+
+
+template<typename Iterator>
+void Geometry_parser<Iterator>::setKeyOffset()
+{
+ //qDebug() << "\nhere\n";
+ int secn = geom.getSectionCount();
+ int rown = geom.sectionList[secn].getRowCount();
+ int keyn = geom.sectionList[secn].rowList[rown].getKeyCount();
+ //qDebug() << "\nsC: " << secn << "\trC: " << rown << "\tkn: " << keyn;
+ geom.sectionList[secn].rowList[rown].keyList[keyn].setOffset(KeyOffset);
+}
+
+
+template<typename Iterator>
+void Geometry_parser<Iterator>::setKeyCordi()
+{
+ int secn = geom.getSectionCount();
+ int rown = geom.sectionList[secn].getRowCount();
+ int keyn = geom.sectionList[secn].rowList[rown].getKeyCount();
+ int vertical = geom.sectionList[secn].rowList[rown].getVertical();
+
+ Key key = geom.sectionList[secn].rowList[rown].keyList[keyn];
+
+ if (vertical == 0) {
+ keyCordiX += key.getOffset();
+ } else {
+ keyCordiY += key.getOffset();
+ }
+
+ geom.sectionList[secn].rowList[rown].keyList[keyn].setKeyPosition(keyCordiX, keyCordiY);
+
+ QString shapeStr = key.getShapeName();
+ if (shapeStr.isEmpty()) {
+ shapeStr = geom.getKeyShape();
+ }
+
+ GShape shapeObj = geom.findShape(shapeStr);
+ int a = shapeObj.size(vertical);
+
+ if (vertical == 0) {
+ keyCordiX += a + geom.keyGap;
+ } else {
+ keyCordiY += a + geom.keyGap;
+ }
+
+ geom.sectionList[secn].rowList[rown].addKey();
+}
+
+
+
+
+Geometry parseGeometry(const QString &model)
+{
+ using boost::spirit::iso8859_1::space;
+ typedef std::string::const_iterator iterator_type;
+ typedef grammar::Geometry_parser<iterator_type> Geometry_parser;
+ Geometry_parser geomertyParser;
+
+ Rules::GeometryId geoId = Rules::getGeometryId(model);
+ QString geometryFile = geoId.fileName;
+ QString geometryName = geoId.geoName;
+
+ qDebug() << "looking for model" << model << "geometryName" << geometryName << "in" << geometryFile;
+
+ QString xkbParentDir = findGeometryBaseDir();
+ geometryFile.prepend(xkbParentDir);
+ QFile gfile(geometryFile);
+
+ if (!gfile.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ qCritical() << "Unable to open the file" << geometryFile;
+ geomertyParser.geom.setParsing(false);
+ return geomertyParser.geom;
+ }
+
+ QString gcontent = gfile.readAll();
+ gfile.close();
+
+ QStringList gcontentList = gcontent.split("xkb_geometry");
+
+ int current = 1;
+ while (geomertyParser.geom.getName() != geometryName && current < gcontentList.size()) {
+ geomertyParser.geom = Geometry();
+ QString input = gcontentList.at(current);
+ input.prepend("xkb_geometry");
+ std::string parserInput = input.toUtf8().constData();
+
+ std::string::const_iterator iter = parserInput.begin();
+ std::string::const_iterator end = parserInput.end();
+
+ bool success = phrase_parse(iter, end, geomertyParser, space);
+
+ if (success && iter == end) {
+// qDebug() << "Geometry parsing succeeded for" << input.left(20);
+ geomertyParser.geom.setParsing(true);
+ } else {
+ qCritical() << "Geometry parsing failed for\n\t" << input.left(30);
+ geomertyParser.geom.setParsing(false);
+ }
+
+ current++;
+ }
+
+ if (geomertyParser.geom.getParsing()) {
+ return geomertyParser.geom;
+ }
+
+ qCritical() << "Failed to get geometry" << geomertyParser.geom.getName() << "falling back to pc104";
+ return parseGeometry("pc104");
+}
+
+QString findGeometryBaseDir()
+{
+ QString xkbDir = Rules::findXkbDir();
+ return QString("%1/geometry/").arg(xkbDir);
+}
+
+}
diff --git a/kcms/keyboard/preview/geometry_parser.h b/kcms/keyboard/preview/geometry_parser.h
new file mode 100644
index 0000000..075a352
--- /dev/null
+++ b/kcms/keyboard/preview/geometry_parser.h
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef GEOMETRY_PARSER_H
+#define GEOMETRY_PARSER_H
+
+#include <boost/config/warning_disable.hpp>
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/include/phoenix_core.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+#include <boost/spirit/include/phoenix_object.hpp>
+#include <boost/fusion/include/adapt_struct.hpp>
+#include <boost/fusion/include/io.hpp>
+#include <boost/spirit/include/phoenix_function.hpp>
+#include <boost/spirit/include/phoenix_statement.hpp>
+#include <boost/spirit/include/phoenix_bind.hpp>
+#include <boost/spirit/home/support/char_encoding/iso8859_1.hpp>
+
+
+#include <iostream>
+#include <QDebug>
+#include <QStringList>
+
+#include "geometry_components.h"
+
+namespace qi = boost::spirit::qi;
+namespace ascii = boost::spirit::ascii;
+namespace phx = boost::phoenix;
+namespace iso = boost::spirit::iso8859_1;
+
+
+namespace grammar
+{
+
+struct keywords : qi::symbols<char, int> {
+ keywords();
+};
+
+template<typename Iterator>
+struct Geometry_parser : qi::grammar<Iterator, iso::space_type> {
+
+ //comments
+ qi::rule<Iterator, std::string(), iso::space_type>comments, ignore;
+ qi::rule<Iterator, double(), iso::space_type>localDimension, priority;
+
+ //general non-temrminals
+ qi::rule<Iterator, std::string(), iso::space_type>name;
+ qi::rule<Iterator, std::string(), iso::space_type>description;
+ qi::rule<Iterator, std::string(), iso::space_type>input;
+
+ //non-teminals for shape
+ qi::rule<Iterator, int(), iso::space_type>shape;
+ qi::rule<Iterator, int(), iso::space_type>shapeDef;
+ qi::rule<Iterator, int(), iso::space_type>shapeC;
+ qi::rule<Iterator, int(), iso::space_type>set;
+ qi::rule<Iterator, int(), iso::space_type>setap;
+ qi::rule<Iterator, int(), iso::space_type>seta;
+ qi::rule<Iterator, int(), iso::space_type>cornerRadius;
+ qi::rule<Iterator, int(), iso::space_type>cordinatea;
+ qi::rule<Iterator, int(), iso::space_type>cordinates;
+
+ //non-teminals for key
+ qi::rule<Iterator, double(), iso::space_type>keygap;
+ qi::rule<Iterator, std::string(), iso::space_type>keyName;
+ qi::rule<Iterator, std::string(), iso::space_type>keyShape;
+ qi::rule<Iterator, std::string(), iso::space_type>keyColor;
+ qi::rule<Iterator, std::string(), iso::space_type>keyDesc;
+ qi::rule<Iterator, std::string(), iso::space_type>keys;
+
+ qi::rule<Iterator, std::string(), iso::space_type>row;
+
+ qi::rule<Iterator, std::string(), iso::space_type>section;
+
+ //non-teminals related to local data
+ qi::rule<Iterator, std::string(), iso::space_type>localShape;
+ qi::rule<Iterator, std::string(), iso::space_type>localColor;
+
+ //Geometry non-terminals
+ qi::rule<Iterator, std::string(), iso::space_type>geomShape;
+ qi::rule<Iterator, int(), iso::space_type>geomTop, geomVertical;
+ qi::rule<Iterator, int(), iso::space_type>geomLeft;
+ qi::rule<Iterator, int(), iso::space_type>geomRowTop;
+ qi::rule<Iterator, int(), iso::space_type>geomRowLeft;
+ qi::rule<Iterator, int(), iso::space_type>geomGap;
+ qi::rule<Iterator, int(), iso::space_type>geomAtt;
+ qi::rule<Iterator, int(), iso::space_type>angle;
+ qi::rule<Iterator, int(), iso::space_type>top;
+ qi::rule<Iterator, int(), iso::space_type>left;
+ qi::rule<Iterator, int(), iso::space_type>width;
+ qi::rule<Iterator, int(), iso::space_type>height;
+
+ qi::rule<Iterator, iso::space_type>start;
+ Geometry geom;
+ keywords keyword;
+ double shapeLenX, shapeLenY, approxLenX, approxLenY, keyCordiX, keyCordiY, KeyOffset;
+ Geometry_parser();
+
+ //functions for shape
+ void getShapeName(std::string n);
+ void setCord();
+ void setApprox();
+
+ //functions for section
+ void sectionName(std::string n);
+ void setSectionShape(std::string n);
+ void setSectionTop(double a);
+ void setSectionLeft(double a);
+ void setSectionAngle(double a);
+ void sectioninit();
+
+ //functions for row
+ void setRowShape(std::string n);
+ void setRowTop(double a);
+ void setRowLeft(double a);
+ void rowinit();
+ void addRow();
+
+ //functions for key
+ void setKeyName(std::string n);
+ void setKeyShape(std::string n);
+ void setKeyNameandShape(std::string n);
+ void setKeyOffset();
+ void setKeyCordi();
+
+ //functionsfor geometry
+ void setGeomShape(std::string n);
+ void getName(std::string n);
+ void getDescription(std::string n);
+
+ //functions for alingment
+ void setVerticalRow();
+ void setVerticalSection();
+ void setVerticalGeometry();
+};
+
+
+
+Geometry parseGeometry(const QString &model);
+QString findGeometryBaseDir();
+}
+
+#endif //geometry_parser
diff --git a/kcms/keyboard/preview/symbol_parser.cpp b/kcms/keyboard/preview/symbol_parser.cpp
new file mode 100644
index 0000000..0e9f033
--- /dev/null
+++ b/kcms/keyboard/preview/symbol_parser.cpp
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 2013 Shivam Makkar (amourphious1992@gmail.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "symbol_parser.h"
+#include "xkb_rules.h"
+
+#include <QString>
+#include <QStringList>
+#include <QDebug>
+#include <QFileDialog>
+#include <QFile>
+
+namespace grammar
+{
+
+symbol_keywords::symbol_keywords()
+{
+ add("key", 2)("include", 1)("//", 3)("*/", 4);
+}
+
+levels::levels()
+{
+ add("ONE", 1)("TWO", 2)("THREE", 3)("FOUR", 4)("SIX", 6)("EIGHT", 8);
+}
+
+template<typename Iterator>
+Symbol_parser<Iterator>::Symbol_parser() :
+ Symbol_parser::base_type(start)
+{
+ using qi::lexeme;
+ using qi::char_;
+ using qi::lit;
+ using qi::_1;
+ using qi::_val;
+ using qi::int_;
+ using qi::double_;
+ using qi::eol;
+
+ newKey = 0;
+
+ name %= '"' >> +(char_ - '"') >> '"';
+
+ group = lit("Group") >> int_;
+
+ comments = lexeme[lit("//") >> *(char_ - eol || symbolKeyword - eol) >> eol
+ || lit("/*") >> *(char_ - lit("*/") || symbolKeyword - lit("*/"))
+ >> lit("*/")];
+
+ include = lit("include")
+ >> name[phx::bind(&Symbol_parser::getInclude, this, _1)];
+
+ type = lit("type") >> '[' >> group >> lit(']') >> lit('=') >> lit("\"")
+ >> *(char_ - lvl)
+ >> *lvl[phx::bind(&Symbol_parser::setLevel, this, _1)]
+ >> *(char_ - lvl - '"') >> lit("\"");
+
+ symbol = +(char_ - ',' - ']');
+
+ symbols = *(lit("symbols") >> '[' >> group >> lit(']') >> lit('=')) >> '['
+ >> symbol[phx::bind(&Symbol_parser::getSymbol, this, _1)]
+ >> *(',' >> symbol[phx::bind(&Symbol_parser::getSymbol, this, _1)])
+ >> ']';
+
+ keyName = '<' >> *(char_ - '>') >> '>';
+
+ key = (lit("key")
+ >> keyName[phx::bind(&Symbol_parser::addKeyName, this, _1)] >> '{'
+ >> *(type >> ',') >> symbols >> *(',' >> type) >> lit("};"))
+ || lit("key") >> lit(".") >> type >> lit(";");
+
+ ee = *(char_ - symbolKeyword - '{') >> '{' >> *(char_ - '}' - ';')
+ >> lit("};");
+
+ start = *(char_ - lit("xkb_symbols") || comments) >> lit("xkb_symbols")
+ >> name[phx::bind(&Symbol_parser::setName, this, _1)] >> '{'
+ >> *(key[phx::bind(&Symbol_parser::addKey, this)] || include || ee
+ || char_ - '}' - symbolKeyword || comments) >> lit("};")
+ >> *(comments || char_);
+}
+
+template<typename Iterator>
+void Symbol_parser<Iterator>::getSymbol(std::string n)
+{
+ int index = layout.keyList[keyIndex].getSymbolCount();
+ layout.keyList[keyIndex].addSymbol(QString::fromUtf8(n.data(), n.size()),
+ index);
+ //qDebug() << "adding symbol: " << QString::fromUtf8(n.data(), n.size());
+ //qDebug() << "added symbol: " << layout.keyList[keyIndex].getSymbol(index) << " in " << keyIndex << \
" at " << index; +}
+
+template<typename Iterator>
+void Symbol_parser<Iterator>::addKeyName(std::string n)
+{
+ QString kname = QString::fromUtf8(n.data(), n.size());
+ if (kname.startsWith("Lat")) {
+ kname = alias.getAlias(layout.country, kname);
+ }
+ keyIndex = layout.findKey(kname);
+ //qDebug() << layout.getKeyCount();
+ if (keyIndex == -1) {
+ layout.keyList[layout.getKeyCount()].keyName = kname;
+ keyIndex = layout.getKeyCount();
+ newKey = 1;
+ }
+ // qDebug() << "key at" << keyIndex;
+}
+
+template<typename Iterator>
+void Symbol_parser<Iterator>::addKey()
+{
+ if (newKey == 1) {
+ layout.addKey();
+ newKey = 0;
+ //qDebug() << "new key";
+ }
+}
+
+template<typename Iterator>
+void Symbol_parser<Iterator>::getInclude(std::string n)
+{
+ layout.addInclude(QString::fromUtf8(n.data(), n.size()));
+}
+
+template<typename Iterator>
+void Symbol_parser<Iterator>::setName(std::string n)
+{
+ layout.setName(QString::fromUtf8(n.data(), n.size()));
+ //qDebug() << layout.getLayoutName();
+}
+
+template<typename Iterator>
+void Symbol_parser<Iterator>::setLevel(int lvl)
+{
+ if (lvl > layout.getLevel()) {
+ layout.setLevel(lvl);
+ qDebug() << lvl;
+ }
+}
+
+QString findSymbolBaseDir()
+{
+ QString xkbDir = Rules::findXkbDir();
+ return QString("%1/symbols/").arg(xkbDir);
+}
+
+QString findLayout(const QString &layout, const QString &layoutVariant)
+{
+
+ QString symbolBaseDir = findSymbolBaseDir();
+ QString symbolFile = symbolBaseDir.append(layout);
+
+ QFile sfile(symbolFile);
+ if (!sfile.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ //qDebug() << "unable to open the file";
+ return QString("I/O ERROR");
+ }
+
+ QString scontent = sfile.readAll();
+ sfile.close();
+ QStringList scontentList = scontent.split("xkb_symbols");
+
+ QString variant;
+ QString input;
+
+ if (layoutVariant.isEmpty()) {
+ input = scontentList.at(1);
+ input.prepend("xkb_symbols");
+ }
+
+ else {
+ int current = 1;
+
+ while (layoutVariant != variant && current < scontentList.size()) {
+ input = scontentList.at(current);
+
+ QString symbolCont = scontentList.at(current);
+
+ int index = symbolCont.indexOf("\"");
+ symbolCont = symbolCont.mid(index);
+ index = symbolCont.indexOf("{");
+ symbolCont = symbolCont.left(index);
+ symbolCont = symbolCont.remove(" ");
+ variant = symbolCont.remove("\"");
+
+ input.prepend("xkb_symbols");
+ current++;
+ }
+ }
+
+ return input;
+}
+
+KbLayout parseSymbols(const QString &layout, const QString &layoutVariant)
+{
+
+ using boost::spirit::iso8859_1::space;
+ typedef std::string::const_iterator iterator_type;
+ typedef grammar::Symbol_parser<iterator_type> Symbol_parser;
+
+ Symbol_parser symbolParser;
+
+ symbolParser.layout.country = layout;
+ QString input = findLayout(layout, layoutVariant);
+
+ if (input == "I/O ERROR") {
+ symbolParser.layout.setParsedSymbol(false);
+ return symbolParser.layout;
+ }
+
+ std::string parserInput = input.toUtf8().constData();
+
+ std::string::const_iterator iter = parserInput.begin();
+ std::string::const_iterator end = parserInput.end();
+
+ bool success = phrase_parse(iter, end, symbolParser, space);
+
+ if (success && iter == end) {
+ qDebug() << "Symbols Parsing succeeded";
+ symbolParser.layout.setParsedSymbol(true);
+
+ } else {
+ qWarning() << "Symbols Parsing failed\n" << input;
+ symbolParser.layout.setParsedSymbol(false);
+ }
+
+ for (int currentInclude = 0;
+ currentInclude < symbolParser.layout.getIncludeCount();
+ currentInclude++) {
+ QString include = symbolParser.layout.getInclude(currentInclude);
+ QStringList includeFile = include.split("(");
+ if (includeFile.size() == 2) {
+ QString file = includeFile.at(0);
+ QString layout = includeFile.at(1);
+ layout.remove(")");
+ input = findLayout(file, layout);
+
+ }
+
+ else {
+ QString a;
+ a.clear();
+ input = findLayout(includeFile.at(0), a);
+ }
+
+ parserInput = input.toUtf8().constData();
+
+ std::string::const_iterator iter = parserInput.begin();
+ std::string::const_iterator end = parserInput.end();
+
+ success = phrase_parse(iter, end, symbolParser, space);
+
+ if (success && iter == end) {
+ qDebug() << "Symbols Parsing succeeded";
+ symbolParser.layout.setParsedSymbol(true);
+
+ } else {
+ qDebug() << "Symbols Parsing failed\n";
+ qDebug() << input;
+ symbolParser.layout.setParsedSymbol(false);
+ }
+
+ }
+
+ //s.layout.display();
+ if (symbolParser.layout.getParsedSymbol()) {
+ return symbolParser.layout;
+ } else {
+ return parseSymbols("us", "basic");
+ }
+}
+
+}
diff --git a/kcms/keyboard/preview/symbol_parser.h b/kcms/keyboard/preview/symbol_parser.h
new file mode 100644
index 0000000..cd7af80
--- /dev/null
+++ b/kcms/keyboard/preview/symbol_parser.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2013 Shivam Makkar (amourphious1992@gmail.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef SYMBOL_PARSER_H
+#define SYMBOL_PARSER_H
+
+#include <boost/config/warning_disable.hpp>
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/include/phoenix_core.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+#include <boost/spirit/include/phoenix_object.hpp>
+#include <boost/fusion/include/adapt_struct.hpp>
+#include <boost/fusion/include/io.hpp>
+#include <boost/spirit/include/phoenix_function.hpp>
+#include <boost/spirit/include/phoenix_statement.hpp>
+#include <boost/spirit/include/phoenix_bind.hpp>
+#include <boost/spirit/home/support/char_encoding/iso8859_1.hpp>
+
+#include <iostream>
+#include <QDebug>
+
+#include "keyboardlayout.h"
+#include "keyaliases.h"
+
+
+namespace qi = boost::spirit::qi;
+namespace ascii = boost::spirit::ascii;
+namespace phx = boost::phoenix;
+namespace iso = boost::spirit::iso8859_1;
+
+
+namespace grammar
+{
+
+struct symbol_keywords : qi::symbols<char, int> {
+ symbol_keywords();
+};
+
+struct levels : qi::symbols<char, int> {
+ levels();
+};
+
+template<typename Iterator>
+struct Symbol_parser : qi::grammar<Iterator, iso::space_type> {
+
+ Symbol_parser();
+
+ qi::rule<Iterator, iso::space_type>start;
+ qi::rule<Iterator, std::string(), iso::space_type>name;
+ qi::rule<Iterator, std::string(), iso::space_type>keyName;
+ qi::rule<Iterator, std::string(), iso::space_type>symbols;
+ qi::rule<Iterator, std::string(), iso::space_type>key;
+ qi::rule<Iterator, std::string(), iso::space_type>type;
+ qi::rule<Iterator, std::string(), iso::space_type>group;
+ qi::rule<Iterator, std::string(), iso::space_type>symbol;
+ qi::rule<Iterator, std::string(), iso::space_type>comments;
+ qi::rule<Iterator, std::string(), iso::space_type>ee;
+ qi::rule<Iterator, std::string(), iso::space_type>include;
+
+ KbLayout layout;
+ int keyIndex, newKey;
+ symbol_keywords symbolKeyword;
+ levels lvl;
+ Aliases alias;
+
+ void getSymbol(std::string n);
+ void addKeyName(std::string n);
+ void getInclude(std::string n);
+ void addKey();
+ void setName(std::string n);
+ void setLevel(int lvl);
+};
+
+KbLayout parseSymbols(const QString &layout, const QString &layoutVariant);
+QString findSymbolBaseDir();
+}
+
+#endif //SYMBOL_PARSER_H
diff --git a/kcms/keyboard/tests/geometry_parser_test.cpp b/kcms/keyboard/tests/geometry_parser_test.cpp
new file mode 100644
index 0000000..6534f02
--- /dev/null
+++ b/kcms/keyboard/tests/geometry_parser_test.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2011 Andriy Rysin (rysin@kde.org)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <QDebug>
+#include <qtest_kde.h>
+
+#include "../preview/geometry_parser.h"
+
+
+
+class GeometryParserTest : public QObject
+{
+ Q_OBJECT
+
+
+private Q_SLOTS:
+ void initTestCase() {
+ }
+
+ void cleanupTestCase() {
+ }
+
+ void testGeometryParser() {
+ QString model = "pc104";
+ Geometry geometry = grammar::parseGeometry(model);
+
+ QCOMPARE(geometry.getName(), model);
+
+ model = "hpdv5";
+ geometry = grammar::parseGeometry(model);
+
+ QCOMPARE(geometry.getName(), QString("dv5"));
+
+ model = "microsoftelite";
+ geometry = grammar::parseGeometry(model);
+
+// QCOMPARE(geometry.getFile(), QString("microsoft"));
+ QCOMPARE(geometry.getName(), QString("elite"));
+
+/*
+ QVERIFY( flags != NULL );
+
+ QVERIFY( ! flags->getTransparentPixmap().isNull() );
+
+ const QIcon iconUs(flags->getIcon("us"));
+ QVERIFY( ! iconUs.isNull() );
+ QVERIFY( flags->getIcon("--").isNull() );
+
+ KeyboardConfig keyboardConfig;
+ LayoutUnit layoutUnit("us");
+ LayoutUnit layoutUnit1("us", "intl");
+ layoutUnit1.setDisplayName("usi");
+ LayoutUnit layoutUnit2("us", "other");
+
+ keyboardConfig.indicatorType = KeyboardConfig::SHOW_FLAG;
+ const QIcon iconUsFlag = flags->getIconWithText(layoutUnit, keyboardConfig);
+ QVERIFY( ! iconUsFlag.isNull() );
+ QCOMPARE( image(iconUsFlag), image(iconUs) );
+
+ keyboardConfig.indicatorType = KeyboardConfig::SHOW_LABEL;
+ const QIcon iconUsText = flags->getIconWithText(layoutUnit, keyboardConfig);
+ QVERIFY( ! iconUsText.isNull() );
+ QVERIFY( image(iconUsText) != image(iconUs) );
+
+ keyboardConfig.layouts.append(layoutUnit1);
+ QCOMPARE( flags->getShortText(layoutUnit, keyboardConfig), QString("us") );
+ QCOMPARE( flags->getShortText(layoutUnit1, keyboardConfig), QString("usi") );
+ QCOMPARE( flags->getShortText(layoutUnit2, keyboardConfig), QString("us") );
+
+ const Rules* rules = Rules::readRules(Rules::NO_EXTRAS);
+ QCOMPARE( flags->getLongText(layoutUnit, rules), QString("English (US)") );
+ QVERIFY( flags->getLongText(layoutUnit1, rules).startsWith("English (US, international with dead \
keys)") ); + QCOMPARE( flags->getLongText(layoutUnit2, rules), QString("other") );
+
+ rules = NULL; // when no rules found
+ QCOMPARE( flags->getLongText(layoutUnit1, rules), QString("us - intl") );
+
+ flags->clearCache();
+*/
+ }
+
+};
+
+// need kde libs for config-workspace.h used in xkb_rules.cpp
+// need GUI for xkb protocol
+QTEST_KDEMAIN( GeometryParserTest, GUI )
+
+#include "geometry_parser_test.moc"
+
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic