/*
   pRepo - Peter's Repository program
        Complex tutorial of gSAFE ( http://hyperprog.com/gsafe/ )

   (C) 2011 Peter Deak  (______@gmail.com)

   License: GPL

*/

#include <QtCore>
#include <QtSql>
#include <QtGui>
#include <QtWebKit>

#include <datalib.h>
#include <hfactory.h>
#include <dialib.h>
#include <dconsole.h>
#include <guilib.h>
#include <printlib.h>
#include <xmlolib.h>

#include "prepo.h"

// ////////////////////////////////////////////////////////////////////////////////////////////

MainDialog::MainDialog(QWidget *parent)
    : QDialog(parent),ui(new Ui::MainWindowBase)
{
    ui->setupUi(this);

    HSqlInterface::setSqlMode("QtSqlite_Win");

    //Initialize HRefreshAgent...

    new HRefreshAgent();

    //Create HFactory object...

    myfactory = new HFactory("");
    connect(myfactory,SIGNAL(errorSignal(QString)),this,SLOT(showError(QString)));

    //Read metadata from Qt resource by HFactory

    QFile *metadatadef_file=NULL;
    metadatadef_file = new QFile(METADEFFILE);
    if(!metadatadef_file->exists())
    {
        error(tr("Error: Missing datadef file!"));
        exit(0);
    }
    myfactory->readFromFile(metadatadef_file);
    delete metadatadef_file;
    metadatadef_file = NULL;

    //Opens the database, or create if not exists

    sdebug(QString("Open the sqlite database file:") + QString(DATABASEFILE));
    bool newcreate=false;
    QFile *database_file=NULL;
    database_file = new QFile(DATABASEFILE);
    if(!database_file->exists())
    {
        error(tr("Error:Can't open the database file!"));
        if(QMessageBox::question(this,tr("New database"),tr("Create new empty database structure?"),tr("No"),tr("Yes")))
            newcreate = true;

        if(!newcreate)
            exit(0);
    }
    delete database_file;
    database_file = NULL;

    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName(DATABASEFILE);
    if(!db.open())
    {
        QMessageBox::information(this,"gSAFE-Qt4",tr("Cannot establish the database connection..."));
        exit(0);
    }

    globalsql = new HSqlHandler();
    connect(globalsql,SIGNAL(errorSignal(QString)),this,SLOT(showError(QString)));

    //Create the database structure

    if(newcreate)
    {
        QString createstr="";
        //Creating a new empty database structure...


        createstr = myfactory->sqlCreateString("settings");
        globalsql->submit0ResultQuery(createstr,tr("Error during structure creation (0)"));
        createstr = myfactory->sqlCreateString("Type");
        globalsql->submit0ResultQuery(createstr,tr("Error during structure creation (1)"));
        createstr = myfactory->sqlCreateString("Place");
        globalsql->submit0ResultQuery(createstr,tr("Error during structure creation (2)"));
        createstr = myfactory->sqlCreateString("Accountable");
        globalsql->submit0ResultQuery(createstr,tr("Error during structure creation (3)"));
        createstr = myfactory->sqlCreateString("Object");
        globalsql->submit0ResultQuery(createstr,tr("Error during structure creation (4)"));
        createstr = myfactory->sqlCreateString("Moving");
        globalsql->submit0ResultQuery(createstr,tr("Error during structure creation (5)"));

        //Popus a dialog to save the settings (insert a record to the setting table

        HTable *settings = myfactory->genHTable("settings");
        HDialog *fsdialog = new HDialog(this,tr("Settings"),settings,NULL,"Ok|OkIsAccept|StrToE",tr("Set the following attributes"));
        while(!fsdialog->exec());
        settings->setSqlFieldValue("next",settings->getSqlFieldValue("start"));
        settings->insertRecord();
        delete fsdialog;
        delete settings;

    }
    //Database succesfull opened...


    objectchangelogger = new HDataChangeLogger(myfactory->genHTable("Moving"),"Unknown","User");
    //------------- Allocate various things --------------------------------------


    pixmaparray_new_edit_del = new QList<QPixmap *>();
        pixmaparray_new_edit_del->push_back(new QPixmap(":/ICONS/new.png" ));
        pixmaparray_new_edit_del->push_back(new QPixmap(":/ICONS/edit.png"));
        pixmaparray_new_edit_del->push_back(new QPixmap(":/ICONS/del.png" ));

    connect(ui->bClose,SIGNAL(clicked()),this,SLOT(close()));
    connect(ui->bObjects,SIGNAL(clicked()),this,SLOT(slotObjects()));
    connect(ui->bTypes,SIGNAL(clicked()),this,SLOT(slotTypes()));
    connect(ui->bPlaces,SIGNAL(clicked()),this,SLOT(slotPlaces()));
    connect(ui->bAcc,SIGNAL(clicked()),this,SLOT(slotAcc()));

    connect(ui->bIn,SIGNAL(clicked()),this,SLOT(slotInObj()));
    connect(ui->bMove,SIGNAL(clicked()),this,SLOT(slotMoveObj()));
    connect(ui->bSetprice,SIGNAL(clicked()),this,SLOT(slotSetCValueObj()));
    connect(ui->bOut,SIGNAL(clicked()),this,SLOT(slotOutObj()));
    connect(ui->bTrace,SIGNAL(clicked()),this,SLOT(slotTraceObj()));

    connect(ui->bConsole,SIGNAL(clicked()),this,SLOT(slotConsole()));
    connect(ui->bAbout,SIGNAL(clicked()),this,SLOT(slotInfo()));

    currList = NULL;
    objt = NULL;
    clicked_outkey = "";
    wstack.clear();
    wstack.push_back(this);
    setSizeGripEnabled(true);
    slotStat("");

    connect(HRefreshAgent::getNotifyAgent(),SIGNAL(getnotify(QString)),this,SLOT(slotStat(QString)));

    //Register custom console commands

    ::register_dconsole_command("createstr",this);
    ::register_dconsole_command("dumpmetadata",this);
}

