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