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
BackupPlugin.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 #include "BackupPlugin.hh"
51 #if QT_VERSION >= 0x050000
52 #else
53 #include <QtGui>
54 #endif
55
56 #include <OpenFlipper/BasePlugin/PluginFunctions.hh>
57 #include <OpenFlipper/common/GlobalOptions.hh>
58
59 #include "GroupBackup.hh"
60
61 //-----------------------------------------------------------------------------
62 BackupPlugin::BackupPlugin():
63 globalBackup_(),
64 backupMenu_(0),
65 backupsEnabledAction_(0),
66 undoMenuAction_(0),
67 redoMenuAction_(0),
68 undoToolAction_(0),
69 redoToolAction_(0),
70 undoContextAction_(0),
71 redoContextAction_(0),
72 maxBackupSpinBox_(0)
73 {
74
75 }
76
77 //-----------------------------------------------------------------------------
78
79 void BackupPlugin::initializePlugin()
80 {
81 int maxBackups = OpenFlipperSettings().value("BackupPlugin/MaxBackups",static_cast<unsigned>(globalBackup_.maxBackups())).toInt();
82 globalBackup_.setMaxBackups(maxBackups);
83 }
84
85 //-----------------------------------------------------------------------------
86
87 void BackupPlugin::pluginsInitialized() {
88
89 // Create Backup menu
90 emit getMenubarMenu(tr("&Backup"), backupMenu_, true );
91
92 if ( OpenFlipper::Options::gui() ) {
93 //construct the menu
94 backupsEnabledAction_ = new QAction("Backups Enabled",0);
95 backupsEnabledAction_->setCheckable(true);
96 connect (backupsEnabledAction_, SIGNAL(triggered(bool)), this, SLOT(slotEnableDisableBackups()) );
97
98 undoMenuAction_ = new QAction(tr("&Undo"), this);
99 undoMenuAction_->setEnabled(false);
100 undoMenuAction_->setStatusTip(tr("Undo the last action."));
101 undoMenuAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"edit-undo.png") );
102 connect(undoMenuAction_, SIGNAL(triggered()), this, SIGNAL( undo() ) );
103
104 redoMenuAction_ = new QAction(tr("&Redo"), this);
105 redoMenuAction_->setEnabled(false);
106 redoMenuAction_->setStatusTip(tr("Redo the last action"));
107 redoMenuAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"edit-redo.png") );
108 connect(redoMenuAction_, SIGNAL(triggered()), this, SIGNAL( redo() ) );
109
110 backupMenu_->addAction(undoMenuAction_);
111 backupMenu_->addAction(redoMenuAction_);
112 backupMenu_->addSeparator();
113 backupMenu_->addAction(backupsEnabledAction_);
114
115 // Add a backup Toolbar
116 QToolBar* toolbar = new QToolBar("Backup Toolbar");
117
118 //Undo
119 undoToolAction_ = new QAction(tr("&Undo"), this);
120 undoToolAction_->setEnabled(false);
121 undoToolAction_->setStatusTip(tr("Undo the last action."));
122 undoToolAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"edit-undo.png") );
123 connect(undoToolAction_, SIGNAL(triggered()), this, SIGNAL( undo() ) );
124 toolbar->addAction(undoToolAction_);
125
126 //Redo
127 redoToolAction_ = new QAction(tr("&Redo"), this);
128 redoToolAction_->setEnabled(false);
129 redoToolAction_->setStatusTip(tr("Redo the last action"));
130 redoToolAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"edit-redo.png") );
131 connect(redoToolAction_, SIGNAL(triggered()), this, SIGNAL( redo() ) );
132 toolbar->addAction(redoToolAction_);
133
134 emit addToolbar( toolbar );
135
136 //the release event does not contain the modifier
137 emit registerKey(Qt::Key_Z, Qt::ControlModifier, tr("Undo Action"));
138 emit registerKey(Qt::Key_Z, (Qt::ControlModifier | Qt::ShiftModifier), tr("Redo Action"));
139
140 //add actions for the context menu
141 undoContextAction_ = new QAction(tr("&Undo"), this);
142 undoContextAction_->setEnabled(false);
143 undoContextAction_->setStatusTip(tr("Undo the last action."));
144 undoContextAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"edit-undo.png") );
145 connect(undoContextAction_, SIGNAL(triggered()), this, SLOT(slotObjectUndo()) );
146 emit addContextMenuItem(undoContextAction_, DATA_ALL, CONTEXTOBJECTMENU);
147
148 redoContextAction_ = new QAction(tr("&Redo"), this);
149 redoContextAction_->setEnabled(false);
150 redoContextAction_->setStatusTip(tr("Redo the last action"));
151 redoContextAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"edit-redo.png") );
152 connect(redoContextAction_, SIGNAL(triggered()), this, SLOT(slotObjectRedo()) );
153 emit addContextMenuItem(redoContextAction_, DATA_ALL, CONTEXTOBJECTMENU);
154
155 //update option widget since it is created earlier
156 if (maxBackupSpinBox_)
157 maxBackupSpinBox_->setValue(globalBackup_.maxBackups());
158
159 }
160
161 //createBackup(int _objectId, QString _name, UpdateType _type= UPDATE_ALL)
162 emit setSlotDescription("createBackup(int,QString)", tr("Creates a backup which can be restored via undo."),
163 QString("objectId,name").split(","), QString("Id of the object,name of the backup").split(","));
164 emit setSlotDescription("createBackup(int,QString,UpdateType)", tr("Creates a backup which can be restored via undo."),
165 QString("objectId,name,type").split(","), QString("Id of the object,name of the backup,updatetypes which are changed").split(","));
166 }
167
168 //-----------------------------------------------------------------------------
169
170 void BackupPlugin::slotAllCleared(){
171 globalBackup_.clear();
172 updateButtons();
173 }
174
175 //-----------------------------------------------------------------------------
176
177 void BackupPlugin::updateButtons() {
178
179 if ( globalBackup_.undoAvailable() ){
180 undoMenuAction_->setText( tr("Undo '%1'").arg( globalBackup_.undoName() ) );
181 undoMenuAction_->setEnabled(true);
182 undoToolAction_->setText( tr("Undo '%1'").arg( globalBackup_.undoName() ) );
183 undoToolAction_->setEnabled(true);
184 } else {
185 undoMenuAction_->setText( tr("Undo") );
186 undoMenuAction_->setEnabled(false);
187 undoToolAction_->setText( tr("Undo") );
188 undoToolAction_->setEnabled(false);
189 }
190
191 if ( globalBackup_.redoAvailable() ){
192 redoMenuAction_->setText( tr("Redo '%1'").arg( globalBackup_.redoName() ) );
193 redoMenuAction_->setEnabled(true);
194 redoToolAction_->setText( tr("Redo '%1'").arg( globalBackup_.redoName() ) );
195 redoToolAction_->setEnabled(true);
196 } else {
197 redoMenuAction_->setText( tr("Redo") );
198 redoMenuAction_->setEnabled(false);
199 redoToolAction_->setText( tr("Redo") );
200 redoToolAction_->setEnabled(false);
201 }
202
203 backupsEnabledAction_->setChecked( OpenFlipper::Options::backupEnabled() );
204 }
205
206 //-----------------------------------------------------------------------------
207
208 void BackupPlugin::slotEnableDisableBackups() {
209 OpenFlipper::Options::enableBackup(backupsEnabledAction_->isChecked());
210 }
211
212 //-----------------------------------------------------------------------------
213
214 void BackupPlugin::slotKeyEvent( QKeyEvent* _event ){
215 switch (_event->key())
216 {
217 case Qt::Key_Z :
218 if ( _event->modifiers() == Qt::ControlModifier )
219 emit undo();
220 else if ( _event->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier) )
221 emit redo();
222 break;
223 default:
224 break;
225 }
226 }
227
228 //-----------------------------------------------------------------------------
229
230 void BackupPlugin::objectDeleted(int _objectid) {
231 globalBackup_.eraseBackups(_objectid);
232 updateButtons();
233 }
234
235 //-----------------------------------------------------------------------------
236
237 void BackupPlugin::slotUpdateContextMenu( int _objectId ){
238
239 //disable everything
240 undoContextAction_->setText( tr("Undo") );
241 undoContextAction_->setEnabled(false);
242 redoContextAction_->setText( tr("Redo") );
243 redoContextAction_->setEnabled(false);
244
245 //get backup data
246 BaseObjectData* object = 0;
247 PluginFunctions::getObject(_objectId, object);
248
249 if ( object != 0 ){
250
251 if ( object->hasObjectData( OBJECT_BACKUPS ) ){
252
253 //get backup object data
254 BackupData* backupData = dynamic_cast< BackupData* >(object->objectData(OBJECT_BACKUPS));
255
256 if ( backupData->undoAvailable() ){
257 undoContextAction_->setData(_objectId);
258 undoContextAction_->setText( tr("Undo '%1'").arg( backupData->undoName() ) );
259 undoContextAction_->setEnabled( !backupData->undoBlocked() );
260 }
261
262 if ( backupData->redoAvailable() ){
263 redoContextAction_->setData(_objectId);
264 redoContextAction_->setText( tr("Redo '%1'").arg( backupData->redoName() ) );
265 redoContextAction_->setEnabled( !backupData->redoBlocked() );
266 }
267 }
268 }
269
270 }
271
272 //-----------------------------------------------------------------------------
273
274 void BackupPlugin::slotObjectUndo(){
275
276 int id = undoContextAction_->data().toInt();
277 emit undo(id);
278 }
279
280 //-----------------------------------------------------------------------------
281
282 void BackupPlugin::slotObjectRedo(){
283
284 int id = undoContextAction_->data().toInt();
285 emit redo(id);
286 }
287
288 //-----------------------------------------------------------------------------
289
290 void BackupPlugin::slotCreateBackup( int _objectid, QString _name, UpdateType _type){
291
292 if ( !OpenFlipper::Options::backupEnabled() )
293 return;
294
295 BaseObjectData* object;
296
297 if ( !PluginFunctions::getObject(_objectid,object) ){
298 emit log(LOGWARN,"Unable to find backup object with id " + QString::number(_objectid));
299 return;
300 }
301
302 //tell TypePlugin to Backup
303 emit generateBackup( _objectid, _name, _type );
304
305 //add global backup
306 IdList groupIds;
307 groupIds.push_back( _objectid );
308
309 bool skipBackup = false;
310
311 if ( globalBackup_.undoAvailable() ){
312 //skip 'Original Object' Backups in global view
313 BackupData* backupData = dynamic_cast< BackupData* >(object->objectData(OBJECT_BACKUPS));
314
315 if ( backupData != 0 )
316 skipBackup = !backupData->undoAvailable();
317 }
318
319 if ( !skipBackup ){
320 GroupBackup* backup = new GroupBackup(groupIds, _name);
321 globalBackup_.storeBackup( backup );
322 }
323
324 updateButtons();
325 emit log(LOGOUT,"Created backup for " + QString::number(_objectid)+ " , Name : '" + _name + "'" );
326 }
327
328 //-----------------------------------------------------------------------------
329
330 void BackupPlugin::slotCreateBackup( IdList _objectids , QString _name, std::vector<UpdateType> _types){
331
332 if ( !OpenFlipper::Options::backupEnabled() )
333 return;
334
335 IdList groupIds;
336
337 if ( _objectids.size() != _types.size() ){
338 emit log(LOGWARN,"Unable to create backup sizes of ids and updateTypes do not match!");
339 return;
340 }
341
342 //generate backups on all objects
343 for (unsigned int i=0; i < _objectids.size(); ++i){
344
345 BaseObjectData* object;
346
347 if ( !PluginFunctions::getObject(_objectids[i],object) ){
348 emit log(LOGWARN,"Unable to find backup object with id " + QString::number(_objectids[i]));
349 continue;
350 }
351
352 //tell TypePlugin to generate a backup
353 emit generateBackup( _objectids[i], _name, _types[i] );
354 groupIds.push_back( _objectids[i] );
355 }
356
357 //add global backup
358 if ( ! groupIds.empty() ){
359
360 GroupBackup* backup = new GroupBackup(groupIds, _name);
361 globalBackup_.storeBackup( backup );
362
363 updateButtons();
364 emit log(LOGOUT,"Created grouped backup, Name : '" + _name + "'" );
365 }
366 }
367
368 //-----------------------------------------------------------------------------
369
370 void BackupPlugin::slotUndo(int _objectid){
371
372 emit aboutToRestore(_objectid);
373 globalBackup_.undo(_objectid);
374 emit restored(_objectid);
375 emit updatedObject(_objectid, UPDATE_ALL);
376
377 updateButtons();
378 }
379
380 //-----------------------------------------------------------------------------
381
382 void BackupPlugin::slotUndo(){
383 GroupBackup* group = dynamic_cast< GroupBackup* >( globalBackup_.currentState() );
384
385 if (group) {
386 IdList ids = group->objectIDs();
387 IdList::const_iterator it, end;
388 for (it = ids.begin(), end = ids.end(); it != end; ++it)
389 emit aboutToRestore(*it);
390
391 globalBackup_.undo();
392
393 for (unsigned int i=0; i < group->objectIDs().size(); i++)
394 {
395 emit restored(group->objectIDs()[i]);
396 emit updatedObject(group->objectIDs()[i], UPDATE_ALL);
397 }
398
399 updateButtons();
400 } else
401 emit log(LOGWARN,"Unable to find the current GroupBackup");
402 }
403
404 //-----------------------------------------------------------------------------
405
406 void BackupPlugin::slotRedo(int _objectid){
407
408 emit aboutToRestore(_objectid);
409 globalBackup_.redo(_objectid);
410 emit restored(_objectid);
411 emit updatedObject(_objectid, UPDATE_ALL);
412
413 updateButtons();
414 }
415
416 //-----------------------------------------------------------------------------
417
418 void BackupPlugin::slotRedo(){
419 globalBackup_.redo();
420
421 GroupBackup* group = dynamic_cast< GroupBackup* >( globalBackup_.currentState() );
422
423 if ( group != 0)
424 for (unsigned int i=0; i < group->objectIDs().size(); i++)
425 {
426 emit restored(group->objectIDs()[i]);
427 emit updatedObject(group->objectIDs()[i], UPDATE_ALL);
428 }
429
430 updateButtons();
431 }
432
433 //-----------------------------------------------------------------------------
434
435 void BackupPlugin::createBackup(int _objectId, QString _name, UpdateType _type)
436 {
437 slotCreateBackup(_objectId,_name,_type);
438 }
439
440 //-----------------------------------------------------------------------------
441
442 bool BackupPlugin::initializeOptionsWidget(QWidget*& _widget)
443 {
444 QLabel* maxBackupLabel = new QLabel();
445 maxBackupLabel->setText(tr("Max. saved backups: "));
446 maxBackupSpinBox_ = new QSpinBox();
447 maxBackupSpinBox_->setValue(globalBackup_.maxBackups());
448 maxBackupSpinBox_->setRange(0,100);
449
450 QHBoxLayout* layout = new QHBoxLayout();
451 layout->addWidget(maxBackupLabel);
452 layout->addWidget(maxBackupSpinBox_);
453
454 QWidget* baseWidget = new QWidget();
455 baseWidget->setLayout(layout);
456 _widget = baseWidget;
457
458 return true;
459 }
460
461 //-----------------------------------------------------------------------------
462
463 void BackupPlugin::applyOptions()
464 {
465 int maxBackups = maxBackupSpinBox_->value();
466 globalBackup_.setMaxBackups(maxBackups);
467 OpenFlipperSettings().setValue("BackupPlugin/MaxBackups", maxBackups);
468 }
469
470 #if QT_VERSION < 0x050000
471 Q_EXPORT_PLUGIN2( backupplugin , BackupPlugin );
472 #endif
473
OpenFlipperSettings
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.
Definition: GlobalOptions.cc:938
GroupData::undo
void undo()
perform an undo if possible
Definition: GroupData.cc:75
BaseObjectData
Definition: BaseObjectData.hh:105
BackupData::storeBackup
void storeBackup(BaseBackup *_backup)
store a backup
Definition: BackupData.cc:80
UpdateType
Update type class.
Definition: UpdateType.hh:70
UPDATE_ALL
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
PluginFunctions::getObject
bool getObject(int _identifier, BSplineCurveObject *&_object)
Definition: PluginFunctionsBSplineCurve.cc:75
BackupData::clear
void clear()
remove all backups
Definition: BackupData.cc:222
BackupPlugin::slotEnableDisableBackups
void slotEnableDisableBackups()
Backups enabled or disabled checkbox.
Definition: BackupPlugin.cc:208
BackupPlugin::backupMenu_
QMenu * backupMenu_
The backup Menu.
Definition: BackupPlugin.hh:174
BackupData::redoBlocked
bool redoBlocked()
return if a redo backup is blocked
Definition: BackupData.cc:213
LOGWARN
Definition: LoggingInterface.hh:106
BackupPlugin
Definition: BackupPlugin.hh:69
GroupBackup
Class that encapsulates simultaneous backups on multiple objects.
Definition: GroupBackup.hh:58
BaseObject::hasObjectData
bool hasObjectData(QString _dataName)
Checks if object data with given name is available.
Definition: BaseObject.cc:806
IdList
std::vector< int > IdList
Standard Type for id Lists used for scripting.
Definition: DataTypes.hh:192
BackupData::undoBlocked
bool undoBlocked()
return if an undo backup is blocked
Definition: BackupData.cc:203
LOGOUT
Definition: LoggingInterface.hh:104
BackupData::currentState
BaseBackup * currentState()
return the current state
Definition: BackupData.cc:249
DATA_ALL
const DataType DATA_ALL(UINT_MAX)
Identifier for all available objects.
BackupData::undoAvailable
bool undoAvailable()
return if an undo backup is available
Definition: BackupData.cc:191
GlobalOptions.hh
BackupData::maxBackups
size_t maxBackups()
return the maximum of backups which are saved
Definition: BackupData.cc:66
OpenFlipperQSettings::value
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
Definition: OpenFlipperQSettings.cc:53
GroupData::redo
void redo()
perform an redo if possible
Definition: GroupData.cc:124
CONTEXTOBJECTMENU
The Menu will be shown when an object was picked.
Definition: ContextMenuInterface.hh:75
BackupData::undoName
QString undoName()
return the name of the next undo backup
Definition: BackupData.cc:141
PluginFunctions.hh
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
GroupData::eraseBackups
void eraseBackups(int _objectid)
erase all backups containing given id
Definition: GroupData.cc:315
BackupData::redoAvailable
bool redoAvailable()
return if a redo backup is available
Definition: BackupData.cc:197
BackupPlugin::createBackup
void createBackup(int _objectId, QString _name, UpdateType _type=UPDATE_ALL)
Tell Backup Plugin to create a backup.
Definition: BackupPlugin.cc:435
BackupData::redoName
QString redoName()
return the name of the next redo backup
Definition: BackupData.cc:151
BackupData::setMaxBackups
void setMaxBackups(size_t _max)
set the maximum of saved backups
Definition: BackupData.cc:73
BackupData
Abstract class that is used to store backups.
Definition: BackupData.hh:66