MainDialog::~MainDialog(void)
{
}

int MainDialog::showError(QString err)
{
    QString msg;
    msg = QString(tr("%1: %2"))
            .arg(tr("Error received"))
            .arg(err);
    sdebug(msg);
    error(msg);
    return 0;
}

int MainDialog::slotConsole(void)
{
    dconsole();
    return 0;
}

int MainDialog::slotInfo(void)
{
    QMessageBox::information(this,tr("About"),
        QString("<strong>pRepo</strong> - %1<br>%2<br>http://hyperprog.com<br><br>%3: %4<br>gSAFE: %5<br><br>%6<br>License: GPLv2")
            .arg(tr("Peter's repository program"))
            .arg(tr("(gSAFE tutorial program)"))
            .arg(tr("Version"))
            .arg(VERSION)
            .arg(GSAFE_VERSION)
            .arg(tr("Author: Peter Deak (hyper80@gmail.com)")));
    return 0;
}

// //Places///////////////////////////////////////////////////////////////////////

int MainDialog::slotPlaces(void)
{
    currList = myfactory->genHList("Place","list");
    currList->extrafeatures = true;

    HDialog *d = new HDialog(wstack.top(),tr("Places"),currList,NULL,
                             "Ok|EscC|ToolCenter|Vert",tr("Places"),"","",pixmaparray_new_edit_del);
    currList->readList();
    connect(currList,SIGNAL(actionOnRecord(QString)),this,SLOT(slotPlacesAct(QString)));
    connect(d->pixTool[0],SIGNAL(clicked()),this,SLOT(slotAddPlaces()));
    connect(d->pixTool[1],SIGNAL(clicked()),this,SLOT(slotEditPlaces()));
    connect(d->pixTool[2],SIGNAL(clicked()),this,SLOT(slotDelPlace()));
    wstack.push_back(d);
    d->exec();
    wstack.pop();
    delete d;
    delete currList;
    currList = NULL;
    return 0;
}

