[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