saveSettings.cc 15.2 KB
Newer Older
1
/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
2 3
*                                                                            *
*                              OpenFlipper                                   *
Jan Möbius's avatar
Jan Möbius committed
4
*      Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen       *
Jan Möbius's avatar
Jan Möbius committed
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
*                           www.openflipper.org                              *
*                                                                            *
*--------------------------------------------------------------------------- *
*  This file is part of OpenFlipper.                                         *
*                                                                            *
*  OpenFlipper is free software: you can redistribute it and/or modify       *
*  it under the terms of the GNU Lesser General Public License as            *
*  published by the Free Software Foundation, either version 3 of            *
*  the License, or (at your option) any later version with the               *
*  following exceptions:                                                     *
*                                                                            *
*  If other files instantiate templates or use macros                        *
*  or inline functions from this file, or you compile this file and          *
*  link it with other files to produce an executable, this file does         *
*  not by itself cause the resulting executable to be covered by the         *
*  GNU Lesser General Public License. This exception does not however        *
*  invalidate any other reasons why the executable file might be             *
*  covered by the GNU Lesser General Public License.                         *
*                                                                            *
*  OpenFlipper is distributed in the hope that it will be useful,            *
*  but WITHOUT ANY WARRANTY; without even the implied warranty of            *
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
*  GNU Lesser General Public License for more details.                       *
*                                                                            *
*  You should have received a copy of the GNU LesserGeneral Public           *
*  License along with OpenFlipper. If not,                                   *
*  see <http://www.gnu.org/licenses/>.                                       *
*                                                                            *
33 34 35
\*===========================================================================*/

/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
36 37 38 39 40
*                                                                            *
*   $Revision$                                                       *
*   $LastChangedBy$                                                *
*   $Date$                     *
*                                                                            *
41
\*===========================================================================*/
42 43 44 45 46 47


#include "Core.hh"

#include "OpenFlipper/common/GlobalOptions.hh"

48 49
#include <ObjectTypes/Light/Light.hh>

50 51 52 53 54 55 56 57
#include "OpenFlipper/BasePlugin/PluginFunctions.hh"

#include "OpenFlipper/widgets/loadWidget/loadWidget.hh"

#include <QFileDialog>
#include <QGroupBox>
#include <QBoxLayout>

58 59
#include <set>

