Salome HOME
222a2d28f6a25dbf94b7bf1f797bfd2c3817a3c9
[modules/gui.git] / tools / RemoteFileBrowser / QMachineBrowser.cxx
1 // Copyright (C) 2017-2022  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony GEAY (EDF R&D)
20
21 #include "QMachineBrowser.h"
22 #include "QRemoteFileBrowser.h"
23
24 #include "QDir"
25 #include "QFileInfo"
26 #include "QVBoxLayout"
27 #include "QPushButton"
28 #include "QMessageBox"
29 #include "QInputDialog"
30 #include "QXmlStreamReader"
31 #include "QProcessEnvironment"
32
33 #include <iostream>
34
35 constexpr const char localhost[]="localhost";
36
37 QMachineSelector::QMachineSelector(QWidget *parent):QComboBox(parent)
38 {
39   this->fillMachines();
40 }
41
42 void QMachineSelector::initLocation()
43 {
44   this->assignToLocalhost();
45 }
46
47 void QMachineSelector::fillMachines()
48 {
49   this->fillMachinesFromCatalog();
50   this->fillMachinesFromSettings();
51 }
52
53 void QMachineSelector::appendEntry(const QString& entry)
54 {
55   for(int i=0;i<this->count();i++)
56     {
57       if(this->itemText(i)==entry)
58         return ;
59     }
60   this->insertItem(this->count(),entry);
61   this->setCurrentIndex(this->count()-1);
62 }
63
64 void QMachineSelector::fillMachinesFromCatalog()
65 {
66   constexpr const char APPLI[]="APPLI";
67   constexpr const char RESOURCES[]="CatalogResources.xml";
68   if(!QProcessEnvironment::systemEnvironment().contains(APPLI))
69     return ;
70   QString appli(QProcessEnvironment::systemEnvironment().value(APPLI));
71   QFileInfo fi(QDir::homePath(),appli);
72   if(!(fi.exists() && fi.isDir()))
73     return ;
74   QFileInfo fi2(QDir(fi.canonicalFilePath()),QString(RESOURCES));
75   if(!(fi2.exists() && fi2.isFile()))
76     return ;
77   QFile file(fi2.canonicalFilePath());
78   if(!file.open(QFile::ReadOnly | QFile::Text))
79     {
80       return ;
81     }
82   QXmlStreamReader reader;
83   reader.setDevice(&file);
84   reader.readNext();
85   while(!reader.atEnd())
86     {
87       if(reader.isStartElement())
88         {
89           if(reader.name()=="machine")
90             {
91               foreach(const QXmlStreamAttribute &attr, reader.attributes())
92                 {
93                   if(attr.name().toString()==QLatin1String("name"))
94                     {
95                       this->insertItem(this->count(),attr.value().toString());
96                     }
97                 }
98             }
99           reader.readNext();
100         }
101       else
102         reader.readNext();
103     }
104 }
105
106 void QMachineSelector::assignToLocalhost()
107 {
108   int i(0);
109   for(;i<this->count();i++)
110     if(this->itemText(i)==localhost)
111       break ;
112   if(i==this->count())
113     {
114       this->insertItem(this->count(),QString(localhost));
115       this->setCurrentIndex(this->count()-1);
116     }
117   else
118     this->setCurrentIndex(i);
119 }
120
121 void QMachineSelector::fillMachinesFromSettings()
122 {
123 }
124
125 QMachineManager::QMachineManager(QWidget *parent):QWidget(parent),_pb(nullptr),_ms(nullptr)
126 {
127   QHBoxLayout *lay(new QHBoxLayout(this));
128   _pb=new QPushButton(this);
129   _pb->setText("Add");
130   _pb->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed);
131   lay->addWidget(_pb);
132   _ms=new QMachineSelector(this);
133   lay->addWidget(_ms);
134   connect(_pb,SIGNAL(clicked()),this,SLOT(newEntryRequested()));
135 }
136
137 void QMachineManager::initLocation()
138 {
139   _ms->initLocation();
140 }
141
142 QString QMachineManager::getSelectedHost() const
143 {
144   return _ms->currentText();
145 }
146
147 void QMachineManager::newEntryRequested()
148 {
149   constexpr int timeEllapse=3000;
150   bool isOK(false);
151   QString newEntry(QInputDialog::getItem(this,"Append new host","Hostname",QStringList(),/*current*/0,/*editable*/true,&isOK,Qt::Tool));
152   if(!isOK)
153     return ;
154   {
155     QProcess proc;
156     {
157       QStringList st(newEntry);
158       st << "-c" << "1" << "-w" << QString::number(timeEllapse/1000);//attempt to send one packet within timeEllapse ms
159       proc.start("ping",st);
160     }
161     if(proc.waitForFinished(-1))
162       {
163         if(proc.exitCode()!=0)
164           {
165             QMessageBox::information(this,"Information",QString("host %1 ping failed !").arg(newEntry));
166             return ;
167           }
168       }
169     else
170       {
171         QMessageBox::information(this,"Information",QString("host %1 ping failed !").arg(newEntry));
172         return ;
173       }
174   }
175   _ms->appendEntry(newEntry);
176 }
177
178 QMachineBrowser::QMachineBrowser(QWidget *parent):QWidget(parent),_msel(nullptr),_le(nullptr)
179 {
180   QVBoxLayout *lay(new QVBoxLayout(this));
181   _msel=new QMachineManager(this);
182   _le=new QLineEdit(this);
183   lay->addWidget(_msel);
184   lay->addWidget(_le);
185   connect(_le,SIGNAL(returnPressed()),this,SIGNAL(locationChanged()));
186 }
187
188 void QMachineBrowser::initLocation()
189 {
190   _msel->initLocation();
191   _le->setText(QDir::currentPath());
192   emit this->locationChanged();
193 }
194
195 QRemoteFileSystemModel *QMachineBrowser::generateModel()
196 {
197   FileLoader *fl(this->generateFileLoader());
198   return new QRemoteFileSystemModel(this,fl);
199 }
200
201 FileLoader *QMachineBrowser::generateFileLoader()
202 {
203   FileLoader *fl(nullptr);
204   QString host(_msel->getSelectedHost());
205   if(host==localhost)
206     fl=new LocalFileLoader(_le->text());
207   else
208     fl=new RemoteFileLoader(host,_le->text());
209   return fl;
210 }