int MainDialog::slotAddPlaces(void)
{
    HTable *t = myfactory->genHTable("Place");
    HDialog *d = new HDialog(wstack.top(),tr("A new place"),t,NULL,
                             "Ok|EscC|Vert|StrToE|OkIsAccept",tr("The new place"));
    wstack.push_back(d);
    while(d->exec())
    {
        t->rereadNextInsertedKey();
        if(t->insertRecord() == 0)
        {
            emit setKeyTo(t->getInsertedKey());
            HRefreshAgent::notify("place");
            break;
        }
        else continue;
    }
    wstack.pop();
    delete d;
    delete t;
    return 0;
}

int MainDialog::slotEditPlaces(void)
{
    QString key;
    if(currList == NULL || currList->soft_current_key.isEmpty())
        return 0;
    key = currList->soft_current_key;
    HTable *t = myfactory->genHTable("Place");
    HDialog *d = new HDialog(wstack.top(),tr("Edit place"),t,NULL,
                             "Ok|EscC|Vert|StrToE|OkIsAccept",tr("Edit the place"));
    t->updateWithKey(key);
    wstack.push_back(d);
    while(d->exec())
    {
        if(t->saveRecord() == 0)
        {
            HRefreshAgent::notify("place");
            break;
        }
        else continue;
    }
    wstack.pop();
    delete d;
    delete t;
    return 0;
}

int MainDialog::slotDelPlace(void)
{
    QString key;
    if(currList == NULL || currList->soft_current_key.isEmpty())
        return 0;
    key = currList->soft_current_key;

    if(QMessageBox::question(wstack.top(),tr("Are you sure?"),tr("Are you sure want to delete this place?"),tr("No"),tr("Yes")))
    {
        if(globalsql->submit1ResultQuery(
                QString("SELECT COUNT(*) FROM object WHERE place=\'%1\';").arg(key),"CL01").toInt() > 0)
        {
            error(tr("You can't delete a place which contains objects! Sorry."));
            return 0;
        }
        globalsql->submit0ResultQuery(QString("DELETE FROM place WHERE pkey=%1").arg(key),"");
        HRefreshAgent::notify("place");
    }
    return 0;
}

// //Types///////////////////////////////////////////////////////////////////////

int MainDialog::slotTypes(void)
{
    currList = myfactory->genHList("Type","list");
    currList->extrafeatures = true;

    HDialog *d = new HDialog(wstack.top(),tr("Types"),currList,NULL,
                             "Ok|EscC|ToolCenter|Vert",tr("Types"),"","",pixmaparray_new_edit_del);
    currList->readList();
    connect(currList,SIGNAL(actionOnRecord(QString)),this,SLOT(slotTypesAct(QString)));
    connect(d->pixTool[0],SIGNAL(clicked()),this,SLOT(slotAddTypes()));
    connect(d->pixTool[1],SIGNAL(clicked()),this,SLOT(slotEditTypes()));
    connect(d->pixTool[2],SIGNAL(clicked()),this,SLOT(slotDelTypes()));
    wstack.push_back(d);
    d->exec();
    wstack.pop();
    delete d;
    delete currList;
    return 0;
}

int MainDialog::slotAddTypes(void)
{
    HTable *t = myfactory->genHTable("Type");
    HDialog *d = new HDialog(wstack.top(),tr("A new type"),t,NULL,
                             "Ok|EscC|Vert|StrToE|OkIsAccept",tr("The new type"));
    wstack.push_back(d);
    while(d->exec())
    {
        t->rereadNextInsertedKey();
        if(t->insertRecord() == 0)
        {
            emit setKeyTo(t->getInsertedKey());
            HRefreshAgent::notify("type");
            break;
        }
        else continue;
    }
    wstack.pop();
    delete d;
    delete t;
    return 0;
}