60 61 62
/// Save Settings (slot is called from CoreWidget's File-Menu)
void Core::saveSettings(){

Jan Möbius's avatar
Jan Möbius committed
63
  // ========================================================================================
64
  // generate the saveSettings-Dialog
Jan Möbius's avatar
Jan Möbius committed
65
  // ========================================================================================
66 67 68

  QFileDialog fileDialog( coreWidget_,
                          tr("Save Settings"),
69
                          OpenFlipperSettings().value("Core/CurrentDir").toString(),
70 71
                          tr("INI files (*.ini);;OBJ files (*.obj )") );

72
  fileDialog.setOption (QFileDialog::DontUseNativeDialog, true);
73 74
  fileDialog.setAcceptMode ( QFileDialog::AcceptSave );
  fileDialog.setFileMode ( QFileDialog::AnyFile );
75

76 77 78 79
  QGridLayout *layout = (QGridLayout*)fileDialog.layout();

  QGroupBox* optionsBox = new QGroupBox( &fileDialog ) ;
  optionsBox->setSizePolicy( QSizePolicy ( QSizePolicy::Expanding , QSizePolicy::Preferred ) );
80
  optionsBox->setTitle(tr("Options"));
81 82
  layout->addWidget( optionsBox, layout->rowCount() , 0 , 1,layout->columnCount() );

Jan Möbius's avatar
Jan Möbius committed
83
  QCheckBox *saveProgramSettings = new QCheckBox(optionsBox);
84 85
  saveProgramSettings->setText(tr("Save program settings"));
  saveProgramSettings->setToolTip(tr("Save all current program settings to the file ( This will include view settings, colors,...) "));
Jan Möbius's avatar
Jan Möbius committed
86 87
  saveProgramSettings->setCheckState( Qt::Unchecked );

88
  QCheckBox *savePluginSettings = new QCheckBox(optionsBox);
89 90
  savePluginSettings->setText(tr("Save per Plugin Settings"));
  savePluginSettings->setToolTip(tr("Plugins should add their current global settings to the file"));
91 92 93
  savePluginSettings->setCheckState( Qt::Checked );

  QCheckBox *saveObjectInfo = new QCheckBox(optionsBox);
94 95
  saveObjectInfo->setText(tr("Save open object information to the file"));
  saveObjectInfo->setToolTip(tr("Save all open Objects and add them to the settings file ( they will be loaded if opening the settings file"));
96 97
  saveObjectInfo->setCheckState( Qt::Checked );

98
  QCheckBox *saveAllBox = new QCheckBox(optionsBox);
99 100
  saveAllBox->setText(tr("Save everything to same folder"));
  saveAllBox->setToolTip(tr("Save all open files to the same folder as the ini file"));
101 102 103
  saveAllBox->setCheckState( Qt::Checked );

  QCheckBox *askOverwrite = new QCheckBox(optionsBox);
104 105
  askOverwrite->setText(tr("Ask before overwriting files"));
  askOverwrite->setToolTip(tr("If a file exists you will get asked what to do"));
106 107 108
  askOverwrite->setCheckState( Qt::Checked );

  QCheckBox *targetOnly = new QCheckBox(optionsBox);
109 110
  targetOnly->setText(tr("Save only target objects"));
  targetOnly->setToolTip(tr("Only objects with target flag will be handled"));
111 112 113
  targetOnly->setCheckState( Qt::Unchecked );

  QBoxLayout* frameLayout = new QBoxLayout(QBoxLayout::TopToBottom,optionsBox);
114 115 116 117 118 119
  frameLayout->addWidget( saveProgramSettings , 0 , 0);
  frameLayout->addWidget( savePluginSettings  , 1 , 0);
  frameLayout->addWidget( saveObjectInfo      , 2 , 0);
  frameLayout->addWidget( saveAllBox          , 3 , 0);
  frameLayout->addWidget( askOverwrite        , 4 , 0);
  frameLayout->addWidget( targetOnly          , 5 , 0);
120 121
  frameLayout->addStretch();

Jan Möbius's avatar
Jan Möbius committed
122
  fileDialog.resize(550 ,600);
123

Jan Möbius's avatar
Jan Möbius committed
124 125 126
  // ========================================================================================
  // show the saveSettings-Dialog and get the target file
  // ========================================================================================
127 128 129 130 131 132 133 134 135 136 137 138
  QStringList fileNames;
  if (fileDialog.exec()) {
    fileNames = fileDialog.selectedFiles();
  } else {
    return;
  }

  if ( fileNames.size() > 1 ) {
    std::cerr << "Too many save filenames selected" << std::endl;
    return;
  }

139
  QString complete_name = fileNames[0];
140

Jan Möbius's avatar
Jan Möbius committed
141
  //check the extension if its a known one
142
  if ( !complete_name.endsWith(".ini", Qt::CaseInsensitive) && !complete_name.endsWith(".obj", Qt::CaseInsensitive) ){
Jan Möbius's avatar
Jan Möbius committed
143 144

    // If its unknown, get the type from the currently selected filter and add this extension to the filename
145
    if ( fileDialog.selectedNameFilter().contains(tr("INI files (*.ini)")) )
146 147 148
      complete_name += ".ini";
    else
      complete_name += ".obj";
Jan Möbius's avatar
Jan Möbius committed
149

150 151
  }

152 153 154 155 156 157 158 159 160 161 162 163
  bool is_saveObjectInfo = saveObjectInfo->isChecked();
  bool is_targetOnly = targetOnly->isChecked();
  bool is_saveAll = saveAllBox->isChecked();
  bool is_askOverwrite = askOverwrite->isChecked();
  bool is_saveProgramSettings = saveProgramSettings->isChecked();
  bool is_savePluginSettings = savePluginSettings->isChecked();

  saveSettings(complete_name, is_saveObjectInfo, is_targetOnly, is_saveAll, is_askOverwrite, is_saveProgramSettings, is_savePluginSettings);
}

