From e7adb16f5f2755f83624be175cac5c253f027623 Mon Sep 17 00:00:00 2001 From: jfmartel Date: Thu, 6 Mar 2025 14:05:49 -0500 Subject: [PATCH] =?UTF-8?q?Ajout=20de=20la=20navigation=20directe=20dans?= =?UTF-8?q?=20les=20r=C3=A9pertoires.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Images/directory.png | Bin 0 -> 36325 bytes SourcePath.txt | 3 + sources/GuiElements/LogsListPage.cpp | 765 +++++++++++++++++++++++++-- sources/GuiElements/LogsListPage.h | 38 +- sources/GuiElements/MainPage.cpp | 20 +- sources/MainPanel.cpp | 2 +- sources/OutilZTVersion.h | 2 +- 7 files changed, 783 insertions(+), 47 deletions(-) create mode 100644 Images/directory.png create mode 100644 SourcePath.txt diff --git a/Images/directory.png b/Images/directory.png new file mode 100644 index 0000000000000000000000000000000000000000..1600437ac9a9406a525627f4ae1464e582a7042d GIT binary patch literal 36325 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 #include #include - +#include +#include +#include "TrainLogFileMgr.h" +#include +#include CLogsListPage::~CLogsListPage() { // delete mListParsingTimer; + delete mLogsTable; } CLogsListPage::CLogsListPage(QGraphicsWidget *Parent) @@ -50,11 +55,28 @@ CLogsListPage::CLogsListPage(QGraphicsWidget *Parent) mProgramHandle = 0; mStationFilter.clear(); + QFile PathSource("SourcePath.txt"); + mNetworkBasePath = NETWORK_LOGS_BASE_PATH; + if(PathSource.open(QIODevice::ReadOnly|QIODevice::Text)) + { + QString Path; + do + { + Path = QString(PathSource.readLine()); + if(Path.contains('#') == false) + { + mNetworkBasePath = Path.chopped(1); + break; + } + } + while(!PathSource.atEnd()); + } + mLogsTable = new QTableWidget(0,4); - QGraphicsProxyWidget *TableProxy = new QGraphicsProxyWidget(this); - TableProxy->setWidget(mLogsTable); - TableProxy->setPos(3,20); - TableProxy->resize(380,350); + mLogListTableProxy = new QGraphicsProxyWidget(this); + mLogListTableProxy->setWidget(mLogsTable); + mLogListTableProxy->setPos(3,20); + mLogListTableProxy->resize(380,350); mLogsTable->resize(380,350); mLogsTable->setSelectionBehavior(QAbstractItemView::SelectRows); mLogsTable->setSelectionMode(QAbstractItemView::SingleSelection); @@ -65,6 +87,103 @@ CLogsListPage::CLogsListPage(QGraphicsWidget *Parent) connect(mLogsTable,SIGNAL(currentCellChanged(int,int,int,int)),this,SLOT(LogsTableCellSelected(int,int,int,int))); connect(mLogsTable,SIGNAL(cellDoubleClicked(int,int)),SLOT(TableDoubleClicked(int,int))); + mLogListTableProxy->hide(); + + mLogsTreeProxy = new QGraphicsProxyWidget(this); + mLogFilesTree = new QTreeWidget; + mLogsTreeProxy->setWidget(mLogFilesTree); + mLogFilesTree->setColumnCount(3); + mLogFilesTree->resize(590,350); + mLogFilesTree->setHeaderLabels(QStringList() << "Passage" << "Décl" << "Zone" << "Compo"); + connect(mLogFilesTree,SIGNAL(itemExpanded(QTreeWidgetItem*)),this,SLOT(LogsTreeItemExpanded(QTreeWidgetItem*))); + connect(mLogFilesTree,SIGNAL(itemSelectionChanged()),this,SLOT(LogsTreeItemSelected())); + connect(mLogFilesTree,SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),this,SLOT(LogsTreeItemDoubleClicked(QTreeWidgetItem*))); + connect(mLogFilesTree,SIGNAL(itemCollapsed(QTreeWidgetItem*)),this,SLOT(LogsTreeItemCollapsed(QTreeWidgetItem*))); + mLogFilesTree->setSortingEnabled(true); + + // mLogsTreeProxy->hide(); + + QTreeWidgetItem* TopStationItem; + TopStationItem = new QTreeWidgetItem(static_cast(nullptr)); + TopStationItem->setText(0,"Angrignon"); + CTreeItemInfo *ItemInfo = new CTreeItemInfo; + ItemInfo->TreeItemType = TREE_ITEM_STATION_TYPE; + ItemInfo->TreeItemPath = QString(mNetworkBasePath) + "ANG"; + TopStationItem->setData(0,Qt::UserRole,QVariant::fromValue((void*)ItemInfo)); + TopStationItem->addChild(new QTreeWidgetItem(QStringList() << "")); + mLogFilesTree->insertTopLevelItem(0,TopStationItem); + + TopStationItem = new QTreeWidgetItem(static_cast(nullptr)); + TopStationItem->setText(0,"Berri-UQAM"); + ItemInfo = new CTreeItemInfo; + ItemInfo->TreeItemType = TREE_ITEM_STATION_TYPE; + ItemInfo->TreeItemPath = QString(mNetworkBasePath) + "BUQ4"; + TopStationItem->setData(0,Qt::UserRole,QVariant::fromValue((void*)ItemInfo)); + TopStationItem->addChild(new QTreeWidgetItem(QStringList() << "")); + mLogFilesTree->insertTopLevelItem(1,TopStationItem); + + TopStationItem = new QTreeWidgetItem(static_cast(nullptr)); + TopStationItem->setText(0,"Côte-Vertu"); + ItemInfo = new CTreeItemInfo; + ItemInfo->TreeItemType = TREE_ITEM_STATION_TYPE; + ItemInfo->TreeItemPath = QString(mNetworkBasePath) + "CVRT"; + TopStationItem->setData(0,Qt::UserRole,QVariant::fromValue((void*)ItemInfo)); + TopStationItem->addChild(new QTreeWidgetItem(QStringList() << "")); + mLogFilesTree->insertTopLevelItem(2,TopStationItem); + + + TopStationItem = new QTreeWidgetItem(static_cast(nullptr)); + TopStationItem->setText(0,"H-Beaugrand"); + ItemInfo = new CTreeItemInfo; + ItemInfo->TreeItemType = TREE_ITEM_STATION_TYPE; + ItemInfo->TreeItemPath = QString(mNetworkBasePath) + "HBGR"; + TopStationItem->setData(0,Qt::UserRole,QVariant::fromValue((void*)ItemInfo)); + TopStationItem->addChild(new QTreeWidgetItem(QStringList() << "")); + mLogFilesTree->insertTopLevelItem(3,TopStationItem); + + + TopStationItem = new QTreeWidgetItem(static_cast(nullptr)); + TopStationItem->setText(0,"Longueuil"); + ItemInfo = new CTreeItemInfo; + ItemInfo->TreeItemType = TREE_ITEM_STATION_TYPE; + ItemInfo->TreeItemPath = QString(mNetworkBasePath) + "LONG"; + TopStationItem->setData(0,Qt::UserRole,QVariant::fromValue((void*)ItemInfo)); + TopStationItem->addChild(new QTreeWidgetItem(QStringList() << "")); + mLogFilesTree->insertTopLevelItem(4,TopStationItem); + + + TopStationItem = new QTreeWidgetItem(static_cast(nullptr)); + TopStationItem->setText(0,"Montmorency"); + ItemInfo = new CTreeItemInfo; + ItemInfo->TreeItemType = TREE_ITEM_STATION_TYPE; + ItemInfo->TreeItemPath = QString(mNetworkBasePath) + "MMO"; + TopStationItem->setData(0,Qt::UserRole,QVariant::fromValue((void*)ItemInfo)); + TopStationItem->addChild(new QTreeWidgetItem(QStringList() << "")); + mLogFilesTree->insertTopLevelItem(5,TopStationItem); + + + TopStationItem = new QTreeWidgetItem(static_cast(nullptr)); + TopStationItem->setText(0,"Snowdon"); + ItemInfo = new CTreeItemInfo; + ItemInfo->TreeItemType = TREE_ITEM_STATION_TYPE; + ItemInfo->TreeItemPath = QString(mNetworkBasePath) + "SNW5"; + TopStationItem->setData(0,Qt::UserRole,QVariant::fromValue((void*)ItemInfo)); + TopStationItem->addChild(new QTreeWidgetItem(QStringList() << "")); + mLogFilesTree->insertTopLevelItem(6,TopStationItem); + + + TopStationItem = new QTreeWidgetItem(static_cast(nullptr)); + TopStationItem->setText(0,"St-Michel"); + ItemInfo = new CTreeItemInfo; + ItemInfo->TreeItemType = TREE_ITEM_STATION_TYPE; + ItemInfo->TreeItemPath = QString(mNetworkBasePath) + "SMIC"; + TopStationItem->setData(0,Qt::UserRole,QVariant::fromValue((void*)ItemInfo)); + TopStationItem->addChild(new QTreeWidgetItem(QStringList() << "")); + mLogFilesTree->insertTopLevelItem(7,TopStationItem); + + mLogFilesTree->sortByColumn(0,Qt::AscendingOrder); + + mSummaryText = new QGraphicsTextItem(this); QFont textfont; textfont.setPointSize(12); @@ -149,6 +268,17 @@ CLogsListPage::CLogsListPage(QGraphicsWidget *Parent) mShowProblematicTrainsChkbx->setChecked(true); connect(mShowProblematicTrainsChkbx,SIGNAL(stateChanged(int)),this,SLOT(CheckBoxClicked(int))); + WidgetProxy = new QGraphicsProxyWidget(this); + mLoadTreeLogDetails = new QCheckBox("Charger détails"); + WidgetProxy->setWidget(mLoadTreeLogDetails); + WidgetProxy->setPos(190,390); + mLoadTreeLogDetails->setChecked(true); + connect(mLoadTreeLogDetails,SIGNAL(stateChanged(int)),this,SLOT(CheckBoxClicked(int))); + + mTreeLoadingStatusLabel = new QGraphicsTextItem(this); + mTreeLoadingStatusLabel->setPlainText(""); + mTreeLoadingStatusLabel->setPos(190,395); + mTreeLoadingStatusLabel->hide(); QGraphicsTextItem *Label = new QGraphicsTextItem(this); Label->setPlainText("Station:"); @@ -174,23 +304,36 @@ CLogsListPage::CLogsListPage(QGraphicsWidget *Parent) mViewZTLogBtn = new CPushButton(this,"./Images/log.png",false,0); mViewZTLogBtn->resize(50,50); - mViewZTLogBtn->setPos(400,25); + mViewZTLogBtn->setPos(400,375); connect(mViewZTLogBtn,SIGNAL(clicked(CPushButton*)),this,SLOT(ViewZTLogBtnClicked(CPushButton*))); mSaveCSVLogBtn = new CPushButton(this,"./Images/csv.png",false,0); mSaveCSVLogBtn->resize(50,50); - mSaveCSVLogBtn->setPos(400,100); + mSaveCSVLogBtn->setPos(400,450); connect(mSaveCSVLogBtn,SIGNAL(clicked(CPushButton*)),this,SLOT(SaveCSVLogBtnClicked(CPushButton*))); mDeleteFileButton = new CPushButton(this,"./Images/file_delete.png",false,0); mDeleteFileButton->resize(50,50); - mDeleteFileButton->setPos(400,175); + mDeleteFileButton->setPos(400,525); connect(mDeleteFileButton,SIGNAL(clicked(CPushButton*)),this,SLOT(DeleteSelectedLog(CPushButton*))); + mLogsTreeMode = new CPushButton(this,"./Images/directory.png",false,0); + mLogsTreeMode->resize(50,50); + mLogsTreeMode->setPos(475,375); + connect(mLogsTreeMode,SIGNAL(clicked(CPushButton*)),this,SLOT(TreeLogsViewModeSelected(CPushButton*))); + + mLogsTableMode = new CPushButton(this,"./Images/database.png",false,0); + mLogsTableMode->resize(50,50); + mLogsTableMode->setPos(475,450); + connect(mLogsTableMode,SIGNAL(clicked(CPushButton*)),this,SLOT(TableLogsViewModeSelected(CPushButton*))); mSaveCSVLogBtn->hide(); mDeleteFileButton->hide(); +// TreeLogsViewModeSelected(mLogsTreeMode); + TableLogsViewModeSelected(mLogsTableMode); + + @@ -241,9 +384,9 @@ void CLogsListPage::ButtonClicked(CTextButtonWidget *BtnPtr) void CLogsListPage::EnableEngineeringMode() { - mSaveCSVLogBtn->show(); - mDeleteFileButton->show(); - mProtectLogChkBx->setEnabled(true); + mSaveCSVLogBtn->hide(); + mDeleteFileButton->hide(); + mProtectLogChkBx->setEnabled(false); } unsigned int CLogsListPage::RefreshList() @@ -482,18 +625,183 @@ void CLogsListPage::LogsTableCellClicked(int row, int column) // qDebug("Selection : %d",row); QList *LogsList = mLogMgrHandle->GetLogsList(); - float MeanSpeed = 0.0; - QString Summary; +// float MeanSpeed = 0.0; +// QString Summary; if(mLogsTable->item(row,0) == 0) return; int ItemIndex = mLogsTable->item(row,0)->data(Qt::UserRole).toInt(); - //if(LogsList->at(row)->mZTLogType == ZT1_LOG_TYPE) - if(LogsList->at(ItemIndex)->mZTLogType == ZT1_LOG_TYPE) + + UpdateSummaryText(LogsList->at(ItemIndex)); +// if(LogsList->at(ItemIndex)->mZTLogType == ZT1_LOG_TYPE) +// { +//// //CZT1LogElement *ZT1LogElement = (CZT1LogElement*) LogsList->at(row); +// CZT1LogElement *ZT1LogElement = (CZT1LogElement*) LogsList->at(ItemIndex); + +// if(ZT1LogElement->mFileProtected == true) +// { +// mProtectLogChkBx->setCheckState(Qt::Checked); +// } +// else +// { +// mProtectLogChkBx->setCheckState(Qt::Unchecked); +// } + +// QString Problem = "N/A"; +// if(ZT1LogElement->mFlags.mIsProblematicPassage == 1) +// { +// Problem = "OUI"; +// } +// else if(ZT1LogElement->mFlags.mIsProblematicPassage == 0) +// { +// Problem = "NON"; +// } +// MeanSpeed = ZT1LogElement->mMeanSpeed; + +// QString TrainType = CZTData::GetModbusTrainTypeString(ZT1LogElement->mFlags.mModbusTrainType); +// if(TrainType == "Inconnu") +// { +// TrainType = CZTData::GetTrainTypeString(ZT1LogElement->mTrainType); +// } + +// QString TrainCompo = "Non Disponible"; +// // if(!((ZT1LogElement->mFlags.mTrainCompo1 == 0) && (ZT1LogElement->mFlags.mTrainCompo2 == 0) && (ZT1LogElement->mFlags.mTrainCompo3 == 0))) +// { +// TrainCompo = QString("%1-%2-%3").arg(ZT1LogElement->mFlags.mTrainCompo1)\ +// .arg(ZT1LogElement->mFlags.mTrainCompo2) +// .arg(ZT1LogElement->mFlags.mTrainCompo3); +// } + +// QString Iti("Principal"); +// if(ZT1LogElement->mFlags.mZT1ITI == ZT_SECONDARY_ITI) +// { +// Iti = "Secondaire (10/22)"; +// } + +// Summary = QString("Passage:\n\nDate: %1\nHeure: %2\nItinéraire: %7\nZone Test : ZT1\nTrain : %3\nCompo: %6\nNombre d'éléments: %4\nProblématique: %5\n\n\nDéclenchements: \n")\ +// .arg(ZT1LogElement->mPassageDateTime.toString("yyyy/MM/dd"))\ +// .arg(ZT1LogElement->mPassageDateTime.toString("hh:mm:ss"))\ +// .arg(TrainType)\ +// .arg(ZT1LogElement->mNbElements)\ +// .arg(Problem) +// .arg(TrainCompo) +// .arg(Iti); +//// Summary.sprintf("Passage:\n\nDate: %s\nHeure: %s\nZone Test : ZT1\nTrain : %s\nNombre d'éléments: %d\nProblématique: %s\n\n\nDéclenchements: \n", +//// ZT1LogElement->mPassageDateTime.toString("yyyy/MM/dd").toAscii().data(), +//// ZT1LogElement->mPassageDateTime.toString("hh:mm:ss").toAscii().data(), +//// CZTData::GetTrainTypeString(ZT1LogElement->mTrainType), +//// ZT1LogElement->mNbElements, +//// Problem.toAscii().data()); + +// if(ZT1LogElement->mZTDetections.size() > 0) +// { +// for(int i = 0; i < ZT1LogElement->mZTDetections.size(); i++) +// { +// QString temp; +// if(ZT1LogElement->mZTDetections.at(i)->mDetectionID == DETECTION_FN_DETECTION) +// { +// temp.sprintf("%s au bogie %d\n",CZTData::GetErrorString(ZT1LogElement->mZTDetections.at(i)->mDetectionID),ZT1LogElement->mZTDetections.at(i)->mRank); +// } +// else +// { +// temp.sprintf("%s au rang %d\n",CZTData::GetErrorString(ZT1LogElement->mZTDetections.at(i)->mDetectionID),ZT1LogElement->mZTDetections.at(i)->mRank); +// } +// Summary += temp; +// if(i >= MAX_DETECTION_LIST_NBR - 1) +// { +// temp = " - Autres déclenchements non affichés -"; +// Summary += temp; +// break; +// } +// } +// } +// else +// Summary += "Aucun déclenchement"; +// } +// //else if(LogsList->at(row)->mZTLogType == ZT2_LOG_TYPE) +// else if(LogsList->at(ItemIndex)->mZTLogType == ZT2_LOG_TYPE) +// { +// //CZT2LogElement *ZT2LogElement = (CZT2LogElement*) LogsList->at(row); +// CZT2LogElement *ZT2LogElement = (CZT2LogElement*) LogsList->at(ItemIndex); + +// if(ZT2LogElement->mFileProtected == true) +// { +// mProtectLogChkBx->setCheckState(Qt::Checked); +// } +// else +// { +// mProtectLogChkBx->setCheckState(Qt::Unchecked); +// } + +// QString Problem = "N/A"; +// if(ZT2LogElement->mFlags.mIsProblematicPassage == 1) +// { +// Problem = "OUI"; +// } +// else if(ZT2LogElement->mFlags.mIsProblematicPassage == 0) +// { +// Problem = "NON"; +// } +//// Summary.sprintf("Statistiques du passage:\n\nDate: %s\nHeure: %s\nZone Test: ZT2\nNombre d'éléments: %d\nProblématique: %s\n\n\n\nDéclenchements: \n", +//// ZT2LogElement->mPassageDateTime.toString("yyyy/MM/dd").toAscii().data(), +//// ZT2LogElement->mPassageDateTime.toString("hh:mm:ss").toAscii().data(), +//// ZT2LogElement->mNbElements, +//// Problem.toAscii().data()); + +// QString TrainType = CZTData::GetModbusTrainTypeString(ZT2LogElement->mFlags.mModbusTrainType); + +// QString TrainCompo = "Non Disponible"; +// if(ZT2LogElement->mFlags.mTrainCompo1 != 0) +// { +// TrainCompo = QString("%1-%2-%3").arg(ZT2LogElement->mFlags.mTrainCompo1)\ +// .arg(ZT2LogElement->mFlags.mTrainCompo2) +// .arg(ZT2LogElement->mFlags.mTrainCompo3); +// } + +// Summary = QString("Passage:\n\nDate: %1\nHeure: %2\nZone Test : ZT2\nTrain : %3\nCompo: %6\nNombre d'éléments: %4\nProblématique: %5\n\n\nDéclenchements: \n")\ +// .arg(ZT2LogElement->mPassageDateTime.toString("yyyy/MM/dd"))\ +// .arg(ZT2LogElement->mPassageDateTime.toString("hh:mm:ss"))\ +// .arg(TrainType)\ +// .arg(ZT2LogElement->mNbElements)\ +// .arg(Problem) +// .arg(TrainCompo); + +// if(ZT2LogElement->mZTDetections.size() > 0) +// { +// for(int i = 0; i < ZT2LogElement->mZTDetections.size(); i++) +// { +// QString temp; +// temp.sprintf("%s au rang %d\n",CZTData::GetErrorString(ZT2LogElement->mZTDetections.at(i)->mDetectionID),ZT2LogElement->mZTDetections.at(i)->mRank); +// Summary += temp; +// if(i >= MAX_DETECTION_LIST_NBR-1) +// { +// temp = "- Autres déclenchements non affichés -"; +// Summary += temp; +// break; +// } +// } +// } +// else +// Summary += "Aucun déclenchement"; + +// } +// mSummaryText->setPlainText(Summary); + + CLogElement* Element = mLogMgrHandle->LoadLogData(LogsList->at(ItemIndex)); + mProgramHandle->LogViewRequest(Element,this); + mLogMgrHandle->FreeLogData(Element); + +} + +int CLogsListPage::UpdateSummaryText(CLogElement *Element) +{ + float MeanSpeed = 0.0; + QString Summary; + if(Element->mZTLogType == ZT1_LOG_TYPE) { // //CZT1LogElement *ZT1LogElement = (CZT1LogElement*) LogsList->at(row); - CZT1LogElement *ZT1LogElement = (CZT1LogElement*) LogsList->at(ItemIndex); + CZT1LogElement *ZT1LogElement = (CZT1LogElement*) Element; if(ZT1LogElement->mFileProtected == true) { @@ -513,7 +821,7 @@ void CLogsListPage::LogsTableCellClicked(int row, int column) { Problem = "NON"; } - MeanSpeed = ZT1LogElement->mMeanSpeed; + MeanSpeed = ZT1LogElement->mMeanSpeed; QString TrainType = CZTData::GetModbusTrainTypeString(ZT1LogElement->mFlags.mModbusTrainType); if(TrainType == "Inconnu") @@ -555,16 +863,16 @@ void CLogsListPage::LogsTableCellClicked(int row, int column) for(int i = 0; i < ZT1LogElement->mZTDetections.size(); i++) { QString temp; - if(ZT1LogElement->mZTDetections.at(i)->mDetectionID == DETECTION_FN_DETECTION) - { - temp.sprintf("%s au bogie %d\n",CZTData::GetErrorString(ZT1LogElement->mZTDetections.at(i)->mDetectionID),ZT1LogElement->mZTDetections.at(i)->mRank); - } - else - { - temp.sprintf("%s au rang %d\n",CZTData::GetErrorString(ZT1LogElement->mZTDetections.at(i)->mDetectionID),ZT1LogElement->mZTDetections.at(i)->mRank); - } + if(ZT1LogElement->mZTDetections.at(i)->mDetectionID == DETECTION_FN_DETECTION) + { + temp.sprintf("%s au bogie %d\n",CZTData::GetErrorString(ZT1LogElement->mZTDetections.at(i)->mDetectionID),ZT1LogElement->mZTDetections.at(i)->mRank); + } + else + { + temp.sprintf("%s au rang %d\n",CZTData::GetErrorString(ZT1LogElement->mZTDetections.at(i)->mDetectionID),ZT1LogElement->mZTDetections.at(i)->mRank); + } Summary += temp; - if(i >= MAX_DETECTION_LIST_NBR - 1) + if(i >= MAX_DETECTION_LIST_NBR - 1) { temp = " - Autres déclenchements non affichés -"; Summary += temp; @@ -576,10 +884,10 @@ void CLogsListPage::LogsTableCellClicked(int row, int column) Summary += "Aucun déclenchement"; } //else if(LogsList->at(row)->mZTLogType == ZT2_LOG_TYPE) - else if(LogsList->at(ItemIndex)->mZTLogType == ZT2_LOG_TYPE) + else if(Element->mZTLogType == ZT2_LOG_TYPE) { //CZT2LogElement *ZT2LogElement = (CZT2LogElement*) LogsList->at(row); - CZT2LogElement *ZT2LogElement = (CZT2LogElement*) LogsList->at(ItemIndex); + CZT2LogElement *ZT2LogElement = (CZT2LogElement*) Element; if(ZT2LogElement->mFileProtected == true) { @@ -630,7 +938,7 @@ void CLogsListPage::LogsTableCellClicked(int row, int column) QString temp; temp.sprintf("%s au rang %d\n",CZTData::GetErrorString(ZT2LogElement->mZTDetections.at(i)->mDetectionID),ZT2LogElement->mZTDetections.at(i)->mRank); Summary += temp; - if(i >= MAX_DETECTION_LIST_NBR-1) + if(i >= MAX_DETECTION_LIST_NBR-1) { temp = "- Autres déclenchements non affichés -"; Summary += temp; @@ -643,11 +951,7 @@ void CLogsListPage::LogsTableCellClicked(int row, int column) } mSummaryText->setPlainText(Summary); - - CLogElement* Element = mLogMgrHandle->LoadLogData(LogsList->at(ItemIndex)); - mProgramHandle->LogViewRequest(Element,this); - mLogMgrHandle->FreeLogData(Element); - + return RET_OK; } void CLogsListPage::StationFilterSelected(int Index) @@ -852,3 +1156,396 @@ void CLogsListPage::TableDoubleClicked(int row, int col) Q_UNUSED(row) // ButtonClicked(mViewLogDataButton); } + +void CLogsListPage::LogsTreeItemExpanded(QTreeWidgetItem *item) +{ + CTreeItemInfo *ItemInfo = (CTreeItemInfo*)item->data(0,Qt::UserRole).value(); + if(ItemInfo) + { + + switch(ItemInfo->TreeItemType) + { + case TREE_ITEM_STATION_TYPE: + { + qDebug("%s",qPrintable(ItemInfo->TreeItemPath)); + + //delete all tree + qDebug("Deleting tree"); + while(item->childCount() > 0) //delete directories branch + { + QTreeWidgetItem *DirItem = item->takeChild(0); + + while(DirItem->childCount() > 0) //delete logs list + { + QTreeWidgetItem *LogItem = DirItem->takeChild(0); + CTreeItemInfo *Info = (CTreeItemInfo*)LogItem->data(0,Qt::UserRole).value(); + if(Info) + delete Info; + // DirItem->removeChild(LogItem); + } + + CTreeItemInfo *Info = (CTreeItemInfo*)DirItem->data(0,Qt::UserRole).value(); + if(Info) + delete Info; + + // item->removeChild(DirItem); + } + + qDebug("Tree deleted. Populating data"); + CTreeItemInfo *Info = (CTreeItemInfo*)item->data(0,Qt::UserRole).value(); + if(Info) + { + PopulateDirectoriesTreeBranch(item,Info->TreeItemPath); + } + else + { + qDebug("Invalid path in station tree item..."); + } + + mLogFilesTree->resizeColumnToContents(0); + + break; + } + case TREE_ITEM_DIR_TYPE: + { + + qDebug("Deleting %d log items",item->childCount()); + while(item->childCount() > 0) //delete log items + { + QTreeWidgetItem *LogItem = item->takeChild(0); + CTreeItemInfo *Info = (CTreeItemInfo*)LogItem->data(0,Qt::UserRole).value(); + if(Info) + delete Info; + + delete LogItem; + //item->removeChild(LogItem); + } + + qDebug("Logs deleted. Populating data"); + CTreeItemInfo *Info = (CTreeItemInfo*)item->data(0,Qt::UserRole).value(); + if(Info) + { + PopulateLogFilesTreeBranch(item,Info->TreeItemPath); + } + else + { + qDebug("Invalid path in station tree item..."); + } + + qDebug("Data populated..."); + mLogFilesTree->resizeColumnToContents(0); + break; + } + case TREE_ITEM_LOGFILE_TYPE: + { + break; + } + } + } +} + +void CLogsListPage::LogsTreeItemCollapsed(QTreeWidgetItem *item) +{ + + if(item->parent()) + { + mLogFilesTree->setCurrentItem(item->parent()); + } + + CTreeItemInfo *ItemInfo = (CTreeItemInfo*)item->data(0,Qt::UserRole).value(); + if(ItemInfo) + { + + switch(ItemInfo->TreeItemType) + { + case TREE_ITEM_STATION_TYPE: + { + qDebug("%s",qPrintable(ItemInfo->TreeItemPath)); + + //delete all tree + qDebug("Deleting %d tree items",item->childCount()); + while(item->childCount() > 0) //delete directories branch + { + QTreeWidgetItem *DirItem = item->takeChild(0); + + qDebug("Deleting %d logs items",DirItem->childCount()); + while(DirItem->childCount() > 0) //delete logs list + { + // qDebug("Taking child"); + QTreeWidgetItem *LogItem = DirItem->takeChild(0); + CTreeItemInfo *Info = (CTreeItemInfo*)LogItem->data(0,Qt::UserRole).value(); + // qDebug("Deleting info"); + if(Info) + { + // qDebug("delete.."); + delete Info; + } + // qDebug("Tree item deleted"); + } + CTreeItemInfo *Info = (CTreeItemInfo*)DirItem->data(0,Qt::UserRole).value(); + if(Info) + delete Info; + +// item->removeChild(DirItem); + } + + qDebug("Tree deleted."); + item->addChild(new QTreeWidgetItem(QStringList() << "VIDE")); //add an empty item + + mLogFilesTree->resizeColumnToContents(0); + + break; + } + case TREE_ITEM_DIR_TYPE: + { + + qDebug("Deleting %d log items",item->childCount()); + while(item->childCount() > 0) //delete log items + { + // qDebug("Taking child"); + QTreeWidgetItem *LogItem = item->takeChild(0); + CTreeItemInfo *Info = (CTreeItemInfo*)LogItem->data(0,Qt::UserRole).value(); + // qDebug("Deleting info"); + if(Info) + { + // qDebug("delete.."); + delete Info; + } + // qDebug("Tree item deleted"); + + delete LogItem; + } + + qDebug("Logs deleted."); + item->addChild(new QTreeWidgetItem(QStringList() << "VIDE")); //add an empty item + + mLogFilesTree->resizeColumnToContents(1); + break; + } + case TREE_ITEM_LOGFILE_TYPE: + { + break; + } + } + } +} +int CLogsListPage::PopulateDirectoriesTreeBranch(QTreeWidgetItem *parent, QString Path) +{ + QDir Directory(Path); + QFileInfoList DirList = Directory.entryInfoList(QDir::Dirs|QDir::NoDotAndDotDot); + if(DirList.isEmpty()) + { + parent->addChild(new QTreeWidgetItem(QStringList() << "VIDE")); //add an empty item + } + else + { + for(int i = 0; i < DirList.size(); i++) + { + QTreeWidgetItem *NewDirItem = new QTreeWidgetItem(QStringList() << DirList.at(i).fileName()); + CTreeItemInfo* ItemInfo = new CTreeItemInfo; + ItemInfo->TreeItemType = TREE_ITEM_DIR_TYPE; + ItemInfo->TreeItemPath = DirList.at(i).absoluteFilePath(); + NewDirItem->setData(0,Qt::UserRole,QVariant::fromValue((void*)ItemInfo)); + NewDirItem->addChild(new QTreeWidgetItem(QStringList() << "VIDE")); //add an empty item + parent->addChild(NewDirItem); + } + } +} + +int CLogsListPage::PopulateLogFilesTreeBranch(QTreeWidgetItem *parent, QString Path) +{ + QDir Directory(Path); + QFileInfoList DirList = Directory.entryInfoList(QDir::Files|QDir::NoDotAndDotDot); + bool ShowZT1Items = (mShowZT1ItemsChkBx->checkState() == Qt::Checked); + bool ShowZT2Items = (mShowZT2ItemsChkBx->checkState() == Qt::Checked); + bool ShowNoDetections = (mShowNoDetectionsChkBx->checkState() == Qt::Checked); + bool LoadLogDetails = (mLoadTreeLogDetails->checkState() == Qt::Checked); + + float LoadingPercent = 0.0; + int Size; + + if(DirList.isEmpty()) + { + parent->addChild(new QTreeWidgetItem(QStringList() << "VIDE")); //add an empty item + } + else + { + Size = DirList.size(); + for(int i = 0; i < Size; i++) + { + LoadingPercent = (float)(i+1)/(float)Size; + LoadingPercent *= 100; + mTreeLoadingStatusLabel->setPlainText(QString("Chargement:%1\%").arg(LoadingPercent)); + + // QApplication::processEvents(); + CTreeItemInfo* ItemInfo = new CTreeItemInfo; + ItemInfo->TreeItemType = TREE_ITEM_LOGFILE_TYPE; + ItemInfo->TreeItemPath = DirList.at(i).filePath(); + + QStringList ItemData; + if(DirList.at(i).suffix() == "bin") + { + if(LoadLogDetails == true) + { + unsigned int ret; + CLogElement* Element = CTrainLogFileMgr::instance()->OpenTrainLog(ItemInfo->TreeItemPath,ret); + if(ret == RET_OK) + { + if(Element->mZTLogType == ZT1_LOG_TYPE && ShowZT1Items == true) + { + CZT1LogElement *ZT1Element = (CZT1LogElement*)Element; + if(!(ShowNoDetections == false && ZT1Element->mZTDetections.size() == 0)) + { + ItemData.append(ZT1Element->mPassageDateTime.toString("yyyy/MM/dd - hh:mm:ss")); + ItemData.append(QString("%1").arg(ZT1Element->mZTDetections.size())); + ItemData.append("ZT1"); + ItemData.append(QString("%1-%2-%3").arg(ZT1Element->mFlags.mTrainCompo1).arg(ZT1Element->mFlags.mTrainCompo2).arg(ZT1Element->mFlags.mTrainCompo3)); + QTreeWidgetItem *NewDirItem = new QTreeWidgetItem(QStringList(ItemData)); + NewDirItem->setData(0,Qt::UserRole,QVariant::fromValue((void*)ItemInfo)); + parent->addChild(NewDirItem); + } + } + else if(Element->mZTLogType == ZT2_LOG_TYPE && ShowZT2Items == true) + { + CZT2LogElement *ZT2Element = (CZT2LogElement*)Element; + if(!(ShowNoDetections == false && ZT2Element->mZTDetections.size() == 0)) + { + ItemData.append(ZT2Element->mPassageDateTime.toString("yyyy/MM/dd - hh:mm:ss")); + ItemData.append(QString("%1").arg(ZT2Element->mZTDetections.size())); + ItemData.append("ZT2"); + ItemData.append(QString("%1-%2-%3").arg(ZT2Element->mFlags.mTrainCompo1).arg(ZT2Element->mFlags.mTrainCompo2).arg(ZT2Element->mFlags.mTrainCompo3)); + QTreeWidgetItem *NewDirItem = new QTreeWidgetItem(QStringList(ItemData)); + NewDirItem->setData(0,Qt::UserRole,QVariant::fromValue((void*)ItemInfo)); + parent->addChild(NewDirItem); + } + + } + delete Element; + } + + else + { + ItemData.append(DirList.at(i).baseName()); + QTreeWidgetItem *NewDirItem = new QTreeWidgetItem(QStringList(ItemData)); + NewDirItem->setData(0,Qt::UserRole,QVariant::fromValue((void*)ItemInfo)); + parent->addChild(NewDirItem); + } + } + else + { + + QTreeWidgetItem *NewDirItem = new QTreeWidgetItem(QStringList() << DirList.at(i).baseName()); + NewDirItem->setData(0,Qt::UserRole,QVariant::fromValue((void*)ItemInfo)); + parent->addChild(NewDirItem); + } + } + else if(DirList.at(i).suffix() == "txt") + { + QTreeWidgetItem *NewDirItem = new QTreeWidgetItem(QStringList() << DirList.at(i).fileName()); + NewDirItem->setData(0,Qt::UserRole,QVariant::fromValue((void*)ItemInfo)); + parent->addChild(NewDirItem); + } + else + { + delete ItemInfo; + } + + if(parent->childCount() == 0) + { + parent->addChild(new QTreeWidgetItem(QStringList() << "VIDE")); //add an empty item + } + + + } + } +} + +void CLogsListPage::LogsTreeItemSelected() +{ + QTreeWidgetItem* Selection = mLogFilesTree->selectedItems().at(0); + if(Selection) + { + CTreeItemInfo *Info = (CTreeItemInfo*)Selection->data(0,Qt::UserRole).value(); + if(Info) + { + if(Info->TreeItemType == TREE_ITEM_LOGFILE_TYPE) + { + QFileInfo FileInfo(Info->TreeItemPath); + if(FileInfo.suffix() == "bin") + { + unsigned int ret; + CLogElement* Element = CTrainLogFileMgr::instance()->OpenTrainLog(Info->TreeItemPath,ret,0,true); + if(ret == RET_OK) + {UpdateSummaryText(Element); + mProgramHandle->LogViewRequest(Element,this); + mLogMgrHandle->FreeLogData(Element); + } + } + } + + } + } +} + +void CLogsListPage::TableLogsViewModeSelected(CPushButton *Btb) +{ + mLogListTableProxy->show(); + mLogsTreeProxy->hide(); + + mShowFNChkBx->show(); + mShowCountChkBx->show(); + mShowPGChkBx->show(); + mShowPPChkBx->show(); + mShowMPM10ChkBx->show(); + mShowMRChkBx->show(); + mShowProblematicTrainsChkbx->show(); + mStationsFilterComboBox->show(); + mViewZTLogBtn->show(); + mProtectLogChkBx->show(); + mLoadTreeLogDetails->hide(); + +} + +void CLogsListPage::TreeLogsViewModeSelected(CPushButton *Btn) +{ + mLogListTableProxy->hide(); + mLogsTreeProxy->show(); + + mShowFNChkBx->hide(); + mShowCountChkBx->hide(); + mShowPGChkBx->hide(); + mShowPPChkBx->hide(); + mShowMPM10ChkBx->hide(); + mShowMRChkBx->hide(); + mShowProblematicTrainsChkbx->hide(); + mStationsFilterComboBox->hide(); + mViewZTLogBtn->hide(); + mProtectLogChkBx->hide(); + mLoadTreeLogDetails->show(); +} + +void CLogsListPage::LogsTreeItemDoubleClicked(QTreeWidgetItem *item) +{ + CTreeItemInfo *Info = (CTreeItemInfo*)item->data(0,Qt::UserRole).value(); + if(Info) + { + if(Info->TreeItemType == TREE_ITEM_LOGFILE_TYPE) + { + QFileInfo FileInfo(Info->TreeItemPath); + if(FileInfo.suffix() == "txt") + { + QFile *LogFile = new QFile(FileInfo.filePath()); + if(LogFile) + { + if(LogFile->open(QIODevice::ReadOnly | QIODevice::Text | QIODevice::Unbuffered) == true) + { + QString LogText(LogFile->readAll()); + mProgramHandle->ShowZTLogRequest(LogText,0,-1); + LogFile->close(); + } + delete LogFile; + } + } + } + } +} diff --git a/sources/GuiElements/LogsListPage.h b/sources/GuiElements/LogsListPage.h index 8f311a1..6a61abf 100644 --- a/sources/GuiElements/LogsListPage.h +++ b/sources/GuiElements/LogsListPage.h @@ -39,11 +39,29 @@ #include #include #include +#include #define MAX_DETECTION_LIST_NBR 6 +//#define NETWORK_LOGS_BASE_PATH "S:\\EEF\\TCPE\\72410\\72410\\BD ZT\\Logs_Reseau\\" +#define NETWORK_LOGS_BASE_PATH "D:\\Main\\Fichiers\\JOB\\OutilZT_Direct\\trains\\" + class COutilZT; +enum eTreeItemType +{ + TREE_ITEM_STATION_TYPE, + TREE_ITEM_DIR_TYPE, + TREE_ITEM_LOGFILE_TYPE +}; + +class CTreeItemInfo +{ +public: + int TreeItemType; + QString TreeItemPath; +}; + class CLogsListPage : public CGuiPage { Q_OBJECT @@ -65,25 +83,34 @@ public: private: QTableWidget *mLogsTable; + QTreeWidget *mLogFilesTree; QGraphicsTextItem *mSummaryText; CTextButtonWidget *mViewLogDataButton; CTextButtonWidget *mExportCSVLogButton; + QGraphicsProxyWidget *mLogListTableProxy, *mLogsTreeProxy; QCheckBox *mShowZT1ItemsChkBx, *mShowZT2ItemsChkBx, *mShowNoDetectionsChkBx; QCheckBox *mShowFNChkBx, *mShowCountChkBx, *mShowPGChkBx, *mShowPPChkBx,*mShowMPM10ChkBx, *mShowMRChkBx, *mShowProblematicTrainsChkbx;//, *mShowAllChkBx; + QCheckBox *mLoadTreeLogDetails; + QGraphicsTextItem *mTreeLoadingStatusLabel; QTimer *mListParsingTimer; QComboBox *mStationsFilterComboBox; QString mStationFilter; - CPushButton *mViewZTLogBtn, *mSaveCSVLogBtn,*mDeleteFileButton; + CPushButton *mViewZTLogBtn, *mSaveCSVLogBtn,*mDeleteFileButton, *mLogsTreeMode, *mLogsTableMode; QCheckBox *mProtectLogChkBx; + QString mNetworkBasePath; //bool mShowZT1Items,mShowZT2Items,mShowNoDetections,mUSBDetected; void ClearTable(); + int PopulateDirectoriesTreeBranch(QTreeWidgetItem *parent, QString Path); + int PopulateLogFilesTreeBranch(QTreeWidgetItem *parent, QString Path); + + int UpdateSummaryText(CLogElement* Element); public slots: @@ -97,8 +124,17 @@ public slots: void SaveCSVLogBtnClicked(CPushButton *); void DeleteSelectedLog(CPushButton*); void ProtectLogCheckBoxClicked(); + void TreeLogsViewModeSelected(CPushButton*); + void TableLogsViewModeSelected(CPushButton*); + + void LogsTreeItemExpanded(QTreeWidgetItem *item); + void LogsTreeItemDoubleClicked(QTreeWidgetItem *item); + void LogsTreeItemCollapsed(QTreeWidgetItem *item); + void LogsTreeItemSelected(); // void ParsingTimerExipred(); }; + + #endif // LOGSLISTPAGE_H diff --git a/sources/GuiElements/MainPage.cpp b/sources/GuiElements/MainPage.cpp index f06c709..1d6ee6d 100644 --- a/sources/GuiElements/MainPage.cpp +++ b/sources/GuiElements/MainPage.cpp @@ -57,29 +57,29 @@ CMainPage::CMainPage(QGraphicsWidget *Parent) // mTimeDisplayText->setZValue(1); mDatabaseModePushButton = new CPushButton(this,"./Images/Save-icon.png"); - mDatabaseModePushButton->setPos(10,10); - mDatabaseModePushButton->resize(50,50); + mDatabaseModePushButton->setPos(5,5); + mDatabaseModePushButton->resize(35,35); connect( mDatabaseModePushButton, SIGNAL( clicked(CPushButton*) ), this, SLOT(ButtonPressed(CPushButton*) ) ); mNetworkModePushButton = new CPushButton(this,"./Images/ethernet.png"); - mNetworkModePushButton->setPos(10,150); - mNetworkModePushButton->resize(50,50); + mNetworkModePushButton->setPos(5,150); + mNetworkModePushButton->resize(35,35); connect( mNetworkModePushButton, SIGNAL( clicked(CPushButton*) ), this, SLOT(ButtonPressed(CPushButton*) ) ); mNetworkModePushButton->hide(); mZTLogsListPushButton = new CPushButton(this,"./Images/log.png"); - mZTLogsListPushButton->setPos(10,80); - mZTLogsListPushButton->resize(50,50); + mZTLogsListPushButton->setPos(5,80); + mZTLogsListPushButton->resize(35,35); connect( mZTLogsListPushButton, SIGNAL( clicked(CPushButton*) ), this, SLOT(ButtonPressed(CPushButton*) ) ); mToolsPushButton = new CPushButton(this,"./Images/tools.png"); - mToolsPushButton->setPos(10,375); - mToolsPushButton->resize(50,50); + mToolsPushButton->setPos(5,375); + mToolsPushButton->resize(35,35); connect( mToolsPushButton, SIGNAL( clicked(CPushButton*) ), this, SLOT(ButtonPressed(CPushButton*) ) ); mDatabaseOptionsPushButton = new CPushButton(this,"./Images/database.png"); - mDatabaseOptionsPushButton->setPos(10,300); - mDatabaseOptionsPushButton->resize(50,50); + mDatabaseOptionsPushButton->setPos(5,300); + mDatabaseOptionsPushButton->resize(35,35); connect( mDatabaseOptionsPushButton, SIGNAL( clicked(CPushButton*) ), this, SLOT(ButtonPressed(CPushButton*) ) ); diff --git a/sources/MainPanel.cpp b/sources/MainPanel.cpp index abf352f..b529584 100644 --- a/sources/MainPanel.cpp +++ b/sources/MainPanel.cpp @@ -139,7 +139,7 @@ Panel::Panel() mDatabaseModeLogViewPage->DisableCloseButton(); mDatabaseModeLogViewPage->show(); - mDatabaseModeLogListPage->setPos(100,0); + mDatabaseModeLogListPage->setPos(45,0); mDatabaseModeLogListPage->resize(400,SCREEN_RES_HEIGHT-100); mDatabaseModeLogListPage->setZValue(1); mDatabaseModeLogListPage->show(); diff --git a/sources/OutilZTVersion.h b/sources/OutilZTVersion.h index 8b494d3..e4eb4d7 100644 --- a/sources/OutilZTVersion.h +++ b/sources/OutilZTVersion.h @@ -1,7 +1,7 @@ #ifndef OUTILZTVERSION_H #define OUTILZTVERSION_H -#define SOFTWARE_VERSION "1.17" +#define SOFTWARE_VERSION "1.18" //Suivi des versions //