int MainDialog::slotEditTypes(void)
{
    QString key;
    if(currList == NULL || currList->soft_current_key.isEmpty())
        return 0;
    key = currList->soft_current_key;
    HTable *t = myfactory->genHTable("Type");
    HDialog *d = new HDialog(wstack.top(),tr("Edit type"),t,NULL,
                             "Ok|EscC|Vert|StrToE|OkIsAccept",tr("Edit the type"));
    t->updateWithKey(key);
    wstack.push_back(d);
    while(d->exec())
    {
        if(t->saveRecord() == 0)
        {
            HRefreshAgent::notify("type");
            break;
        }
        else continue;
    }
    wstack.pop();
    delete d;
    delete t;
    return 0;
}

int MainDialog::slotDelTypes(void)
{
    QString key;
    if(currList == NULL || currList->soft_current_key.isEmpty())
        return 0;
    key = currList->soft_current_key;

    if(QMessageBox::question(wstack.top(),tr("Are you sure?"),tr("Are you sure want to delete this type?"),tr("No"),tr("Yes")))
        {
            if(globalsql->submit1ResultQuery(
                    QString("SELECT COUNT(*) FROM object WHERE type=\'%1\';").arg(key),"CL01").toInt() > 0)
            {
                error(tr("You can't delete a type which contains objects! Sorry."));
                return 0;
            }
            globalsql->submit0ResultQuery(QString("DELETE FROM type WHERE tkey=%1").arg(key),"");
            HRefreshAgent::notify("type");
        }
    return 0;
}

// //Accountables///////////////////////////////////////////////////////////////////////

int MainDialog::slotAcc(void)
{
    currList = myfactory->genHList("Accountable","list");
    currList->extrafeatures = true;

    HDialog *d = new HDialog(wstack.top(),tr("Accountables"),currList,NULL,
                             "Ok|EscC|ToolCenter|Vert",tr("Accountables"),"","",pixmaparray_new_edit_del);
    currList->readList();
    connect(currList,SIGNAL(actionOnRecord(QString)),this,SLOT(slotAccAct(QString)));
    connect(d->pixTool[0],SIGNAL(clicked()),this,SLOT(slotAddAcc()));
    connect(d->pixTool[1],SIGNAL(clicked()),this,SLOT(slotEditAcc()));
    connect(d->pixTool[2],SIGNAL(clicked()),this,SLOT(slotDelAcc()));
    wstack.push_back(d);
    d->exec();
    wstack.pop();
    delete d;
    delete currList;
    return 0;
}

int MainDialog::slotAddAcc(void)
{
    HTable *t = myfactory->genHTable("Accountable");
    HDialog *d = new HDialog(wstack.top(),tr("A new accountable"),t,NULL,
                             "Ok|EscC|Vert|StrToE|OkIsAccept",tr("The new accountable"));
    wstack.push_back(d);
    while(d->exec())
    {
        t->rereadNextInsertedKey();
        if(t->insertRecord() == 0)
        {
            emit setKeyTo(t->getInsertedKey());
            HRefreshAgent::notify("accountable");
            break;
        }
        else continue;
    }
    wstack.pop();
    delete d;
    delete t;
    return 0;
}

int MainDialog::slotEditAcc(void)
{
    QString key;
    if(currList == NULL || currList->soft_current_key.isEmpty())
        return 0;
    key = currList->soft_current_key;
    HTable *t = myfactory->genHTable("Accountable");
    HDialog *d = new HDialog(wstack.top(),tr("Edit accountable"),t,NULL,
                             "Ok|EscC|Vert|StrToE|OkIsAccept",tr("Edit the accountable"));
    t->updateWithKey(key);
    wstack.push_back(d);
    while(d->exec())
    {
        if(t->saveRecord() == 0)
        {
            HRefreshAgent::notify("accountable");
            break;
        }
        else continue;
    }
    wstack.pop();
    delete d;
    delete t;
    return 0;
}

