[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [plasma-desktop/amourphious/keyboard] kcms/keyboard: geometry preview changes added, clean up needed
From:       shivam makkar <amourphious1992 () gmail ! com>
Date:       2014-09-25 20:01:49
Message-ID: E1XXFEb-0007yb-ST () scm ! kde ! org
[Download RAW message or body]

Git commit 4a979c5b5e84432434b279844cf0f07de47c8c18 by shivam makkar.
Committed on 25/09/2014 at 20:00.
Pushed by makkar into branch 'amourphious/keyboard'.

geometry preview changes added, clean up needed (not tested)

M  +45   -23   kcms/keyboard/CMakeLists.txt
M  +13   -3    kcms/keyboard/kcm_add_layout_dialog.cpp
M  +1    -0    kcms/keyboard/kcm_add_layout_dialog.h
M  +31   -22   kcms/keyboard/kcm_keyboard_widget.cpp
M  +0    -3    kcms/keyboard/preview/TODO
A  +232  -0    kcms/keyboard/preview/geometry_components.cpp     [License: GPL (v2+)]
A  +303  -0    kcms/keyboard/preview/geometry_components.h     [License: GPL (v2+)]
A  +506  -0    kcms/keyboard/preview/geometry_parser.cpp     [License: GPL (v2+)]
A  +157  -0    kcms/keyboard/preview/geometry_parser.h     [License: GPL (v2+)]
M  +247  -240  kcms/keyboard/preview/kbpreviewframe.cpp
M  +45   -14   kcms/keyboard/preview/kbpreviewframe.h
M  +40   -36   kcms/keyboard/preview/keyaliases.cpp
M  +4    -3    kcms/keyboard/preview/keyaliases.h
M  +80   -148  kcms/keyboard/preview/keyboardlayout.cpp
M  +73   -23   kcms/keyboard/preview/keyboardlayout.h
M  +54   -8    kcms/keyboard/preview/keyboardpainter.cpp
M  +8    -1    kcms/keyboard/preview/keyboardpainter.h
M  +0    -0    kcms/keyboard/preview/keysym2ucs.cpp
M  +0    -0    kcms/keyboard/preview/keysym2ucs.h
M  +0    -0    kcms/keyboard/preview/keysymbols.cpp
M  +0    -0    kcms/keyboard/preview/keysymbols.h
M  +8    -1    kcms/keyboard/preview/keysymhelper.cpp
M  +2    -2    kcms/keyboard/preview/keysymhelper.h
A  +243  -0    kcms/keyboard/preview/model_to_geometry.cpp     [License: GPL (v2+)]
A  +113  -0    kcms/keyboard/preview/model_to_geometry.h     [License: GPL (v2+)]
A  +298  -0    kcms/keyboard/preview/symbol_parser.cpp     [License: GPL (v2+)]
A  +93   -0    kcms/keyboard/preview/symbol_parser.h     [License: GPL (v2+)]

http://commits.kde.org/plasma-desktop/4a979c5b5e84432434b279844cf0f07de47c8c18

diff --git a/kcms/keyboard/CMakeLists.txt b/kcms/keyboard/CMakeLists.txt
index 28355a5..a6e5884 100644
--- a/kcms/keyboard/CMakeLists.txt
+++ b/kcms/keyboard/CMakeLists.txt
@@ -99,30 +99,52 @@ install( TARGETS keyboard_layout_widget DESTINATION ${PLUGIN_INSTALL_DIR} )
 ### kcm keyboard ###
 include_directories("preview")
 
-set(kcm_keyboard_PART_SRCS 
-  kcm_keyboard.cpp
-  kcm_keyboard_widget.cpp
-  kcm_view_models.cpp
-  kcm_add_layout_dialog.cpp
-  keyboard_config.cpp
-  x11_helper.cpp
-  xkb_helper.cpp
-  xkb_rules.cpp
-  flags.cpp
-  iso_codes.cpp
-  kcmmisc.cpp
-  bindings.cpp
-  preview/keyaliases.cpp
-  preview/keyboardlayout.cpp
-  preview/keyboardpainter.cpp
-  preview/keysymbols.cpp
-  preview/keysymhelper.cpp
-  preview/kbpreviewframe.cpp
-  preview/keysym2ucs.cpp
-)
-
+find_package(Boost)
+
+if(Boost_FOUND)
+  ADD_DEFINITIONS(-DNEW_GEOMETRY=1)
+
+  set (CMAKE_CXX_FLAGS "-fexceptions")
+  set (CMAKE_CXX_FLAGS "-fpermissive")
+
+  set(preview_SRCS
+    preview/geometry_components.cpp
+    preview/geometry_parser.cpp
+    preview/kbpreviewframe.cpp
+    preview/keyboardlayout.cpp
+    preview/symbol_parser.cpp
+    preview/keyaliases.cpp
+    preview/keyboardlayout.cpp
+    preview/keyboardpainter.cpp
+    preview/keysymhelper.cpp
+    preview/keysym2ucs.cpp
+    preview/model_to_geometry.cpp)
+  
+else(Boost_FOUND)
+
+  message("Boost not found, install Boost libraries to enable keyboard geometry preview")
+
+endif(Boost_FOUND)
+
+
+set(kcm_keyboard_PART_SRCS
+    kcm_keyboard.cpp
+    kcm_keyboard_widget.cpp
+    kcm_view_models.cpp
+    kcm_add_layout_dialog.cpp
+    keyboard_config.cpp
+    x11_helper.cpp
+    xkb_helper.cpp
+    xkb_rules.cpp
+    flags.cpp
+    iso_codes.cpp
+    kcmmisc.cpp
+    bindings.cpp
+    LanguageDetection/training_text_map.cpp
+    LanguageDetection/languagedetector.cpp
+    ${preview_SRCS} )
 
-ki18n_wrap_ui(kcm_keyboard_PART_SRCS kcm_keyboard.ui kcm_add_layout_dialog.ui kcmmiscwidget.ui)
+qt5_wrap_ui(kcm_keyboard_PART_SRCS kcm_keyboard.ui kcm_add_layout_dialog.ui kcmmiscwidget.ui)
 
 add_library(kcm_keyboard MODULE ${kcm_keyboard_PART_SRCS})
 
diff --git a/kcms/keyboard/kcm_add_layout_dialog.cpp b/kcms/keyboard/kcm_add_layout_dialog.cpp
index 444da8e..b830588 100644
--- a/kcms/keyboard/kcm_add_layout_dialog.cpp
+++ b/kcms/keyboard/kcm_add_layout_dialog.cpp
@@ -66,7 +66,11 @@ AddLayoutDialog::AddLayoutDialog(const Rules* rules_, Flags* flags_, bool showLa
     languageChanged(0);
     connect(layoutDialogUi->languageComboBox, SIGNAL(activated(int)), this, SLOT(languageChanged(int)));
     connect(layoutDialogUi->layoutComboBox, SIGNAL(activated(int)), this, SLOT(layoutChanged(int)));
-    connect(layoutDialogUi->prevbutton,SIGNAL(clicked()),this,SLOT(preview()));
+#ifdef NEW_GEOMETRY
+    connect(layoutDialogUi->prevbutton, SIGNAL(clicked()), this, SLOT(preview()));
+#else
+    layoutDialogUi->prevbutton->setVisible(false);
+#endif
 }
 
 void AddLayoutDialog::languageChanged(int langIdx)
@@ -154,12 +158,18 @@ void AddLayoutDialog::accept()
 }
 
 
-void AddLayoutDialog::preview(){
+#ifdef NEW_GEOMETRY
+void AddLayoutDialog::preview()
+{
     int index = layoutDialogUi->variantComboBox->currentIndex();
     QString variant = layoutDialogUi->variantComboBox->itemData(index).toString();
     KeyboardPainter* layoutPreview = new KeyboardPainter();
-    layoutPreview->generateKeyboardLayout(selectedLayout, variant);
+
+    QString title = Flags::getLongText(LayoutUnit(selectedLayout, variant), rules);
+    layoutPreview->generateKeyboardLayout(selectedLayout, variant, model, title);
     layoutPreview->setModal(true);
     layoutPreview->exec();
+
     delete layoutPreview;
 }
+#endif
diff --git a/kcms/keyboard/kcm_add_layout_dialog.h b/kcms/keyboard/kcm_add_layout_dialog.h
index 6b82271..88d9f17 100644
--- a/kcms/keyboard/kcm_add_layout_dialog.h
+++ b/kcms/keyboard/kcm_add_layout_dialog.h
@@ -48,6 +48,7 @@ public Q_SLOTS:
 private:
 	const Rules* rules;
 	Flags* flags;
+    const QString& model;
 	Ui_AddLayoutDialog* layoutDialogUi;
 	QString selectedLanguage;
 	QString selectedLayout;
diff --git a/kcms/keyboard/kcm_keyboard_widget.cpp b/kcms/keyboard/kcm_keyboard_widget.cpp
index 9029ff1..bbd67a5 100644
--- a/kcms/keyboard/kcm_keyboard_widget.cpp
+++ b/kcms/keyboard/kcm_keyboard_widget.cpp
@@ -34,7 +34,9 @@
 #include <QDebug>
 
 #include "keyboard_config.h"
+#ifdef NEW_GEOMETRY
 #include "preview/keyboardpainter.h"
+#endif
 #include "xkb_rules.h"
 #include "flags.h"
 #include "x11_helper.h"
@@ -230,7 +232,7 @@ void KCMKeyboardWidget::addLayout()
 		return;
 	}
 
