Developer Documentation
loadWidget.cc
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41 
42 /*===========================================================================*\
43 * *
44 * $Revision$ *
45 * $LastChangedBy$ *
46 * $Date$ *
47 * *
48 \*===========================================================================*/
49 
50 
51 
52 
53 #include "loadWidget.hh"
54 
55 #include "FileOptionsDialog.hh"
56 
57 #include <QFileInfo>
58 
59 LoadWidget::LoadWidget(std::vector<fileTypes>& _supportedTypes , QWidget *parent)
60  : QFileDialog(parent),
61  loadMode_(true),
62  supportedTypes_(_supportedTypes)
63 {
64  setOption (QFileDialog::DontUseNativeDialog, true);
65 
66  // Get our layout
67  QGridLayout *gridLayout = (QGridLayout*)layout();
68 
69  //supported Types
70  optionsBox_ = new QCheckBox(tr("use defaults"), this);
71  optionsBox_->setChecked( OpenFlipperSettings().value("Core/File/UseLoadDefaults",false).toBool() );
72 
73  // add the options box to the bottom
74  gridLayout->addWidget( optionsBox_, gridLayout->rowCount() , 1 );
75 
76  // Add a very nice label for it
77  QLabel* typeLabel = new QLabel(tr("Options:") , this);
78  gridLayout->addWidget( typeLabel, gridLayout->rowCount() -1 , 0 );
79 
80  //overwrite dialog shouldn't be handled by the qfiledialog
81  setConfirmOverwrite(false);
82 
83  setDirectory( OpenFlipperSettings().value("Core/CurrentDir").toString() );
84 }
85 
88 {
89 
90 }
91 
94 
95  QStringList allFilters;
96 
97  //TODO All files filter
98 
99  for (int i=0; i < (int)supportedTypes_.size(); i++){
100  QStringList filters = supportedTypes_[i].loadFilters.split(";;");
101  for (int f=filters.size()-1; f >= 0; f--){
102  if (filters[f].trimmed() == "") { filters.removeAt(f); continue; }
103  if (filters[f].contains( tr("All files") ) ) filters.removeAt(f);
104  }
105 
106  allFilters.append( filters );
107  }
108 
109  allFilters.removeDuplicates();
110  allFilters.sort();
111 
112  QStringList allExt;
113 
114  //get all possible extensions
115  for (int i=0; i < allFilters.size(); i++){
116  QString ext = allFilters[i].section("(",1).section(")",0,0);
117  allExt.append( ext.split(" ") );
118  }
119 
120  for (int f=allExt.size()-1; f >= 0; f--)
121  if (allExt[f].trimmed() == "") allExt.removeAt(f);
122 
123  allExt.removeDuplicates();
124  allExt.sort();
125 
126  QString allFiles = tr("All Files (");
127 
128  for (int i=0; i < allExt.size(); i++)
129  allFiles += " " + allExt[i];
130 
131  allFiles += " )";
132 
133  allFilters.push_front(allFiles);
134 
135  setNameFilters(allFilters);
136 }
137 
140 
141  QStringList allFilters;
142 
143  bool multipleFiles = (ids_.size() > 1);
144 
145  for (int i=0; i < (int)supportedTypes_.size(); i++)
146  if ( supportedTypes_[i].type.contains(_type) ){
147 
148  if ( multipleFiles && !supportedTypes_[i].saveMultipleObjects)
149  continue;
150 
151  QStringList filters = supportedTypes_[i].saveFilters.split(";;");
152  for (int f=filters.size()-1; f >= 0; f--){
153  if (filters[f].trimmed() == "") { filters.removeAt(f); continue; }
154  if (filters[f].contains( tr("All files") ) ) filters.removeAt(f);
155  }
156 
157  allFilters.append( filters );
158  }
159 
160  allFilters.removeDuplicates();
161  allFilters.sort();
162 
163  QStringList allExt;
164 
165  //get all possible extensions
166  for (int i=0; i < allFilters.size(); i++){
167  QString ext = allFilters[i].section("(",1).section(")",0,0);
168  allExt.append( ext.split(" ") );
169  }
170 
171  for (int f=allExt.size()-1; f >= 0; f--)
172  if (allExt[f].trimmed() == "") allExt.removeAt(f);
173 
174  allExt.removeDuplicates();
175  allExt.sort();
176 
177  QString allFiles = tr("All Files (");
178 
179  for (int i=0; i < allExt.size(); i++)
180  allFiles += " " + allExt[i];
181 
182  allFiles += " )";
183 
184  allFilters.push_front(allFiles);
185 
186  setNameFilters(allFilters);
187 }
188 
189 
192 
193  //get selection
194  QStringList files = selectedFiles();
195 
196  //get all extensions
197  QStringList ext;
198 
199  for (int i=0; i < files.size(); i++)
200  ext.push_back( QFileInfo(files[i]).suffix() );
201 
202 
203  //find plugins that can handle the current extensions
204  pluginForExtension_.clear();
205 
206  for (int i=0; i < ext.size(); i++){
207 
208  for (uint t=0; t < supportedTypes_.size(); t++){
209 
210  QString filters = supportedTypes_[t].loadFilters;
211 
212  // Take only part inside brackets
213  filters = filters.section("(",1).section(")",0,0);
214 
215  QStringList separateFilters = filters.split(" ");
216 
217  bool found = false;
218 
219  for ( int filterId = 0 ; filterId < separateFilters.size(); ++filterId ) {
220 
221  if (separateFilters[filterId].endsWith(ext[i],Qt::CaseInsensitive)){
222  pluginForExtension_[ ext[i] ] = t;
223  found = true;
224  }
225 
226  }
227 
228  if ( found )
229  break;
230 
231  }
232  }
233 
234  // display options for all dataTypes
235  if ( !optionsBox_->isChecked() ){
236 
237  FileOptionsDialog options(supportedTypes_,ext, loadMode_);
238 
239  connect(&options, SIGNAL(setPluginForExtension(QString,int)), this, SLOT(slotSetPluginForExtension(QString,int)) );
240 
241  if ( !options.exec() )
242  return;
243  }
244 
245 
246  //load the selected files
247  QStringList loadableFiles;
248  IdList pluginIds;
249  for (int i=0; i < files.size(); i++){
250 
251  QFileInfo fi(files[i]);
252  QString filename = fi.absoluteFilePath();
253  OpenFlipperSettings().setValue("Core/CurrentDir", fi.absolutePath());
254  QFile file(filename);
255 
256  if (fi.isDir() || !file.exists()) continue; //do nothing if its a not a valid file
257  QString ext = fi.suffix();
258 
259  // if the default options should be used find the default plugin
260  if (optionsBox_->isChecked()) {
261  QString pluginName = OpenFlipperSettings().value(QString("Core/File/DefaultLoader/").append(ext)).toString();
262 
263  // find the id of the plugin
264  bool found = false;
265  unsigned int j;
266  for (j = 0; j < supportedTypes_.size(); ++j) {
267  if (supportedTypes_[j].name == pluginName) {
268  found = true;
269  break;
270  }
271  }
272 
273  if (found)
274  pluginForExtension_[ ext ] = j;
275  }
276 
277  //emit load signal
278  if ( pluginForExtension_.find( ext ) != pluginForExtension_.end() ){
279  emit load(filename, pluginForExtension_[ ext ]);
280  loadableFiles.push_back(filename);
281  pluginIds.push_back(pluginForExtension_[ext]);
282  }
283  }
284  emit loadFiles(loadableFiles, pluginIds);
285 }
286 
289  //get selection
290  QStringList files = selectedFiles();
291 
292  if ( files.size() != 1 ) {
293  std::cerr << "Error: zero or multiple save files selected!" << std::endl;
294  return;
295  }
296 
297  QString filename = files[0];
298 
299  if (QFileInfo(filename).completeSuffix().isEmpty()) {
300 
301  int s = selectedNameFilter().indexOf("*")+1;
302  int e = selectedNameFilter().indexOf(" ", s);
303  int e2 = selectedNameFilter().indexOf(")", s);
304  if (e == -1 || e2 < e) e = e2;
305 
306  QString ext = selectedNameFilter().mid(s,e-s);
307  filename += ext;
308  }
309 
310  QFile f(filename);
311  QFileInfo fi(filename);
312 
313  //find plugin that can handle the current extension
314  pluginForExtension_.clear();
315 
316  for (uint t=0; t < supportedTypes_.size(); t++){
317 
318  QString filters = supportedTypes_[t].saveFilters;
319 
320  // Take only part inside brackets
321  filters = filters.section("(",1).section(")",0,0);
322 
323  QStringList separateFilters = filters.split(" ");
324 
325  bool found = false;
326 
327  for ( int filterId = 0 ; filterId < separateFilters.size(); ++filterId ) {
328 
329  if (separateFilters[filterId].endsWith(fi.suffix(),Qt::CaseInsensitive)){
330  pluginForExtension_[ fi.suffix() ] = t;
331  found = true;
332  }
333 
334  }
335 
336  if ( found )
337  break;
338 
339  }
340 
341  // display options for all dataTypes
342  if ( !optionsBox_->isChecked() ){
343 
344  FileOptionsDialog options(supportedTypes_,QStringList(fi.suffix()), loadMode_);
345 
346  connect(&options, SIGNAL(setPluginForExtension(QString,int)), this, SLOT(slotSetPluginForExtension(QString,int)) );
347 
348  if ( !options.exec() )
349  return;
350  }
351 
352  if (f.exists()){ //check for extension
353  int ret = QMessageBox::warning(this, tr("File exists"),tr("This file already exists.\n"
354  "Do you want to overwrite the file?"),QMessageBox::Yes|QMessageBox::No,QMessageBox::No);
355  if (ret == QMessageBox::No)
356  return; //abort if users doesn't want to overwrite
357  }
358 
359  const std::map< QString, int >::iterator saving_plugin =
360  pluginForExtension_.find( fi.suffix() );
361  if ( saving_plugin != pluginForExtension_.end() ){
362  if (ids_.size() == 1)
363  emit save(ids_[0],filename, saving_plugin->second);
364  else
365  emit save(ids_ ,filename, saving_plugin->second);
366  }
367 
368  OpenFlipperSettings().setValue("Core/CurrentDir", fi.absolutePath() );
369 }
370 
373  setAcceptMode ( QFileDialog::AcceptOpen );
374  setWindowTitle(tr("Load Object"));
375  loadMode_ = true;
376 
377  setFileMode(QFileDialog::ExistingFiles);
378 
379  // Set directory to last Directory used for Opening Files
380  setDirectory(OpenFlipperSettings().value("Core/CurrentDir").toString() );
381 
382  slotSetLoadFilters();
383 
384  return this->exec();
385 }
386 
388 int LoadWidget::showSave(int _id, QString _filename){
389  setAcceptMode ( QFileDialog::AcceptSave );
390  setFileMode( QFileDialog::AnyFile );
391  setWindowTitle(tr("Save Object"));
392  loadMode_ = false;
393 
394  ids_.clear();
395  ids_.push_back(_id);
396 
397  //set dataType
398  BaseObjectData* object;
399  PluginFunctions::getObject(_id,object);
400 
401  //check if we can save this dataType
402  bool typeFound = false;
403 
404  for (int i=0; i < (int)supportedTypes_.size(); i++)
405  if ( object->dataType( supportedTypes_[i].type ) )
406  typeFound = true;
407 
408 
409  if (!typeFound){
410  std::cerr << "No suitable plugin for saving this dataType." << std::endl;
411  return QDialog::Rejected;
412  }
413 
414  slotSetSaveFilters( object->dataType() );
415 
416  //display correct path/name
417  QFileInfo fi(_filename);
418  QFile file(_filename);
419 
420  setDirectory(OpenFlipperSettings().value("Core/CurrentDir").toString() );
421  selectFile ( fi.fileName() );
422 
423  //try to select the best fitting name filter
424  for (int i=0; i < nameFilters().count(); i++){
425  int s = nameFilters()[i].indexOf("*")+2;
426  int e = nameFilters()[i].indexOf(" ", s);
427  int e2 = nameFilters()[i].indexOf(")", s);
428  if (e == -1 || e2 < e) e = e2;
429 
430  QString ext = nameFilters()[i].mid(s,e-s);
431 
432  if (ext == fi.completeSuffix()){
433  selectNameFilter(nameFilters()[i]);
434  break;
435  }
436  }
437 
438  return this->exec();
439 }
440 
442 int LoadWidget::showSave(IdList _ids, QString _filename){
443  setAcceptMode ( QFileDialog::AcceptSave );
444  setFileMode( QFileDialog::AnyFile );
445  setWindowTitle(tr("Save Objects"));
446  loadMode_ = false;
447 
448  ids_ = _ids;
449 
450  DataType types = 0;
451 
452  for (uint i=0; i < _ids.size(); i++){
453 
454  BaseObjectData* object;
455  PluginFunctions::getObject(_ids[i], object);
456 
457  types |= object->dataType();
458  }
459 
460  //check if we can save this dataType
461  bool typeFound = false;
462 
463  for (int i=0; i < (int)supportedTypes_.size(); i++)
464  if ( supportedTypes_[i].type.contains(types) )
465  typeFound = true;
466 
467 
468  if (!typeFound){
469  std::cerr << "No suitable plugin for saving this dataType." << std::endl;
470  return QDialog::Rejected;
471  }
472 
473  slotSetSaveFilters( types );
474 
475  //display correct path/name
476  QFileInfo fi(_filename);
477  QFile file(_filename);
478 
479  setDirectory(OpenFlipperSettings().value("Core/CurrentDir").toString() );
480  selectFile ( fi.fileName() );
481 
482  //try to select the best fitting name filter
483  for (int i=0; i < nameFilters().count(); i++){
484  int s = nameFilters()[i].indexOf("*")+2;
485  int e = nameFilters()[i].indexOf(" ", s);
486  int e2 = nameFilters()[i].indexOf(")", s);
487  if (e == -1 || e2 < e) e = e2;
488 
489  QString ext = nameFilters()[i].mid(s,e-s);
490 
491  if (ext == fi.completeSuffix()){
492  selectNameFilter(nameFilters()[i]);
493  break;
494  }
495  }
496 
497  return this->exec();
498 }
499 
500 bool LoadWidget::validFilename() {
501 
502  // Only proceed if selected file is REALLY a file
503  // Consider two cases:
504  // Case 1: Filename is neither a valid file nor a directory -> continue and wait for valid file
505  // Case 2: Entered filename is a directory -> Change to directory and wait for valid file
506  QString firstEntered = selectedFiles()[0];
507 
508  // Test if directory exists
509  QDir testdir(firstEntered);
510  if(testdir.exists()) {
511  setDirectory(testdir);
512  return false;
513  }
514 
515  // Test if file exists
516  QFile file(firstEntered);
517  if(!file.exists()) return false;
518 
519  return true;
520 }
521 
523 {
524  QFileInfo firstEntered = selectedFiles()[0];
525  // Test if directory exists
526  return QDir(firstEntered.dir()).exists();
527 }
528 
529 void LoadWidget::accept() {
530 
531  if( (!loadMode_) || validFilename() ) {
532 
533  if ( loadMode_ )
534  loadFile();
535  else
536  {
537  if (!dirExists()) //if dir does not exist, don't accept
538  return;
539  saveFile();
540  }
541 
542  QFileDialog::accept();
543  }
544 }
545 
546 void LoadWidget::slotSetPluginForExtension(QString _extension, int _pluginId ){
547  pluginForExtension_[ _extension ] = _pluginId;
548 }
549 
550 
int showLoad()
show Widget for loading Files
Definition: loadWidget.cc:372
void slotSetSaveFilters(DataType _type)
adjust save-filters to current datatype
Definition: loadWidget.cc:139
Predefined datatypes.
Definition: DataTypes.hh:96
int showSave(int _id, QString _filename)
show Widget for saving Files
Definition: loadWidget.cc:388
bool getObject(int _identifier, BSplineCurveObject *&_object)
bool dataType(DataType _type) const
Definition: BaseObject.cc:232
void slotSetLoadFilters()
adjust load-filters to current datatype
Definition: loadWidget.cc:93
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.
~LoadWidget()
Destructor.
Definition: loadWidget.cc:87
void setValue(const QString &key, const QVariant &value)
Wrapper function which makes it possible to enable Debugging output with -DOPENFLIPPER_SETTINGS_DEBUG...
void loadFile()
find suitable plugin for loading current file
Definition: loadWidget.cc:191
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
std::vector< int > IdList
Standard Type for id Lists used for scripting.
Definition: DataTypes.hh:192
void saveFile()
find suitable plugin for saving current file
Definition: loadWidget.cc:288
bool dirExists()
returns true, if the directory of the specified filename (user input via widget) exists ...
Definition: loadWidget.cc:522