int MainDialog::slotDelAcc(void)
{
    QString key;
    if(currList == NULL || currList->soft_current_key.isEmpty())
        return 0;
    key = currList->soft_current_key;

    if(QMessageBox::question(wstack.top(),tr("Are you sure?"),tr("Are you sure want to delete this accountable?"),tr("No"),tr("Yes")))
        {
            if(globalsql->submit1ResultQuery(
                    QString("SELECT COUNT(*) FROM object WHERE acc=\'%1\';").arg(key),"CL01").toInt() > 0)
            {
                error(tr("You can't delete an accountable which contains objects! Sorry."));
                return 0;
            }
            globalsql->submit0ResultQuery(QString("DELETE FROM accountable WHERE akey=%1").arg(key),"");
            HRefreshAgent::notify("accountable");
        }
    return 0;
}

// //Objects///////////////////////////////////////////////////////////////////////

int MainDialog::slotInObj(void) //Add incoming object

{
    QString repnum;
    int nextrepnum;

    objt = myfactory->genHTable("Object","record");

    //Make a new repository number

    repnum = globalsql->submit1ResultQuery("SELECT prefix FROM settings LIMIT 1",tr("Error query next rep. prefix")).toString();
    nextrepnum = globalsql->submit1ResultQuery("SELECT next FROM settings LIMIT 1",tr("Error query next rep. num.")).toInt();
    objt->setSqlFieldValue("repnumber",QString("%1%2").arg(repnum).arg(nextrepnum));

    //Check if allow empty accountable

    if(!globalsql->submit1ResultQuery("SELECT allowemptyacc FROM settings LIMIT 1",tr("Error query next settings")).toBool())
        objt->fieldBySqlName("acc")->addNotValidValue("NULL");

    //Add toolbuttons to make possible to add items from here. (type,place,accountable)

    ((HSqlChoose *)objt->fieldBySqlName("type"))->addToolButton(this,tr("Add new type..."));
    ((HSqlChoose *)objt->fieldBySqlName("place"))->addToolButton(this,tr("Add new place..."));
    ((HSqlChoose *)objt->fieldBySqlName("acc"))->addToolButton(this,tr("Add new accountable..."));

    HDialog *d = new HDialog(wstack.top(),tr("New object"),objt,NULL,
                             "Ok|EscC|Vert|OkIsAccept|StrToE",tr("Add a new object"),"","",NULL);
    wstack.push_back(d);
    while(d->exec())
    {
        bool ok=true;
        objt->rereadNextInsertedKey();
        objt->transaction();
        if(objt->insertRecord(false,true,false) != 0)
            ok = false;
        //save the next prepository number

        globalsql->submit0ResultQuery(QString("UPDATE settings SET next=%1;").arg(nextrepnum+1),tr("Error set next rep num."),true);
        if(globalsql->errorStatus())
            ok = false;
        if(ok)
        {
            objt->commit();
            HRefreshAgent::notify("object");
            break;
        }
        else
        {
            objt->rollback();
            continue;
        }
    }
    wstack.pop();
    delete d;
    delete objt;
    objt = NULL;
    return 0;
}

int MainDialog::toolbuttonclicked(void)
{
    if(objt == NULL)
        return 0;
    if( ((HSqlChoose *)objt->fieldBySqlName("type"))->toolbarbutton_down_text == tr("Add new type...") )
        return slotAddTypes();
    if( ((HSqlChoose *)objt->fieldBySqlName("place"))->toolbarbutton_down_text == tr("Add new place...") )
        return slotAddPlaces();
    if( ((HSqlChoose *)objt->fieldBySqlName("acc"))->toolbarbutton_down_text == tr("Add new accountable...") )
        return slotAddAcc();
    return 0;
}

//Object list dialog

