fixed memory leak in database, fixed wrong carid in races, some updates

This commit is contained in:
2014-09-13 16:14:24 +02:00
parent 990a6ad03d
commit b18e3f9943
12 changed files with 342 additions and 62 deletions

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 3.0.1, 2014-09-04T23:23:32. -->
<!-- Written by QtCreator 3.0.1, 2014-09-13T13:57:17. -->
<qtcreator>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>

View File

@@ -13,10 +13,32 @@ DataBase::DataBase()
this->db->setDatabaseName("Renndatenbank.sqlite");
std::cout << "Konstruktor Database" << std::endl;
}
vector< vector<QString> > DataBase::getData2(std::string statement, int cols){
vector<QString> data;
vector< vector<QString> > lines;
bool ok = this->db->open();
QString qstr;
if(ok){
QSqlQuery query;
query.exec(QString::fromStdString(statement));
while(query.next()){
for(int i = 0; i < cols; i++){
qstr = query.value(i).toString();
data.push_back(qstr);
}
lines.push_back(data);
data.erase(data.begin(), data.begin()+cols);
}
}
this->db->close();
return lines;
}
vector< vector<QString> > DataBase::getData(std::string statement, int cols){
char * buffer = new char[statement.length()-1];
char * buffer = new char[statement.length()+1];
strcpy(buffer,statement.c_str());
vector<QString> data;
vector< vector<QString> > lines;
@@ -36,11 +58,12 @@ vector< vector<QString> > DataBase::getData(std::string statement, int cols){
}
}
this->db->close();
delete[] buffer;
return lines;
}
void DataBase::setData(std::string statement){
char * buffer = new char[statement.length()];
char * buffer = new char[statement.length()+1];
strcpy(buffer,statement.c_str());
bool ok = this->db->open();
if(ok){

View File

@@ -14,6 +14,7 @@ class DataBase
public:
DataBase();
vector< vector<QString> > getData(std::string statement, int cols);
vector< vector<QString> > getData2(std::string statement, int cols);
void setData(std::string statement);
private:
QSqlDatabase *db;

View File

@@ -26,11 +26,6 @@ MainWindow::MainWindow(QWidget *parent) :
this->db = new DataBase;
vector< vector <QString> > daten = db->getData("select * from Fahrer", 2);
//DataBase ndb;
//vector< vector <QString> > daten2 = ndb.getData("select * from Fahrer", 2);
//DataBase ndb2;
//vector< vector <QString> > daten3 = ndb2.getData("select * from Fahrer", 2);
}
@@ -49,4 +44,5 @@ void MainWindow::WindowRennen(){
this->interfaceRennliste = new WindowRennliste(this->db, this);
this->interfaceRennliste->show();
this->interfaceRace->setWindowRennliste(this->interfaceRennliste);
this->interfaceRennliste->setWindowRace(this->interfaceRace);
}

View File

@@ -4,31 +4,31 @@
#include <string>
#include <sstream>
#include <iostream>
#define FAHRZEIT 5;
using std::vector;
using std::string;
using std::cout;
using std::endl;
WindowRace::WindowRace(DataBase *db, QWidget *parent) :
QMainWindow(parent),
ui(new Ui::WindowRace)
{
ui->setupUi(this);
this->ui->pBNextRace->setEnabled(false);
this->finished = false;
this->db = db;
vector< vector< QString > > res;
res = db->getData("select id from fahrer", 1);
res = db->getData("select dauer from renndauer", 1);
this->fahrzeit = res[0][0].toInt();
vector< vector< QString > > res2;
res2 = db->getData("select id from fahrer", 1);
firstTimeDea = true;
firstTimeShell = true;
started = false;
countdownValue = FAHRZEIT;
countdownValue = this->fahrzeit;
countdown = new Countdown;
startAmpelThread = new Ampel;
@@ -48,8 +48,7 @@ WindowRace::WindowRace(DataBase *db, QWidget *parent) :
QObject::connect(startAmpelThread, SIGNAL(ampelUpdate()), this, SLOT(laufcheck()));
QObject::connect(ui->pBBreak, SIGNAL(clicked()), this, SLOT(breakCounter()));
QObject::connect(this->ui->pBNextRace, SIGNAL(clicked()), this, SLOT(prepareNextRace()));
QObject::connect(this->ui->pBStop, SIGNAL(clicked()), this, SLOT(stopClicked()));
ui->lCountdown->setText(timeWrapper(countdownValue));
@@ -76,22 +75,116 @@ WindowRace::WindowRace(DataBase *db, QWidget *parent) :
ui->hW11->setVisible(true);
ui->hW21->setVisible(true);
string statement;
vector< vector<QString> > fahrer, autos, rennid, tableData;
statement = "select id_rennen from aktrennen group by id_rennen order by id_rennen DESC limit 1";
rennid = this->db->getData(statement, 1);
this->renn_id = rennid[0][0].toInt();
statement = "select fahrershellid, autoshellid, fahrerdeaid, autodeaid from aktrennen where id_rennen like "+rennid[0][0].toStdString()+" limit 1";
tableData = db->getData2(statement, 4);
statement = "select name from fahrer where id like " + tableData[0][0].toStdString();
fahrer = this->db->getData2(statement, 1);
statement = "select name from AutoKonfiguration where id_auto like " + tableData[0][1].toStdString()+" order by seit DESC";
autos = this->db->getData2(statement, 1);
this->ui->gbShell->setTitle("Shell, "+fahrer[0][0]+", "+autos[0][0]);
statement = "select name from fahrer where id like " + tableData[0][2].toStdString();
fahrer = this->db->getData2(statement, 1);
statement = "select name from AutoKonfiguration where id_auto like " + tableData[0][3].toStdString()+" order by seit DESC";
autos = this->db->getData2(statement, 1);
this->ui->gbDea->setTitle("Dea, "+fahrer[0][0]+", "+autos[0][0]);
this->shellDriverId = tableData[0][0].toInt();
this->shellCarId = tableData[0][1].toInt();
this->deaDriverId = tableData[0][2].toInt();
this->deaCarId = tableData[0][3].toInt();
}
void WindowRace::prepareNextRace(){
this->firstTimeShell = true;
this->firstTimeDea = true;
this->ui->lWShellTime->clear();
this->ui->lWDeaTime->clear();
this->ui->lBestZeitDea->setText("");
this->ui->lBestZeitShell->setText("");
this->ui->lCurRoundTimeShell->setText("");
this->ui->lCurRoundDea->setText("");
this->finished = false;
this->paused = false;
this->countdownValue = FAHRZEIT;
this->started = false;
this->countdownValue = this->fahrzeit;
this->ampelCounter = 0;
this->startAmpelThread->terminate();
this->countdown->terminate();
this->ui->pBNextRace->setEnabled(false);
this->ui->lCountdown->setText(timeWrapper(countdownValue));
//Ampel Setup
ui->WAmpel15->hide();
ui->WAmpel25->hide();
ui->hW15->setVisible(true);
ui->hW25->setVisible(true);
ui->WAmpel14->hide();
ui->WAmpel24->hide();
ui->hW14->setVisible(true);
ui->hW24->setVisible(true);
ui->WAmpel13->hide();
ui->WAmpel23->hide();
ui->hW13->setVisible(true);
ui->hW23->setVisible(true);
ui->WAmpel12->hide();
ui->WAmpel22->hide();
ui->hW12->setVisible(true);
ui->hw22->setVisible(true);
ui->WAmpel11->hide();
ui->WAmpel21->hide();
ui->hW11->setVisible(true);
ui->hW21->setVisible(true);
}
void WindowRace::setDriverAndCar(vector<QString> vec){
this->ui->gbShell->setTitle("Shell, "+vec[0]+", "+vec[1]);
this->ui->gbDea->setTitle("Dea, "+vec[2]+", "+vec[3]);
}
void WindowRace::stopClicked(){
this->prepareNextRace();
}
void WindowRace::setWindowRennliste(WindowRennliste *ptrInstance){
this->wRennliste = ptrInstance;
QObject::connect(this->ui->pBNextRace, SIGNAL(clicked()), this->wRennliste, SLOT(changeSelection()));
}
void WindowRace::setDriverAndCarId(vector<QString> vec){
this->shellDriverId = vec[0].toInt();
this->shellCarId = vec[1].toInt();
this->deaDriverId = vec[2].toInt();
this->deaCarId = vec[3].toInt();
}
void WindowRace::closeEvent(QCloseEvent *event){
QMessageBox msgBox;
msgBox.setText("The document has been modified.");
msgBox.setInformativeText("Do you want to save your changes?");
msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Save);
int ret = msgBox.exec();
this->wRennliste->schliessen();
event->accept();
}
void WindowRace::breakCounter(){
if(!paused){
@@ -159,6 +252,10 @@ void WindowRace::shellSlot(){
}
item->setText(QString::number((double)zeit/1000));
ui->lWShellTime->addItem(item);
QString statement = "insert into Zeiten (id_rennen, id_fahrer, id_auto, id_bahn, zeit) values ("+QString::number(this->renn_id)+
", "+QString::number(this->shellDriverId)+", "+QString::number(this->shellCarId)+", 1, "+QString::number(zeit)+")";
cout << statement.toStdString() << endl;
this->db->setData(statement.toStdString());
ui->lWShellTime->scrollToBottom();
ui->lBestZeitShell->setText(QString::number((double)getMinimum(VecShell)/1000));
ui->lCurRoundTimeShell->setText(QString::number((double)zeit/1000));
@@ -180,6 +277,10 @@ void WindowRace::deaSlot(){
}
item->setText(QString::number((double)zeit/1000));
ui->lWDeaTime->addItem(item);
QString statement = "insert into Zeiten (id_rennen, id_fahrer, id_auto, id_bahn, zeit) values ("+QString::number(this->renn_id)+
", "+QString::number(this->deaDriverId)+", "+QString::number(this->deaCarId)+", 2, "+QString::number(zeit)+")";
cout << statement.toStdString() << endl;
this->db->setData(statement.toStdString());
ui->lWDeaTime->scrollToBottom();
ui->lBestZeitDea->setText(QString::number((double)getMinimum(VecDea)/1000));
ui->lCurRoundDea->setText(QString::number((double)zeit/1000));
@@ -257,7 +358,6 @@ void WindowRace::ampelSlot(){
ui->hW11->hide();
ui->hW21->hide();
}
}
void WindowRace::go(){

View File

@@ -10,6 +10,9 @@
#include "ampel.h"
#include "database.h"
#include "windowrennliste.h"
#include <QMessageBox>
using std::string;
namespace Ui {
class WindowRace;
@@ -23,8 +26,16 @@ public:
explicit WindowRace(DataBase *db, QWidget *parent = 0);
~WindowRace();
void setWindowRennliste(WindowRennliste *ptrInstance);
void setDriverAndCar(vector<QString> vec);
void setDriverAndCarId(vector<QString> vec);
private:
int shellDriverId;
int deaDriverId;
int deaCarId;
int shellCarId;
void closeEvent(QCloseEvent *event);
bool started;
Countdown *countdown;
HardwareSetup *Hardware;
@@ -44,8 +55,11 @@ private:
DataBase *db;
bool finished;
WindowRennliste *wRennliste;
int fahrzeit;
int renn_id;
public slots:
void stopClicked();
void prepareNextRace();
void breakCounter();
void countdownUpdate();

View File

@@ -20,7 +20,7 @@
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QGroupBox" name="groupBox_5">
<widget class="QGroupBox" name="gbShell">
<property name="maximumSize">
<size>
<width>300</width>
@@ -501,7 +501,7 @@
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QGroupBox" name="groupBox_6">
<widget class="QGroupBox" name="gbDea">
<property name="maximumSize">
<size>
<width>300</width>

View File

@@ -4,6 +4,7 @@
#include <QBrush>
#include <iostream>
#include <QDebug>
#include "windowrace.h"
using std::vector;
using std::string;
@@ -11,24 +12,25 @@ WindowRennliste::WindowRennliste(DataBase *db, QWidget *parent) :
QMainWindow(parent),
ui(new Ui::WindowRennliste)
{
this->selectedRow = 0;
ui->setupUi(this);
this->windowClose = false;
this->selectedRow = 0;
this->ui->tWRennliste->setSelectionBehavior(QAbstractItemView::SelectRows);
this->ui->tWRennliste->setSelectionMode(QAbstractItemView::SingleSelection);
QObject::connect(this->ui->tWRennliste, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(listClick(const QModelIndex&)));
this->db = db;
string statement;
vector< vector<QString> > fahrer, autos, rennid;
statement = "select id_rennen from aktrennen group by id_rennen order by id_rennen DESC limit 1";
rennid = this->db->getData(statement, 1);
statement = "select fahrershellid, autoshellid, fahrerdeaid, autodeaid from aktrennen where id_rennen like "+rennid[0][0].toStdString();
tableData = db->getData(statement, 4);
this->tableData = db->getData(statement, 4);
this->ui->tWRennliste->setRowCount(this->tableData.size());
this->ui->tWRennliste->setColumnCount(6);
QStringList header;
@@ -41,13 +43,14 @@ WindowRennliste::WindowRennliste(DataBase *db, QWidget *parent) :
this->ui->tWRennliste->horizontalHeader()->setSectionResizeMode(i, QHeaderView::Stretch);
}
for(unsigned int i = 0; i < tableData.size(); i++){
statement = "select name from fahrer where id like " + tableData[i][0].toStdString();
fahrer = this->db->getData(statement, 1);
this->ui->tWRennliste->setItem(i, 0, new QTableWidgetItem(fahrer[0][0]));
this->ui->tWRennliste->item(i,0)->setFlags(Qt::ItemIsEnabled);
statement = "select name from AutoKonfiguration where id like " + tableData[i][1].toStdString()+" order by seit DESC";
statement = "select name from AutoKonfiguration where id_auto like " + tableData[i][1].toStdString()+" order by seit DESC";
autos = this->db->getData(statement, 1);
this->ui->tWRennliste->setItem(i, 1, new QTableWidgetItem(autos[0][0]));
this->ui->tWRennliste->item(i,1)->setFlags(Qt::ItemIsEnabled);
@@ -59,7 +62,7 @@ WindowRennliste::WindowRennliste(DataBase *db, QWidget *parent) :
this->ui->tWRennliste->setItem(i, 3, new QTableWidgetItem(fahrer[0][0]));
this->ui->tWRennliste->item(i,3)->setFlags(Qt::ItemIsEnabled);
statement = "select name from AutoKonfiguration where id like " + tableData[i][3].toStdString()+" order by seit DESC";
statement = "select name from AutoKonfiguration where id_auto like " + tableData[i][3].toStdString()+" order by seit DESC";
autos = this->db->getData(statement, 1);
this->ui->tWRennliste->setItem(i, 4, new QTableWidgetItem(autos[0][0]));
this->ui->tWRennliste->item(i,4)->setFlags(Qt::ItemIsEnabled);
@@ -70,14 +73,92 @@ WindowRennliste::WindowRennliste(DataBase *db, QWidget *parent) :
this->ui->tWRennliste->item(0, i)->setBackground(Qt::green);
}
}
void WindowRennliste::setWindowRace(WindowRace *instance){
this->instanceWindowRace = instance;
}
vector<QString> WindowRennliste::getDriverAndCarSettings(){
vector<QString> vec;
vec.push_back(this->ui->tWRennliste->item(this->selectedRow+1, 0)->text());
vec.push_back(this->ui->tWRennliste->item(this->selectedRow+1, 1)->text());
vec.push_back(this->ui->tWRennliste->item(this->selectedRow+1, 3)->text());
vec.push_back(this->ui->tWRennliste->item(this->selectedRow+1, 4)->text());
return vec;
}
vector<QString> WindowRennliste::getDriverAndCarId(){
//shellFahrer shellAuto deaFahrer deaAuto
return this->tableData[this->selectedRow];
}
void WindowRennliste::listClick(const QModelIndex & index){
QString driverShell = this->ui->tWRennliste->item(index.row(), 0)->text();
QString carShell = this->ui->tWRennliste->item(index.row(), 1)->text();
QString driverDea = this->ui->tWRennliste->item(index.row(), 3)->text();
QString carDea = this->ui->tWRennliste->item(index.row(), 4)->text();
vector<QString> vec;
vec.push_back(driverShell);
vec.push_back(carShell);
vec.push_back(driverDea);
vec.push_back(carDea);
this->instanceWindowRace->setDriverAndCar(vec);
this->instanceWindowRace->prepareNextRace();
this->setSelection(index.row());
this->sendIds();
}
void WindowRennliste::closeEvent(QCloseEvent *event){
if(!this->windowClose){
this->setWindowState(Qt::WindowMinimized);
event->ignore();
}
else{
event->accept();
}
}
void WindowRennliste::schliessen(){
this->windowClose = true;
this->close();
}
void WindowRennliste::setSelection(int row){
for(int i = 0; i < 6; i++){
this->ui->tWRennliste->item(this->selectedRow, i)->setBackground(Qt::yellow);
}
this->selectedRow = row;
for(int i = 0; i < 6; i++){
this->ui->tWRennliste->item(row, i)->setBackground(Qt::green);
}
this->sendIds();
vector<QString> vec;
vec.push_back(this->ui->tWRennliste->item(this->selectedRow, 0)->text());
vec.push_back(this->ui->tWRennliste->item(this->selectedRow, 1)->text());
vec.push_back(this->ui->tWRennliste->item(this->selectedRow, 3)->text());
vec.push_back(this->ui->tWRennliste->item(this->selectedRow, 4)->text());
this->instanceWindowRace->setDriverAndCar(vec);
}
void WindowRennliste::sendIds(){
this->instanceWindowRace->setDriverAndCarId(this->getDriverAndCarId());
}
void WindowRennliste::changeSelection(){
if(this->selectedRow + 1 < this->tableData.size()){
for(unsigned int i = 0; i < 6; i++){
this->ui->tWRennliste->item(this->selectedRow, i)->setBackground(Qt::gray);
this->ui->tWRennliste->item(this->selectedRow+1, i)->setBackground(Qt::green);
}
this->selectedRow += 1;
this->sendIds();
vector<QString> vec;
vec.push_back(this->ui->tWRennliste->item(this->selectedRow, 0)->text());
vec.push_back(this->ui->tWRennliste->item(this->selectedRow, 1)->text());
vec.push_back(this->ui->tWRennliste->item(this->selectedRow, 3)->text());
vec.push_back(this->ui->tWRennliste->item(this->selectedRow, 4)->text());
this->instanceWindowRace->setDriverAndCar(vec);
}
}

View File

@@ -5,7 +5,9 @@
#include "database.h"
#include <vector>
#include <string>
#include <QCloseEvent>
class WindowRace;
using std::vector;
namespace Ui {
@@ -17,16 +19,25 @@ class WindowRennliste : public QMainWindow
Q_OBJECT
public:
void schliessen();
explicit WindowRennliste(DataBase *db, QWidget *parent = 0);
~WindowRennliste();
void setWindowRace(WindowRace *instance);
vector<QString> getDriverAndCarSettings();
vector<QString> getDriverAndCarId();
void sendIds();
private:
bool windowClose;
void closeEvent(QCloseEvent *event);
void setSelection(int row);
WindowRace *instanceWindowRace;
unsigned int selectedRow;
vector< vector<QString> > tableData;
DataBase *db;
Ui::WindowRennliste *ui;
public slots:
void listClick(const QModelIndex & index);
void changeSelection();
};

View File

@@ -18,11 +18,14 @@ WindowsSettings::WindowsSettings(DataBase *db, QWidget *parent) :
ui->setupUi(this);
QObject::connect(ui->pBSpeichernStrecke, SIGNAL(clicked()), this, SLOT(StreckeSpeichernSlot()));
QObject::connect(ui->pBAbbrechenStrecke, SIGNAL(clicked()), this, SLOT(AbbrechnSlot()));
QObject::connect(ui->pBAbbrechenStrecke, SIGNAL(clicked()), this, SLOT(AbbrechenSlot()));
QObject::connect(this->ui->pbAbbrechenDauer, SIGNAL(clicked()), this, SLOT(AbbrechenSlot()));
QObject::connect(this->ui->pbSaveDauer, SIGNAL(clicked()), this, SLOT(SaveDauerSlot()));
QObject::connect(this->ui->pbSaveAndExitDauer, SIGNAL(clicked()), this, SLOT(SaveDauerAndExitSlot()));
this->db = db;
//Shell prepare
string statement = "select geraden, kurven_aussen, "
"kurven_innen, steilkurve_innen, steilkurve_aussen, seit "
@@ -49,15 +52,23 @@ WindowsSettings::WindowsSettings(DataBase *db, QWidget *parent) :
ui->lEDeaSteilkurveInnen->setText(res[0][3]);
ui->lEDeaSteilkurveAussen->setText(res[0][4]);
//string statement= "insert into AutoKonfiguration ('seit') values ('"+currentDateTime()+"')";
//db->setData(statement);
//duration prepare
statement = "select dauer from renndauer";
res = db->getData(statement, 1);
this->ui->leRenndauer->setText(res[0][0]);
}
void WindowsSettings::AbbrechnSlot(){
void WindowsSettings::AbbrechenSlot(){
this->close();
}
void WindowsSettings::SaveDauerSlot(){
string statement = "update renndauer set dauer="+this->ui->leRenndauer->text().toStdString()+" where id like 1";
this->db->setData(statement);
}
void WindowsSettings::SaveDauerAndExitSlot(){
this->SaveDauerSlot();
this->AbbrechenSlot();
}
void WindowsSettings::StreckeSpeichernSlot(){
@@ -82,8 +93,6 @@ void WindowsSettings::StreckeSpeichernSlot(){
" values ("+deaGeraden+", "+deaKurvenAussen+", "+deaKurvenInnen+", "+deaSteilInnen+", "+deaSteilAussen+", '"+QString::fromStdString(currentDateTime())+"', 2)");
//cout << statement.toStdString() << endl;
db->setData(statement.toStdString());
}
WindowsSettings::~WindowsSettings()

View File

@@ -23,9 +23,10 @@ private:
string currentDateTime();
DataBase *db;
public slots:
void AbbrechnSlot();
void SaveDauerSlot();
void AbbrechenSlot();
void StreckeSpeichernSlot();
void SaveDauerAndExitSlot();
};

View File

@@ -18,30 +18,74 @@
<item>
<widget class="QTabWidget" name="Strecke">
<property name="currentIndex">
<number>1</number>
<number>0</number>
</property>
<widget class="QWidget" name="Dauer">
<attribute name="title">
<string>Dauer</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_19">
<item>
<layout class="QVBoxLayout" name="verticalLayout_18" stretch="0,2,1">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7" stretch="1,1">
<item>
<widget class="QGroupBox" name="groupBox_13">
<property name="geometry">
<rect>
<x>60</x>
<y>30</y>
<width>149</width>
<height>65</height>
</rect>
</property>
<property name="title">
<string>Renndauer in Sekunden </string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_17">
<item>
<widget class="QLineEdit" name="lineEdit_11"/>
<widget class="QLineEdit" name="leRenndauer"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_14">
<property name="title">
<string>Mindestrundenzeit in Millisekunden</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_20">
<item>
<widget class="QLineEdit" name="lEMinRundenzeit"/>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QWidget" name="widget" native="true"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QPushButton" name="pbAbbrechenDauer">
<property name="text">
<string>Abbrechen</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pbSaveAndExitDauer">
<property name="text">
<string>Speichern und Schließen</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pbSaveDauer">
<property name="text">
<string>Speichern</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">