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