void Core::saveSettings(QString complete_name, bool is_saveObjectInfo, bool is_targetOnly, bool is_saveAll,
                        bool is_askOverwrite, bool is_saveProgramSettings, bool is_savePluginSettings){
Jan Möbius's avatar
Jan Möbius committed
164
  // Get the chosen directory and remember it.
165 166
  QFileInfo fileInfo(complete_name);
  OpenFlipperSettings().setValue("Core/CurrentDir", fileInfo.absolutePath() );
167

Jan Möbius's avatar
Jan Möbius committed
168 169 170
  // ========================================================================================
  // update status information
  // ========================================================================================
171 172 173
  OpenFlipper::Options::savingSettings(true);

  if ( OpenFlipper::Options::gui() ) {
174
    coreWidget_->statusMessage( tr("Saving Settings to ") + complete_name + " ...");
175 176 177
    coreWidget_->setStatus(ApplicationStatus::BLOCKED );
  }

Jan Möbius's avatar
Jan Möbius committed
178 179 180 181
  // ========================================================================================
  // Save the objects itself
  // ========================================================================================
  // Depending on the checkbox iterate over all objects or only the selected ones.
182

183 184 185
  // Memorize saved files new file names
  std::map<int,QString> savedFiles;

186
  if ( is_saveObjectInfo ) {
187

188
    PluginFunctions::IteratorRestriction restriction;
189
    if ( is_targetOnly )
190
      restriction = PluginFunctions::TARGET_OBJECTS;
191
    else
192 193
      restriction = PluginFunctions::ALL_OBJECTS;

194 195 196
    // Store saved file's original names (in order to get number of duplicates)
    std::multiset<QString> originalFiles;

197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
    QString extension("");
    bool applyToAll = false;
    // get the supported extensions for when no extension is given
    QStringList allFilters;
    std::vector<fileTypes> types = supportedTypes();
    for (int i=0; i < (int)types.size(); i++) {
      QString filters = types[i].saveFilters;

      // only take the actual extensions
      filters = filters.section("(",1).section(")",0,0);
      if (filters.trimmed() == "")
        continue;

      QStringList separateFilters = filters.split(" ");
      bool found = false;
      for ( int filterId = 0 ; filterId < separateFilters.size(); ++filterId ) {
        if (separateFilters[filterId].trimmed() == "")
          continue;

        found = true;
        allFilters.append(separateFilters[filterId]);
      }

      if (!found)
        allFilters.append( filters );
    }

    allFilters.removeDuplicates();
    allFilters.sort();

    // create a dialog to set extensions if none are given once
    QDialog extensionDialog(coreWidget_, Qt::Dialog);
    QGridLayout extensionLayout;
    QCheckBox extensionCheckBox("Apply extension to all Objects without preset extensions");
    QComboBox extensionComboBox;
    QDialogButtonBox extensionButtons(QDialogButtonBox::Ok);
    QDialogButtonBox::connect(&extensionButtons, SIGNAL(accepted()), &extensionDialog, SLOT(accept()));
    extensionComboBox.addItems(allFilters);
    extensionLayout.addWidget(&extensionComboBox);
    extensionLayout.addWidget(&extensionCheckBox);
    extensionLayout.addWidget(&extensionButtons);
    extensionDialog.setLayout(&extensionLayout);

240 241
    //Iterate over opened objects and save them
    for ( PluginFunctions::ObjectIterator o_it(restriction);
Jan Möbius's avatar
 
Jan Möbius committed
242
                                          o_it != PluginFunctions::objectsEnd(); ++o_it)
243
    {
244
      QString filename;
245

246
      if ( is_saveAll )
247 248
      {
        // Use path of settings file for all objects
249
        filename = fileInfo.absolutePath() + OpenFlipper::Options::dirSeparator() + o_it->name();
250
      }
251 252 253 254 255 256 257
      else
      {
        // Use objects own path if it has one. Otherwise also use path of settings file
        filename = o_it->path() + OpenFlipper::Options::dirSeparator() + o_it->name();

        // handle the case that the object was created in current session and not loaded from disk
        if (o_it->path() == ".") {
258 259
          filename = fileInfo.absolutePath() + OpenFlipper::Options::dirSeparator() + o_it->name();
          std::cerr << "newpath : " << fileInfo.absolutePath().toStdString() << std::endl;
260 261 262
          std::cerr << "name  : " << o_it->name().toStdString() << std::endl;
        }
      }
263

264 265
      // enforce that all files end with obj extension if its an obj-settings file
      if ( complete_name.endsWith("obj") )
266
      {
267 268 269 270 271 272 273 274
        if (!filename.endsWith("obj"))
        {
          // remove old extension
          int pos = filename.lastIndexOf(".");
          filename.remove(pos+1, filename.length() - pos);
          // add obj extension
          filename += "obj";
        }
275
      }
276 277 278 279 280 281 282
      
      // Don't save default light source objects
      LightObject* light = 0;
      PluginFunctions::getObject( o_it->id(), light );
      if(light != 0) {
          if(light->defaultLight()) continue;
      }
283

284 285 286 287 288 289 290 291 292 293 294 295 296
      // Store original file name
      originalFiles.insert(filename);

      // If a file with the same name already has been saved,
      // rename it.
      unsigned int c = originalFiles.count(filename);
      if(c > 1) {
          QFileInfo finfo(filename);
          filename = finfo.absolutePath() + OpenFlipper::Options::dirSeparator();
          filename += finfo.baseName() + QString("_%1").arg((c-1)) + ".";
          filename += finfo.completeSuffix();
      }

297 298 299
      // check if we have an extension for the object
      if (QFileInfo(filename).suffix() == "") {

300
        if (!applyToAll) {
301

302 303
          extensionDialog.move(coreWidget_->width()/2 - extensionDialog.width(),
                               coreWidget_->height()/2 - extensionDialog.height());
304

305
          extensionDialog.setWindowTitle("Please specify a file extension for " + o_it->name());
306

307 308 309 310 311 312 313 314 315
          if (extensionDialog.exec() && !allFilters.isEmpty()) {
            if (extensionCheckBox.isChecked())
              applyToAll = true;
            extension = extensionComboBox.currentText();
            extension = QFileInfo(extension).suffix();
            filename += "." + extension;
          } else {
            emit log(LOGERR, tr("Unabel to save %1. No extension specified.").arg(o_it->name()));
            continue;
316 317
          }
        } else {
318
          filename += "." + extension;
319 320
        }
      }
321

322
      // decide whether to use saveObject or saveObjectTo
323
      if ( !QFile(filename).exists() || !is_askOverwrite )
324 325 326
        saveObject( o_it->id(), filename);
      else
        saveObjectTo(o_it->id(), filename);
327

328 329 330
      // Store saved file's name
      savedFiles.insert(std::pair<int,QString>(o_it->id(),filename));

331
    }
332 333 334
  }


Jan Möbius's avatar
Jan Möbius committed
335 336 337
  // ========================================================================================
  // Finally save all Settings
  // ========================================================================================
338
  if ( complete_name.endsWith("obj") ) {
Jan Möbius's avatar
Jan Möbius committed
339

340
    //write to obj
341
    writeObjFile(complete_name, is_saveAll, is_targetOnly, savedFiles);
Jan Möbius's avatar
Jan Möbius committed
342

343 344 345 346 347 348 349 350 351
  } else {
      // write to ini
      writeIniFile( complete_name,
                    is_saveAll,
                    is_targetOnly,
                    is_saveProgramSettings,
                    is_savePluginSettings,
                    is_saveObjectInfo,
                    savedFiles);
352 353
  }

Jan Möbius's avatar
Jan Möbius committed
354
  // update status
355 356 357
  OpenFlipper::Options::savingSettings(false);

  if ( OpenFlipper::Options::gui() ) {
358
    coreWidget_->statusMessage( tr("Saving Settings to ") + complete_name + tr(" ... Done"), 4000);
359 360 361 362 363
    coreWidget_->setStatus(ApplicationStatus::READY );
  }

  //add to recent files
  if ( OpenFlipper::Options::gui() )
364
    coreWidget_->addRecent( complete_name, DATA_UNKNOWN );
365 366

}