Developer Documentation

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
saveSettings.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 #include "Core.hh"
52
53 #include <ObjectTypes/Light/Light.hh>
54
56 void Core::saveSettings(){
57
58 // ========================================================================================
59 // generate the saveSettings-Dialog
60 // ========================================================================================
61
62 QFileDialog fileDialog( coreWidget_,
63 tr("Save Settings"),
64 OpenFlipperSettings().value("Core/CurrentDir").toString(),
65 tr("INI files (*.ini);;OBJ files (*.obj )") );
66
67 fileDialog.setOption (QFileDialog::DontUseNativeDialog, true);
68 fileDialog.setAcceptMode ( QFileDialog::AcceptSave );
69 fileDialog.setFileMode ( QFileDialog::AnyFile );
70
71 QGridLayout *layout = (QGridLayout*)fileDialog.layout();
72
73 QGroupBox* optionsBox = new QGroupBox( &fileDialog ) ;
74 optionsBox->setSizePolicy( QSizePolicy ( QSizePolicy::Expanding , QSizePolicy::Preferred ) );
75 optionsBox->setTitle(tr("Options"));
76 layout->addWidget( optionsBox, layout->rowCount() , 0 , 1,layout->columnCount() );
77
78 QCheckBox *saveProgramSettings = new QCheckBox(optionsBox);
79 saveProgramSettings->setText(tr("Save program settings"));
80 saveProgramSettings->setToolTip(tr("Save all current program settings to the file ( This will include view settings, colors,...) "));
81 saveProgramSettings->setCheckState( Qt::Unchecked );
82
83 QCheckBox *savePluginSettings = new QCheckBox(optionsBox);
84 savePluginSettings->setText(tr("Save per Plugin Settings"));
85 savePluginSettings->setToolTip(tr("Plugins should add their current global settings to the file"));
86 savePluginSettings->setCheckState( Qt::Checked );
87
88 QCheckBox *saveObjectInfo = new QCheckBox(optionsBox);
89 saveObjectInfo->setText(tr("Save open object information to the file"));
90 saveObjectInfo->setToolTip(tr("Save all open Objects and add them to the settings file ( they will be loaded if opening the settings file"));
91 saveObjectInfo->setCheckState( Qt::Checked );
92
93 QCheckBox *saveAllBox = new QCheckBox(optionsBox);
94 saveAllBox->setText(tr("Save everything to same folder"));
95 saveAllBox->setToolTip(tr("Save all open files to the same folder as the ini file"));
96 saveAllBox->setCheckState( Qt::Checked );
97
98 QCheckBox *askOverwrite = new QCheckBox(optionsBox);
99 askOverwrite->setText(tr("Ask before overwriting files"));
100 askOverwrite->setToolTip(tr("If a file exists you will get asked what to do"));
101 askOverwrite->setCheckState( Qt::Checked );
102
103 QCheckBox *targetOnly = new QCheckBox(optionsBox);
104 targetOnly->setText(tr("Save only target objects"));
105 targetOnly->setToolTip(tr("Only objects with target flag will be handled"));
106 targetOnly->setCheckState( Qt::Unchecked );
107
108 QBoxLayout* frameLayout = new QBoxLayout(QBoxLayout::TopToBottom,optionsBox);
109 frameLayout->addWidget( saveProgramSettings , 0 , 0);
110 frameLayout->addWidget( savePluginSettings , 1 , 0);
111 frameLayout->addWidget( saveObjectInfo , 2 , 0);
112 frameLayout->addWidget( saveAllBox , 3 , 0);
113 frameLayout->addWidget( askOverwrite , 4 , 0);
114 frameLayout->addWidget( targetOnly , 5 , 0);
115 frameLayout->addStretch();
116
117 fileDialog.resize(550 ,600);
118
119 // ========================================================================================
120 // show the saveSettings-Dialog and get the target file
121 // ========================================================================================
122 QStringList fileNames;
123 if (fileDialog.exec()) {
124 fileNames = fileDialog.selectedFiles();
125 } else {
126 return;
127 }
128
129 if ( fileNames.size() > 1 ) {
130 std::cerr << "Too many save filenames selected" << std::endl;
131 return;
132 }
133
134 QString complete_name = fileNames[0];
135
136 //check the extension if its a known one
137 if ( !complete_name.endsWith(".ini", Qt::CaseInsensitive) && !complete_name.endsWith(".obj", Qt::CaseInsensitive) ){
138
139 // If its unknown, get the type from the currently selected filter and add this extension to the filename
140 if ( fileDialog.selectedNameFilter().contains(tr("INI files (*.ini)")) )
141 complete_name += ".ini";
142 else
143 complete_name += ".obj";
144
145 }
146
147 bool is_saveObjectInfo = saveObjectInfo->isChecked();
148 bool is_targetOnly = targetOnly->isChecked();
149 bool is_saveAll = saveAllBox->isChecked();
150 bool is_askOverwrite = askOverwrite->isChecked();
151 bool is_saveProgramSettings = saveProgramSettings->isChecked();
152 bool is_savePluginSettings = savePluginSettings->isChecked();
153
154 saveSettings(complete_name, is_saveObjectInfo, is_targetOnly, is_saveAll, is_askOverwrite, is_saveProgramSettings, is_savePluginSettings);
155 }
156
157 void Core::saveSettings(QString complete_name, bool is_saveObjectInfo, bool is_targetOnly, bool is_saveAll,
158 bool is_askOverwrite, bool is_saveProgramSettings, bool is_savePluginSettings){
159 // Get the chosen directory and remember it.
160 QFileInfo fileInfo(complete_name);
161 OpenFlipperSettings().setValue("Core/CurrentDir", fileInfo.absolutePath() );
162
163 // ========================================================================================
164 // update status information
165 // ========================================================================================
166 OpenFlipper::Options::savingSettings(true);
167
168 if ( OpenFlipper::Options::gui() ) {
169 coreWidget_->statusMessage( tr("Saving Settings to ") + complete_name + " ...");
170 coreWidget_->setStatus(ApplicationStatus::BLOCKED );
171 }
172
173 // ========================================================================================
174 // Save the objects itself
175 // ========================================================================================
176 // Depending on the checkbox iterate over all objects or only the selected ones.
177
178 // Memorize saved files new file names
179 std::map<int,QString> savedFiles;
180
181 if ( is_saveObjectInfo ) {
182
183 PluginFunctions::IteratorRestriction restriction;
184 if ( is_targetOnly )
185 restriction = PluginFunctions::TARGET_OBJECTS;
186 else
187 restriction = PluginFunctions::ALL_OBJECTS;
188
189 // Store saved file's original names (in order to get number of duplicates)
190 std::multiset<QString> originalFiles;
191
192 // Store default extensions per type
193 std::map<DataType,QString> defaultExtensions;
194 // get the supported extensions for when no extension is given
195 QMultiMap<DataType,QString> allFilters; // type -> supported extension
196 const std::vector<fileTypes>& types = supportedTypes();
197 for (int i=0; i < (int)types.size(); i++) {
198 QString filters = types[i].saveFilters;
199
200 // only take the actual extensions
201 filters = filters.section("(",1).section(")",0,0);
202 if (filters.trimmed() == "")
203 continue;
204
205 QStringList separateFilters = filters.split(" ");
206 bool found = false;
207 for ( int filterId = 0 ; filterId < separateFilters.size(); ++filterId ) {
208 if (separateFilters[filterId].trimmed() == "")
209 continue;
210
211 found = true;
212 allFilters.insert(types[i].type,separateFilters[filterId]);
213 }
214
215 if (!found)
216 allFilters.insert(types[i].type,filters);
217 }
218
219 // create a dialog to set extensions if none are given once
220 QDialog extensionDialog(coreWidget_, Qt::Dialog);
221 QGridLayout extensionLayout;
222 const QString extensionCheckBoxPrefixString = "Apply extension to all Objects without preset extensions with DataType: ";
223 QCheckBox extensionCheckBox;
224 QComboBox extensionComboBox;
225 QDialogButtonBox extensionButtons(QDialogButtonBox::Ok);
226 QDialogButtonBox::connect(&extensionButtons, SIGNAL(accepted()), &extensionDialog, SLOT(accept()));
227 //extensionComboBox.addItems(allFilters);
228 extensionLayout.addWidget(&extensionComboBox);
229 extensionLayout.addWidget(&extensionCheckBox);
230 extensionLayout.addWidget(&extensionButtons);
231 extensionDialog.setLayout(&extensionLayout);
232
233 //Iterate over opened objects and save them
234 for ( PluginFunctions::ObjectIterator o_it(restriction);
235 o_it != PluginFunctions::objectsEnd(); ++o_it)
236 {
237 QString filename;
238
239 if ( is_saveAll )
240 {
241 // Use path of settings file for all objects
242 filename = fileInfo.absolutePath() + OpenFlipper::Options::dirSeparator() + o_it->name();
243 }
244 else
245 {
246 // Use objects own path if it has one. Otherwise also use path of settings file
247 filename = o_it->path() + OpenFlipper::Options::dirSeparator() + o_it->name();
248
249 // handle the case that the object was created in current session and not loaded from disk
250 if (o_it->path() == ".") {
251 filename = fileInfo.absolutePath() + OpenFlipper::Options::dirSeparator() + o_it->name();
252 std::cerr << "newpath : " << fileInfo.absolutePath().toStdString() << std::endl;
253 std::cerr << "name : " << o_it->name().toStdString() << std::endl;
254 }
255 }
256
257 // enforce that all files end with obj extension if its an obj-settings file
258 if ( complete_name.endsWith("obj") )
259 {
260 if (!filename.endsWith("obj"))
261 {
262 // remove old extension
263 int pos = filename.lastIndexOf(".");
264 filename.remove(pos+1, filename.length() - pos);
265 // add obj extension
266 filename += "obj";
267 }
268 }
269
270 // Don't save default light source objects
271 LightObject* light = 0;
272 PluginFunctions::getObject( o_it->id(), light );
273 if(light != 0) {
274 if(light->defaultLight()) continue;
275 }
276
277 // Store original file name
278 originalFiles.insert(filename);
279
280 // If a file with the same name already has been saved,
281 // rename it.
282 size_t c = originalFiles.count(filename);
283 if(c > 1) {
284 QFileInfo finfo(filename);
285 filename = finfo.absolutePath() + OpenFlipper::Options::dirSeparator();
286 filename += finfo.baseName() + QString("_%1").arg(c-1) + ".";
287 filename += finfo.completeSuffix();
288 }
289
290 // check if the name of the object specifies already the extension
291 bool extInName = false;
292 for (QMultiMap<DataType,QString>::const_iterator e_it = allFilters.begin(); e_it != allFilters.end(); ++e_it)
293 {
294 // suffix is the same as one extension and
295 extInName = e_it.key().contains(o_it->dataType()) && e_it.value() == QString("*.")+QFileInfo(filename).suffix();
296 if (extInName)
297 break;
298 }
299
300 if (!extInName)
301 {
302 // search for the default data type
303 std::map<DataType,QString>::const_iterator defaultExtIt = defaultExtensions.find(o_it->dataType());
304 bool useDefault = defaultExtIt != defaultExtensions.end();
305 QString extension = (useDefault) ? defaultExtIt->second : "";
306
307 // if no default extension for the datatype was given, request one
308 if (!useDefault)
309 {
310 // present only those filters, which support the type
311 QStringList supportedFilters;
312 for (QMultiMap<DataType,QString>::const_iterator it = allFilters.begin(); it != allFilters.end() ; ++it)
313 {
314 if (it.key().contains(o_it->dataType()))
315 supportedFilters.append(it.value());
316 }
317
318 extensionComboBox.clear();
319 extensionComboBox.addItems(supportedFilters);
320 extensionDialog.setWindowTitle("Please specify a file extension for " + o_it->name());
321 extensionCheckBox.setText(extensionCheckBoxPrefixString + typeName(o_it->dataType()));
322 extensionDialog.move(coreWidget_->width()/2 - extensionDialog.width(),
323 coreWidget_->height()/2 - extensionDialog.height());
324
325 if (extensionDialog.exec() && !supportedFilters.isEmpty())
326 {
327 extension = extensionComboBox.currentText();
328 extension = QFileInfo(extension).suffix();
329 filename += "." + extension;
330 if (extensionCheckBox.isChecked())
331 defaultExtensions[o_it->dataType()] = extension;
332
333 } else
334 {
335 emit log(LOGERR, tr("Unabel to save %1. No extension specified.").arg(o_it->name()));
336 continue;
337 }
338 } else
339 {
340 filename += "." + extension;
341 }
342 }
343
344
345 // decide whether to use saveObject or saveObjectTo
346 if ( !QFile(filename).exists() || !is_askOverwrite )
347 saveObject( o_it->id(), filename);
348 else
349 saveObjectTo(o_it->id(), filename);
350
351 // Store saved file's name
352 savedFiles.insert(std::pair<int,QString>(o_it->id(),filename));
353
354 }
355 }
356
357
358 // ========================================================================================
359 // Finally save all Settings
360 // ========================================================================================
361 if ( complete_name.endsWith("obj") ) {
362
363 //write to obj
364 writeObjFile(complete_name, is_saveAll, is_targetOnly, savedFiles);
365
366 } else {
367 // write to ini
368 writeIniFile( complete_name,
369 is_saveAll,
370 is_targetOnly,
371 is_saveProgramSettings,
372 is_savePluginSettings,
373 is_saveObjectInfo,
374 savedFiles);
375 }
376
377 // update status
378 OpenFlipper::Options::savingSettings(false);
379
380 if ( OpenFlipper::Options::gui() ) {
381 coreWidget_->statusMessage( tr("Saving Settings to ") + complete_name + tr(" ... Done"), 4000);
382 coreWidget_->setStatus(ApplicationStatus::READY );
383 }
384
385 //add to recent files
386 if ( OpenFlipper::Options::gui() )
387 coreWidget_->addRecent( complete_name, DATA_UNKNOWN );
388
389 }
OpenFlipperSettings
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.
Definition: GlobalOptions.cc:938
Core::saveObject
bool saveObject(int _id, QString _filename)
Save an object.
Definition: saveFunctions.cc:71
PluginFunctions::ALL_OBJECTS
const QStringList ALL_OBJECTS
Iterable object range.
Definition: PluginFunctions.hh:441
Core::saveSettings
void saveSettings()
Save current status to a settings file. Solicit file name through dialog.
Definition: saveSettings.cc:56
LOGERR
Definition: LoggingInterface.hh:107
DATA_UNKNOWN
const DataType DATA_UNKNOWN(0)
None of the other Objects.
Core::writeObjFile
void writeObjFile(QString _filename, bool _relativePaths, bool _targetOnly, std::map< int, QString > &_fileMapping)
Write current status to obj file (Application and File Options)
Definition: ParseObj.cc:71
PluginFunctions::getObject
bool getObject(int _identifier, BSplineCurveObject *&_object)
Definition: PluginFunctionsBSplineCurve.cc:75
Core::saveObjectTo
bool saveObjectTo(int _id, QString _filename)
Definition: saveFunctions.cc:217
LightObject::defaultLight
bool defaultLight() const
Is light default light source?
Definition: LightObject.hh:130
LightObject
Definition: LightObject.hh:78
typeName
DLLEXPORT QString typeName(DataType _id)
Get the name of a type with given id.
Definition: Types.cc:165
PluginFunctions::TARGET_OBJECTS
const QStringList TARGET_OBJECTS("target")
Iterable object range.
Core::log
void log(Logtype _type, QString _message)
Logg with OUT,WARN or ERR as type.
ApplicationStatus::BLOCKED
Status is processing and blocked system will not allow interaction (red light)
Definition: StatusbarInterface.hh:82
PluginFunctions::ObjectIterator
Core Data Iterator.
Definition: PluginFunctions.hh:452
PluginFunctions::objectsEnd
DLLEXPORT ObjectIterator objectsEnd()
Return Iterator to Object End.
Definition: PluginFunctionsIterator.cc:187
CoreWidget::addRecent
void addRecent(QString _filename, DataType _type)
Add a recent file and update menu.
Definition: CoreWidget.cc:893
Light.hh
Core::coreWidget_
CoreWidget * coreWidget_
The main applications widget ( only created in gui mode )
Definition: Core.hh:1553
Core.hh
PluginFunctions::IteratorRestriction
QStringList IteratorRestriction
Iterable object range.
Definition: PluginFunctions.hh:439
Core::writeIniFile
void writeIniFile(QString _filename, bool _relativePaths, bool _targetOnly, bool _saveSystemSettings, bool _savePluginSettings, bool _saveObjectInfo, std::map< int, QString > &_fileMapping)
Write current status to ini file (Application and File Options)
Definition: ParseIni.cc:546
ApplicationStatus::READY
Status is ready (green light)
Definition: StatusbarInterface.hh:80
OpenFlipperQSettings::setValue
void setValue(const QString &key, const QVariant &value)
Wrapper function which makes it possible to enable Debugging output with -DOPENFLIPPER_SETTINGS_DEBUG...
Definition: OpenFlipperQSettings.cc:68