int MainDialog::objectList(QString role,QString mode,QString filter)
{
    QString caption=tr("Objects"),text=tr("Objects");
    QString readfilter="";
    currList = myfactory->genHList("Object",role);
    currList->extrafeatures = true;

    if(mode == "baselist")
    {
        connect(currList,SIGNAL(actionOnRecord(QString)),this,SLOT(slotViewObject(QString)));
    }
    if(mode == "modify")
    {
        text = tr("Select object to modify");
        readfilter = " AND status=\'a\' ";
        connect(currList,SIGNAL(actionOnRecord(QString)),this,SLOT(slotModifyObject(QString)));
    }
    if(mode == "setcval")
    {
        text = tr("Select object to modify current value");
        readfilter = " AND status=\'a\' ";
        connect(currList,SIGNAL(actionOnRecord(QString)),this,SLOT(slotSetCValueObject(QString)));
    }

    if(mode == "out")
    {
        text = tr("Select object to sold/refuse");
        readfilter = " AND status=\'a\' ";
        connect(currList,SIGNAL(actionOnRecord(QString)),this,SLOT(slotOutObject(QString)));
    }
    if(mode == "trace")
    {
        text = tr("Select object to trace");
        connect(currList,SIGNAL(actionOnRecord(QString)),this,SLOT(slotTraceObject(QString)));
    }
    if(mode == "place")
    {
        text = tr("Objects is in this place");
        connect(currList,SIGNAL(actionOnRecord(QString)),this,SLOT(slotViewObject(QString)));
        readfilter = QString(" AND place=\'%1\' ").arg(filter);
    }
    if(mode == "type")
    {
        text = tr("Objects is in type");
        connect(currList,SIGNAL(actionOnRecord(QString)),this,SLOT(slotViewObject(QString)));
        readfilter = QString(" AND type=\'%1\' ").arg(filter);
    }
    if(mode == "acc")
    {
        text = tr("Objects which assigned to this accountable");
        connect(currList,SIGNAL(actionOnRecord(QString)),this,SLOT(slotViewObject(QString)));
        readfilter = QString(" AND acc=\'%1\' ").arg(filter);
    }

    HDialog *d = new HDialog(wstack.top(),caption,currList,NULL,
                             "Ok|EscC|Vert",text,"","",NULL);
    currList->readList(readfilter);
    wstack.push_back(d);
    connect(currList,SIGNAL(alternateActionOnRecord(QString)),this,SLOT(slotAlterOnObj(QString)));
    d->exec();
    wstack.pop();
    delete d;
    delete currList;
    currList = NULL;
    return 0;
}

//Activate on right click on an object in object list

int MainDialog::slotAlterOnObj(QString key)
{
    QMenu *popup = new QMenu(this);

    popup->addAction(tr("Add new object"),this,SLOT(slotInObj()));
    popup->addAction(tr("Move/Edit object"),this,SLOT(slotMenuEdit()));
    popup->addAction(tr("Sold/Refuse object"),this,SLOT(slotMenuRefuse()));
    popup->addAction(tr("Trace object"),this,SLOT(slotMenuTrace()));

    clicked_outkey = key;
    popup->exec(QCursor::pos());
    clicked_outkey = "";
    delete popup;
    return 0;
}

int MainDialog::objectViewEdit(QString key,QString role,bool readonly) //View/Edit an object

