diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..4003a792221ca1b5b550f98f18a9361c87374bd8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,25 @@
+.pydevproject
+.project
+.cproject
+.settings
+Makefile
+moc
+obj
+bin
+objects
+core*
+*~
+*.pyc
+*.so
+*.so*
+.pylintrc
+.metadata
+.idea
+.cvsignore
+.nse_depinfo
+software
+oldsrc
+ui_*
+qrc*.cpp
+.qmake.stash
+CVS
diff --git a/CHANGELOG b/CHANGELOG
new file mode 100644
index 0000000000000000000000000000000000000000..38f70113d109df3c1aad4e69324195ba117c810b
--- /dev/null
+++ b/CHANGELOG
@@ -0,0 +1,26 @@
+release_10: porting to QT5 (from phonon to Qt Multimedia)
+
+release_09: Fixed sorting problem on the tree widgets. Added missing modulators to the combo box.
+
+release_08: Fixed scroll issue on updates in TTreeWidget
+            Ported to QTango5
+
+release_07: added Test Sound button
+
+release_06: Ticket 975: General Interlock: sounds and important/blocking alarm
+	Added sound support.
+	Tabs with recent alarms are evidentiated by an alarm bell icon.
+ 	Recent alarms are bold.
+
+
+release_04: Ticket 774 ferminterlock: manca history per "PS and Vacuum"
+            Added search box on each tab. Text based search.
+            Queries have been modified.
+            See http://acswww.elettra.trieste.it/bugzilla/show_bug.cgi?id=774
+
+
+release_05: ticket 983: 
+srv-tango-srf/interlock/plc_mod_ll --> f/interlock/plc_mod_ll
+srv-tango-srf/interlock/plc_int_ll.01 --> f/interlock/plc_int_ll.01
+srv-tango-srf/interlock/plc_int_ll.02 --> f/interlock/plc_int_l
+database:  su srv-log-srf --> srv-db-srf
diff --git a/README b/README
new file mode 100644
index 0000000000000000000000000000000000000000..1eb9ab1376f970f9dd451af773deb0fe8aae972b
--- /dev/null
+++ b/README
@@ -0,0 +1,11 @@
+ferminterlock
+
+USAGE:
+
+ferminterlock f/interlock/plc_mod_ll f/interlock/plc_int_ll.01 f/interlock/plc_int_ll.02 srv-padres-srf:20000/srv-padres-srf/interlock/plc_int_ll.03  --sound-file-name /runtime/share/sounds/generalintlkpanel_beep.ogg
+
+Contacts:
+
+giacomo.strangolino@elettra....
+graziano.scalamera@elettra...
+
diff --git a/README.md b/README.md
index 7a48adc6e30a5ee66d57bbfe852bae3e4c41621d..e1032499add118143f73a8af7c047ae97c0689c9 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,14 @@
 # ferminterlock
 
 pannello fermi interlock 