-    AddLayoutDialog dialog(rules, keyboardConfig->isFlagShown() ? flags : NULL, \
keyboardConfig->isLabelShown(), this); +    AddLayoutDialog dialog(rules, keyboardConfig->isFlagShown() ? \
flags : NULL, keyboardConfig->keyboardModel, keyboardConfig->isLabelShown(), this);  \
dialog.setModal(true);  if( dialog.exec() == QDialog::Accepted ) {
     	keyboardConfig->layouts.append( dialog.getSelectedLayoutUnit() );
@@ -337,8 +339,9 @@ void KCMKeyboardWidget::initializeLayoutsUI()
 	connect(uiWidget->moveUpBtn, SIGNAL(clicked(bool)), this, SLOT(moveUp()));
 	connect(uiWidget->moveDownBtn, SIGNAL(clicked(bool)), this, SLOT(moveDown()));
 
-    connect(uiWidget->previewButton,SIGNAL(clicked(bool)),this,SLOT(previewLayout()));
-
+#ifdef NEW_GEOMETRY
+    connect(uiWidget->previewButton, SIGNAL(clicked(bool)), this, SLOT(previewLayout()));
+#endif
 	connect(uiWidget->xkbGrpClearBtn, SIGNAL(clicked(bool)), this, SLOT(clearGroupShortcuts()));
 	connect(uiWidget->xkb3rdLevelClearBtn, SIGNAL(clicked(bool)), this, SLOT(clear3rdLevelShortcuts()));
 
@@ -363,31 +366,33 @@ void KCMKeyboardWidget::initializeLayoutsUI()
 	connect(uiWidget->layoutLoopCountSpinBox, SIGNAL(valueChanged(int)), this, SLOT(uiChanged()));
 }
 
