Developer Documentation
FileOptionsDialog.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 #include "FileOptionsDialog.hh"
45 
46 FileOptionsDialog::FileOptionsDialog(std::vector<fileTypes>& _supportedTypes, QStringList _extensions, bool _loadMode, QWidget *parent)
47  : QDialog(parent),
48  ext_(_extensions),
49  supportedTypes_(_supportedTypes),
50  loadMode_(_loadMode),
51  defaultPluginBox_(NULL)
52 {
53 
54  ext_.removeDuplicates();
55 
56  QGridLayout* grid = new QGridLayout;
57 
58  QVector< int > usefulPlugins;
59 
60  //check if more than one plugin is able to handle this extension
61  for (int i=0; i < ext_.size(); i++){
62  int count = 0;
63  QStringList names;
64 
65  for (unsigned int t=0; t < supportedTypes_.size(); t++){
66 
67  QString filters;
68 
69  if (loadMode_)
70  filters = supportedTypes_[t].loadFilters;
71  else
72  filters = supportedTypes_[t].saveFilters;
73 
74  // Only take the parts inside the brackets
75  filters = filters.section("(",1).section(")",0,0);
76 
77  // Split into blocks
78  QStringList separateFilters = filters.split(" ");
79 
80  for ( int filterId = 0 ; filterId < separateFilters.size(); ++filterId ) {
81  separateFilters[filterId] = separateFilters[filterId].trimmed();
82 
83  if (separateFilters[filterId].endsWith("." + ext_[i],Qt::CaseInsensitive)){
84  count++;
85  names.push_back( supportedTypes_[t].name );
86  usefulPlugins.push_back( t );
87  continue;
88  }
89 
90  }
91 
92  }
93 
94  //more than one plugin can handle the extension
95  if (count > 1){
96  QLabel* label = new QLabel( tr("For *.%1 use plugin ").arg(ext_[i]) );
97  QComboBox* box = new QComboBox();
98 
99  defaultPluginBox_ = new QCheckBox(tr("Make this plugin the default"));
100 
101  box->addItems(names);
102  box->setAccessibleName(ext_[i]);
103 
104  currentName_ = box->currentText();
105  currentExtension_ = ext_[i];
106 
107  grid->addWidget(label, grid->rowCount(), 0);
108  grid->addWidget(box, grid->rowCount()-1, 1);
109  grid->addWidget(defaultPluginBox_, grid->rowCount()+1, 0);
110 
111  connect(box, SIGNAL(currentIndexChanged(QString)), this, SLOT(slotPluginChanged(QString)) );
112  connect(defaultPluginBox_, SIGNAL(stateChanged(int)), this, SLOT(slotPluginDefault(int)) );
113  boxes_.push_back(box);
114  }
115  }
116 
117  //force TriangleMesh as initial value if available
118  for (int i=0; i < boxes_.count(); i++){
119 
120  for (int t=0; t < (boxes_[i])->count(); t++)
121  if ( (boxes_[i])->itemText(t).contains("TriangleMesh") ){
122  (boxes_[i])->setCurrentIndex(t);
123  break;
124  }
125  }
126 
127  QGroupBox* group = new QGroupBox(tr("Extensions with multiple plugins"));
128  group->setLayout(grid);
129 
130  if (boxes_.count() == 0)
131  group->setVisible(false);
132 
133 
134  //add option widgets from all fileplugins
135  for (unsigned int t=0; t < supportedTypes_.size(); t++){
136 
137  if ( !usefulPlugins.contains(t) )
138  continue;
139 
140  QWidget* widget;
141 
142  if (loadMode_)
143  widget = supportedTypes_[t].plugin->loadOptionsWidget("");
144  else
145  widget = supportedTypes_[t].plugin->saveOptionsWidget("");
146 
147  if (widget != 0)
148  tabs_.addTab(widget, supportedTypes_[t].name);
149  }
150 
151  //add buttons at bottom
152  QPushButton* cancel = new QPushButton(tr("&Cancel"));
153  QPushButton* ok = new QPushButton(tr("&Ok"));
154 
155  QHBoxLayout* buttonLayout = new QHBoxLayout;
156 
157  buttonLayout->addWidget(cancel);
158  buttonLayout->addStretch();
159  buttonLayout->addWidget(ok);
160 
161  QVBoxLayout* layout = new QVBoxLayout;
162  layout->addWidget(group);
163  layout->addWidget(&tabs_);
164  layout->addLayout(buttonLayout);
165 
166  setLayout(layout);
167 
168  connect( cancel, SIGNAL(clicked()), this, SLOT(reject()) );
169  connect( ok, SIGNAL(clicked()), this, SLOT(accept()) );
170 
171 }
172 
173 FileOptionsDialog::~FileOptionsDialog()
174 {
175  //remove tabs
176  for (int i=tabs_.count()-1; i >= 0; i--)
177  tabs_.removeTab(i);
178 
179  //and set parent of widgets to NULL
180  for (unsigned int t=0; t < supportedTypes_.size(); t++){
181 
182  QWidget* widget;
183 
184  if (loadMode_)
185  widget = supportedTypes_[t].plugin->loadOptionsWidget("");
186  else
187  widget = supportedTypes_[t].plugin->saveOptionsWidget("");
188 
189  if (widget != 0)
190  widget->setParent(0);
191  }
192 }
193 
194 int FileOptionsDialog::exec(){
195 
196  if ( tabs_.count() == 0 && boxes_.count() == 0 )
197  return QDialog::Accepted;
198  else {
199  return QDialog::exec();
200  }
201 }
202 
203 bool FileOptionsDialog::makePluginDefault() {
204  if (!defaultPluginBox_)
205  return false;
206 
207  return defaultPluginBox_->isChecked();
208 }
209 
210 void FileOptionsDialog::slotPluginChanged(QString _name){
211 
212  QComboBox* box = dynamic_cast<QComboBox*>(QObject::sender());
213 
214  for (unsigned int t=0; t < supportedTypes_.size(); t++)
215  if ( supportedTypes_[t].name == _name ){
216 
217  currentName_ = _name;
218  currentExtension_ = box->accessibleName();
219 
220  if (makePluginDefault()) {
221  OpenFlipperSettings().setValue(QString("Core/File/DefaultLoader/").append(currentExtension_), currentName_);
222  }
223 
224  emit setPluginForExtension(box->accessibleName(), t ); //accessibleName contains the extension
225  break;
226  }
227 }
228 
229 void FileOptionsDialog::slotPluginDefault(int _state) {
230  // store the name of the default plugin for loading
231  if (_state == Qt::Checked) {
232  OpenFlipperSettings().setValue(QString("Core/File/DefaultLoader/").append(currentExtension_), currentName_);
233  } else {
234  OpenFlipperSettings().setValue(QString("Core/File/DefaultLoader/").append(currentExtension_), "");
235  }
236 }
237 
void setValue(const QString &key, const QVariant &value)
Wrapper function which makes it possible to enable Debugging output with -DOPENFLIPPER_SETTINGS_DEBUG...
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.