+
+
+# usage
+
+ferminterlock f/interlock/plc_mod_ll f/interlock/plc_int_ll.01 f/interlock/plc_int_ll.02 srv-padres-srf:20000/srv-padres-srf/interlock/plc_int_ll.03  --sound-file-name /runtime/share/sounds/generalintlkpanel_beep.ogg
+
+# contatcts
+
+giacomo.strangolino@elettra....
+graziano.scalamera@elettra...
+
diff --git a/general.pro b/general.pro
new file mode 100644
index 0000000000000000000000000000000000000000..c33b9c8c32c1dfed6c4eae733ec90c7824fb9627
--- /dev/null
+++ b/general.pro
@@ -0,0 +1,51 @@
+include(/usr/local/qtango/include/qtango6/qtango.pri)
+
+CONFIG += debug
+QT += sql
+QT += multimedia
+
+DEFINES -= QT_NO_DEBUG_OUTPUT
+
+RESOURCES += general.qrc
+
+# DEFINES -= QT_NO_DEBUG_OUTPUT
+
+
+SOURCES += src/tlabelitem.cpp \
+           src/ttreewidget.cpp \
+           src/ttablewidget.cpp \
+           src/interlock.cpp \
+           src/main.cpp \
+           src/queryconfiguration.cpp \
+           src/mysqlmodel.cpp \
+    src/ttreeview.cpp \
+    src/Sound.cpp \
+    src/tabwidget.cpp \
+    src/treeitem.cpp
+
+HEADERS += src/tlabelitem.h \
+           src/ttreewidget.h \
+           src/ttablewidget.h \
+           src/interlock.h \
+           src/queryconfiguration.h \
+           src/mysqlmodel.h \
+    src/ttreeview.h \
+    src/Sound.h \
+    src/tabwidget.h \
+    src/treeitem.h
+
+
+FORMS    = src/interlock.ui src/queryconfiguration.ui
+
+TARGET   = bin/ferminterlock-gui
+
+sounds.files = sounds/generalintlkpanel_beep.ogg
+sounds.path = $${INSTALL_ROOT}/share/sounds
+
+INSTALLS += sounds
+
+OTHER_FILES += \
+    properties.txt
+    
+
+QMAKE_POST_LINK = $(STRIP) $(TARGET)
diff --git a/general.qrc b/general.qrc
new file mode 100644
index 0000000000000000000000000000000000000000..af52b0ef565fbf1114dab091726c5a9b9b0b5214
--- /dev/null
+++ b/general.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC><RCC version="1.0">
+    <qresource>
+        <file>icons/alarm.png</file>
+    </qresource>
+</RCC>
+
diff --git a/icons/alarm.png b/icons/alarm.png
new file mode 100644
index 0000000000000000000000000000000000000000..38859f8adc3df521c9a345fc859b048b0b18530f
Binary files /dev/null and b/icons/alarm.png differ
diff --git a/properties.txt b/properties.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/sounds/generalintlkpanel_bark.ogg b/sounds/generalintlkpanel_bark.ogg
new file mode 100644
index 0000000000000000000000000000000000000000..045d609cd69238da7e360a4667a889a02d8c7fe1
Binary files /dev/null and b/sounds/generalintlkpanel_bark.ogg differ
diff --git a/sounds/generalintlkpanel_beep.ogg b/sounds/generalintlkpanel_beep.ogg
new file mode 100644
index 0000000000000000000000000000000000000000..20de4c76c7cfd5f8e0aecbcc691f71a43f3b3c74
Binary files /dev/null and b/sounds/generalintlkpanel_beep.ogg differ
diff --git a/src/Sound.cpp b/src/Sound.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8b81201a6b53ad2d2798c27732433d187f53378c
--- /dev/null
+++ b/src/Sound.cpp
@@ -0,0 +1,67 @@
+#include "Sound.h"
+#include <QString>
+#include <QSound>
+#include <QtDebug>
+#include <macros.h>
+
+Sound::Sound(const QString& sound_file)
+{
+    m_init(sound_file);
+}
+
+Sound::Sound(QObject *parent, const QString &sound_file) : QObject(parent)
+{
+   m_init(sound_file);
+}
+
+void Sound::m_init(const QString& sound_file)
+{
+    mSoundEffect.setSource(QUrl::fromLocalFile(sound_file));
+    set_loop_delay(500);
+    m_loop_timer.setSingleShot(true);
+    m_loop_enabled = false;
+    connect(&mSoundEffect, SIGNAL(playingChanged()), this, SLOT(playingChanged()));
+    connect(&m_loop_timer, SIGNAL(timeout()), &mSoundEffect, SLOT(play()));
+}
+
+void Sound::play()
+{
+    if (m_loop_enabled) return;
+    mSoundEffect.play();
+}
+
+void Sound::loop()
+{
+    if(!m_loop_enabled){
+        m_loop_enabled = true;
+        mSoundEffect.play();
+    }
+}
+
+void Sound::playingChanged()
+{
+    if(m_loop_enabled && !mSoundEffect.isPlaying())
+        m_loop_timer.start();
+}
+
+void Sound::stop()
+{
+    m_loop_enabled = false;
+    m_loop_timer.stop();
+    mSoundEffect.stop();
+}
+
+void Sound::set_loop_delay(int delay)
+{
+    m_loop_timer.setInterval(delay);
+}
+
+int  Sound::get_loop_delay()
+{
+    return m_loop_timer.interval();
+}
+
+void Sound::timer_timeout() {
+    mSoundEffect.play();
+}
+
diff --git a/src/Sound.h b/src/Sound.h
new file mode 100644
index 0000000000000000000000000000000000000000..f143721422ceee1ed6c718c7688b073ae8602bf5
--- /dev/null
+++ b/src/Sound.h
@@ -0,0 +1,39 @@
+#ifndef SOUND_H
+#define SOUND_H
+
+#include <QString>
+#include <QObject>
+#include <QTimer>
+#include <QSoundEffect>
+#include <QFile>
+
+class Sound:public QObject
+{
+   Q_OBJECT
+public:
+   Sound(const QString& sound_file);
+   Sound(QObject *parent, const QString& sound_file);
+   void set_loop_delay(int);
+   int get_loop_delay();
+public slots:
+   void play();
+   void stop();
+   void loop();
+private slots:
+   void playingChanged();
+   void timer_timeout();
+private:
+   bool m_loop_enabled;
+   QTimer m_loop_timer;
+   QSoundEffect mSoundEffect;
+
+   void m_init(const QString &sound_file);
+};
+
+
+
+
+#endif
+
+
+
diff --git a/src/interlock.cpp b/src/interlock.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ff2a443cb9a1cb733741f374592682bc3ba3815e
--- /dev/null
+++ b/src/interlock.cpp
@@ -0,0 +1,393 @@
+/***************************************************************************
+ *   Copyright (C) 2007 by Vincenzo Forchi`,,,   *
+ *   vincenzo.forchi@elettra.trieste.it   *
+ *                                                                         *
+ *   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.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+
+#include "interlock.h"
+#include "Sound.h"
+#include <qtango.h>
+#include <device_factory.h>
+#include <QtSql>
+#include <QScrollBar>
+#include "mysqlmodel.h"
+#include <TLog>
+#include <QMessageBox>
+#include <elettracolors.h>
+
+Interlock::Interlock(QWidget *parent) : QWidget(parent)
+{
+    QStringList args = qApp->arguments();
+    if(args.size() < 5)
+    {
+        QMessageBox::information(this, "Usage",
+                                 QString("%1 f/interlock/plc_mod_ll f/interlock/plc_int_ll.01"
+                                         "\nf/interlock/plc_int_ll.02 srv-padres-srf:20000/srv-tango-srf/interlock/plc_int_ll.03").
+                                 arg(args.first()));
+        exit(EXIT_FAILURE);
+    }
+
+    if(args.contains("--sound-file-name") && args.size() > args.indexOf("--sound-file-name"))
+    {
+        Sound *sound = new Sound(this, args.at(args.indexOf("--sound-file-name") + 1));
+    }
+    else
+    {
+        printf("\e[1;35m - if you want to enable sounds for alarms, provide as second argument the name of the sound file\e[0m\n");
+        ui.pbTestSound->setHidden(true);
+        ui.line->setHidden(true);
+    }
+
+    modDeviceName = QApplication::arguments()[1];
+    vacPsDeviceName = QApplication::arguments()[2];
+
+    Config::instance()->setOverrideValuesAttributePropertyName("labels");
+
+    ui.setupUi(this);
+    setupDb();
+    configureUi();
+    createConnections();
+    QTimer::singleShot(50, this, SLOT(connectTango()));
+}
+
+void Interlock::setupDb()
+{
+    /* connect to db */
+    db = QSqlDatabase::addDatabase("QMYSQL");
+    db.setHostName("srv-db-srf-02");
+    db.setDatabaseName("intlkfermi");
+    db.setUserName("ifermi");
+    db.setPassword("ferm");
+    if (!db.open())
+        QMessageBox::critical(0, "Error", "Can't establish connection with db intlkboost on host log");
+
+    queryType = QueryConfiguration::LastDay;
+    modulatorModel = new MySqlModel();
+    psvacModel = new MySqlModel();
+    ui.treeLogs->setModel(modulatorModel);
+    ui.treeLogsPSVAC->setModel(psvacModel);
+
+    dbTimer = new QTimer(this);
+    connect(dbTimer, SIGNAL(timeout()), this, SLOT(readFromDb()));
+}
+
+void Interlock::createConnections()
+{
+    connect(ui.treeAlarms, SIGNAL(acknowledgeSelected()), this, SLOT(acknowledgeSelected()));
+    connect(ui.pushRefresh, SIGNAL(clicked()), this, SLOT(readFromDb()));
+    connect(ui.pushRefreshPSVacuum, SIGNAL(clicked()), this, SLOT(readFromDb()));
+    connect(ui.pushQueryConfiguration, SIGNAL(clicked()), this, SLOT(queryConfiguration()));
+    connect(ui.pushQueryConfigurationPSVAC, SIGNAL(clicked()), this, SLOT(queryConfiguration()));
+    connect(ui.comboAck, SIGNAL(currentIndexChanged(int)), this, SLOT(changeAckTarget(int)));
+    connect(ui.tabWidget, SIGNAL(currentChanged(int)), this, SLOT(tabChanged(int)));
+
+    /* 1 tab: mod filter */
+    connect(ui.pbClearModFilter, SIGNAL(clicked()), ui.leFilterMod, SLOT(clear()));
+    connect(ui.leFilterMod, SIGNAL(textChanged(QString)), ui.treeAlarms, SLOT(filter(QString)));
+
+    /* 2 tab: mod history */
+    connect(ui.pbClearModHist, SIGNAL(clicked()), ui.leFilterModHist, SLOT(clear()));
+    connect(ui.leFilterModHist, SIGNAL(textChanged(QString)), ui.treeLogs, SLOT(filter(QString)));
+
+    /* 3 tab: ps vac linac */
+    connect(ui.pbClearFilterVacLinac, SIGNAL(clicked()), ui.leFilterPsVacLinac, SLOT(clear()));
+    connect(ui.leFilterPsVacLinac, SIGNAL(textChanged(QString)), ui.treeAlarmsVPS, SLOT(filter(QString)));
+
+    /* 4 tab: ps vacuum uh */
+    connect(ui.pbClearFilterPSVacUH, SIGNAL(clicked()), ui.leFilterPsVacUH, SLOT(clear()));
+    connect(ui.leFilterPsVacUH, SIGNAL(textChanged(QString)), ui.treeAlarmsVUH, SLOT(filter(QString)));
+
+    /* 5 tab ps vacuum padres */
+    connect(ui.pbClearFilterPsVacPadres, SIGNAL(clicked()), ui.leFilterPsVacPadres, SLOT(clear()));
+    connect(ui.leFilterPsVacPadres, SIGNAL(textChanged(QString)), ui.treeAlarmsPadres, SLOT(filter(QString)));
+
+    /* 6. tab ps and vacuum history */
+    connect(ui.pbClearFilterPsVacHistory, SIGNAL(clicked()), ui.leFilterPsVacHistory, SLOT(clear()));
+    connect(ui.leFilterPsVacHistory, SIGNAL(textChanged(QString)), ui.treeLogsPSVAC, SLOT(filter(QString)));
+
+    /* sound */
+    Sound *sound = findChild<Sound *>();
+    if(sound)
+    {
+        connect(ui.treeAlarms,          SIGNAL(newAlarmArrived()), sound, SLOT(play()));
+        connect(ui.treeAlarmsPadres,    SIGNAL(newAlarmArrived()), sound, SLOT(play()));
+        connect(ui.treeAlarmsVPS,       SIGNAL(newAlarmArrived()), sound, SLOT(play()));
+        connect(ui.treeAlarmsVUH,       SIGNAL(newAlarmArrived()), sound, SLOT(play()));
+        connect(ui.pbTestSound, SIGNAL(clicked()), sound, SLOT(play()));
+    }
+    connect(ui.treeAlarms,          SIGNAL(newAlarmArrived()), this, SLOT(newAlarmArrived()));
+    connect(ui.treeAlarmsPadres,    SIGNAL(newAlarmArrived()), this, SLOT(newAlarmArrived()));
+    connect(ui.treeAlarmsVPS,       SIGNAL(newAlarmArrived()), this, SLOT(newAlarmArrived()));
+    connect(ui.treeAlarmsVUH,       SIGNAL(newAlarmArrived()), this, SLOT(newAlarmArrived()));
+}
+
+void Interlock::configureUi()
+{
+    QStringList headers;
+    headers << "Date Time" << "Name" << "Description";
+    foreach(TTreeWidget *ttw, findChildren<TTreeWidget *>(QRegExp("treeAlarms.*")))
+        ttw->setHeaderLabels(headers);
+    QStringList mods;
+    for(int i = 0; i <= 15; i++)
+        mods << QString("mod%1").arg(i, 2, 10, QChar('0'));
+    mods.push_front("General");
+    ui.comboAck->insertItems(0, mods);
+}
+
+Interlock::~Interlock()
+{
+}
+
+void Interlock::connectTango()
+{
+    /* mod */
+    ui.treeAlarms->setPeriod(1000);
+    ui.treeAlarms->setSource(modDeviceName + "/Db_alarm");
+    ui.tAck->setTargets(modDeviceName + QString("->Acknowledge(%1)").arg(ui.comboAck->itemData(0).toInt()));
+    /* vacuum and power supply */
+    ui.treeAlarmsVPS->setPeriod(1000);
+    ui.treeAlarmsVPS->setSource(vacPsDeviceName + "/Db_alarm");
+    /* Ps and vacuum UH */
+    ui.treeAlarmsVUH->setSource("$3/Db_alarm");
+    /* padres */
+    ui.treeAlarmsPadres->setSource("$4/Db_alarm");
+}
+
+void Interlock::changeAckTarget(int idx)
+{
+    /* item list (idx == 0) starts with "general".
+   * Then modulators follow, from mod00 (idx == 1) to mod12.
+   * So the correct argin is obtained subtracting 1 to the combo box index.
+   */
+    int argin = idx - 1;
+    ui.tAck->setTargets(modDeviceName + QString("->Acknowledge(%1)").arg(argin));
+}
+
+void Interlock::newAlarmArrived()
+{
+    /* get sender */
+    QString oName = sender()->objectName();
+    int tabIndex = -1;
+    if(oName == "treeAlarms")
+        tabIndex = 0;
+    else if(oName == "treeAlarmsVPS")
+        tabIndex = 2;
+    else if(oName == "treeAlarmsVUH")
+        tabIndex = 3;
+    else if(oName == "treeAlarmsPadres")
+        tabIndex = 4;
+
+    ui.tabWidget->setTabIcon(tabIndex, QIcon(":icons/alarm.png"));
+}
+
+/* icon removal is made inside custom TabBar.
+ * See tabwidget.h
+ */
+void Interlock::tabChanged(int idx)
+{
+    if(idx == ModHistory || idx == PsVacHistory)
+    {
+        dbTimer->start(10000);
+        this->readFromDb();
+    }
+    else
+    {
+        dbTimer->stop();
+    }
+}
+
+void Interlock::acknowledgeSelected()
+{
+    /// //////////////////
+    printf("\e[1;33m - da implementare - \e[0m\n");
+    return;
+    /// //////////////////
+
+    QVector<double> v_attr(ui.treeAlarms->dataSize(), 0);
+    //	QVector<long> v_comm(ui.treeAlarms->dataSize(), 0);
+    foreach (QTreeWidgetItem *it, ui.treeAlarms->selectedItems())
+    {
+        //qDebug() << it->text(3);
+        v_attr[it->text(3).toInt()] = 1;
+        //		v_comm << it->text(3).toLong();
+    }
+    try {
+        DeviceAttribute attr;
+        attr.set_name("Db_alarm");
+        vector<double> dati = v_attr.toStdVector();
+        attr << dati;
+        Tango::DeviceProxy *dpr = DeviceFactory::instance()->getDeviceProxy(modDeviceName);
+        if(dpr)
+            dpr->write_attribute(attr);
+    }
+    catch (DevFailed &e)
+    {
+        TLog log(e);
+        time_t now = time(NULL);
+        QPair<time_t, DevErrorList> err(now, e.errors);
+        TUtil::instance()->addLog(log.toTimeErrlistPair(), log.formatMessage());
+        QMessageBox::critical(0, "Error", log.formatMessage());
+    }
+    ui.treeAlarms->clearSelection();
+}
+
+void Interlock::queryConfiguration()
+{
+    QueryConfiguration win;
+    win.setQueryType(queryType);
+    if (queryType == QueryConfiguration::Interval)
+    {
+        win.setStartDateTime(begin);
+        win.setStopDateTime(end);
+    }
+
+    if (win.exec() == QDialog::Accepted)
+    {
+        queryType = win.queryType();
+        begin = win.startDateTime();
+        end = win.stopDateTime();
+        readFromDb();
+    }
+}
+
+void Interlock::readFromDb()
+{
+    MySqlModel *model = NULL;
+    QString dbnam;
+    bool modulator = true;
+    if(ui.tabWidget->currentIndex() == ModHistory)
+    {
+        model = modulatorModel;
+        dbnam = "real_time_";
+    }
+    else if(ui.tabWidget->currentIndex() == PsVacHistory)
+    {
+        modulator = false;
+        model = psvacModel;
+        dbnam = "vac_mag_";
+    }
+    else
+        return;
+
+    if (!db.isOpen())
+    {
+        if (!db.open())
+        {
+            QMessageBox::critical(0, "Error", "Can't establish connection with db FastInterlock on host log");
+            return;
+        }
+    }
+    QDateTime adesso = QDateTime::currentDateTime();
+    int year = adesso.date().year();
+
+    QString query, endquery;
+    if(modulator)
+    {
+        query = "SELECT FROM_UNIXTIME(" + dbnam + "%1.timestamp) AS 'Date Time', mod_description.name AS 'Name', "
+                + dbnam + "%1.event AS 'Event', "
+                "mod_description.comment AS Description, mod_description.modulator AS 'Modulator' FROM "
+                + dbnam + "%1 left join mod_description on (" + dbnam +
+                "%1.id_mod_description=mod_description.id_mod_description) WHERE timestamp>%2 "
+                ;
+        endquery = " ORDER BY timestamp desc";
+    }
+    else
+    {
+        query = "SELECT FROM_UNIXTIME(" + dbnam + "%1.timestamp) AS 'Date Time', vac_mag_desc.name AS 'Name', "
+                + dbnam + "%1.event AS 'Event', "
+                "vac_mag_desc.comment AS Description, vac_mag_desc.plc  AS 'PLC' FROM "
+                + dbnam + "%1 left join vac_mag_desc on (" + dbnam +
+                "%1.id_vac_mag_desc=vac_mag_desc.id_vac_mag_desc) WHERE timestamp>%2 "
+                ;
+        endquery = " ORDER BY timestamp desc";
+    }
+    unsigned int inizioRicerca;
+    switch (queryType)
+    {
+    case QueryConfiguration::LastDay:
+        inizioRicerca = adesso.addDays(-1).toTime_t();
+        year = adesso.date().year();
+        query = QString(query).arg(year).arg(inizioRicerca) + endquery;
+        break;
+    case QueryConfiguration::LastWeek:
+        inizioRicerca = adesso.addDays(-7).toTime_t();
+        year = adesso.date().year();
+        query = QString(query).arg(year).arg(inizioRicerca) + endquery;
+        break;
+    case QueryConfiguration::LastMonth:
+        inizioRicerca = adesso.addMonths(-1).toTime_t();
+        year = adesso.date().year();
+        query = QString(query).arg(year).arg(inizioRicerca) + endquery;
+        break;
+    case QueryConfiguration::Interval:
+        year = end.date().year();
+        query = QString(query).arg(year).arg(begin.toTime_t());
+        query += QString(" AND timestamp<%1").arg(end.toTime_t()) + endquery;
+        break;
+    default:
+        break;
+    }
+    model->setQuery(query);
+
+    /* must apply filter if set */
+    if(modulator)
+        ui.treeLogs->updateFilter();
+    else
+        ui.treeLogsPSVAC->updateFilter();
+
+    QSqlError error = model->lastError();
+    if (error.type() != QSqlError::NoError)
+    {
+        QMessageBox::critical(0, "Database Error", QString("Error reading from Db:\n") + error.text() + "\nreconnecting");
+        db.close();
+        if (!db.open())
+            QMessageBox::critical(0, "Error", "Can't establish connection with db FastInterlock on host log");
+    }
+}
+
+void Interlock::on_tabWidget_currentChanged(int idx)
+{
+    if (idx == 3)
+    {
+        readFromDb();
+        dbTimer->start();
+    }
+    else
+        dbTimer->stop();
+}
+
+void Interlock::modSelected(bool en)
+{
+    //   ui.cbStatSelection->setEnabled(en);
+    //   changeStatView(ui.cbStatSelection->currentIndex()); /* will also update descriptions */
+}
+
+void Interlock::changeStatView(int index)
+{
+    QString attname;
+    QString devName = modDeviceName;
+    /* if Select is checked, then set Stat_mod_NUMBER, otherwise Stat_system */
+    //   if(ui.rbSelectMod->isChecked())
+    //    attname = QString("Stat_mod_%1").arg(index);
+    //   else
+    attname = "Stat_system";
+
+    //   QString src = devName + "/" + attname;
+    //   ui.tableStates->setSource(src);
+}
+
diff --git a/src/interlock.h b/src/interlock.h
new file mode 100644
index 0000000000000000000000000000000000000000..e8e283b27810483e98e6a562a0beef8b4990f56a
--- /dev/null
+++ b/src/interlock.h
@@ -0,0 +1,78 @@
+/***************************************************************************
+ *   Copyright (C) 2007 by Vincenzo Forchi`,,,   *
+ *   vincenzo.forchi@elettra.trieste.it   *
+ *                                                                         *
+ *   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.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+
+#ifndef interlock_H
+#define interlock_H
+
+#include "ui_interlock.h"
+#include "queryconfiguration.h"
+#include <QString>
+#include <QSqlDatabase>
+
+//class QGraphicsScene;
+class MySqlModel;
+
+class Interlock: public QWidget
+{
+    Q_OBJECT
+
+public:
+
+    enum Tabs { Mod, ModHistory, PsVacLinac, PsVacUH, PsVacPadres, PsVacHistory };
+
+    Interlock(QWidget * =NULL);
+    ~Interlock();
+
+//     QStringList getProperty(string, string);
+
+protected slots:
+    void connectTango();
+    void acknowledgeSelected();
+    void queryConfiguration();
+    void readFromDb();
+    void on_tabWidget_currentChanged(int);
+	void changeStatView(int index);
+	void modSelected(bool en);
+	void changeAckTarget(int);
+    void tabChanged(int idx);
+    void newAlarmArrived();
+
+private:
+    Ui::Interlock ui;
+    QString modDeviceName, vacPsDeviceName;
+
+    QSqlDatabase db;
+    MySqlModel  *modulatorModel, *psvacModel;
+
+    QueryConfiguration::QueryType       queryType;
+    QDateTime   begin, end;
+    QTimer      *dbTimer;
+	
+	void setupDb();
+	void configureUi();
+	void createConnections();
+
+//    QGraphicsScene *boosterScene;
+
+};
+
+
+#endif
diff --git a/src/interlock.ui b/src/interlock.ui
new file mode 100644
index 0000000000000000000000000000000000000000..daffa12150ad3356e7bb64737620962c63b74038
--- /dev/null
+++ b/src/interlock.ui
@@ -0,0 +1,553 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Interlock</class>
+ <widget class="QWidget" name="Interlock">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>898</width>
+    <height>530</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>General Fermi Interlock</string>
+  </property>
+  <layout class="QVBoxLayout">
+   <property name="spacing">
+    <number>6</number>
+   </property>
+   <property name="margin">
+    <number>9</number>
+   </property>
+   <item>
+    <widget class="TabWidget" name="tabWidget">
+     <property name="currentIndex">
+      <number>0</number>
+     </property>
+     <widget class="QWidget" name="tabAlarms">
+      <attribute name="title">
+       <string>Modulator</string>
+      </attribute>
+      <layout class="QGridLayout">
+       <property name="margin">
+        <number>9</number>
+       </property>
+       <property name="spacing">
+        <number>6</number>
+       </property>
+       <item row="1" column="8">
+        <widget class="QPushButton" name="pbTestSound">
+         <property name="text">
+          <string>Test Sound</string>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="1">
+        <widget class="QLineEdit" name="leFilterMod">
+         <property name="toolTip">
+          <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Filter&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Start typing text to filter items on the second column of the view.&lt;/p&gt;&lt;p&gt;The search is &lt;span style=&quot; font-style:italic;&quot;&gt;case insensitive&lt;/span&gt;.&lt;/p&gt;&lt;p&gt;Click on the &lt;span style=&quot; font-style:italic;&quot;&gt;Clear&lt;/span&gt; button to clear the text on the box.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="3">
+        <spacer>
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>40</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item row="1" column="6">
+        <widget class="TPushButton" name="tAck">
+         <property name="enabled">
+          <bool>true</bool>
+         </property>
+         <property name="text">
+          <string>Ack</string>
+         </property>
+        </widget>
+       </item>
+       <item row="0" column="0" colspan="9">
+        <widget class="TTreeWidget" name="treeAlarms">
+         <property name="enabled">
+          <bool>false</bool>
+         </property>
+         <property name="alternatingRowColors">
+          <bool>true</bool>
+         </property>
+         <property name="selectionMode">
+          <enum>QAbstractItemView::SingleSelection</enum>
+         </property>
+         <property name="rootIsDecorated">
+          <bool>false</bool>
+         </property>
+         <column>
+          <property name="text">
+           <string notr="true">1</string>
+          </property>
+         </column>
+        </widget>
+       </item>
+       <item row="1" column="5">
+        <widget class="TComboBox" name="comboAck">
+         <property name="enabled">
+          <bool>true</bool>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="2">
+        <widget class="QPushButton" name="pbClearModFilter">
+         <property name="text">
+          <string>Clear</string>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="0">
+        <widget class="QLabel" name="label">
+         <property name="text">
+          <string>Filter by label:</string>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="7">
+        <widget class="Line" name="line">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="tab">
+      <attribute name="title">
+       <string>Modulator History</string>
+      </attribute>
+      <layout class="QVBoxLayout">
+       <property name="spacing">
+        <number>6</number>
+       </property>
+       <property name="margin">
+        <number>9</number>
+       </property>
+       <item>
+        <widget class="TTreeView" name="treeLogs">
+         <property name="alternatingRowColors">
+          <bool>true</bool>
+         </property>
+         <property name="selectionMode">
+          <enum>QAbstractItemView::NoSelection</enum>
+         </property>
+         <property name="rootIsDecorated">
+          <bool>false</bool>
+         </property>
+         <property name="itemsExpandable">
+          <bool>false</bool>
+         </property>
+         <property name="allColumnsShowFocus">
+          <bool>true</bool>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <layout class="QHBoxLayout">
+         <property name="spacing">
+          <number>6</number>
+         </property>
+         <property name="margin">
+          <number>0</number>
+         </property>
+         <item>
+          <widget class="QPushButton" name="pushRefresh">
+           <property name="text">
+            <string>Refresh</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QLabel" name="label_2">
+           <property name="text">
+            <string>Filter by name:</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QLineEdit" name="leFilterModHist">
+           <property name="toolTip">
+            <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Filter&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Start typing text to filter items on the second column of the view.&lt;/p&gt;&lt;p&gt;The search is &lt;span style=&quot; font-style:italic;&quot;&gt;case insensitive&lt;/span&gt;.&lt;/p&gt;&lt;p&gt;Click on the &lt;span style=&quot; font-style:italic;&quot;&gt;Clear&lt;/span&gt; button to clear the text on the box.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QPushButton" name="pbClearModHist">
+           <property name="text">
+            <string>Clear</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <spacer>
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>40</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+         <item>
+          <widget class="QPushButton" name="pushQueryConfiguration">
+           <property name="text">
+            <string>Log Period</string>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="tab_2">
+      <attribute name="title">
+       <string>PS and Vacuum Linac</string>
+      </attribute>
+      <layout class="QGridLayout" name="gridLayout_2">
+       <item row="1" column="4">
+        <spacer name="horizontalSpacer_2">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>40</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item row="1" column="2">
+        <widget class="QLineEdit" name="leFilterPsVacLinac">
+         <property name="toolTip">
+          <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Filter&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Start typing text to filter items on the second column of the view.&lt;/p&gt;&lt;p&gt;The search is &lt;span style=&quot; font-style:italic;&quot;&gt;case insensitive&lt;/span&gt;.&lt;/p&gt;&lt;p&gt;Click on the &lt;span style=&quot; font-style:italic;&quot;&gt;Clear&lt;/span&gt; button to clear the text on the box.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="0">
+        <widget class="QLabel" name="label_3">
+         <property name="text">
+          <string>Filter by label:</string>
+         </property>
+        </widget>
+       </item>
+       <item row="0" column="0" colspan="7">
+        <widget class="TTreeWidget" name="treeAlarmsVPS">
+         <property name="enabled">
+          <bool>false</bool>
+         </property>
+         <property name="alternatingRowColors">
+          <bool>true</bool>
+         </property>
+         <property name="selectionMode">
+          <enum>QAbstractItemView::MultiSelection</enum>
+         </property>
+         <property name="rootIsDecorated">
+          <bool>false</bool>
+         </property>
+         <column>
+          <property name="text">
+           <string notr="true">1</string>
+          </property>
+         </column>
+        </widget>
+       </item>
+       <item row="1" column="6">
+        <widget class="TPushButton" name="tAckPSV">
+         <property name="enabled">
+          <bool>false</bool>
+         </property>
+         <property name="text">
+          <string>Ack</string>
+         </property>
+         <property name="targets">
+          <string>$2-&gt;Acknowledge(0);;</string>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="3">
+        <widget class="QPushButton" name="pbClearFilterVacLinac">
+         <property name="text">
+          <string>Clear</string>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="tab_3">
+      <attribute name="title">
+       <string>PS &amp;and Vacuum UH</string>
+      </attribute>
+      <layout class="QGridLayout" name="gridLayout_3">
+       <item row="1" column="6">
+        <widget class="TPushButton" name="tAckPSUH">
+         <property name="enabled">
+          <bool>false</bool>
+         </property>
+         <property name="text">
+          <string>Ack</string>
+         </property>
+         <property name="targets">
+          <string>$3-&gt;Acknowledge(0);;;</string>
+         </property>
+        </widget>
+       </item>
+       <item row="0" column="0" colspan="7">
+        <widget class="TTreeWidget" name="treeAlarmsVUH">
+         <property name="enabled">
+          <bool>false</bool>
+         </property>
+         <property name="alternatingRowColors">
+          <bool>true</bool>
+         </property>
+         <property name="selectionMode">
+          <enum>QAbstractItemView::MultiSelection</enum>
+         </property>
+         <property name="rootIsDecorated">
+          <bool>false</bool>
+         </property>
+         <column>
+          <property name="text">
+           <string notr="true">1</string>
+          </property>
+         </column>
+        </widget>
+       </item>
+       <item row="1" column="5">
+        <spacer name="horizontalSpacer">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>40</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item row="1" column="4">
+        <widget class="QPushButton" name="pbClearFilterPSVacUH">
+         <property name="text">
+          <string>Clear</string>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="2">
+        <widget class="QLabel" name="label_4">
+         <property name="text">
+          <string>Filter by label:</string>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="3">
+        <widget class="QLineEdit" name="leFilterPsVacUH">
+         <property name="toolTip">
+          <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Filter&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Start typing text to filter items on the second column of the view.&lt;/p&gt;&lt;p&gt;The search is &lt;span style=&quot; font-style:italic;&quot;&gt;case insensitive&lt;/span&gt;.&lt;/p&gt;&lt;p&gt;Click on the &lt;span style=&quot; font-style:italic;&quot;&gt;Clear&lt;/span&gt; button to clear the text on the box.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="tab_4">
+      <attribute name="title">
+       <string>PS and Vacuum Padres</string>
+      </attribute>
+      <layout class="QGridLayout" name="gridLayout">
+       <item row="2" column="4">
+        <spacer name="horizontalSpacer_3">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>40</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item row="2" column="5">
+        <widget class="TPushButton" name="tpbAckPSVPadres">
+         <property name="text">
+          <string>Ack</string>
+         </property>
+         <property name="targets">
+          <string>$4-&gt;Acknowledge(0);;</string>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="2">
+        <widget class="QPushButton" name="pbClearFilterPsVacPadres">
+         <property name="text">
+          <string>Clear</string>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="1">
+        <widget class="QLineEdit" name="leFilterPsVacPadres">
+         <property name="toolTip">
+          <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Filter&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Start typing text to filter items on the second column of the view.&lt;/p&gt;&lt;p&gt;The search is &lt;span style=&quot; font-style:italic;&quot;&gt;case insensitive&lt;/span&gt;.&lt;/p&gt;&lt;p&gt;Click on the &lt;span style=&quot; font-style:italic;&quot;&gt;Clear&lt;/span&gt; button to clear the text on the box.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="0">
+        <widget class="QLabel" name="label_5">
+         <property name="text">
+          <string>Filter by label:</string>
+         </property>
+        </widget>
+       </item>
+       <item row="0" column="0" colspan="6">
+        <widget class="TTreeWidget" name="treeAlarmsPadres">
+         <property name="enabled">
+          <bool>false</bool>
+         </property>
+         <property name="alternatingRowColors">
+          <bool>true</bool>
+         </property>
+         <property name="selectionMode">
+          <enum>QAbstractItemView::MultiSelection</enum>
+         </property>
+         <property name="rootIsDecorated">
+          <bool>false</bool>
+         </property>
+         <column>
+          <property name="text">
+           <string notr="true">1</string>
+          </property>
+         </column>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="tab_5">
+      <attribute name="title">
+       <string>PS and Vacuum History</string>
+      </attribute>
+      <layout class="QGridLayout" name="gridLayout_4">
+       <item row="0" column="0" colspan="6">
+        <widget class="TTreeView" name="treeLogsPSVAC">
+         <property name="alternatingRowColors">
+          <bool>true</bool>
+         </property>
+         <property name="selectionMode">
+          <enum>QAbstractItemView::NoSelection</enum>
+         </property>
+         <property name="rootIsDecorated">
+          <bool>false</bool>
+         </property>
+         <property name="itemsExpandable">
+          <bool>false</bool>
+         </property>
+         <property name="allColumnsShowFocus">
+          <bool>true</bool>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="0">
+        <widget class="QPushButton" name="pushRefreshPSVacuum">
+         <property name="text">
+          <string>Refresh</string>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="1">
+        <widget class="QLabel" name="label_6">
+         <property name="text">
+          <string>Filter by name:</string>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="2">
+        <widget class="QLineEdit" name="leFilterPsVacHistory">
+         <property name="toolTip">
+          <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Filter&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Start typing text to filter items on the second column of the view.&lt;/p&gt;&lt;p&gt;The search is &lt;span style=&quot; font-style:italic;&quot;&gt;case insensitive&lt;/span&gt;.&lt;/p&gt;&lt;p&gt;Click on the &lt;span style=&quot; font-style:italic;&quot;&gt;Clear&lt;/span&gt; button to clear the text on the box.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="3">
+        <widget class="QPushButton" name="pbClearFilterPsVacHistory">
+         <property name="text">
+          <string>Clear</string>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="4">
+        <spacer name="horizontalSpacer_4">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>245</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item row="1" column="5">
+        <widget class="QPushButton" name="pushQueryConfigurationPSVAC">
+         <property name="text">
+          <string>Log Period</string>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
+ <customwidgets>
+  <customwidget>
+   <class>TComboBox</class>
+   <extends>QComboBox</extends>
+   <header>TComboBox</header>
+  </customwidget>
+  <customwidget>
+   <class>TPushButton</class>
+   <extends>QPushButton</extends>
+   <header>TPushButton</header>
+  </customwidget>
+  <customwidget>
+   <class>TTreeWidget</class>
+   <extends>QTreeWidget</extends>
+   <header>ttreewidget.h</header>
+  </customwidget>
+  <customwidget>
+   <class>TTreeView</class>
+   <extends>QTreeView</extends>
+   <header>ttreeview.h</header>
+  </customwidget>
+  <customwidget>
+   <class>TabWidget</class>
+   <extends>QTabWidget</extends>
+   <header>tabwidget.h</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
+ <tabstops>
+  <tabstop>treeAlarms</tabstop>
+  <tabstop>tAck</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..041d61ad313f2a0c2b2439deb4a05ef500fda805
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,58 @@
+/***************************************************************************
+ *   Copyright (C) 2007 by Vincenzo Forchi`,,,   *
+ *   vincenzo.forchi@elettra.trieste.it   *
+ *                                                                         *
+ *   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.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+
+#include <TApplication>
+#include "interlock.h"
+#include <X11/Xlib.h>
+#include <QX11Info>
+#include <tutil.h>
+#include <elettracolors.h>
+
+#define CVSVERSION "$Name:  $"
+
+/* uncomment to set application color */
+//#include <elettracolors.h>
+
+int main( int argc, char ** argv ) {
+
+    TApplication a( argc, argv );
+    /* uncomment to set application color */
+    a.setPalette(EPalette("fermi"));
+    QString version(CVSVERSION);
+    a.setApplicationVersion(version);
+    a.setApplicationName("FermiInterlock");
+    a.setProperty("author", "Giacomo");
+    a.setProperty("mail", "giacomo.strangolino@elettra.trieste.it");
+    a.setProperty("phone", "375-8073");
+    a.setProperty("office", "T2PT025");
+    a.setProperty("hwReferent", "Graziano");
+    
+    Interlock mw;
+    mw.setWindowTitle("Fermi Interlock");
+    mw.show();
+
+    /* register to window manager */
+    Display *disp = QX11Info::display();
+    Window root_win = (Window) mw.winId();
+    XSetCommand(disp, root_win, argv, argc);
+	
+    return a.exec();
+}
diff --git a/src/mysqlmodel.cpp b/src/mysqlmodel.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fefdbb655b6b446898db4490b3686897a479b03f
--- /dev/null
+++ b/src/mysqlmodel.cpp
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2004-2006 Trolltech ASA. All rights reserved.
+**
+** This file is part of the example classes of the Qt Toolkit.
+**
+** This file may be used under the terms of the GNU General Public
+** License version 2.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of
+** this file.  Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+** http://www.trolltech.com/products/qt/opensource.html
+**
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://www.trolltech.com/products/qt/licensing.html or contact the
+** sales department at sales@trolltech.com.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#include <QtGui>
+
+#include "mysqlmodel.h"
+
+MySqlModel::MySqlModel(QObject *parent)  : QSqlQueryModel(parent)
+{
+}
+
+QVariant MySqlModel::data(const QModelIndex &index, int role) const
+{
+    QVariant value = QSqlQueryModel::data(index, role);
+    if (value.isValid() && role == Qt::DisplayRole) {
+        if (index.column() == 0)
+        {
+            QString d = value.toString();
+            d.replace('T', ' ');
+            return d;
+        }
+    }
+    return value;
+}
diff --git a/src/mysqlmodel.h b/src/mysqlmodel.h
new file mode 100644
index 0000000000000000000000000000000000000000..339749c661b89a3709c63ed25c8acde2fc5f84d1
--- /dev/null
+++ b/src/mysqlmodel.h
@@ -0,0 +1,39 @@
+/****************************************************************************
+**
+** Copyright (C) 2004-2006 Trolltech ASA. All rights reserved.
+**
+** This file is part of the example classes of the Qt Toolkit.
+**
+** This file may be used under the terms of the GNU General Public
+** License version 2.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of
+** this file.  Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+** http://www.trolltech.com/products/qt/opensource.html
+**
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://www.trolltech.com/products/qt/licensing.html or contact the
+** sales department at sales@trolltech.com.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#ifndef MYSQLMODEL_H
+#define MYSQLMODEL_H
+
+#include <QSqlQueryModel>
+
+class MySqlModel : public QSqlQueryModel
+{
+    Q_OBJECT
+
+public:
+    MySqlModel(QObject *parent = 0);
+
+    QVariant data(const QModelIndex &item, int role) const;
+};
+
+#endif
diff --git a/src/queryconfiguration.cpp b/src/queryconfiguration.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6f23ae0285c4c0b767e3971dee5a4cb107ddb253
--- /dev/null
+++ b/src/queryconfiguration.cpp
@@ -0,0 +1,106 @@
+/***************************************************************************
+ *   Copyright (C) 2006 by Vincenzo Forchi`,,,   *
+ *   tus@ken   *
+ *                                                                         *
+ *   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.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+
+#include "queryconfiguration.h"
+
+#include <QDateTime>
+#include <QMessageBox>
+
+#include <QtDebug>
+
+QueryConfiguration::QueryConfiguration(QDialog *parent) : QDialog(parent)
+{
+	ui.setupUi(this);
+	ui.dateStart->setDate(QDate::currentDate());
+	ui.dateStop->setDate(QDate::currentDate());
+	ui.timeStart->setTime(QTime::currentTime());
+	ui.timeStop->setTime(QTime::currentTime());
+	connect(ui.comboPeriod, SIGNAL(currentIndexChanged(int)), this, SLOT(enableFrame(int)));
+	connect((QObject*) ui.buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(ok()));
+}
+
+QueryConfiguration::~QueryConfiguration()
+{
+}
+
+void QueryConfiguration::enableFrame(int index)
+{
+	if (index == 3)
+		ui.frame->setEnabled(true);
+	else
+		ui.frame->setEnabled(false);
+}
+
+void QueryConfiguration::ok()
+{
+	if (ui.comboPeriod->currentIndex() == 3)
+	{
+		QDateTime begin, end;
+		begin.setDate(ui.dateStart->date());
+		begin.setTime(ui.timeStart->time());
+		end.setDate(ui.dateStop->date());
+		end.setTime(ui.timeStop->time());
+		if (begin >= end)
+			QMessageBox::warning(0, "Warning", "Invalid interval: check starting and ending dates");
+		else
+			accept();
+	}
+	else
+		accept();
+}
+
+void QueryConfiguration::setQueryType(QueryType qt)
+{
+	ui.comboPeriod->setCurrentIndex((int) qt);
+}
+
+QueryConfiguration::QueryType QueryConfiguration::queryType()
+{
+	return (QueryType) ui.comboPeriod->currentIndex();
+}
+
+void QueryConfiguration::setStartDateTime(QDateTime dt)
+{
+	ui.dateStart->setDate(dt.date());
+	ui.timeStart->setTime(dt.time());
+}
+
+void QueryConfiguration::setStopDateTime(QDateTime dt)
+{
+	ui.dateStop->setDate(dt.date());
+	ui.timeStop->setTime(dt.time());
+}
+
+QDateTime QueryConfiguration::startDateTime()
+{
+	QDateTime dt;
+	dt.setDate(ui.dateStart->date());
+	dt.setTime(ui.timeStart->time());
+	return dt;
+}
+
+QDateTime QueryConfiguration::stopDateTime()
+{
+	QDateTime dt;
+	dt.setDate(ui.dateStop->date());
+	dt.setTime(ui.timeStop->time());
+	return dt;
+}
diff --git a/src/queryconfiguration.h b/src/queryconfiguration.h
new file mode 100644
index 0000000000000000000000000000000000000000..40cf385f9e8e3808c0710b544b88828f5e8cec11
--- /dev/null
+++ b/src/queryconfiguration.h
@@ -0,0 +1,61 @@
+/***************************************************************************
+ *   Copyright (C) 2006 by Vincenzo Forchi`,,,   *
+ *   tus@ken   *
+ *                                                                         *
+ *   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.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+
+#ifndef QUERYCONFIGURATION_H
+#define QUERYCONFIGURATION_H
+
+#include "ui_queryconfiguration.h"
+
+class QueryConfiguration : public QDialog
+{
+    Q_OBJECT
+
+public:
+    QueryConfiguration(QDialog * =NULL);
+    ~QueryConfiguration();
+
+    enum QueryType
+    {
+	LastDay,
+	LastWeek,
+	LastMonth,
+	Interval,
+	All
+    };
+
+    void 	setQueryType(QueryType);
+    QueryType	queryType();
+
+    void	setStartDateTime(QDateTime);
+    void	setStopDateTime(QDateTime);
+    QDateTime	startDateTime();
+    QDateTime	stopDateTime();
+
+protected slots:
+    void enableFrame(int);
+    void ok();
+
+private:
+    Ui::QueryConfiguration ui;
+};
+
+
+#endif
diff --git a/src/queryconfiguration.ui b/src/queryconfiguration.ui
new file mode 100644
index 0000000000000000000000000000000000000000..e6be30920911e0a84dc765f402532fe3beab5584
--- /dev/null
+++ b/src/queryconfiguration.ui
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>QueryConfiguration</class>
+ <widget class="QDialog" name="QueryConfiguration">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>380</width>
+    <height>194</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Display</string>
+  </property>
+  <layout class="QGridLayout">
+   <property name="margin">
+    <number>9</number>
+   </property>
+   <property name="spacing">
+    <number>6</number>
+   </property>
+   <item row="1" column="0">
+    <widget class="QFrame" name="frame">
+     <property name="enabled">
+      <bool>false</bool>
+     </property>
+     <property name="minimumSize">
+      <size>
+       <width>220</width>
+       <height>60</height>
+      </size>
+     </property>
+     <property name="frameShape">
+      <enum>QFrame::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Raised</enum>
+     </property>
+     <layout class="QGridLayout">
+      <property name="margin">
+       <number>9</number>
+      </property>
+      <property name="spacing">
+       <number>6</number>
+      </property>
+      <item row="1" column="1">
+       <widget class="QDateEdit" name="dateStop">
+        <property name="displayFormat">
+         <string>dd MMM yyyy</string>
+        </property>
+        <property name="calendarPopup">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="1">
+       <widget class="QDateEdit" name="dateStart">
+        <property name="minimumSize">
+         <size>
+          <width>80</width>
+          <height>0</height>
+         </size>
+        </property>
+        <property name="displayFormat">
+         <string>dd MMM yyyy</string>
+        </property>
+        <property name="calendarPopup">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="2">
+       <widget class="QTimeEdit" name="timeStop">
+        <property name="displayFormat">
+         <string>h:mm</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="2">
+       <widget class="QTimeEdit" name="timeStart">
+        <property name="displayFormat">
+         <string>h:mm </string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="0">
+       <widget class="QLabel" name="label">
+        <property name="text">
+         <string>From:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="0">
+       <widget class="QLabel" name="label_2">
+        <property name="text">
+         <string>To:</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item row="2" column="0">
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="0">
+    <widget class="QComboBox" name="comboPeriod">
+     <item>
+      <property name="text">
+       <string>Last Day</string>
+      </property>
+     </item>
+     <item>
+      <property name="text">
+       <string>Last Week</string>
+      </property>
+     </item>
+     <item>
+      <property name="text">
+       <string>Last Month</string>
+      </property>
+     </item>
+     <item>
+      <property name="text">
+       <string>Interval</string>
+      </property>
+     </item>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>QueryConfiguration</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>249</x>
+     <y>134</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>258</x>
+     <y>148</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/src/tabwidget.cpp b/src/tabwidget.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cbad1dc22b6715731d66b59efd3339eb0aa1c061
--- /dev/null
+++ b/src/tabwidget.cpp
@@ -0,0 +1,21 @@
+#include "tabwidget.h"
+
+void TabBar::mouseReleaseEvent(QMouseEvent *e)
+{
+    int ci = currentIndex();
+    QIcon curIcon = tabIcon(ci);
+    if(!curIcon.isNull())
+    {
+        setTabIcon(ci, QIcon());
+    }
+    QTabBar::mouseReleaseEvent(e);
+}
+
+
+TabWidget::TabWidget(QWidget *parent) :
+    QTabWidget(parent)
+{
+    setTabBar(new TabBar(this));
+}
+
+
diff --git a/src/tabwidget.h b/src/tabwidget.h
new file mode 100644
index 0000000000000000000000000000000000000000..eca8ae555f90792a9c4009b8323d79043d92b41b
--- /dev/null
+++ b/src/tabwidget.h
@@ -0,0 +1,31 @@
+#ifndef TABWIDGET_H
+#define TABWIDGET_H
+
+#include <QTabWidget>
+#include <QTabBar>
+
+class TabBar : public QTabBar
+{
+    Q_OBJECT
+public:
+    TabBar(QWidget *parent ) : QTabBar(parent) {}
+
+protected:
+    void mouseReleaseEvent(QMouseEvent *e);
+
+};
+
+class TabWidget : public QTabWidget
+{
+    Q_OBJECT
+public:
+    explicit TabWidget(QWidget *parent = 0);
+    
+signals:
+    
+public slots:
+
+    
+};
+
+#endif // TABICON_H
diff --git a/src/tlabelitem.cpp b/src/tlabelitem.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b86edd2f53616e10c12dc223a970d8e31e1bf808
--- /dev/null
+++ b/src/tlabelitem.cpp
@@ -0,0 +1,137 @@
+#include <QtGui>
+
+#include "tlabelitem.h"
+#include <elettracolors.h>
+#include <QGraphicsSceneHoverEvent>
+
+TLabelItem::TLabelItem(QObject *p) : QObject(p), QTangoComProxyReader(this)//, app(0)
+{
+	m_stateColors			= QVector<QColor>(14, EColor(Elettra::darkYellow));
+	m_stateColors[Tango::ON]	= EColor(Elettra::green);
+	m_stateColors[Tango::FAULT]	= EColor(Elettra::red);
+	m_stateColors[Tango::ALARM]	= EColor(Elettra::red);
+
+	m_trueColor	= Qt::green;
+	m_trueString	= "True";
+	m_falseColor	= Qt::red;
+	m_falseString	= "False";
+
+	m_mode = Simple;
+	ellipseRect = QRectF(0,0,10,10);
+
+    setAcceptHoverEvents(true);
+	setFlags(QGraphicsItem::ItemIsMovable);
+
+	connect(qtangoComHandle(), SIGNAL(newData(const TVariant&)), this, SLOT(refresh(const TVariant&)),
+	  Qt::DirectConnection);
+}
+
+void TLabelItem::refresh(const TVariant& v)
+{
+	//setToolTip(QString::fromStdString(getDeviceName()));
+	if (v.quality() == ATTR_INVALID)
+	{
+		brushColor = Qt::gray;
+		setText("####");
+	}
+	else
+	{
+		if (v.canConvertToState())
+		{
+			Tango::DevState s = v.toState();
+			brushColor = m_stateColors.at(s);
+			setText(Config::instance()->stateString(s));
+		}
+		else if (v.canConvertToBool())
+		{
+			if (v.toBool())
+			{
+				brushColor = m_trueColor;
+				setText(m_trueString);
+			}
+			else
+			{
+				brushColor = m_falseColor;
+				setText(m_falseString);
+			}
+		}
+		else if (v.canConvertToString())
+		{
+			brushColor = Qt::white;
+			setText(v.toString());
+		}
+	}
+}
+
+void TLabelItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+	painter->setPen(Qt::black);
+	painter->setBrush(brushColor);
+	
+	QRectF r = boundingRect();
+	if (m_mode == Simple)
+	{
+		painter->drawEllipse(ellipseRect);
+	}
+	else
+	{
+		painter->drawRect(r.x()-2, r.y()-1, r.width()+4, r.height()+2);
+		QGraphicsSimpleTextItem::paint(painter, option, widget);
+	}
+}
+
+/*void TLabelItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
+{
+	Q_UNUSED(event);
+	if (helperApplication.isNull())
+	{
+		string a = TLoggingFactory::instance()->findHelperApplication(getDeviceName());
+		if (a != "")
+		{
+			helperApplication = QString::fromStdString(a + " " + getDeviceName());
+		}
+		else
+			helperApplication = QString("atkpanel ") +  QString::fromStdString(getDeviceName());
+	}
+	if (!helperApplication.isNull())
+	{
+		launchHelperApplication();
+	}
+}*/
+
+/*void TLabelItem::launchHelperApplication()
+{
+	if (!app)
+		app = new EApplicationLauncher(helperApplication);
+	app->Rise();
+}*/
+    
+void TLabelItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
+{
+	Q_UNUSED(event);
+	if (ellipseRect.contains(event->pos()))
+		m_mode = Zoomed;
+	update();
+}
+
+void TLabelItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
+{
+	Q_UNUSED(event);
+	if (ellipseRect.contains(event->pos()))
+		m_mode = Zoomed;
+	update();
+}
+
+void TLabelItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
+{
+	Q_UNUSED(event);
+	m_mode = Simple;
+	update();
+}
+
+/*QRectF TLabelItem::boundingRect()
+{
+	qDebug("TLabelItem::boundingRect");
+	return QGraphicsSimpleTextItem::boundingRect();
+}*/
+
diff --git a/src/tlabelitem.h b/src/tlabelitem.h
new file mode 100644
index 0000000000000000000000000000000000000000..cffb8a94df107c3284d9a1d47a42aea83c698e8b
--- /dev/null
+++ b/src/tlabelitem.h
@@ -0,0 +1,60 @@
+#ifndef TLABELITEM_H
+#define TLABELITEM_H
+
+#include <QGraphicsSimpleTextItem>
+#include <qtangocore.h>
+#include <QObject>
+#include <QVector>
+#include <QRectF>
+#include <EApplicationLauncher>
+#include <com_proxy_reader.h>
+
+class TLabelItem : public QObject, public QGraphicsSimpleTextItem, public QTangoComProxyReader
+{
+Q_OBJECT
+
+    enum Mode { Simple, Zoomed };
+
+public:
+    TLabelItem(QObject * = 0);
+
+    void setTrueColor(QColor c) { m_trueColor = c; };
+    QColor trueColor() { return m_trueColor; };
+
+    void setFalseColor(QColor c) { m_falseColor = c; };
+    QColor falseColor() { return m_falseColor; };
+
+    void setTrueString(QString s) { m_trueString = s; };
+    QString trueString() { return m_trueString; };
+
+    void setFalseString(QString s) { m_falseString = s; };
+    QString falseString() { return m_falseString; };
+
+//    QRectF boundingRect();
+
+protected slots:
+    void refresh(const TVariant& v);
+
+protected:
+    void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
+//    void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
+    void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
+    void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
+    void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
+//    void launchHelperApplication();
+
+    QVector<QColor> 	m_stateColors;
+    QColor		m_trueColor;
+    QColor		m_falseColor;
+    QString		m_trueString;
+    QString		m_falseString;
+
+    QColor		brushColor;
+    Mode		m_mode;
+    QRectF		ellipseRect;
+//    EApplicationLauncher *app;
+//    QString helperApplication;
+
+};
+
+#endif
diff --git a/src/treeitem.cpp b/src/treeitem.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..63070c47fcf8936088a4957c0f81e3df7a5eab7a
--- /dev/null
+++ b/src/treeitem.cpp
@@ -0,0 +1,12 @@
+#include "treeitem.h"
+
+TreeItem::TreeItem(QTreeWidget *parent, const QStringList& items)
+    : QTreeWidgetItem(parent, items)
+{
+
+}
+
+bool TreeItem::operator< (const QTreeWidgetItem &other) const
+{
+    return this->data(0, Qt::UserRole).toInt() < other.data(0, Qt::UserRole).toInt();
+}
diff --git a/src/treeitem.h b/src/treeitem.h
new file mode 100644
index 0000000000000000000000000000000000000000..4c99846d86aef2fa3dd96bfc7d46d6b30dc5acd2
--- /dev/null
+++ b/src/treeitem.h
@@ -0,0 +1,18 @@
+#ifndef TREEITEM_H
+#define TREEITEM_H
+
+#include <QTreeWidgetItem>
+
+class TreeItem : public QTreeWidgetItem
+{
+public:
+    TreeItem(QTreeWidget *parent, const QStringList& items);
+
+    bool operator <(const QTreeWidgetItem &other) const;
+signals:
+
+public slots:
+
+};
+
+#endif // TREEITEM_H
diff --git a/src/ttablewidget.cpp b/src/ttablewidget.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a79f45a65ac6a4b4b7f3a226bdee25c91c4713a1
--- /dev/null
+++ b/src/ttablewidget.cpp
@@ -0,0 +1,61 @@
+#include <QtDebug>
+
+#include "ttablewidget.h"
+#include <elettracolors.h>
+
+TTableWidget::TTableWidget(QWidget *p) : QTableWidget(p), QTangoComProxyReader(this)
+{
+	setColumnCount(16);
+	setAutoConfiguration(true);
+	connect(qtangoComHandle(), SIGNAL(newData(const TVariant&)), this, SLOT(refresh(const TVariant&)),
+	  Qt::DirectConnection);
+	connect(qtangoComHandle(), SIGNAL(attributeAutoConfigured(const TangoConfigurationParameters *)), this, SLOT(configure(const 	TangoConfigurationParameters *)));
+	setDesiredAttributePropertyList(QStringList() << "labels");
+}
+
+void TTableWidget::configure(const TangoConfigurationParameters *cp)
+{
+  if(cp->propertyFound("labels"))
+  {
+     _labels = cp->attributePropertyValue("labels");
+     printf("\e[1;32m configuring labels on ttable\e[0m\n");
+     qslisttoc(_labels);
+     refresh(currentValue());
+  }
+  else
+   perr("TTableWidget::configure(): source \"%s\" hasn't got the values property", qstoc(source()));
+     
+}
+
+void TTableWidget::refresh(const TVariant& v)
+{
+   printf("\e[0;33mrefresh()\e[0m\n");
+	if (v.quality() == ATTR_INVALID)
+	{
+		setDisabled(true);
+	}
+	else if (v.canConvertToBoolVector())
+	{
+		setDisabled(false);
+		QVector<bool> data = v.toBoolVector();
+		if (data == oldData)
+			return;
+		oldData = data;
+		clear();
+		setRowCount(data.size() / columnCount() + (data.size()%columnCount() ? 1 : 0));
+		for (unsigned int i = 0; i < data.size(); i++)
+		{
+			QTableWidgetItem *item = new QTableWidgetItem();
+			item->setFlags(Qt::ItemIsEnabled);
+			item->setBackground(QBrush(EColor(data[i] ? Elettra::green : Elettra::red)));
+			item->setText(_labels.value(i));
+			item->setTextAlignment(Qt::AlignCenter);
+			item->setToolTip(_descriptions.value(i));
+			setItem(i / columnCount(), i % columnCount(), item);
+			printf("\e[1;36msetting label \"%s\" ", qstoc(_labels.value(i)));
+		}
+		printf("\n\e[1;32m --- done refresh()\e[0m\n");
+		resizeColumnsToContents();
+	}
+}
+
diff --git a/src/ttablewidget.h b/src/ttablewidget.h
new file mode 100644
index 0000000000000000000000000000000000000000..b74ee282e3df8d7af43eade9f7cf107b3c764f18
--- /dev/null
+++ b/src/ttablewidget.h
@@ -0,0 +1,33 @@
+#ifndef TTABLEWIDGET_H
+#define TTABLEWIDGET_H
+
+#include <QTableWidget>
+#include <QStringList>
+#include <qtangocore.h>
+#include <com_proxy_reader.h>
+
+class TTableWidget : public QTableWidget, public QTangoComProxyReader
+{
+Q_OBJECT
+
+public:
+    TTableWidget(QWidget * = 0);
+
+    void setLabels(QStringList l){ _labels = l; };
+    QStringList labels(){ return _labels; };
+
+    void setDescriptions(QStringList d){ _descriptions = d; };
+    QStringList descriptions(){ return _descriptions; };
+
+protected slots:
+    void refresh(const TVariant &v);
+	void configure(const TangoConfigurationParameters *cp);
+
+protected:
+    QStringList _labels;
+    QStringList _descriptions;
+    QVector<bool> oldData;
+
+};
+
+#endif
diff --git a/src/ttreeview.cpp b/src/ttreeview.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e1654e6d51b719c3b51e73a4eb4cd1dbd21e805e
--- /dev/null
+++ b/src/ttreeview.cpp
@@ -0,0 +1,26 @@
+#include "ttreeview.h"
+#include <QHeaderView>
+
+TTreeView::TTreeView(QWidget *parent) :
+    QTreeView(parent)
+{
+    header()->setSectionResizeMode(QHeaderView::ResizeToContents);
+}
+
+void TTreeView::updateFilter()
+{
+    filter(mCurrentFilter);
+}
+
+void TTreeView::filter(const QString&  text)
+{
+    mCurrentFilter = text;
+    for(int i = 0; i< this->model()->rowCount(); i++)
+    {
+        if(text.isEmpty())
+            setRowHidden(i, QModelIndex(), false);
+
+        setRowHidden(i, QModelIndex(),
+                     !(model()->data(model()->index(i, 1)).toString().contains(text, Qt::CaseInsensitive)));
+    }
+}
diff --git a/src/ttreeview.h b/src/ttreeview.h
new file mode 100644
index 0000000000000000000000000000000000000000..8988ffd103bea970048d42e4e640e22afe1379c3
--- /dev/null
+++ b/src/ttreeview.h
@@ -0,0 +1,24 @@
+#ifndef TTREEVIEW_H
+#define TTREEVIEW_H
+
+#include <QTreeView>
+
+class TTreeView : public QTreeView
+{
+    Q_OBJECT
+public:
+    explicit TTreeView(QWidget *parent = 0);
+    
+signals:
+    
+public slots:
+    void filter(const QString&  text);
+
+    void updateFilter();
+
+private:
+    QString mCurrentFilter;
+    
+};
+
+#endif // TTREEVIEW_H
diff --git a/src/ttreewidget.cpp b/src/ttreewidget.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d2df60ef7d2ddac1e02b4e86d08ee23fc99b1307
--- /dev/null
+++ b/src/ttreewidget.cpp
@@ -0,0 +1,184 @@
+#include <QtDebug>
+
+#include <QMenu>
+#include <QContextMenuEvent>
+#include <QHeaderView>
+#include <QDateTime>
+#include "ttreewidget.h"
+#include <elettracolors.h>
+#include <QScrollBar>
+#include "treeitem.h"
+
+#define DECOLOR_COUNT_MAX 10
+#define DECOLOR_INTERVAL 500 /* milliseconds of decoloring effect */
+
+TTreeWidget::TTreeWidget(QWidget *p) : QTreeWidget(p), QTangoComProxyReader(this), _dataSize(0)
+{
+	setAutoConfiguration(true);
+	setDesiredAttributePropertyList(QStringList() << "labels" << "positions");
+    header()->setSectionResizeMode(QHeaderView::ResizeToContents);
+    setSortingEnabled(true);
+    sortByColumn(0);
+	connect(qtangoComHandle(), SIGNAL(newData(const TVariant&)), this, SLOT(refresh(const TVariant&)),
+	  Qt::DirectConnection);
+	connect(qtangoComHandle(), SIGNAL(attributeAutoConfigured(const TangoConfigurationParameters *)), this, SLOT(configure(const 		TangoConfigurationParameters *)));  
+
+    tmpCounter = 1;
+
+}
+
+void TTreeWidget::configure(const TangoConfigurationParameters *cp)
+{
+   if(cp->propertyFound("labels"))
+	_labels = cp->attributePropertyValue("labels");
+   
+   if(cp->propertyFound("positions"))
+      _descriptions = cp->attributePropertyValue("positions");
+}
+
+void TTreeWidget::refresh(const TVariant& v)
+{
+    /* save scrollbar value */
+    int scrollPos = this->verticalScrollBar()->value();
+    /* first time do not emit signal for sound */
+    bool alarmPresent;
+//	setToolTip(getMessage());
+	if (v.quality() == ATTR_INVALID)
+	{
+		setDisabled(true);
+         }
+/*	else if (canConvertToBoolVector())
+	{
+		setDisabled(false);
+		clear();
+		vector<bool>	data = getDataAsBoolVector();
+		QList<QTreeWidgetItem *> items;
+		for (unsigned int i = 0; i < data.size(); i++)
+		{
+			QTreeWidgetItem *item = new QTreeWidgetItem((QTreeWidget*) 0, QStringList(_labels.value(i)));
+     			items.append(item);
+		}
+		insertTopLevelItems(0, items);
+	}*/
+	else if (v.canConvertToDoubleVector())
+        {
+		setDisabled(false);
+        QVector<double>	data = v.toDoubleVector();
+    //    qSort(data.begin(), data.end());
+
+		if (data == oldData)
+			return;
+
+        qDebug() << __FUNCTION__ << data << data.size();
+
+        double lastTimestamp = data.last();
+        double previousLastTimestamp;
+        if(oldData.isEmpty()) /* first refresh, no matter if visible or not */
+        {
+            previousLastTimestamp = QDateTime::currentDateTime().toTime_t();
+            qDebug() << "setting last timestamp seen in first time " << objectName() <<
+                        previousLastTimestamp << QDateTime::currentDateTime();
+            mLastTimestampSeen = previousLastTimestamp;
+        }
+        else
+            previousLastTimestamp = oldData.last();
+
+        alarmPresent = lastTimestamp > previousLastTimestamp && !oldData.isEmpty();
+        if(lastTimestamp > previousLastTimestamp)
+            mAlarmColor = KRED;
+
+        /* now we can update oldData, sorted */
+		oldData = data;
+		clear();
+		_dataSize = data.size();
+
+
+		QList<QTreeWidgetItem *> items;
+
+        for (int i = data.size() - 1; i >= 0; i--)
+		{
+			if (data[i])
+			{
+				QStringList cells;
+				QDateTime date;
+                date.setTime_t((int) data[i]);
+				date = date.addMSecs((int)(1000 *(data[i] - (int) data[i])));
+				cells << date.toString("d MMM yyyy hh:mm:ss.zzz") << _labels.value(i) << _descriptions.value(i) << QString().setNum(i);
+                                TreeItem *item = new TreeItem(this, cells);
+                                item->setData(0, Qt::UserRole, data[i]);
+                items.append(item);
+                if(data[i] > mLastTimestampSeen) /* red colour new alarms */
+                {
+                    QFont f = item->font(0);
+                    f.setBold(true);
+                    for(int i = 0; i < item->columnCount(); i++)
+                        item->setFont(i, f);
+                }
+			}
+		}
+		insertTopLevelItems(0, items);
+
+        if(alarmPresent)
+        {
+            emit newAlarmArrived();
+        }
+	}
+    filter(mCurrentFilter);
+
+    /* restore last scroll position */
+    if(scrollPos != this->verticalScrollBar()->value())
+        this->verticalScrollBar()->setValue(scrollPos);
+}
+
+void TTreeWidget::filter(const QString& text)
+{
+    mCurrentFilter = text;
+    QList<QTreeWidgetItem *> items = this->findItems("*", Qt::MatchWildcard, 0);
+    if(text.isEmpty()) /* show all items */
+    {
+        foreach(QTreeWidgetItem* it, items)
+            if(it->isHidden())
+                it->setHidden(false);
+    }
+    else
+    {
+        foreach(QTreeWidgetItem* it, items)
+        {
+            it->setHidden(!it->text(1).contains(text, Qt::CaseInsensitive));
+        }
+    }
+}
+
+void TTreeWidget::ackSelected()
+{
+	emit acknowledgeSelected();
+}
+
+void TTreeWidget::ackAll()
+{
+	emit acknowledgeAll();
+}
+
+void TTreeWidget::contextMenuEvent(QContextMenuEvent *event)
+{
+        QMenu *menu = new QMenu(this);
+        menu->addAction("Acknowledge Selected", this, SLOT(ackSelected()));
+        menu->addAction("Acknowledge All", this, SLOT(ackAll()));
+        menu->exec(event->globalPos());
+}
+
+void TTreeWidget::hideEvent(QHideEvent *e)
+{
+    QTreeWidget::hideEvent(e);
+    mLastTimestampSeen = QDateTime::currentDateTime().toTime_t();
+    qDebug() << "hide event: last timestamp seen for " << objectName() << QDateTime::currentDateTime() << mLastTimestampSeen;
+}
+
+void TTreeWidget::showEvent(QShowEvent *e)
+{
+    QTreeWidget::showEvent(e);
+    mLastTimestampSeen = QDateTime::currentDateTime().toTime_t();
+    qDebug() << "show event : last timestamp seen for " << objectName() << QDateTime::currentDateTime() << mLastTimestampSeen;
+
+}
+
diff --git a/src/ttreewidget.h b/src/ttreewidget.h
new file mode 100644
index 0000000000000000000000000000000000000000..ff8827546ce76519903f033d040b0da7f092c771
--- /dev/null
+++ b/src/ttreewidget.h
@@ -0,0 +1,56 @@
+#ifndef TTREEWIDGET_H
+#define TTREEWIDGET_H
+
+#include <QTreeWidget>
+#include <QStringList>
+#include <qtangocore.h>
+#include <com_proxy_reader.h>
+
+class TTreeWidget : public QTreeWidget, public QTangoComProxyReader
+{
+Q_OBJECT
+
+public:
+    TTreeWidget(QWidget * = 0);
+
+    void setLabels(QStringList l){ _labels = l; };
+    QStringList labels(){ return _labels; };
+
+    void setDescriptions(QStringList d){ _descriptions = d; };
+    QStringList descriptions(){ return _descriptions; };
+
+    unsigned int dataSize(){ return _dataSize; };
+
+signals:
+    void acknowledgeAll();
+    void acknowledgeSelected();
+    void newAlarmArrived();
+
+protected slots:
+    void refresh(const TVariant &v);
+	void configure(const TangoConfigurationParameters *cp);
+    void ackSelected();
+    void ackAll();
+
+    void filter(const QString& text);
+
+protected:
+    void contextMenuEvent(QContextMenuEvent *);
+    QStringList _labels;
+    QStringList _descriptions;
+    unsigned int _dataSize;
+    QVector<double> oldData;
+
+    void showEvent(QShowEvent *e);
+    void hideEvent(QHideEvent *);
+
+private:
+    QString mCurrentFilter;
+    int mDecolorCount;
+    QColor mAlarmColor;
+    double mLastTimestampSeen;
+
+    int tmpCounter;
+};
+
+#endif