+#ifdef NEW_GEOMETRY
 void KCMKeyboardWidget::previewLayout(){
-    QMessageBox q;
-    QModelIndex index = uiWidget->layoutsTableView->currentIndex() ;
+    QModelIndex index = uiWidget->layoutsTableView->currentIndex();
+
     QModelIndex idcountry = index.sibling(index.row(),0) ;
     QString country=uiWidget->layoutsTableView->model()->data(idcountry).toString();
     QModelIndex idvariant = index.sibling(index.row(),2) ;
     QString variant=uiWidget->layoutsTableView->model()->data(idvariant).toString();
-    if(index.row()==-1 || index.column()==-1){
-        q.setText(i18n("No layout selected "));
-        q.exec();
-    }
-    else{
-        KeyboardPainter* layoutPreview = new KeyboardPainter();
-        const LayoutInfo* layoutInfo = rules->getLayoutInfo(country);
-        foreach(const VariantInfo* variantInfo, layoutInfo->variantInfos) {
-            if(variant==variantInfo->description){
-                variant=variantInfo->name;
-                break;
-            }
+    QString model = keyboardConfig->keyboardModel;
+
+    KeyboardPainter* layoutPreview = new KeyboardPainter();
+    const LayoutInfo* layoutInfo = rules->getLayoutInfo(country);
+    foreach(const VariantInfo* variantInfo, layoutInfo->variantInfos) {
+        if(variant==variantInfo->description){
+            variant=variantInfo->name;
+            break;
         }
-        layoutPreview->generateKeyboardLayout(country,variant);
-        layoutPreview->exec();
-        layoutPreview->setModal(true);
     }
+
+    QString title = Flags::getLongText( LayoutUnit(country, variant), rules );
+    layoutPreview->generateKeyboardLayout(country, variant, model, title);
+    layoutPreview->exec();
+    layoutPreview->setModal(true);
+    delete layoutPreview;
 }
+#endif
+
 
 void KCMKeyboardWidget::configureLayoutsChanged()
 {
@@ -417,8 +422,12 @@ void KCMKeyboardWidget::layoutSelectionChanged()
 	uiWidget->removeLayoutBtn->setEnabled( ! selected.isEmpty() );
 	QPair<int, int> rowsRange( getSelectedRowRange(selected) );
 	uiWidget->moveUpBtn->setEnabled( ! selected.isEmpty() && rowsRange.first > 0);
-    uiWidget->previewButton->setEnabled(! selected.isEmpty());
-	uiWidget->moveDownBtn->setEnabled( ! selected.isEmpty() && rowsRange.second < \
keyboardConfig->layouts.size()-1 ); +#ifdef NEW_GEOMETRY
+    uiWidget->previewButton->setEnabled( \
uiWidget->layoutsTableView->selectionModel()->selectedRows().size() == 1 ); +#else
+    uiWidget->previewButton->setVisible(false);
+#endif
+    uiWidget->moveDownBtn->setEnabled( ! selected.isEmpty() && rowsRange.second < \
keyboardConfig->layouts.size()-1 );  }
 
 void KCMKeyboardWidget::removeLayout()
diff --git a/kcms/keyboard/preview/TODO b/kcms/keyboard/preview/TODO
old mode 100644
new mode 100755
index 784924f..6920404
--- a/kcms/keyboard/preview/TODO
+++ b/kcms/keyboard/preview/TODO
@@ -1,9 +1,6 @@
 Important:
-* display tooltip for each key with key description from symbol file
 
 Good to have:
-* read keyboard geometry and show it properly instead of default keyboard
-* use some common parser to parse symbol and geometry descriptions
 * replace symkey2ucs with something more reliable (e.g. XLookupString?)
 
 Cleanup:
diff --git a/kcms/keyboard/preview/geometry_components.cpp \
b/kcms/keyboard/preview/geometry_components.cpp new file mode 100755
index 0000000..8bc9262
--- /dev/null
+++ b/kcms/keyboard/preview/geometry_components.cpp
@@ -0,0 +1,232 @@
+/*
+ *  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];
+    else
+        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;
+            }
+            else
+                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(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(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 100755
index 0000000..428603b
--- /dev/null
+++ b/kcms/keyboard/preview/geometry_components.h
@@ -0,0 +1,303 @@
+/*
+ *  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(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(QString n){
+      name = n;
+  }
+
+  void setShapeName(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(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(QString n){
+      name = n;
+  }
+
+  void setShapeName(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(QString n){
+      name = n;
+  }
+
+  void setDescription(QString d){
+      description = d;
+  }
+
+  void setKeyShape(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(QString n);
+  void setShapeCord(double a, double b);
+  void setShapeApprox(double a, double b);
+  void addShape();
+  void display();
+  void addSection();
+  GShape findShape(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 100755
index 0000000..7d5c6c0
--- /dev/null
+++ b/kcms/keyboard/preview/geometry_parser.cpp
@@ -0,0 +1,506 @@
+ /*
+ *  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 "x11_helper.h"
+#include "model_to_geometry.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(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;
+        ModelToGeometryTable m2g = ModelToGeometryTable();
+
+        m2g.createTable();
+        QString geometryFile = m2g.getGeometryFile(model);
+        QString geometryName = m2g.getGeometryName(model);
+        //qDebug()<< geometryFile << geometryName;
+
+        QString xkbParentDir = findGeometryBaseDir();
+        geometryFile.prepend(xkbParentDir);
+        QFile gfile(geometryFile);
+         if (!gfile.open(QIODevice::ReadOnly | QIODevice::Text)){
+             qDebug()<<"unable to open the file";
+             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");
+            //qDebug()<<input;
+            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";
+                geomertyParser.geom.setParsing(true);
+            }
+            else{
+                qDebug() << "Geometry Parsing failed\n";
+                qDebug()<<input;
+                geomertyParser.geom.setParsing(false);
+
+            }
+
+            current++;
+
+        }
+        //g.geom.display();
+        if(geomertyParser.geom.getParsing())
+            return geomertyParser.geom;
+        else
+            return parseGeometry("pc104");
+    }
+
+    QString findGeometryBaseDir()
+    {
+        QString xkbDir = X11Helper::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 100755
index 0000000..db09758
--- /dev/null
+++ b/kcms/keyboard/preview/geometry_parser.h
@@ -0,0 +1,157 @@
+/*
+ *  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(QString model);
+  QString findGeometryBaseDir();
+}
+
+#endif //geometry_parser
diff --git a/kcms/keyboard/preview/kbpreviewframe.cpp b/kcms/keyboard/preview/kbpreviewframe.cpp
old mode 100644
new mode 100755
index 3368355..409cc2e
--- a/kcms/keyboard/preview/kbpreviewframe.cpp
+++ b/kcms/keyboard/preview/kbpreviewframe.cpp
@@ -19,348 +19,355 @@
 
 #include "kbpreviewframe.h"
 
+#include "geometry_parser.h"
+#include "geometry_components.h"
+#include "keyboardlayout.h"
+#include "symbol_parser.h"
+#include "model_to_geometry.h"
+
 #include <QFile>
 #include <QFont>
+#include <QFileDialog>
+#include <QHelpEvent>
+#include <math.h>
+#include <QMessageBox>
+#include <QRect>
+#include <QDesktopWidget>
 
-#include <KLocalizedString>
+#include <KApplication>
+#include <KLocale>
 
 
-static const QColor keyBorderColor("#d4d4d4");
-static const QColor lev12color("#d4d4d4");
-static const QColor lev34color("#FF3300");
-static const int sz=20, kszx=70, kszy=70;
 
-static const int xOffset[] = {15, 15, 40, 40 };
-static const int yOffset[] = {10, 40, 10, 40 };
+static const QColor keyBorderColor("#d4d4d4");
+static const QColor lev12color(Qt::black);
+static const QColor lev34color("#0033FF");
+static const QColor unknownSymbolColor("#FF3300");
+static const int xOffset[] = {10, 10, -15, -15 };
+static const int yOffset[] = {5, -20, 5, -20 };
 static const QColor color[] = { lev12color, lev12color, lev34color, lev34color };
+static const int keyLevel[3][4] = { { 1, 0, 3, 2}, { 1, 0, 5, 4}, { 1, 0, 7, 6} };
+static const QRegExp fkKey("^FK\\d+$");
 
 
-// TODO: parse geometry files and display keyboard according to current keyboard model
-
 KbPreviewFrame::KbPreviewFrame(QWidget *parent) :
-    QFrame(parent)
+    QFrame(parent),
+    geometry(*new Geometry())
 {
      setFrameStyle( QFrame::Box );
      setFrameShadow(QFrame::Sunken);
+     setMouseTracking(true);
+     scaleFactor = 1;
+     l_id = 0;
 }
 
-void KbPreviewFrame::paintTLDE(QPainter &painter,int &x,int &y)
-{
-    painter.setPen(keyBorderColor);
-    painter.drawRect(x, y, kszx, kszy);
+KbPreviewFrame::~KbPreviewFrame() {
+    delete &geometry;
+}
 
-    const QList <QString> symbols = keyboardLayout.TLDE.symbols;
 
-    for(int level=0; level<symbols.size(); level++) {
-    	painter.setPen(color[level]);
-    	painter.drawText(x+xOffset[level], y+yOffset[level], sz, sz, Qt::AlignTop, \
                symbol.getKeySymbol(symbols.at(level)));
-    }
+int KbPreviewFrame::getWidth() const { return geometry.width; }
+int KbPreviewFrame::getHeight() const { return geometry.height; }
 
-}
 
-void KbPreviewFrame::paintAERow(QPainter &painter,int &x,int &y)
+//writes text on the keys call only by paintevent
+void KbPreviewFrame::drawKeySymbols(QPainter &painter, QPoint temp[], const GShape& s, const QString& \
name)  {
-    paintTLDE(painter, x, y);
-
-    const int noAEk=12;
-    for(int i=0; i<noAEk; i++){
-        x+=kszx;
+    int keyindex = keyboardLayout.findKey(name);
+    int szx = scaleFactor*s.size(0)/2 < 20 ? scaleFactor*s.size(0)/3 : 20;
+    int szy = scaleFactor*s.size(1)/2 < 20 ? scaleFactor*s.size(1)/3 : 20;
+    QFont kbfont;
+    if(szx > szy)
+        kbfont.setPointSize(szy/2 < 9 ? szy : 9);
+    else
+        kbfont.setPointSize(szx/2 < 9 ? szx/2 : 9);
 
-        painter.setPen(keyBorderColor);
-        painter.drawRect(x, y, kszx, kszy);
+    painter.setFont(kbfont);
 
-        QList<QString> symbols = keyboardLayout.AE[i].symbols;
+    int cordinate[] = {0, 3, 1, 2};
+    float tooltipX = 0, toolTipY = 0;
+    QString tip;
+    if(keyindex != -1){
+        KbKey key = keyboardLayout.keyList.at(keyindex);
 
-        for(int level=0; level<symbols.size(); level++) {
-        	painter.setPen(color[level]);
-        	painter.drawText(x+xOffset[level], y+yOffset[level], sz, sz, Qt::AlignTop, \
                symbol.getKeySymbol(symbols.at(level)));
-        }
-    }
+        for(int level=0; level< (key.getSymbolCount() < 4 ? key.getSymbolCount() : 4); level++) {
 
-    x += kszx;
+            if(keyLevel[l_id][level] < key.getSymbolCount()){
 
-    const int bkspszx=100,bk1x=10;//,bk1y=20,
-    const int bk2y=60;
+                QString txt = symbol.getKeySymbol(key.getSymbol(keyLevel[l_id][level]));
 
-    painter.setPen(keyBorderColor);
-    painter.drawRect(x, y,bkspszx,kszy);
+                QColor txtColor = txt[0] == -1 ? unknownSymbolColor : color[level];
 
-    painter.setPen(lev12color);
-//    painter.drawText(x+bk1x, y+bk1y,i18n("<--"));
-    painter.drawText(x+bk1x, y+bk2y,i18n("Backspace"));
-}
+                painter.setPen(txtColor);
 
-void KbPreviewFrame::paintADRow(QPainter &painter,int &x,int&y)
-{
-    const int noADk=12;
-    const int tabszx=100;
-    const int tab3y=45;
+                painter.drawText(temp[cordinate[level]].x()+xOffset[level]*scaleFactor/2.5, \
temp[cordinate[level]].y()+yOffset[level]*scaleFactor/2.5, szx, szy, Qt::AlignTop, txt);  
-    painter.setPen(keyBorderColor);
-    painter.drawRect(x, y, tabszx,kszy);
+                QString currentSymbol = key.getSymbol(keyLevel[l_id][level]);
+                currentSymbol = currentSymbol.size() < 3 ? currentSymbol.append("\t") : currentSymbol;
 
-    painter.setPen(lev12color);
-//    painter.drawText(x+tab1x, y+tab1y,i18n("<--"));
-    painter.drawText(x+xOffset[0], y+tab3y, i18nc("Tab key", "Tab"));
-//    painter.drawText(x+tab2x, y+tab2y,i18n("-->"));
-    x+=tabszx;
+                if(level == 0)
+                    tip.append(currentSymbol);
+                else
+                    tip.append("\n" + currentSymbol);
+            }
+        }
 
+        for(int i = 0 ; i < 4; i++){
+            tooltipX += temp[i].x();
+            toolTipY += temp[i].y();
+        }
 
-    for(int i=0; i<noADk; i++){
-        QList<QString> symbols = keyboardLayout.AD[i].symbols;
+        tooltipX = tooltipX/4;
+        toolTipY = toolTipY/4;
+        QPoint tooltipPoint = QPoint(tooltipX, toolTipY);
 
-        painter.setPen(keyBorderColor);
-        painter.drawRect(x, y,kszx,kszy);
+        tooltip.append(tip);
+        tipPoint.append(tooltipPoint);
+    }
+    else{
+        painter.setPen(Qt::black);
 
-        for(int level=0; level<symbols.size(); level++) {
-        	painter.setPen(color[level]);
-        	painter.drawText(x+xOffset[level], y+yOffset[level], sz, sz, Qt::AlignTop, \
symbol.getKeySymbol(symbols.at(level))); +        if( name.contains(fkKey) ){
+            QString tempName = name;
+            tempName.remove("K");
+            painter.drawText(temp[0].x()+s.size(0)-10, temp[0].y()+3*scaleFactor*s.size(1)/5, tempName);
         }
+        else{
+            painter.setFont(kbfont);
+            painter.drawText(temp[0].x()+s.size(0)-10, temp[0].y()+3*scaleFactor*s.size(1)/5, name);
+        }
+        tip = name;
 
-        x+=kszx;
-    }
-
-    painter.setPen(keyBorderColor);
-    painter.drawRect(x, y,kszx,kszy);
+        for(int i = 0 ; i < 4; i++){
+            tooltipX += temp[i].x();
+            toolTipY += temp[i].y();
+        }
 
-    QList<QString> symbols = keyboardLayout.BKSL.symbols;
+        tooltipX = tooltipX/4;
+        toolTipY = toolTipY/4;
+        QPoint tooltipPoint = QPoint(tooltipX, toolTipY);
 
-    for(int level=0; level<symbols.size(); level++) {
-    	painter.setPen(color[level]);
-    	painter.drawText(x+xOffset[level], y+yOffset[level], sz, sz, Qt::AlignTop, \
symbol.getKeySymbol(symbols.at(level))); +        tooltip.append(tip);
+        tipPoint.append(tooltipPoint);
     }
 }
 
-void KbPreviewFrame::paintACRow(QPainter &painter,int &x,int &y)
-{
-    const int sz = 20, kszx = 70, kszy = 70, capszx = 100;
-    const int noACk = 11;
-    const int lvl2x = 40, shifx = 10, shify = 60, retsz = 140;
 
-    painter.setPen(keyBorderColor);
-    painter.drawRect(x, y,capszx,kszy);
+//draws key shape on QFrame called only by paint event
+void KbPreviewFrame::drawShape(QPainter &painter, const GShape& s, int x, int y, int i, const QString& \
name){ +    painter.setPen(Qt::black);
+    int cordi_count = s.getCordi_count();
 
-    painter.setPen(lev12color);
-//    painter.drawText(x+shifx, y+sz,i18n("^"));
-    painter.drawText(x+shifx, y+shify,i18n("Caps Lock"));
-    x+=capszx;
+    if(geometry.sectionList[i].getAngle()==0){
+        if (cordi_count == 1){
+            int width = s.getCordii(0).x();
+            int height = s.getCordii(0).y();
 
-    for(int i=0; i<noACk; i++){
-        painter.setPen(keyBorderColor);
-        painter.drawRect(x, y,kszx,kszy);
+            painter.drawRoundedRect(scaleFactor*x+2, scaleFactor*y, scaleFactor*width, \
scaleFactor*height, 4, 4);  
-        QList<QString> symbols = keyboardLayout.AC[i].symbols;
+            QPoint temp[4];
 
-        for(int level=0; level<symbols.size(); level++) {
-        	painter.setPen(color[level]);
-        	painter.drawText(x+xOffset[level], y+yOffset[level], sz, sz, Qt::AlignTop, \
                symbol.getKeySymbol(symbols.at(level)));
-        }
+            temp[0]=QPoint(scaleFactor*x, scaleFactor*y);
+            temp[1]=QPoint(scaleFactor*(s.getCordii(0).x()+x), scaleFactor*y);
+            temp[2]=QPoint(scaleFactor*(s.getCordii(0).x()+x), scaleFactor*(s.getCordii(0).y()+y));
+            temp[3]=QPoint(scaleFactor*(x), scaleFactor*(s.getCordii(0).y()+y));
 
-        x+=kszx;
-    }
-
-    painter.setPen(keyBorderColor);
-    painter.drawRect(x, y,retsz,kszy);
-
-    painter.setPen(lev12color);
-//    painter.drawText(x+ret1x, y+ret1y,i18n("|"));
-//    painter.drawText(x+ret2x, y+ret2y,i18n("<--"));
-    painter.drawText(x+shify,y+lvl2x,i18n("Enter"));
-}
-
-void KbPreviewFrame::paintABRow(QPainter &painter,int &x,int &y)
-{
-    const int noABk=10;
-    for(int i=0; i<noABk; i++) {
-        painter.setPen(keyBorderColor);
-        painter.drawRect(x, y,kszx,kszy);
+            drawKeySymbols(painter, temp, s, name);
+        }
+        else{
+            QPoint temp[cordi_count];
 
-        QList<QString> symbols = keyboardLayout.AB[i].symbols;
+            for(int i=0;i<cordi_count;i++){
+                temp[i].setX(scaleFactor*(s.getCordii(i).x()+x+1));
+                temp[i].setY(scaleFactor*(s.getCordii(i).y()+y+1));
+            }
 
-        for(int level=0; level<symbols.size(); level++) {
-        	painter.setPen(color[level]);
-        	painter.drawText(x+xOffset[level], y+yOffset[level], sz, sz, Qt::AlignTop, \
symbol.getKeySymbol(symbols.at(level))); +            painter.drawPolygon(temp, cordi_count);
+            drawKeySymbols(painter, temp, s, name);
         }
-
-        x+=kszx;
     }
-}
-
-void KbPreviewFrame::paintBottomRow(QPainter &painter,int &x,int &y)
-{
-    const int txtx=30, txty=35, ctrlsz=100, altsz=100, spsz=400, kszy=70;
-
-    painter.setPen(keyBorderColor);
-    painter.drawRect(x, y, ctrlsz, kszy);
-    painter.setPen(lev12color);
-    painter.drawText(x+txtx, y+txty,i18n("Ctrl"));
-
-    x+=ctrlsz;
+    else{
+        QPoint temp[cordi_count == 1 ? 4 : cordi_count];
+        int size;
+
+        if(cordi_count== 1){
+            temp[0]=QPoint(x, y);
+            temp[1]=QPoint(s.getCordii(0).x()+x, y);
+            temp[2]=QPoint(s.getCordii(0).x()+x, s.getCordii(0).y()+y);
+            temp[3]=QPoint(x, s.getCordii(0).y()+y);
+            size = 4;
+        }
+        else{
+            size = cordi_count;
 
-    painter.setPen(keyBorderColor);
-    painter.drawRect(x, y, altsz, kszy);
-    painter.setPen(lev12color);
-    painter.drawText(x+txtx, y+txty,i18n("Alt"));
+            for(int i=0;i<cordi_count;i++){
+                temp[i].setX((s.getCordii(i).x()+x+1));
+                temp[i].setY((s.getCordii(i).y()+y+1));
+            }
+        }
 
-    x+=altsz;
+        double refX, refY;
 
-    painter.setPen(keyBorderColor);
-    painter.drawRect(x, y, spsz, kszy);
+        refX = geometry.sectionList[i].getLeft();
+        refY = geometry.sectionList[i].getTop();
 
-    x+=spsz;
+        //qDebug()<<"\ntransform";
+        for(int j=0; j<size; j++){
+            double x = temp[j].x()-refX;
+            double y = temp[j].y()-refY;
 
-    painter.drawRect(x, y, altsz, kszy);
+            //qDebug()<<"("<<x<<","<<y<<")->";
 
-    painter.setPen(lev34color);
-    painter.drawText(x+txtx, y+txty,i18n("AltGr"));
+            float theta = ( 3.1459 * geometry.sectionList[i].getAngle() )/180;
+            double x_ = x*cos(theta) - y*sin(theta);
 
-    x+=ctrlsz;
+            //qDebug()<<"x_= "<<x<<"*"<<cos(theta)<<"-"<<y<<"*"<<sin(theta);
 
-    painter.setPen(keyBorderColor);
-    painter.drawRect(x, y, ctrlsz, kszy);
+            double y_ = x*sin(theta) + y*cos(theta);
 
-    painter.setPen(lev12color);
-    painter.drawText(x+txtx, y+txty, i18n("Ctrl"));
-}
+            //qDebug()<<"\ny_= "<<x<<"*"<<sin(theta)<<"+"<<y<<"*"<<cos(theta);
+            //qDebug()<<"("<<x_<<","<<y_<<")\n";
 
-void KbPreviewFrame::paintFnKeys(QPainter &painter,int &x,int &y)
-{
-    const int escsz=50, escx=20, escy=55;
+            temp[j]=QPoint(scaleFactor*(x_+refX), scaleFactor*(y_+refY));
+        }
 
-    painter.setPen(keyBorderColor);
-    painter.drawRect(x, y, escsz, escsz);
+        /*for(int i=0;i<size;i++){
+            qDebug()<<temp[i];
+        }*/
 
-    painter.setPen(lev12color);
-    painter.drawText(escx, escy, i18n("Esc"));
+        painter.drawPolygon(temp, size);
+        drawKeySymbols(painter, temp, s, name);
+    }
 
-    const int spacex=50;
-    x+=spacex;
+}
 