{
    bool ro = readonly;
    if(key.isEmpty())
        return 0;

    //Generate the metadata object

    objt = myfactory->genHTable("Object",role);

    //Set logger

    objectchangelogger->setPos("slotViewEditObject");
    objt->setDataChangeLogger(objectchangelogger);

    //Read the data from SQL

    objt->updateWithKey(key);

    //Set readonly if necessary (ro requested, or sold item)

    if(objt->getSqlFieldValue("status").toString() == "o")
        ro = true;
    if(ro)
        objt->setReadonly();

    if(role == "out")
        objt->setSqlFieldValue("status","o");

    //Check if allow empty accountable

    if(!globalsql->submit1ResultQuery("SELECT allowemptyacc FROM settings LIMIT 1",tr("Error query next settings")).toBool())
        objt->fieldBySqlName("acc")->addNotValidValue("NULL");

    ((HSqlChoose *)objt->fieldBySqlName("type"))->addToolButton(this,tr("Add new type..."));
    ((HSqlChoose *)objt->fieldBySqlName("place"))->addToolButton(this,tr("Add new place..."));
    ((HSqlChoose *)objt->fieldBySqlName("acc"))->addToolButton(this,tr("Add new accountable..."));

    HDialog *d = new HDialog(wstack.top(),tr("Object"),objt,NULL,
                             "Ok|EscC|Vert|OkIsAccept|StrToE",tr("Object's data"),"","",NULL);

    wstack.push_back(d);
    while(d->exec())
    {
        if(ro)
            break;
        if(role == "setcval")
            objt->setSqlFieldValue("lcdate",QDate::currentDate());
        if(objt->saveRecord() == 0)
        {
            HRefreshAgent::notify("object");
            break;
        }
        else continue;
    }
    wstack.pop();
    delete d;
    delete objt;
    objectchangelogger->setPos("Unknown");
    objt = NULL;
    return 0;
}

// //Trace an object changes //////////////////////////////////////////////////////////////////

int MainDialog::slotTraceObject(QString key)
{
    int i,c;
    if(key.isEmpty())
        return 0;

    HDataField *df;
    HTable *ot = myfactory->genHTable("Object");
    ot->updateWithKey(key);

    HPlainDataMatrix *m;
    m = globalsql->submitNResultQuery(4,
            QString("SELECT sqlfieldname,oldvalue,newvalue,changetime FROM object_moving "
                    "WHERE changedkey=\'%1\' "
                    "ORDER BY changetime;").arg(key),tr("Error query changes"));

    m->setHeaderCell(0,tr("Changed data"));
    m->setHeaderCell(1,tr("Old value"));
    m->setHeaderCell(2,tr("New value"));

    c = m->rowCount();
    for(i=0;i<c;++i)
    {
        df = ot->fieldBySqlName(m->getCellStr(i,0));
        if(df != NULL)
        {
            QString explain_txt="";
            QString old_display_str="";
            QString new_display_str="";

            explain_txt = df->getExplainText();
            old_display_str = df->dbValueToDispValue(QString(m->getCellStr(i,1))).toString();
            new_display_str = df->dbValueToDispValue(QString(m->getCellStr(i,2))).toString();

            if(!explain_txt.isEmpty())
                m->setCellStr(i,0,explain_txt);
            if(!old_display_str.isEmpty())
                m->setCellStr(i,1,old_display_str);
            if(!new_display_str.isEmpty())
                m->setCellStr(i,2,new_display_str);
        }
    }

    HPlainDMD *pdmd = new HPlainDMD(wstack.top(),m,true);
    pdmd->exec();
    delete pdmd;
    delete m;
    delete ot;
    return 0;
}

// Small slots for events //////////////////////////////////////////////////////////////////////////

int MainDialog::slotViewObject(QString key)     {    return objectViewEdit(key,"",true);        }
int MainDialog::slotModifyObject(QString key)   {    return objectViewEdit(key,"modify",false); }
int MainDialog::slotSetCValueObject(QString key){    return objectViewEdit(key,"setcval",false);}
int MainDialog::slotOutObject(QString key)      {    return objectViewEdit(key,"out",false);    }
int MainDialog::slotMenuEdit(void)              {    return objectViewEdit(clicked_outkey,"modify",false);  }
int MainDialog::slotMenuRefuse(void)            {    return objectViewEdit(clicked_outkey,"out",false);     }

int MainDialog::slotPlacesAct(QString key)      {    return objectList("list","place",key);     }
int MainDialog::slotTypesAct(QString key)       {    return objectList("list","type",key);      }
int MainDialog::slotAccAct(QString key)         {    return objectList("list","acc",key);       }
int MainDialog::slotObjects(void)               {    return objectList("list","baselist");      }
int MainDialog::slotMoveObj(void)               {    return objectList("list","modify");        }
int MainDialog::slotSetCValueObj(void)          {    return objectList("list","setcval");       }
int MainDialog::slotOutObj(void)                {    return objectList("list","out");           }
int MainDialog::slotTraceObj(void)              {    return objectList("list","trace");         }

int MainDialog::slotMenuTrace(void)             {    return slotTraceObject(clicked_outkey);    }

// //Small statistics///////////////////////////////////////////////////////////////////

int MainDialog::slotStat(QString tblname)
{
    Q_UNUSED(tblname)
    int pnum = globalsql->submit1ResultQuery("SELECT count(*) FROM place;","S_E1").toInt();
    int anum = globalsql->submit1ResultQuery("SELECT count(*) FROM accountable;","S_E2").toInt();
    int tnum = globalsql->submit1ResultQuery("SELECT count(*) FROM type;","S_E3").toInt();
    int onum = globalsql->submit1ResultQuery("SELECT count(*) FROM object;","S_E4").toInt();
    int oanum = globalsql->submit1ResultQuery("SELECT count(*) FROM object WHERE status=\'a\';","S_E5").toInt();
    double osum = globalsql->submit1ResultQuery("SELECT sum(invalue) FROM object;","S_E6").toDouble();
    double oasum = globalsql->submit1ResultQuery("SELECT sum(invalue) FROM object WHERE status=\'a\';","S_E7").toDouble();

    ui->label->setText(
            QString("%1: %2  (%3: %4)\n%5: %6  (%7: %8)\n%9: %10\n%11: %12\n%13: %14")
                .arg(tr("Objects in the system")).arg(onum)
                .arg(tr("Active")).arg(oanum)
                .arg(tr("Sum incoming value in the system")).arg(osum)
                .arg(tr("Active")).arg(oasum)
                .arg(tr("Types in the system")).arg(tnum)
                .arg(tr("Places in the system")).arg(::doubleToQString(pnum,0,2,1))
                .arg(tr("Accountables in the system")).arg(::doubleToQString(anum,0,2,1))
            );
    return 0;
}

// //Other//////////////////////////////////////////////////////////////////////////////

void MainDialog::keyPressEvent(QKeyEvent *e)
{
    if(e->key() == Qt::Key_Escape)
        close();
}

QString MainDialog::donsole_command_interpreter(QString commandString)
{
    if(commandString == "createstr")
    {
        QString createstr="=========================================================\n";
        createstr += myfactory->sqlCreateString("settings");    createstr.append("\n");
        createstr += myfactory->sqlCreateString("Type");        createstr.append("\n");
        createstr += myfactory->sqlCreateString("Place");       createstr.append("\n");
        createstr += myfactory->sqlCreateString("Accountable"); createstr.append("\n");
        createstr += myfactory->sqlCreateString("Object");      createstr.append("\n");
        createstr += myfactory->sqlCreateString("Moving");      createstr.append("\n");
        return createstr;
    }
    if(commandString == "dumpmetadata")
    {
        QFile f(METADEFFILE);
        if (!f.open(QIODevice::ReadOnly | QIODevice::Text))
            return tr("Error, cannot provide the resource.");
        QTextStream in(&f);
        return in.readAll();
    }
    return "Ok.";
}

// //////////////////////////////////////////////////////////////////////////// //


int main(int argi,char **argc)
{
    QApplication app(argi,argc);

#ifdef LANG_HU
    QTranslator qtTranslator;
    qtTranslator.load(LANGUAGEFILE);
    app.installTranslator(&qtTranslator);
#endif

    MainDialog *maindialog = new MainDialog(0);
    maindialog->show();

    app.exec();
    return 0;
}
//end code.