VPTissue Reference Manual
ConverterWindow.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2011-2016 Universiteit Antwerpen
3  *
4  * Licensed under the EUPL, Version 1.1 or as soon they will be approved by
5  * the European Commission - subsequent versions of the EUPL (the "Licence");
6  * You may not use this work except in compliance with the Licence.
7  * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl5
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the Licence is distributed on an "AS IS" basis,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the Licence for the specific language governing
13  * permissions and limitations under the Licence.
14  */
20 #include "ConverterWindow.h"
21 
23 #include "gui/ConversionList.h"
25 #include "util/misc/Exception.h"
26 #include "util/misc/StringUtils.h"
27 
28 #include <QApplication>
29 #include <QBoxLayout>
30 #include <QCloseEvent>
31 #include <QComboBox>
32 #include <QFileDialog>
33 #include <QFormLayout>
34 #include <QGroupBox>
35 #include <QLabel>
36 #include <QLineEdit>
37 #include <QMenu>
38 #include <QMessageBox>
39 #include <QProgressDialog>
40 #include <QPushButton>
41 #include <QSignalMapper>
42 #include <QString>
43 
44 #include <algorithm>
45 #include <cassert>
46 
47 
48 using namespace std;
49 using namespace SimPT_Sim::Util;
50 
51 namespace SimPT_Shell {
52 
53 const QRegExp ConverterWindow::g_export_name_regex("[^\\x0-\\x1F<>:/\\\\|]*"); // The allowed characters are anything except 0x0-0x1F, '<', '>', ':', '"', '/', '\', and '|'. (Windows file naming)
54 
55 ConverterWindow::ConverterWindow(
56  Ws::Project* project,
57  std::vector<IConverterFormat*> formats,
58  shared_ptr<SimShell::Ws::MergedPreferences> prefs,
59  const string& window_title,
60  QWidget* parent)
61  : QDialog(parent),
62  m_project(project),
63  m_formats(formats),
64  m_preferences(prefs)
65 {
66  setWindowModality(Qt::WindowModal);
67  setWindowTitle(QString::fromStdString(window_title));
68  setMinimumSize(400, 500);
69 
70  // GUI layout
71  QVBoxLayout *layout = new QVBoxLayout();
72 
73  // Conversion list & loading
74  m_conversion_list = new ConversionList();
75  connect(m_conversion_list, SIGNAL(CheckedChanged()), this, SLOT(CheckConversionEnabled()));
76  layout->addWidget(m_conversion_list);
77 
78  // Separator line
79  QFrame *line = new QFrame();
80  line->setFrameShape(QFrame::HLine);
81  line->setFrameShadow(QFrame::Sunken);
82  layout->addWidget(line);
83 
84  // Exporters
85  QFormLayout *exportLayout = new QFormLayout();
86 
87  // Formats ComboBox
88  QHBoxLayout *comboLayout = new QHBoxLayout();
89  m_export_format = new QComboBox();
90  for (auto format : m_formats) {
91  QString formatName = QString::fromStdString(format->GetName());
92  m_export_format->addItem(formatName);
93  }
94  connect(m_export_format, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(SLOT_ExportFormatChanged(const QString&)));
95  comboLayout->addWidget(m_export_format);
96  m_options_button = new QPushButton("Options...");
97  m_options_button->setEnabled(false);
98  connect(m_options_button, SIGNAL(clicked()), this, SLOT(SLOT_OptionsTriggered()));
99  comboLayout->addWidget(m_options_button);
100  comboLayout->addStretch();
101  exportLayout->addRow(new QLabel("Export Format"), comboLayout);
102 
103  // Export path
104  QHBoxLayout *exportPathLayout = new QHBoxLayout();
105 
106  m_export_path = new QLineEdit();
107  m_export_path->setReadOnly(true);
108  m_export_path->setText(QString::fromStdString(m_project->GetPath()));
109  exportPathLayout->addWidget(m_export_path);
110  connect(m_export_path, SIGNAL(textChanged(const QString&)), this, SLOT(CheckConversionEnabled()));
111 
112  QPushButton *browseExportPathButton = new QPushButton("Browse...");
113  exportPathLayout->addWidget(browseExportPathButton);
114  connect(browseExportPathButton, SIGNAL(clicked()), this, SLOT(BrowseExportPath()));
115 
116  exportLayout->addRow("Export Path", exportPathLayout);
117 
118  // Export name
119  m_export_name = new QLineEdit();
120  m_export_name->setText("leaf");
121  exportLayout->addRow("Export Prefix", m_export_name);
122  m_export_name->setValidator(new QRegExpValidator(g_export_name_regex));
123  connect(m_export_name, SIGNAL(textChanged(const QString&)), this, SLOT(CheckConversionEnabled()));
124 
125  layout->addLayout(exportLayout);
126 
127  // Convert & Close buttons
128  QHBoxLayout *buttonLayout = new QHBoxLayout();
129  buttonLayout->addStretch();
130 
131  QPushButton *closeButton = new QPushButton("Close");
132  connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
133  buttonLayout->addWidget(closeButton);
134 
135  m_convert_button = new QPushButton("Convert");
136  m_convert_button->setEnabled(false);
137  m_convert_button->setDefault(true);
138  connect(m_convert_button, SIGNAL(clicked()), this, SLOT(Convert()));
139  buttonLayout->addWidget(m_convert_button);
140 
141 
142  layout->addLayout(buttonLayout);
143 
144  setLayout(layout);
145 
146  // Get list of input files
147  Refresh();
148 }
149 
151 {
152 }
153 
154 void ConverterWindow::CheckConversionEnabled()
155 {
156  bool enabled = m_conversion_list->HasCheckedEntries() && !m_export_path->text().isEmpty() && QDir(m_export_path->text()).exists() && !m_export_name->text().isEmpty();
157  m_convert_button->setEnabled(enabled);
158 }
159 
160 void ConverterWindow::BrowseExportPath()
161 {
162  QString exportPath = QFileDialog::getExistingDirectory(this, "Select export directory", !m_export_path->text().isEmpty() ? m_export_path->text() : QDir::homePath());
163  if (!exportPath.isEmpty()) {
164  m_export_path->setText(exportPath);
165  }
166 }
167 
168 void ConverterWindow::Convert()
169 {
170  auto checked = m_conversion_list->GetCheckedEntries();
171 
172  vector<int> timesteps;
173  for (auto& checked_entry : checked) {
174  timesteps.push_back(checked_entry.timestep);
175  }
176 
177  auto format = *find_if(m_formats.begin(), m_formats.end(), [this] (const IConverterFormat *format) -> bool { return format->GetName() == m_export_format->currentText().toStdString(); });
178 
179  QProgressDialog progress("Converting...", "Cancel", 0, checked.size(), this);
180  progress.setWindowTitle("Please wait");
181  progress.setMinimumDuration(0);
182  progress.setWindowModality(Qt::WindowModal);
183 
184  FileConversion conversion(
185  m_project,
186  timesteps,
187  m_preferences,
188  format,
189  m_export_path->text().toStdString(),
190  m_export_name->text().toStdString());
191 
192  try {
193  conversion.Run([&](int i) {
194  QApplication::processEvents();
195  progress.setValue(i);
196  if (progress.wasCanceled()) {
197  throw 0;
198  }
199  });
200  }
201  catch (exception &e) {
202  QMessageBox::critical(this, "Error exporting steps", e.what(), QMessageBox::Ok);
203  }
204  catch (...) {
205  QMessageBox::critical(this, "Error exporting steps", "Unknown exception occurred", QMessageBox::Ok);
206  }
207 }
208 
210 {
211  m_conversion_list->Clear();
212  m_step_to_name_map.clear();
213  m_step_to_file_map.clear();
214 
215  for (auto& file : *m_project) {
216  auto sim_file = static_pointer_cast<Ws::StartupFileBase>(file.second);
217  for (auto step : sim_file->GetTimeSteps()) {
218  m_step_to_name_map[step].push_back(file.first);
219  m_step_to_file_map[step] = sim_file;
220  }
221  }
222 
223  for (auto& it : m_step_to_name_map) {
224  string files;
225  for (auto file_it = it.second.begin(); file_it != it.second.end(); file_it++) {
226  if (file_it != it.second.begin()) {
227  files += ", ";
228  }
229  files += *file_it;
230  }
231  m_conversion_list->AddEntry({it.first, files});
232  }
233 
234  m_convert_button->setEnabled(false);
235 }
236 
237 void ConverterWindow::SLOT_ExportFormatChanged(const QString&)
238 {
239  //auto format = *find_if(m_formats.begin(), m_formats.end(), [this] (IGuiFormat *format) -> bool { return format->GetName() == m_export_format->currentText().toStdString(); });
240  //m_options_button->setEnabled(format->HasOptions());
241 }
242 
243 void ConverterWindow::SLOT_OptionsTriggered()
244 {
245  /*auto format = *find_if(m_formats.begin(), m_formats.end(), [this] (IGuiFormat *format) -> bool { return format->GetName() == m_export_format->currentText().toStdString(); });
246  auto options = format->ShowOptions(this);
247  options->exec();
248  delete options;*/
249 }
250 
251 } // namespace
virtual ~ConverterWindow()
Destructor.
Abstraction of project info on filesystem, as well as a maintainer of a work session.
STL namespace.
Interface for ConversionList.
void AddEntry(const EntryType &)
Add entry.
Interface for Conversion.
Namespace for miscellaneous utilities.
Definition: PTreeFile.cpp:44
Namespace for SimPT shell package.
Definition: Client.cpp:50
Interface for ConverterWindow.
void Clear()
Clear all entries.
Base class representing the file types used to initiate a session.
Interface for StartupFileBase.
String manipulation utilities.
see the online Qt documentation
virtual const std::string & GetPath() const
Definition: Project_def.h:208
Header file for Exception class.
Widget containing the list of steps in conversion and associated functionality.
see the online Qt documentation
void Refresh()
Refresh list of input files.