-    const int fnkeyspace=60, fnkeysizex=50, fnkeysizey=50, fkc=15, fky=30, fnkig=4, fng=3;
-    int f=1;
 
-    for(int i=0;i<fng;i++){
-        x+=spacex;
+//event handling for tooltip
+bool KbPreviewFrame::event(QEvent* event){
 
-        for(int j=0;j<fnkig;j++){
-            x += fnkeyspace;
-            painter.setPen(keyBorderColor);
-            painter.drawRect(x, y, fnkeysizex, fnkeysizey);
+    if (event->type() == QEvent::ToolTip) {
+        QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);
+        int index = itemAt(helpEvent->pos());
 
-            painter.setPen(lev12color);
-            painter.drawText(x+fkc, y+fky, i18nc("Function key", "F%1", f));
-            f++;
+        if (index != -1) {
+            QToolTip::showText(helpEvent->globalPos(), tooltip.at(index));
         }
+        else {
+             QToolTip::hideText();
+             event->ignore();
+        }
+
+        return true;
     }
+    return QWidget::event(event);
 }
 
+
 void KbPreviewFrame::paintEvent(QPaintEvent *)
 {
-    QPainter painter(this);
+    if( geometry.getParsing() && keyboardLayout.getParsedSymbol() ){
+        QPainter painter(this);
 
-    QFont kbfont;
-    kbfont.setPointSize(12);
+        QFont kbfont;
+        kbfont.setPointSize(9);
 
-    painter.setFont(kbfont);
-    painter.setBrush(QBrush(Qt::darkGray));
+        painter.setFont(kbfont);
+        painter.setBrush(QBrush("#C3C8CB"));
+        painter.setRenderHint(QPainter::Antialiasing);
 
-    const int strtx=0,strty=0,endx=1390,endy=490,kszy=70;
-    const int row1x=10,row1y=30,row2x=10,row2y=90,row5x=10,row5y=330,row3x=10,row3y=170,shifx=10,shify=60,row4x=10,row4y=250,row6x=110,row6y=410;
                
-    const int shiftsz=155;
+        const int strtx=0, strty=0, endx=geometry.getWidth(), endy=geometry.getHeight();
 
-    painter.setPen(keyBorderColor);
-    painter.drawRect(strtx, strty, endx, endy);
 
-    painter.setPen(lev12color);
-    painter.setBrush(QBrush(Qt::black));
+        painter.setPen("#EDEEF2");
 
-    int x, y;
-    x=row1x;
-    y=row1y;
+        painter.drawRect(strtx, strty, scaleFactor*endx+60, scaleFactor*endy+60);
 
-    paintFnKeys(painter,x, y);
+        painter.setPen(Qt::black);
+        painter.setBrush(QBrush("#EDEEF2"));
 
-    x=row2x;
-    y=row2y;
+        for(int i=0;i<geometry.getSectionCount();i++){
 
-    paintAERow(painter,x, y);
+            painter.setPen(Qt::black);
 
-    x=row3x;
-    y=row3y;
+            for(int j=0;j<geometry.sectionList[i].getRowCount();j++){
 
-    paintADRow(painter,x, y);
+                int keyn = geometry.sectionList[i].rowList[j].getKeyCount();
 
-    x=row4x;
-    y=row4y;
+                for(int k=0;k<keyn;k++){
 
-    paintACRow(painter,x, y);
+                    Key temp = geometry.sectionList[i].rowList[j].keyList[k];
 
-    x=row5x;
-    y=row5y;
+                    int x = temp.getPosition().x();
+                    int y = temp.getPosition().y();
 
-    painter.setPen(keyBorderColor);
-    painter.drawRect(x, y,shiftsz,kszy);
-    painter.setPen(lev12color);
-    painter.drawText(x+shifx, y+shify,i18n("Shift"));
-    x+=shiftsz;
+                    GShape s;
 
-    paintABRow(painter,x, y);
+                    s = geometry.findShape(temp.getShapeName());
+                    QString name = temp.getName();
 
-    painter.setPen(keyBorderColor);
-    painter.drawRect(x, y,shiftsz,kszy);
-    painter.setPen(lev12color);
-    painter.drawText(x+shifx, y+shify,i18n("Shift"));
+                    drawShape(painter,s,x,y,i,name);
 
-    x=row6x;
-    y=row6y;
-
-    paintBottomRow(painter,x, y);
+                }
+            }
+        }
 
-    if( symbol.isFailed() ) {
-        painter.setPen(keyBorderColor);
-        painter.drawRect(strtx, strty, endx, endy);
+        if( symbol.isFailed() ) {
+            painter.setPen(keyBorderColor);
+            painter.drawRect(strtx, strty, endx, endy);
 
-        const int midx=470, midy=240;
-        painter.setPen(lev12color);
-        painter.drawText(midx, midy, i18n("No preview found"));
+            const int midx=470, midy=240;
+            painter.setPen(lev12color);
+            painter.drawText(midx, midy, i18n("No preview found"));
+        }
+    }
+    else{
+        QMessageBox errorBox;
+        errorBox.setText("Unable to open Preview !");
+        errorBox.exec();
     }
 
 }
 
-
-void KbPreviewFrame::generateKeyboardLayout(const QString& layout, const QString& layoutVariant)
+// this function draws the keyboard preview on a QFrame
+void KbPreviewFrame::generateKeyboardLayout(const QString& layout, const QString& layoutVariant, const \
QString& model)  {
-    QString filename = keyboardLayout.findSymbolBaseDir();
-    filename.append(layout);
+    geometry = grammar::parseGeometry(model);
+    int endx = geometry.getWidth(), endy = geometry.getHeight();
+
+    QDesktopWidget* desktopWidget = qApp->desktop();
+    QRect screenGeometry = desktopWidget->screenGeometry();
+    int screenWidth = screenGeometry.width();
+    //int screenHeight = screenGeometry.height();
+    //int screenWidth = QApplication::desktop()->screenGeometry().width();
+
+    scaleFactor = 2.5;
+    qDebug()<<scaleFactor;
+    while (scaleFactor*endx + screenWidth/20 > screenWidth)
+        scaleFactor -= 0.2;
+    qDebug()<<scaleFactor;
+
+    setFixedSize(scaleFactor*endx+60, scaleFactor*endy+60);
+    qDebug()<<screenWidth<<":"<<scaleFactor<<scaleFactor*endx+60<<scaleFactor*endy+60;
+    keyboardLayout = grammar::parseSymbols(layout, layoutVariant);
+}
 
-    QFile file(filename);
-    file.open(QIODevice::ReadOnly | QIODevice::Text);
-    QString content = file.readAll();
-    file.close();
 
-    QList<QString> symstr = content.split("xkb_symbols ");
+//this functions give the index of the tooltip over which mouse hovers
+int KbPreviewFrame::itemAt(const QPoint& pos){
+    int distance =  10000;
+    int closest = 0;
+    for(int i = 0; i < tipPoint.size(); i++){
 
-    if( layoutVariant.isEmpty() ) {
-        keyboardLayout.generateLayout(symstr.at(1), layout);
-    }
-    else {
-        for(int i=1;i<symstr.size();i++) {
-            QString h=symstr.at(i);
-            int k=h.indexOf("\"");
-            h=h.mid(k);
-            k=h.indexOf("{");
-            h=h.left(k);
-            h=h.remove(" ");
-            QString f="\"";
-            f.append(layoutVariant);
-            f.append("\"");
-            f=f.remove(" ");
-
-            if(h==f){
-                keyboardLayout.generateLayout(symstr.at(i), layout);
-                break;
-            }
+        int temp = sqrt((pos.x()-tipPoint.at(i).x())*(pos.x()-tipPoint.at(i).x()) + \
(pos.y()-tipPoint.at(i).y())*(pos.y()-tipPoint.at(i).y())); +
+        if(distance > temp){
+            distance = temp;
+            closest = i;
         }
     }
-}
 
+    if(distance < 25)
+        return closest;
+    else
+        return -1;
+}
diff --git a/kcms/keyboard/preview/kbpreviewframe.h b/kcms/keyboard/preview/kbpreviewframe.h
old mode 100644
new mode 100755
index ffbbfa0..48a72a8
--- a/kcms/keyboard/preview/kbpreviewframe.h
+++ b/kcms/keyboard/preview/kbpreviewframe.h
@@ -19,37 +19,68 @@
 #define KBPREVIEWFRAME_H
 
 #include "keyboardlayout.h"
+
 #include "keysymhelper.h"
 #include "keyaliases.h"
 
 #include <QPainter>
 #include <QFrame>
+#include <QHash>
+#include <QToolTip>
+
+class Geometry;
+class GShape;
+
 
 class KbPreviewFrame : public QFrame
 {
     Q_OBJECT
     
 private:
-	void paintTLDE(QPainter &painter, int &x, int &y);
-	void paintAERow(QPainter &painter, int &x, int &y);
-	void paintADRow(QPainter &painter, int &x, int &y);
-	void paintACRow(QPainter &painter, int &x, int &y);
-	void paintABRow(QPainter &painter, int &x, int &y);
-	void paintBottomRow(QPainter &painter, int &x, int &y);
-	void paintFnKeys(QPainter &painter, int &x, int &y);
-
-	KeySymHelper symbol;
-	Aliases alias;
-    KeyboardLayout keyboardLayout;
-	
+    static const int width = 1100, height = 490;
+
+    KeySymHelper symbol;
+    Aliases alias;
+    QStringList tooltip;
+    QList <QPoint> tipPoint;
+    int l_id;
+    Geometry& geometry;
+    float scaleFactor;
+    KbLayout keyboardLayout;
+
+    void drawKeySymbols(QPainter &painter, QPoint temp[], const GShape& s, const QString& name);
+    void drawShape(QPainter &painter, const GShape& s, int x, int y, int i, const QString& name);
+
+    int itemAt(const QPoint &pos);
+
+
+protected:
+    bool event(QEvent *event);
+
 public:
     explicit KbPreviewFrame(QWidget *parent = 0);
-
+    virtual ~KbPreviewFrame();
     void paintEvent(QPaintEvent * event);
-    void generateKeyboardLayout(const QString &country, const QString &layoutVariant);
+    void generateKeyboardLayout(const QString &country, const QString &layoutVariant, const QString& \
model); +    int getWidth() const;
+    int getHeight() const;
+
+    int getLevel(){
+        return keyboardLayout.getLevel();
+    }
+
+    void setL_id(int lId){
+        l_id = lId;
+        repaint();
+    }
+
     QString getLayoutName() const {
     	return keyboardLayout.getLayoutName();
     }
+
+    float getScaleFactor(){
+        return scaleFactor;
+    }
 };
 
 #endif // KBPREVIEWFRAME_H 
diff --git a/kcms/keyboard/preview/keyaliases.cpp b/kcms/keyboard/preview/keyaliases.cpp
old mode 100644
new mode 100755
index 71d6a00..74aa6bb
--- a/kcms/keyboard/preview/keyaliases.cpp
+++ b/kcms/keyboard/preview/keyaliases.cpp
@@ -17,6 +17,8 @@
  */
 
 #include "keyaliases.h"
+#include "x11_helper.h"
+
 #include <QString>
 #include <QMap>
 #include <QMessageBox>
@@ -40,10 +42,14 @@ Aliases::Aliases()
     file.open(QIODevice::ReadOnly | QIODevice::Text);
     QString content = file.readAll();
     file.close();
+
     QList<QString>als;
     als=content.split("xkb_keycodes");
-    for(int i=1;i<als.size();i++){
+
+    for(int i=1; i<als.size(); i++){
+
         QString temp=als.at(i);
+
         temp=temp.remove(" ");
         temp=temp.remove("\n");
         temp=temp.remove("\"");
@@ -52,32 +58,49 @@ Aliases::Aliases()
         temp=temp.remove(";");
         temp=temp.remove("}");
         temp=temp.remove("{");
+
         QList<QString>alskeys;
+
         alskeys=temp.split("alias");
+
         if(temp.startsWith("qwerty")){
+
             for(int k=1;k<alskeys.size();k++){
+
                 QString tmp=alskeys.at(k);
                 int inofeq=tmp.indexOf("=");
+
                 QString lat=tmp.left(inofeq);
                 QString key=tmp.mid(inofeq+1);
+
                 qwerty[lat]=key;
             }
         }
+
         if(temp.startsWith("azerty")){
+
             for(int k=1;k<alskeys.size();k++){
                 QString tmp=alskeys.at(k);
+
                 int inofeq=tmp.indexOf("=");
+
                 QString lat=tmp.left(inofeq);
                 QString key=tmp.mid(inofeq+1);
+
                 azerty[lat]=key;
             }
-      }
-       if(temp.startsWith("qwertz")){
+        }
+
+        if(temp.startsWith("qwertz")){
             for(int k=1;k<alskeys.size();k++){
-                 QString tmp=alskeys.at(k);
-                 int inofeq=tmp.indexOf("=");
-                 QString lat=tmp.left(inofeq);
+
+                QString tmp=alskeys.at(k);
+
+                int inofeq=tmp.indexOf("=");
+
+                QString lat=tmp.left(inofeq);
                  QString key=tmp.mid(inofeq+1);
+
                  qwertz[lat]=key;
             }
        }
@@ -85,43 +108,24 @@ Aliases::Aliases()
 
 }
 
+
 QString Aliases::getAlias(const QString& cname, const QString& name)
 {
     QMessageBox q;
-    QString a=name;
-    if(cname=="ma"){
-        a=azerty.value(name);
+    QString a = name;
+
+    if(cname=="ma" || cname == "be" || cname == "fr"){
+        a = azerty.value(name);
     }
     else{
-        a=qwerty.value(name);
+        a = qwerty.value(name);
     }
+
     return a;
 }
 
-QString Aliases::findaliasdir(){
-
-    QString aliasdir;
-    QString xkbParentDir;
-
-    QString base(XLIBDIR);
-    if( base.count('/') >= 3 ) {
-        // .../usr/lib/X11 -> /usr/share/X11/xkb vs .../usr/X11/lib -> /usr/X11/share/X11/xkb
-        QString delta = base.endsWith("X11") ? "/../../share/X11" : "/../share/X11";
-        QDir baseDir(base + delta);
-        if( baseDir.exists() ) {
-            xkbParentDir = baseDir.absolutePath();
-        }
-        else {
-            QDir baseDir(base + "/X11");	// .../usr/X11/lib/X11/xkb (old XFree)
-            if( baseDir.exists() ) {
-                xkbParentDir = baseDir.absolutePath();
-            }
-        }
-    }
-
-    if( xkbParentDir.isEmpty() ) {
-        xkbParentDir = "/usr/share/X11";
-    }
-    aliasdir=QString("%1/xkb/keycodes/aliases").arg(xkbParentDir);
-    return(aliasdir);
+QString Aliases::findaliasdir()
+{
+    QString xkbDir = X11Helper::findXkbDir();
+    return QString("%1/keycodes/aliases").arg(xkbDir);
 }
diff --git a/kcms/keyboard/preview/keyaliases.h b/kcms/keyboard/preview/keyaliases.h
old mode 100644
new mode 100755
index 3769e4e..699917a
--- a/kcms/keyboard/preview/keyaliases.h
+++ b/kcms/keyboard/preview/keyaliases.h
@@ -18,15 +18,16 @@
 #ifndef ALIASES_H
 #define ALIASES_H
 
-#include <QtCore/QMap>
+#include <QMap>
 
 class Aliases
 {
 private:
-	QMap<QString,QString>qwerty;
+    QMap<QString,QString>qwerty;
     QMap<QString,QString>azerty;
     QMap<QString,QString>qwertz;
-	QString findaliasdir();
+    QString findaliasdir();
+
 public:
     Aliases();
     QString getAlias(const QString &type, const QString &name);
diff --git a/kcms/keyboard/preview/keyboardlayout.cpp b/kcms/keyboard/preview/keyboardlayout.cpp
old mode 100644
new mode 100755
index 9be0483..30bf118
--- a/kcms/keyboard/preview/keyboardlayout.cpp
+++ b/kcms/keyboard/preview/keyboardlayout.cpp
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com)
+ *  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
@@ -18,169 +18,101 @@
 
 
 #include "keyboardlayout.h"
-#include "keysymbols.h"
 
-#include <QMessageBox>
+#include <QDebug>
+#include <QString>
 #include <QList>
-#include <QFile>
-#include <QDir>
 
-#include <QX11Info>
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#include <X11/XKBlib.h>
-#include <X11/extensions/XKBrules.h>
-#include <fixx11h.h>
-#include <config-workspace.h>
 
-
-//TODO: replace this with grammar parser (e.g. antlr)
+KbKey::KbKey(){
+    symbolCount = 0;
+    symbols << QString();
+}
 
 
-KeyboardLayout::KeyboardLayout()
-{
+void KbKey::setKeyName(QString n){
+        keyName = n;
 }
 
-void KeyboardLayout::generateLayout(QString a,const QString& cname)
-{
-    includeSymbol(a,cname);
-    int i=a.indexOf("name[Group1]=");
-    i+=13;
-
-    QString n=a.mid(i);
-    n=n.simplified();
-    i=n.indexOf("\"",1);
-    layoutName=n.left(i);
-    layoutName.remove("\"");
-    layoutName.simplified();
-    i=n.indexOf("key");
-    n=n.mid(i);
-
-    QList<QString> st;
-    st=n.split("key");
-
-    KeySymbols dum;
-    QString r,y;
-
-    for(int k=0;k<st.size();k++){
-        dum.setKey(st.at(k));
-        if(dum.keyname.startsWith("Lat"))
-            dum.keyname=alias.getAlias(cname,dum.keyname);
-        if(dum.keyname=="TLDE"){
-            r=st.at(k);
-            TLDE.setKey(r);
-        }
-        if(dum.keyname=="BKSL"){
-            r=st.at(k);
-            BKSL.setKey(r);
-        }
-        if(dum.keyname.contains("AE")){
-            QString ind=dum.keyname.right(2);
-            int index=ind.toInt();
-            r=st.at(k);
-            AE[index-1].setKey(r);
-        }
-        if(dum.keyname.contains("AD")){
-            QString ind=dum.keyname.right(2);
-            int index=ind.toInt();
-            r=st.at(k);
-            AD[index-1].setKey(r);
-        }
-        if(dum.keyname.contains("AC")){
-            QString ind=dum.keyname.right(2);
-            int index=ind.toInt();
-            r=st.at(k);
-            AC[index-1].setKey(r);
-        }
-        if(dum.keyname.contains("AB")){
-            QString ind=dum.keyname.right(2);
-            int index=ind.toInt();
-            r=st.at(k);
-            AB[index-1].setKey(r);
-        }
+
+void KbKey::addSymbol(QString n, int i){
+    if( !symbols.contains(n)){
+        symbols[i] = n;
+        symbolCount++;
+        symbols << QString();
     }
 }
 
-void KeyboardLayout::includeSymbol(QString a,const QString& cname)
-{
-    int k=a.indexOf("include");
-    a=a.mid(k);
-
-    QList<QString>tobeinclude;
-    tobeinclude=a.split("include");
-
-    QString r;
-    for(int o=1;o<tobeinclude.size();o++){
-        QString d=tobeinclude.at(o);
-        d.simplified();
-        int k=d.indexOf("\"",2);
-
-        QString incsym=d.left(k);
-        incsym.remove(" ");
-        incsym.remove("\"");
-
-        QList<QString> incfile;
-        incfile=incsym.split("(");
-        for(int i=0;i<incfile.size();i++){
-                QString z=incfile.at(i);
-                z.remove(" ");
-            incfile[i]=z;
-        }
-        if(incfile.size()==1)
-            incfile<<"basic";
-        else{
-            QString ns=incfile.at(1);
-            ns.remove(")");
-            incfile[1]=ns;
-        }
-        r=incfile.at(0);
-        r.append(incfile.at(1));
-
-        QString filename=findSymbolBaseDir();
-        filename.append(incfile.at(0));
-
-        QFile file(filename);
-        file.open(QIODevice::ReadOnly | QIODevice::Text);
-
-        QString content = file.readAll();
-        QList<QString> symstrlist;
-
-        symstrlist=content.split("xkb_symbols ");
-        for(int u=1;u<symstrlist.size();u++){
-            QString cur=symstrlist.at(u);
-            int pos = cur.indexOf("{");
-            cur=cur.left(pos);
-            if(cur.contains(incfile.at(1))){
-                generateLayout(symstrlist.at(u),cname);
-                break;
-            }
-        }
+
+QString KbKey::getSymbol(int i){
+    if(i < symbolCount)
+        return symbols[i];
+    else
+        return QString();
+}
+
+
+void KbKey::display(){
+    qDebug()<<keyName<<" : ";
+    for(int i=0; i<symbolCount; i++)
+        qDebug()<<"\t"<<symbols[i];
+}
+
+
+KbLayout::KbLayout(){
+    keyCount = 0;
+    includeCount = 0;
+    level = 4;
+    keyList << KbKey();
+    include << QString();
+    parsedSymbol = true;
+}
+
+
+void KbLayout::setName(QString n){
+    name = n;
+}
+
+
+void KbLayout::addInclude(QString n){
+    if(!include.contains(n)){
+        include[includeCount] = n;
+        includeCount++;
+        include << QString();
     }
 }
 
-QString KeyboardLayout::findSymbolBaseDir()
-{
-    QString xkbParentDir;
-
-    QString base(XLIBDIR);
-    if( base.count('/') >= 3 ) {
-        // .../usr/lib/X11 -> /usr/share/X11/xkb vs .../usr/X11/lib -> /usr/X11/share/X11/xkb
-        QString delta = base.endsWith("X11") ? "/../../share/X11" : "/../share/X11";
-        QDir baseDir(base + delta);
-        if( baseDir.exists() ) {
-            xkbParentDir = baseDir.absolutePath();
-        }
-        else {
-            QDir baseDir(base + "/X11");	// .../usr/X11/lib/X11/xkb (old XFree)
-            if( baseDir.exists() ) {
-                xkbParentDir = baseDir.absolutePath();
-            }
+
+void KbLayout :: addKey(){
+    keyCount++;
+    keyList << KbKey();
+}
+
+
+QString KbLayout :: getInclude(int i){
+    if(i < includeCount)
+        return include[i];
+    else
+        return QString();
+}
+
+
+int KbLayout :: findKey(QString n){
+    for(int i = 0 ; i < keyCount ; i++){
+        if(keyList[i].keyName == n){
+            return i;
         }
     }
+    return -1;
+}
 
-    if( xkbParentDir.isEmpty() ) {
-        xkbParentDir = "/usr/share/X11";
-    }
 
-    return QString("%1/xkb/symbols/").arg(xkbParentDir);
+void KbLayout::display(){
+//    qDebug() << name << "\n";
+//    for(int i = 0; i<includeCount; i++){
+//        qDebug() << include[i];
+//    }
+    for(int i = 0 ; i < keyCount; i++ ){
+        keyList[i].display();
+    }
 }
diff --git a/kcms/keyboard/preview/keyboardlayout.h b/kcms/keyboard/preview/keyboardlayout.h
old mode 100644
new mode 100755
index 2d0c088..12b56b0
--- a/kcms/keyboard/preview/keyboardlayout.h
+++ b/kcms/keyboard/preview/keyboardlayout.h
@@ -15,36 +15,86 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
- 
-#ifndef KEYBOARDLAYOUT_H
-#define KEYBOARDLAYOUT_H
 
-#include "keysymbols.h"
+#ifndef KEYBOARDLAYOUT_NEW_H
+#define KEYBOARDLAYOUT_NEW_H
+
 #include "keyaliases.h"
+#include <QString>
+#include <QStringList>
+#include <QList>
 
-#include <QApplication>
 
-class KeyboardLayout
-{
-    QString layoutName;
-    Aliases alias;
+class KbKey{
+private:
+    QList<QString> symbols;
+    int symbolCount;
     
 public:
-    KeyboardLayout();
-
-    KeySymbols TLDE;
-    KeySymbols BKSL;
-    KeySymbols AE[12];
-    KeySymbols AD[12];
-    KeySymbols AC[11];
-    KeySymbols AB[11];
-
-    void generateLayout(QString a, const QString &cname);
-    QString findSymbolBaseDir();
-    void includeSymbol(QString a, const QString &cname);
+    QString keyName;
+
+    KbKey();
+
+    void setKeyName(QString n);
+    void addSymbol(QString n, int i);
+    QString getSymbol(int i);
+
+    int getSymbolCount(){
+        return symbolCount;
+    }
+
+    void display();
+};
+
+
+class KbLayout{
+private:
+    QList<QString> include;
+    QString name;
+    int keyCount, includeCount, level;
+    bool parsedSymbol;
+
+public:
+    QList <KbKey> keyList;
+    QString country;
+
+    KbLayout();
+
+    void setName(QString n);
+    void addInclude(QString n);
+    void addKey();
+    QString getInclude(int i);
+    int findKey(QString n);
+
+    void setLevel(int lvl){
+        level = lvl;
+    }
+
+    int getLevel(){
+        return level;
+    }
+
+    int getKeyCount(){
+        return keyCount;
+    }
+
+    int getIncludeCount(){
+        return includeCount;
+    }
+
     QString getLayoutName() const {
-    	return layoutName;
+        return name;
+    }
+
+    void setParsedSymbol(bool state){
+        parsedSymbol = state;
     }
+
+    bool getParsedSymbol(){
+        return parsedSymbol;
+    }
+
+    void display();
 };
 
-#endif // KEYBOARDLAYOUT_H
+#endif //KEYBOARDLAYOUT_NEW_H
diff --git a/kcms/keyboard/preview/keyboardpainter.cpp b/kcms/keyboard/preview/keyboardpainter.cpp
old mode 100644
new mode 100755
index 268fcb0..72ec874
--- a/kcms/keyboard/preview/keyboardpainter.cpp
+++ b/kcms/keyboard/preview/keyboardpainter.cpp
@@ -17,37 +17,83 @@
  */
 
 #include "keyboardpainter.h"
+#include "geometry_components.h"
+#include "../flags.h"
 
 #include <QHBoxLayout>
 #include <QVBoxLayout>
 #include <QPushButton>
-
-#include <KLocalizedString>
+#include <QComboBox>
+#include <QDebug>
+#include <KLocale>
 
 
 KeyboardPainter::KeyboardPainter():
+    kbDialog(new QDialog(this)),
     kbframe(new KbPreviewFrame(this)),
-    exitButton(new QPushButton(i18n("Close"),this))
+    exitButton(new QPushButton(i18n("Close"), this)),
+    levelBox(new QComboBox(this))
 {
-    kbframe->setFixedSize( 1030, 490 );
-    exitButton->setFixedSize(120, 30);
+    kbframe->setFixedSize(1100, 490);
+    exitButton->setFixedSize( 120, 30 );
+    levelBox->setFixedSize( 360, 30 );
 
     QVBoxLayout* vLayout = new QVBoxLayout( this );
+    QHBoxLayout* hLayout = new QHBoxLayout();
+
+    hLayout->addWidget(exitButton, 0, Qt::AlignLeft);
+    hLayout->addWidget(levelBox, 0, Qt::AlignRight);
+    hLayout->addSpacing(30);
+
     vLayout->addWidget(kbframe);
-    vLayout->addWidget(exitButton);
+    vLayout->addLayout(hLayout);
 
     connect(exitButton, SIGNAL(clicked()), this, SLOT(close()));
+    connect(levelBox, SIGNAL(activated(int)), this, SLOT(levelChanged(int)));
 
     setWindowTitle(kbframe->getLayoutName());
 }
 
-void KeyboardPainter::generateKeyboardLayout(const QString& layout, const QString& variant)
+
+void KeyboardPainter::generateKeyboardLayout(const QString& layout, const QString& variant, const \
QString& model, const QString& title)  {
-    kbframe->generateKeyboardLayout(layout, variant);
+    kbframe->generateKeyboardLayout(layout, variant, model);
+    kbframe->setFixedSize(getWidth(),getHeight());
+    kbDialog->setFixedSize(getWidth(),getWidth());
+    setWindowTitle(title);
+
+    int level = kbframe->getLevel();
+
+    if(level > 4){
+        levelBox->addItem( i18nc("Keyboard layout levels", "Level %1, %2", 3, 4) );
+        for(int i=5; i <= level; i += 2) {
+            levelBox->addItem( i18nc("Keyboard layout levels", "Level %1, %2", i, i+1) );
+        }
+    }
+    else {
+        levelBox->setVisible(false);
+    }
+}
+
+void KeyboardPainter::levelChanged(int l_id){
+    kbframe->setL_id(l_id);
+}
+
+int KeyboardPainter::getHeight(){
+   int height = kbframe->getHeight();
+   height = kbframe->getScaleFactor() * height + 50;
+   return height;
+}
+
+int KeyboardPainter::getWidth(){
+   int width = kbframe->getWidth();
+   width = kbframe->getScaleFactor() * width + 20;
+   return width;
 }
 
 KeyboardPainter::~KeyboardPainter()
 {
     delete kbframe;
     delete exitButton;
+    delete levelBox;
 }
diff --git a/kcms/keyboard/preview/keyboardpainter.h b/kcms/keyboard/preview/keyboardpainter.h
old mode 100644
new mode 100755
index dde7b38..19438c1
--- a/kcms/keyboard/preview/keyboardpainter.h
+++ b/kcms/keyboard/preview/keyboardpainter.h
@@ -25,6 +25,7 @@
 #include <QDialog>
 
 class QPushButton;
+class QComboBox;
 
 class KeyboardPainter : public QDialog
 {
@@ -33,12 +34,18 @@ class KeyboardPainter : public QDialog
 public:
     explicit KeyboardPainter();
     ~KeyboardPainter();
+    void generateKeyboardLayout(const QString& layout, const QString& variant, const QString& model, \
const QString& title); +    int getHeight();
+    int getWidth();
 
-    void generateKeyboardLayout(const QString& layout, const QString& variant);
+public Q_SLOTS:
+    void levelChanged(int l_id);
     
 private:
+    QDialog *kbDialog;
     KbPreviewFrame *kbframe;
     QPushButton *exitButton;
+    QComboBox *levelBox;
 };
 
 #endif // KEYBOARDPAINTER_H
diff --git a/kcms/keyboard/preview/keysym2ucs.cpp b/kcms/keyboard/preview/keysym2ucs.cpp
old mode 100644
new mode 100755
diff --git a/kcms/keyboard/preview/keysym2ucs.h b/kcms/keyboard/preview/keysym2ucs.h
old mode 100644
new mode 100755
diff --git a/kcms/keyboard/preview/keysymbols.cpp b/kcms/keyboard/preview/keysymbols.cpp
old mode 100644
new mode 100755
diff --git a/kcms/keyboard/preview/keysymbols.h b/kcms/keyboard/preview/keysymbols.h
old mode 100644
new mode 100755
diff --git a/kcms/keyboard/preview/keysymhelper.cpp b/kcms/keyboard/preview/keysymhelper.cpp
old mode 100644
new mode 100755
index 1d6654e..b84b9d1
--- a/kcms/keyboard/preview/keysymhelper.cpp
+++ b/kcms/keyboard/preview/keysymhelper.cpp
@@ -37,13 +37,20 @@ QString KeySymHelper::getKeySymbol(const QString& opton)
     if( keySymbolMap.contains(opton) )
         return keySymbolMap[opton];
 
+    const char* str = opton.toAscii().data();
+    
 #if 0
     //TODO: figure out how to use this so we don't need our own symkey2ucs mapping
     int res = Xutf8LookupString(XIC ic, XKeyPressedEvent *event, char *buffer_return, int bytes_buffer, \
KeySym *keysym_return, Status *status_return);  
 #else
 
-    KeySym keysym = XStringToKeysym(opton.toLatin1().constData());
+    KeySym keysym = XStringToKeysym(str);
+
+    //TODO: make it more generic
+//    if( keysym == 0xfe03 )
+//	return "L3";
+    
     long ucs = keysym2ucs(keysym);
 
 //    if( ucs == -1 && (keysym >= 0xFE50 && keysym <= 0xFE5F) ) {
diff --git a/kcms/keyboard/preview/keysymhelper.h b/kcms/keyboard/preview/keysymhelper.h
old mode 100644
new mode 100755
index 763e872..fee47fe
--- a/kcms/keyboard/preview/keysymhelper.h
+++ b/kcms/keyboard/preview/keysymhelper.h
@@ -19,8 +19,8 @@
 #ifndef KEYSYMHELPER_H
 #define KEYSYMHELPER_H
 
-#include <QtCore/QString>
-#include <QtCore/QMap>
+#include <QString>
+#include <QMap>
 
 class KeySymHelper
 {
diff --git a/kcms/keyboard/preview/model_to_geometry.cpp b/kcms/keyboard/preview/model_to_geometry.cpp
new file mode 100755
index 0000000..8fcf065
--- /dev/null
+++ b/kcms/keyboard/preview/model_to_geometry.cpp
@@ -0,0 +1,243 @@
+/*
+ *  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 "model_to_geometry.h"
+#include "../x11_helper.h"
+
+#include <QFile>
+#include <QDebug>
+#include <QRegExp>
+
+ModelGroup :: ModelGroup(){
+
+}
+
+void ModelGroup :: addGroupModel(QString model){
+    if( !groupModels.contains(model) ){
+        groupModels << model;
+    }
+}
+
+int ModelGroup :: containsModel(QString model){
+    for(int i = 0 ; i < groupModels.size() ; i++){
+        if (model == groupModels.at(i)){
+            return i;
+        }
+    }
+    return -1;
+}
+
+void ModelGroup :: display(){
+    //qDebug()<<groupName<<"\t"<<modelCount<<"\t"<<groupModels;
+}
+
+ModelToGeometry :: ModelToGeometry(){
+}
+
+ModelToGeometryTable :: ModelToGeometryTable(){
+
+    modelGroups << ModelGroup();
+    entryCount = 0;
+    modelGroupCount = 0;
+
+}
+
+void ModelToGeometryTable :: addEntry(ModelToGeometry entry){
+    table << entry;
+    entryCount++;
+}
+
+QString ModelToGeometryTable :: getGeometryFile(QString model){
+
+    if( !parsing )
+        return "pc";
+
+    for (int i = 0; i < entryCount ; i++){
+
+        ModelToGeometry entry = table.at(i);
+        QString tempModel = entry.getModel();
+
+        if(tempModel.startsWith('$')){
+            for ( int j = 0; j < modelGroupCount; j++){
+                ModelGroup temp = modelGroups.at(j);
+                if (temp.getGroupName() == tempModel && temp.containsModel(model) > -1){
+                    return entry.getGeometryFile();
+                }
+            }
+        }
+        else{
+            if (tempModel == model){
+                return entry.getGeometryFile();
+            }
+        }
+
+    }
+    return defaultGeometryFile;
+}
+
+
+QString ModelToGeometryTable :: getGeometryName(QString model){
+
+    if( !parsing )
+        return "pc104";
+
+    for (int i = 0; i < entryCount ; i++){
+
+        ModelToGeometry entry = table.at(i);
+        QString tempModel = entry.getModel();
+        if(tempModel.startsWith('$')){
+            for ( int j = 0; j < modelGroupCount; j++){
+                ModelGroup temp = modelGroups.at(j);
+                if (temp.getGroupName() == tempModel && temp.containsModel(model) > -1){
+                    if(! (entry.getGeometryName() == "%m") ){
+                        return entry.getGeometryName();
+                    }
+                    else{
+                        return model;
+                    }
+                }
+            }
+        }
+        else{
+            if (tempModel == model){
+                return entry.getGeometryName();
+           }
+        }
+    }
+    return defaultGeometryName;
+}
+
+void ModelToGeometryTable :: addModelGroup(){
+    modelGroups << ModelGroup();
+    modelGroupCount++;
+}
+
+void ModelToGeometryTable :: createTable(){
+
+    QString xkbDir = X11Helper::findXkbDir();
+    QString xkbRulesDir = QString("%1/rules/base").arg(xkbDir);
+    QFile baseFile(xkbRulesDir);
+    if (!baseFile.open(QIODevice::ReadOnly | QIODevice::Text)){
+        qDebug()<<"unable to open the file";
+        parsing = false;
+    }
+    else{
+        QString baseContent = baseFile.readAll();
+        baseFile.close();
+
+        QString tableStr = baseContent;
+
+        QRegExp tableExp ("[!]\\s*\\b(model)\\b\\s*=\\s*\\b(geometry)\\b\\n*[^!]*");
+        QRegExp tableHeader ("[!]\\s*\\b(model)\\b\\s*=\\s*\\b(geometry)\\b\\n");
+
+        int index = tableExp.indexIn(tableStr);
+        int tableLength = tableExp.matchedLength();
+        tableStr = tableStr.mid(index, tableLength);
+        tableStr.remove(tableHeader);
+        //qDebug()<<tableStr;
+        QStringList entries = tableStr.split("\n");
+
+        bool defaultEntry = false;
+
+        for (int i = 1 ; i < entries.size() - 1; i++){
+
+            QString tupple = entries.at(i);
+
+            ModelToGeometry currentEntry;
+            tupple.remove(" ");
+            tupple.remove("\t");
+            QStringList tuppleElements = tupple.split("=");
+            if(tuppleElements.size() == 2){
+                QString kbModel = tuppleElements.at(0);
+                currentEntry.setKbModel(kbModel);
+
+                if( kbModel == "*"){
+                    defaultEntry = true;
+                }
+                if(kbModel.startsWith("$")){
+                    modelGroups[modelGroupCount].setGroupName(kbModel);
+                    addModelGroup();
+                }
+
+                QString geomInfo = tuppleElements.at(1);
+                QStringList geometryFileinfo = geomInfo.split("(");
+                if(geometryFileinfo.size() == 2){
+                    QString geometryFile = geometryFileinfo.at(0);
+                    currentEntry.setGeometryFile(geometryFile);
+                    QString geometryName = geometryFileinfo.at(1);
+                    geometryName.remove(")");
+                    if(geometryName == "intl")
+                        geometryName = "60";
+                    currentEntry.setGeometryName(geometryName);
+                    addEntry(currentEntry);
+                    if(defaultEntry){
+                        defaultGeometryFile = geometryFile;
+                        defaultGeometryName = geometryName;
+                        defaultEntry = false;
+                        parsing = true;
+                    }
+                }
+            }
+        }
+        createModelGroups(baseContent);
+        //display();
+    }
+}
+void ModelToGeometryTable :: createModelGroups(QString content){
+
+    QString groupStr = content;
+
+    for(int i = 0 ; i < modelGroupCount; i++){
+        QString input = groupStr;
+        QString gname = modelGroups[i].getGroupName();
+        gname.remove('$');
+        QRegExp variable("[!]\\s*[$]\\b(" + gname + ")\\b[^\\n]*");
+
+        int index = variable.indexIn(input);
+        int len = variable.matchedLength();
+        input = input.mid(index, len);
+
+        //qDebug()<<"input: "<<input;
+
+        QString modelList = input.split("=").at(1);
+        QStringList models = modelList.split(" ");
+
+        ModelGroup temp =  modelGroups.at(i);
+
+        for(int j = 1; j < models.size(); j++){
+            //qDebug()<<"model At"<<j<<":"<<models.at(j);
+            QString model = models.at(j);
+            temp.addGroupModel(model);
+        }
+
+        modelGroups.replace(i, temp);
+
+    }
+}
+
+void ModelToGeometryTable :: display(){
+    for(int i = 0 ; i < entryCount; i++){
+        ModelToGeometry temp = table.at(i);
+        qDebug() << temp.getModel() << "\t"<<temp.getGeometryFile()<<"\t"<<temp.getGeometryName();
+    }
+    for (int i = 0; i < modelGroupCount; i ++){
+        ModelGroup temp = modelGroups.at(i);
+        temp.display();
+    }
+}
+
diff --git a/kcms/keyboard/preview/model_to_geometry.h b/kcms/keyboard/preview/model_to_geometry.h
new file mode 100755
index 0000000..c3a6263
--- /dev/null
+++ b/kcms/keyboard/preview/model_to_geometry.h
@@ -0,0 +1,113 @@
+/*
+ *  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 MODEL_TO_GEOMETRY_H
+#define  MODEL_TO_GEOMETRY_H
+
+#include <QString>
+#include <QStringList>
+
+
+class ModelGroup {
+
+    QStringList groupModels;
+    QString groupName;
+
+
+public:
+
+
+    ModelGroup();
+
+    void addGroupModel( QString model );
+
+    void setGroupName(QString name){
+        groupName = name;
+    }
+
+    QString getGroupName(){
+        return groupName;
+    }
+
+    int containsModel(QString model);
+
+    void display();
+};
+
+
+class ModelToGeometry{
+
+    QString geometryName;
+    QString geometryFile;
+    QString kbModel;
+
+public :
+
+    ModelToGeometry();
+
+    void setGeometryName(QString name){
+        geometryName = name;
+    }
+
+    void setGeometryFile(QString file){
+        geometryFile = file;
+    }
+
+    void setKbModel(QString model){
+        kbModel = model;
+    }
+
+    QString getGeometryFile(){
+        return geometryFile;
+    }
+
+    QString getGeometryName(){
+        return geometryName;
+    }
+
+    QString getModel(){
+        return kbModel;
+    }
+
+};
+
+
+class ModelToGeometryTable{
+
+    int entryCount, modelGroupCount;
+    QList <ModelGroup> modelGroups;
+    QString defaultGeometryFile, defaultGeometryName;
+    bool parsing;
+
+public:
+    QList <ModelToGeometry> table;
+
+    ModelToGeometryTable();
+
+
+    QString getGeometryName(QString model);
+    QString getGeometryFile(QString model);
+    void createTable();
+    void addEntry(ModelToGeometry currentEntry);
+    void display();
+    void createModelGroups(QString content);
+    void addModelGroup();
+
+};
+
+#endif //model_to_geometry.h
diff --git a/kcms/keyboard/preview/symbol_parser.cpp b/kcms/keyboard/preview/symbol_parser.cpp
new file mode 100755
index 0000000..b230e53
--- /dev/null
+++ b/kcms/keyboard/preview/symbol_parser.cpp
@@ -0,0 +1,298 @@
+/*
+ *  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 <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 = X11Helper::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{
+        qDebug() << "Symbols Parsing failed\n";
+        qDebug()<<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 100755
index 0000000..0f93d5d
--- /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"
+#include "x11_helper.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


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic