1b4dd51f122bb6c5f1916c9c8c112121f60b8570
[occt.git] / samples / tools / TInspectorEXE / src / TInspectorEXE_OpenFileDialog.cxx
1 // Created on: 2017-06-16
2 // Created by: Natalia ERMOLAEVA
3 // Copyright (c) 2017 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement. 
15
16 #include <TInspectorEXE_OpenFileDialog.hxx>
17 #include <TInspectorEXE_OpenFileViewModel.hxx>
18
19 #include <inspector/TInspector_Communicator.hxx>
20
21 #include <QApplication>
22 #include <QCompleter>
23 #include <QDir>
24 #include <QFileDialog>
25 #include <QFileSystemModel>
26 #include <QItemSelectionModel>
27 #include <QGroupBox>
28 #include <QHBoxLayout>
29 #include <QHeaderView>
30 #include <QLabel>
31 #include <QLineEdit>
32 #include <QScrollBar>
33 #include <QTableView>
34 #include <QToolButton>
35 #include <QPushButton>
36 #include <QVBoxLayout>
37 #include <QWidget>
38
39 const int FONT_POINT_SIZE = 18;
40 const int ICON_SIZE = 40;
41
42 const int OPEN_DIALOG_WIDTH = 550;
43 const int OPEN_DIALOG_HEIGHT = 200;
44
45 const int MARGIN_DIALOG = 4;
46 const int SPACING_DIALOG = 2;
47
48 TInspector_Communicator* MyCommunicator;
49
50 // =======================================================================
51 // function : StartButton
52 // purpose :
53 // =======================================================================
54 QPushButton* TInspectorEXE_OpenButton::StartButton()
55 {
56   if (!myStartButton)
57   {
58     myStartButton = new QPushButton();
59     myStartButton->setIcon (QIcon (":folder_open.png"));
60     connect (myStartButton, SIGNAL (clicked()), this, SLOT (onStartButtonClicked()));
61   }
62   return myStartButton;
63 }
64
65 // =======================================================================
66 // function : onStartButtonClicked
67 // purpose :
68 // =======================================================================
69 void TInspectorEXE_OpenButton::onStartButtonClicked()
70 {
71   QPushButton* aButton = (QPushButton*)sender();
72   TCollection_AsciiString aPluginName (aButton->objectName().toStdString().c_str());
73   if (aPluginName.IsEmpty())
74     return;
75   
76   QString aDataDirName = QDir::currentPath();
77   if (myDefaultDirs.IsBound (aPluginName))
78     aDataDirName = myDefaultDirs.Find (aPluginName).ToCString();
79
80   QString aFileName = TInspectorEXE_OpenFileDialog::OpenFile (0, aDataDirName);
81   aFileName = QDir().toNativeSeparators (aFileName);
82   if (!aFileName.isEmpty()) {
83     QApplication::setOverrideCursor (Qt::WaitCursor);
84     TInspectorEXE_OpenFileDialog::Communicator()->OpenFile (aPluginName, TCollection_AsciiString (aFileName.toUtf8().data()));
85     QApplication::restoreOverrideCursor();
86   }
87 }
88
89 // =======================================================================
90 // function : changeMargins
91 // purpose :
92 // =======================================================================
93 void changeMargins (QBoxLayout* theLayout)
94 {
95   theLayout->setContentsMargins (MARGIN_DIALOG, MARGIN_DIALOG, MARGIN_DIALOG, MARGIN_DIALOG);
96   theLayout->setSpacing (SPACING_DIALOG);
97 }
98
99 // =======================================================================
100 // function : Constructor
101 // purpose :
102 // =======================================================================
103 TInspectorEXE_OpenFileDialog::TInspectorEXE_OpenFileDialog (QWidget* theParent, const QString& theDataDirName)
104 : QDialog(theParent), myDataDir (theDataDirName)
105 {
106   setWindowTitle (theDataDirName);
107
108   QVBoxLayout* aDialogLay = new QVBoxLayout (this);
109   changeMargins (aDialogLay);
110
111   // Title label
112   QLabel* aTitleLabel = new QLabel (this);
113   aTitleLabel->setText (tr ("Open File"));
114   aDialogLay->addWidget (aTitleLabel);
115
116   // Samples View
117   QGroupBox* aSamplesBox = new QGroupBox (this);
118   aSamplesBox->setTitle (tr ("Samples"));
119   aDialogLay->addWidget (aSamplesBox);
120   QVBoxLayout* aSampleLay = new QVBoxLayout (aSamplesBox);
121   changeMargins (aSampleLay);
122   mySamplesView = createTableView (readSampleNames());
123   aSampleLay->addWidget (mySamplesView);
124
125   // Select file
126   QGroupBox* aSelectFileBox = new QGroupBox (this);
127   aSelectFileBox->setTitle (tr ("Select file"));
128   aDialogLay->addWidget (aSelectFileBox);
129   QGridLayout* aSelectFileLay = new QGridLayout (aSelectFileBox);
130   aSelectFileLay->setContentsMargins (MARGIN_DIALOG, MARGIN_DIALOG, MARGIN_DIALOG, MARGIN_DIALOG);
131
132   mySelectedName = new QLineEdit (aSelectFileBox);
133   QCompleter* aCompleter = new QCompleter();
134   QFileSystemModel* aFileSystemModel = new QFileSystemModel;
135   aFileSystemModel->setRootPath (QDir::rootPath());
136   aCompleter->setModel (aFileSystemModel);
137   mySelectedName->setCompleter (aCompleter);
138   aSelectFileLay->addWidget (mySelectedName, 1, 0);
139
140   QToolButton* aSelectFileBtn = new QToolButton (aSelectFileBox);
141   aSelectFileBtn->setIcon (QIcon (":folder_open.png"));
142   aSelectFileLay->addWidget (aSelectFileBtn, 1, 1);
143
144   myFolderApplyOpen = new QToolButton (aSelectFileBox);
145   myFolderApplyOpen->setIcon (QIcon (":folder_import.png"));
146   myFolderApplyOpen->setIconSize (QSize (ICON_SIZE, ICON_SIZE));
147   myFolderApplyOpen->setEnabled (false);
148   aSelectFileLay->addWidget (myFolderApplyOpen, 0, 2, 2, 1);
149
150   connect (mySelectedName, SIGNAL (textChanged (const QString&)),
151            this, SLOT (onNameChanged (const QString&)));
152   connect (aSelectFileBtn, SIGNAL (clicked()), this, SLOT (onSelectClicked()));
153   connect (myFolderApplyOpen, SIGNAL (clicked()), this, SLOT (onApplySelectClicked()));
154
155   resize (OPEN_DIALOG_WIDTH, OPEN_DIALOG_HEIGHT);
156 }
157
158 // =======================================================================
159 // function : OpenFile
160 // purpose :
161 // =======================================================================
162 QString TInspectorEXE_OpenFileDialog::OpenFile (QWidget* theParent, const QString& theDataDirName)
163 {
164   QString aFileName;
165   TInspectorEXE_OpenFileDialog* aDialog = new TInspectorEXE_OpenFileDialog(theParent, theDataDirName);
166   if (aDialog->exec() == QDialog::Accepted)
167     aFileName = aDialog->GetFileName();
168
169   return aFileName;
170 }
171
172 // =======================================================================
173 // function : Communicator
174 // purpose :
175 // =======================================================================
176 TInspector_Communicator* TInspectorEXE_OpenFileDialog::Communicator()
177 {
178   if (!MyCommunicator)
179     MyCommunicator = new TInspector_Communicator();
180   return MyCommunicator;
181 }
182
183 // =======================================================================
184 // function : onSampleSelectionChanged
185 // purpose :
186 // =======================================================================
187 void TInspectorEXE_OpenFileDialog::onSampleSelectionChanged (const QItemSelection& theSelected,
188                                                              const QItemSelection&)
189 {
190   QItemSelectionModel* aSelectionModel = (QItemSelectionModel*)sender();
191   if (!aSelectionModel)
192     return;
193   if (theSelected.isEmpty())
194     return;
195
196   QModelIndex anIndex = theSelected.first().indexes().first();
197   if (!anIndex.isValid())
198     return;
199
200   myFileName = aSelectionModel->model()->data (anIndex, Qt::ToolTipRole).toString();
201   accept();
202 }
203
204 // =======================================================================
205 // function : onNameChanged
206 // purpose :
207 // =======================================================================
208 void TInspectorEXE_OpenFileDialog::onNameChanged (const QString& theText)
209 {
210   QFileInfo aFileInfo (theText);
211   bool anExists = aFileInfo.exists() && aFileInfo.isFile();
212   myFolderApplyOpen->setEnabled (anExists);
213 }
214
215 // =======================================================================
216 // function : onSelectClicked
217 // purpose :
218 // =======================================================================
219 void TInspectorEXE_OpenFileDialog::onSelectClicked()
220 {
221   QString anEnteredPath;
222   QString aDirName = mySelectedName->text();
223   if (!aDirName.isEmpty())
224   {
225     QDir aDir (aDirName);
226     if (aDir.exists())
227       anEnteredPath = aDirName;
228   }
229
230   QString aFileName = QFileDialog::getOpenFileName (0, "Open document", anEnteredPath);
231
232   if (aFileName.isEmpty())
233     return; // do nothing, left the previous value
234
235   mySelectedName->setText (aFileName);
236   onNameChanged (aFileName);
237 }
238
239 // =======================================================================
240 // function : onApplySelectClicked
241 // purpose :
242 // =======================================================================
243 void TInspectorEXE_OpenFileDialog::onApplySelectClicked()
244 {
245   myFileName = mySelectedName->text();
246   accept();
247 }
248
249 // =======================================================================
250 // function : createTableView
251 // purpose :
252 // =======================================================================
253 QTableView* TInspectorEXE_OpenFileDialog::createTableView (const QStringList& theFileNames)
254 {
255   QTableView* aTableView = new QTableView (this);
256   aTableView->setFrameStyle (QFrame::NoFrame);
257   QPalette aPalette = aTableView->viewport()->palette();
258   QColor aWindowColor = aPalette.color (QPalette::Window);
259   aPalette.setBrush (QPalette::Base, aWindowColor);
260   aTableView->viewport()->setPalette (aPalette);
261
262   aTableView->horizontalHeader()->setVisible (false);
263   aTableView->verticalHeader()->setVisible (false);
264   aTableView->setGridStyle (Qt::NoPen);
265   aTableView->setModel (createModel (theFileNames));
266   aTableView->setItemDelegateForRow (0, new TInspectorEXE_OpenFileItemDelegate (aTableView,
267                                                           aPalette.color (QPalette::Highlight)));
268   aTableView->viewport()->setAttribute (Qt::WA_Hover);
269   int aCellHeight = ICON_SIZE + aTableView->verticalHeader()->defaultSectionSize();
270   aTableView->setRowHeight (0, aCellHeight);
271   int aScrollHeight = aTableView->horizontalScrollBar()->sizeHint().height();
272   aTableView->setMinimumHeight (aCellHeight + aScrollHeight);
273   QItemSelectionModel* aSelectionModel = new QItemSelectionModel (aTableView->model());
274   connect (aSelectionModel, SIGNAL (selectionChanged (const QItemSelection&, const QItemSelection&)),
275            this, SLOT (onSampleSelectionChanged (const QItemSelection&, const QItemSelection&)));
276   aTableView->setSelectionModel (aSelectionModel);
277
278   return aTableView;
279 }
280
281 // =======================================================================
282 // function : createModel
283 // purpose :
284 // =======================================================================
285 QAbstractItemModel* TInspectorEXE_OpenFileDialog::createModel (const QStringList& theFileNames)
286 {
287   TInspectorEXE_OpenFileViewModel* aModel = new TInspectorEXE_OpenFileViewModel (this);
288   aModel->Init (theFileNames);
289   return aModel;
290 }
291
292 // =======================================================================
293 // function : readSampleNames
294 // purpose :
295 // =======================================================================
296 QStringList TInspectorEXE_OpenFileDialog::readSampleNames()
297 {
298   QStringList aNames;
299
300   QDir aDir(myDataDir);
301   aDir.setSorting(QDir::Name);
302
303   QFileInfoList aDirEntries = aDir.entryInfoList();
304   for (int aDirId = 0; aDirId < aDirEntries.size(); ++aDirId)
305   {
306     QFileInfo aFileInfo = aDirEntries.at(aDirId);
307     if (aFileInfo.isFile())
308       aNames.append (aFileInfo.absoluteFilePath());
309   }
310   return aNames;
311 }