1 /* 2 * Copyright (c) 2014 Dmitry Kazakov <dimula73@gmail.com> 3 * Copyright (c) 2014 Mohit Goyal <mohit.bits2011@gmail.com> 4 * 5 * This library is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU Lesser General Public License as published by 7 * the Free Software Foundation; either version 2.1 of the License, or 8 * (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 */ 19 /**************************************************************************** 20 ** 21 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 22 ** All rights reserved. 23 ** Contact: Nokia Corporation (qt-info@nokia.com) 24 ** 25 ** This file is part of the QtGui module of the Qt Toolkit. 26 ** 27 ** $QT_BEGIN_LICENSE:LGPL$ 28 ** No Commercial Usage 29 ** This file contains pre-release code and may not be distributed. 30 ** You may use this file in accordance with the terms and conditions 31 ** contained in the Technology Preview License Agreement accompanying 32 ** this package. 33 ** 34 ** GNU Lesser General Public License Usage 35 ** Alternatively, this file may be used under the terms of the GNU Lesser 36 ** General Public License version 2.1 as published by the Free Software 37 ** Foundation and appearing in the file LICENSE.LGPL included in the 38 ** packaging of this file. Please review the following information to 39 ** ensure the GNU Lesser General Public License version 2.1 requirements 40 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 41 ** 42 ** In addition, as a special exception, Nokia gives you certain additional 43 ** rights. These rights are described in the Nokia Qt LGPL Exception 44 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 45 ** 46 ** If you have questions regarding the use of this file, please contact 47 ** Nokia at qt-info@nokia.com. 48 ** 49 ** 50 ** 51 ** 52 ** 53 ** 54 ** 55 ** 56 ** $QT_END_LICENSE$ 57 ** 58 ****************************************************************************/ 59 60 #include <QDebug> 61 #include <klocalizedstring.h> 62 #include <kstandardaction.h> 63 #include <kactioncollection.h> 64 #include "kundo2stack.h" 65 #include "kundo2stack_p.h" 66 #include "kundo2group.h" 67 68 #include <core/kexi.h> 69 #include <kexiutils/KexiIcon.h> 70 71 #include <QtGlobal> 72 73 74 #ifndef QT_NO_UNDOCOMMAND 75 76 /*! 77 \class KUndo2Command 78 \brief The KUndo2Command class is the base class of all commands stored on a KUndo2QStack. 79 80 For an overview of Qt's Undo Framework, see the 81 \l{Overview of Qt's Undo Framework}{overview document}. 82 83 A KUndo2Command represents a single editing action on a document; for example, 84 inserting or deleting a block of text in a text editor. KUndo2Command can apply 85 a change to the document with redo() and undo the change with undo(). The 86 implementations for these functions must be provided in a derived class. 87 88 \snippet doc/src/snippets/code/src_gui_util_qundostack.cpp 0 89 90 A KUndo2Command has an associated text(). This is a short string 91 describing what the command does. It is used to update the text 92 properties of the stack's undo and redo actions; see 93 KUndo2QStack::createUndoAction() and KUndo2QStack::createRedoAction(). 94 95 KUndo2Command objects are owned by the stack they were pushed on. 96 KUndo2QStack deletes a command if it has been undone and a new command is pushed. For example: 97 98 \snippet doc/src/snippets/code/src_gui_util_qundostack.cpp 1 99 100 In effect, when a command is pushed, it becomes the top-most command 101 on the stack. 102 103 To support command compression, KUndo2Command has an id() and the virtual function 104 mergeWith(). These functions are used by KUndo2QStack::push(). 105 106 To support command macros, a KUndo2Command object can have any number of child 107 commands. Undoing or redoing the parent command will cause the child 108 commands to be undone or redone. A command can be assigned 109 to a parent explicitly in the constructor. In this case, the command 110 will be owned by the parent. 111 112 The parent in this case is usually an empty command, in that it doesn't 113 provide its own implementation of undo() and redo(). Instead, it uses 114 the base implementations of these functions, which simply call undo() or 115 redo() on all its children. The parent should, however, have a meaningful 116 text(). 117 118 \snippet doc/src/snippets/code/src_gui_util_qundostack.cpp 2 119 120 Another way to create macros is to use the convenience functions 121 KUndo2QStack::beginMacro() and KUndo2QStack::endMacro(). 122 123 \sa KUndo2QStack 124 */ 125 126 /*! 127 Constructs a KUndo2Command object with the given \a parent and \a text. 128 129 If \a parent is not 0, this command is appended to parent's child list. 130 The parent command then owns this command and will delete it in its 131 destructor. 132 133 \sa ~KUndo2Command() 134 */ 135 136 KUndo2Command::KUndo2Command(const KUndo2MagicString &text, KUndo2Command *parent): 137 m_hasParent(parent != 0), 138 m_timedID(0), 139 m_endOfCommand(QTime::currentTime()) 140 { 141 d = new KUndo2CommandPrivate; 142 if (parent != 0) { 143 parent->d->child_list.append(this); 144 } 145 setText(text); 146 setTime(); 147 } 148 149 /*! 150 Constructs a KUndo2Command object with parent \a parent. 151 152 If \a parent is not 0, this command is appended to parent's child list. 153 The parent command then owns this command and will delete it in its 154 destructor. 155 156 \sa ~KUndo2Command() 157 */ 158 159 KUndo2Command::KUndo2Command(KUndo2Command *parent): 160 m_hasParent(parent != 0),m_timedID(0) 161 { 162 d = new KUndo2CommandPrivate; 163 if (parent != 0) 164 parent->d->child_list.append(this); 165 setTime(); 166 } 167 168 /*! 169 Destroys the KUndo2Command object and all child commands. 170 171 \sa KUndo2Command() 172 */ 173 174 KUndo2Command::~KUndo2Command() 175 { 176 qDeleteAll(d->child_list); 177 delete d; 178 } 179 180 /*! 181 Returns the ID of this command. 182 183 A command ID is used in command compression. It must be an integer unique to 184 this command's class, or -1 if the command doesn't support compression. 185 186 If the command supports compression this function must be overridden in the 187 derived class to return the correct ID. The base implementation returns -1. 188 189 KUndo2QStack::push() will only try to merge two commands if they have the 190 same ID, and the ID is not -1. 191 192 \sa mergeWith(), KUndo2QStack::push() 193 */ 194 195 int KUndo2Command::id() const 196 { 197 return -1; 198 } 199 200 /*! 201 Attempts to merge this command with \a command. Returns true on 202 success; otherwise returns false. 203 204 If this function returns true, calling this command's redo() must have the same 205 effect as redoing both this command and \a command. 206 Similarly, calling this command's undo() must have the same effect as undoing 207 \a command and this command. 208 209 KUndo2QStack will only try to merge two commands if they have the same id, and 210 the id is not -1. 211 212 The default implementation returns false. 213 214 \snippet doc/src/snippets/code/src_gui_util_qundostack.cpp 3 215 216 \sa id() KUndo2QStack::push() 217 */ 218 219 bool KUndo2Command::mergeWith(const KUndo2Command *command) 220 { 221 Q_UNUSED(command); 222 return false; 223 } 224 225 /*! 226 Applies a change to the document. This function must be implemented in 227 the derived class. Calling KUndo2QStack::push(), 228 KUndo2QStack::undo() or KUndo2QStack::redo() from this function leads to 229 undefined beahavior. 230 231 The default implementation calls redo() on all child commands. 232 233 \sa undo() 234 */ 235 236 void KUndo2Command::redo() 237 { 238 for (int i = 0; i < d->child_list.size(); ++i) 239 d->child_list.at(i)->redo(); 240 } 241 242 /*! 243 Reverts a change to the document. After undo() is called, the state of 244 the document should be the same as before redo() was called. This function must 245 be implemented in the derived class. Calling KUndo2QStack::push(), 246 KUndo2QStack::undo() or KUndo2QStack::redo() from this function leads to 247 undefined beahavior. 248 249 The default implementation calls undo() on all child commands in reverse order. 250 251 \sa redo() 252 */ 253 254 void KUndo2Command::undo() 255 { 256 for (int i = d->child_list.size() - 1; i >= 0; --i) 257 d->child_list.at(i)->undo(); 258 } 259 260 /*! 261 Returns a short text string describing what this command does; for example, 262 "insert text". 263 264 The text is used when the text properties of the stack's undo and redo 265 actions are updated. 266 267 \sa setText(), KUndo2QStack::createUndoAction(), KUndo2QStack::createRedoAction() 268 */ 269 270 QString KUndo2Command::actionText() const 271 { 272 if(d->actionText!=NULL) 273 return d->actionText; 274 else 275 return QString(); 276 } 277 278 /*! 279 Returns a short text string describing what this command does; for example, 280 "insert text". 281 282 The text is used when the text properties of the stack's undo and redo 283 actions are updated. 284 285 \sa setText(), KUndo2QStack::createUndoAction(), KUndo2QStack::createRedoAction() 286 */ 287 288 KUndo2MagicString KUndo2Command::text() const 289 { 290 return d->text; 291 } 292 293 /*! 294 Sets the command's text to be the \a text specified. 295 296 The specified text should be a short user-readable string describing what this 297 command does. 298 299 \sa text() KUndo2QStack::createUndoAction() KUndo2QStack::createRedoAction() 300 */ 301 302 void KUndo2Command::setText(const KUndo2MagicString &undoText) 303 { 304 d->text = undoText; 305 d->actionText = undoText.toSecondaryString(); 306 } 307 308 /*! 309 Returns the number of child commands in this command. 310 311 \sa child() 312 */ 313 314 int KUndo2Command::childCount() const 315 { 316 return d->child_list.count(); 317 } 318 319 /*! 320 Returns the child command at \a index. 321 322 \sa childCount(), KUndo2QStack::command() 323 */ 324 325 const KUndo2Command *KUndo2Command::child(int index) const 326 { 327 if (index < 0 || index >= d->child_list.count()) 328 return 0; 329 return d->child_list.at(index); 330 } 331 332 bool KUndo2Command::hasParent() 333 { 334 return m_hasParent; 335 } 336 int KUndo2Command::timedId() 337 { 338 return m_timedID; 339 } 340 void KUndo2Command::setTimedID(int value) 341 { 342 m_timedID = value; 343 } 344 345 bool KUndo2Command::timedMergeWith(KUndo2Command *other) 346 { 347 if(other->timedId() == this->timedId() && other->timedId()!=-1 ) 348 m_mergeCommandsVector.append(other); 349 else 350 return false; 351 return true; 352 } 353 void KUndo2Command::setTime() 354 { 355 m_timeOfCreation = QTime::currentTime(); 356 } 357 QTime KUndo2Command::time() 358 { 359 return m_timeOfCreation; 360 } 361 void KUndo2Command::setEndTime() 362 { 363 m_endOfCommand = QTime::currentTime(); 364 } 365 QTime KUndo2Command::endTime() 366 { 367 return m_endOfCommand; 368 } 369 370 void KUndo2Command::undoMergedCommands() 371 { 372 373 undo(); 374 if (!mergeCommandsVector().isEmpty()) { 375 QVectorIterator<KUndo2Command*> it(mergeCommandsVector()); 376 it.toFront(); 377 while (it.hasNext()) { 378 KUndo2Command* cmd = it.next(); 379 cmd->undoMergedCommands(); 380 } 381 } 382 } 383 384 void KUndo2Command::redoMergedCommands() 385 { 386 if (!mergeCommandsVector().isEmpty()) { 387 388 QVectorIterator<KUndo2Command*> it(mergeCommandsVector()); 389 it.toBack(); 390 while (it.hasPrevious()) { 391 KUndo2Command* cmd = it.previous(); 392 cmd->redoMergedCommands(); 393 } 394 } 395 redo(); 396 } 397 QVector<KUndo2Command*> KUndo2Command::mergeCommandsVector() 398 { 399 return m_mergeCommandsVector; 400 } 401 bool KUndo2Command::isMerged() 402 { 403 return !m_mergeCommandsVector.isEmpty(); 404 } 405 406 KUndo2CommandExtraData* KUndo2Command::extraData() const 407 { 408 return d->extraData.data(); 409 } 410 411 void KUndo2Command::setExtraData(KUndo2CommandExtraData *data) 412 { 413 d->extraData.reset(data); 414 } 415 416 417 #endif // QT_NO_UNDOCOMMAND 418 419 #ifndef QT_NO_UNDOSTACK 420 421 /*! 422 \class KUndo2QStack 423 \brief The KUndo2QStack class is a stack of KUndo2Command objects. 424 425 For an overview of Qt's Undo Framework, see the 426 \l{Overview of Qt's Undo Framework}{overview document}. 427 428 An undo stack maintains a stack of commands that have been applied to a 429 document. 430 431 New commands are pushed on the stack using push(). Commands can be 432 undone and redone using undo() and redo(), or by triggering the 433 actions returned by createUndoAction() and createRedoAction(). 434 435 KUndo2QStack keeps track of the \a current command. This is the command 436 which will be executed by the next call to redo(). The index of this 437 command is returned by index(). The state of the edited object can be 438 rolled forward or back using setIndex(). If the top-most command on the 439 stack has already been redone, index() is equal to count(). 440 441 KUndo2QStack provides support for undo and redo actions, command 442 compression, command macros, and supports the concept of a 443 \e{clean state}. 444 445 \section1 Undo and Redo Actions 446 447 KUndo2QStack provides convenient undo and redo QAction objects, which 448 can be inserted into a menu or a toolbar. When commands are undone or 449 redone, KUndo2QStack updates the text properties of these actions 450 to reflect what change they will trigger. The actions are also disabled 451 when no command is available for undo or redo. These actions 452 are returned by KUndo2QStack::createUndoAction() and KUndo2QStack::createRedoAction(). 453 454 \section1 Command Compression and Macros 455 456 Command compression is useful when several commands can be compressed 457 into a single command that can be undone and redone in a single operation. 458 For example, when a user types a character in a text editor, a new command 459 is created. This command inserts the character into the document at the 460 cursor position. However, it is more convenient for the user to be able 461 to undo or redo typing of whole words, sentences, or paragraphs. 462 Command compression allows these single-character commands to be merged 463 into a single command which inserts or deletes sections of text. 464 For more information, see KUndo2Command::mergeWith() and push(). 465 466 A command macro is a sequence of commands, all of which are undone and 467 redone in one go. Command macros are created by giving a command a list 468 of child commands. 469 Undoing or redoing the parent command will cause the child commands to 470 be undone or redone. Command macros may be created explicitly 471 by specifying a parent in the KUndo2Command constructor, or by using the 472 convenience functions beginMacro() and endMacro(). 473 474 Although command compression and macros appear to have the same effect to the 475 user, they often have different uses in an application. Commands that 476 perform small changes to a document may be usefully compressed if there is 477 no need to individually record them, and if only larger changes are relevant 478 to the user. 479 However, for commands that need to be recorded individually, or those that 480 cannot be compressed, it is useful to use macros to provide a more convenient 481 user experience while maintaining a record of each command. 482 483 \section1 Clean State 484 485 KUndo2QStack supports the concept of a clean state. When the 486 document is saved to disk, the stack can be marked as clean using 487 setClean(). Whenever the stack returns to this state through undoing and 488 redoing commands, it emits the signal cleanChanged(). This signal 489 is also emitted when the stack leaves the clean state. This signal is 490 usually used to enable and disable the save actions in the application, 491 and to update the document's title to reflect that it contains unsaved 492 changes. 493 494 \sa KUndo2Command, KUndo2View 495 */ 496 497 #ifndef QT_NO_ACTION 498 499 KUndo2Action::KUndo2Action(const QString &textTemplate, const QString &defaultText, QObject *parent) 500 : QAction(parent) 501 { 502 m_textTemplate = textTemplate; 503 m_defaultText = defaultText; 504 505 } 506 507 void KUndo2Action::setPrefixedText(const QString &text) 508 { 509 if (text.isEmpty()) 510 setText(m_defaultText); 511 else 512 setText(m_textTemplate.arg(text)); 513 } 514 515 #endif // QT_NO_ACTION 516 517 /*! \internal 518 Sets the current index to \a idx, emitting appropriate signals. If \a clean is true, 519 makes \a idx the clean index as well. 520 */ 521 522 void KUndo2QStack::setIndex(int idx, bool clean) 523 { 524 bool was_clean = m_index == m_clean_index; 525 if (m_lastMergedIndex <= idx) { 526 m_lastMergedSetCount = idx - m_lastMergedIndex; 527 528 } else { 529 m_lastMergedSetCount = 1; 530 m_lastMergedIndex = idx-1; 531 } 532 if(idx == 0){ 533 m_lastMergedSetCount = 0; 534 m_lastMergedIndex = 0; 535 } 536 if (idx != m_index) { 537 m_index = idx; 538 emit indexChanged(m_index); 539 emit canUndoChanged(canUndo()); 540 emit undoTextChanged(undoText()); 541 emit canRedoChanged(canRedo()); 542 emit redoTextChanged(redoText()); 543 } 544 545 if (clean) 546 m_clean_index = m_index; 547 548 bool is_clean = m_index == m_clean_index; 549 if (is_clean != was_clean) 550 emit cleanChanged(is_clean); 551 } 552 553 void KUndo2QStack::purgeRedoState() 554 { 555 bool macro = !m_macro_stack.isEmpty(); 556 if (macro) return; 557 558 bool redoStateChanged = false; 559 bool cleanStateChanged = false; 560 561 while (m_index < m_command_list.size()) { 562 delete m_command_list.takeLast(); 563 redoStateChanged = true; 564 } 565 566 if (m_clean_index > m_index) { 567 m_clean_index = -1; // we've deleted the clean state 568 cleanStateChanged = true; 569 } 570 571 if (redoStateChanged) { 572 emit canRedoChanged(canRedo()); 573 emit redoTextChanged(redoText()); 574 } 575 576 if (cleanStateChanged) { 577 emit cleanChanged(isClean()); 578 } 579 } 580 581 /*! \internal 582 If the number of commands on the stack exceedes the undo limit, deletes commands from 583 the bottom of the stack. 584 585 Returns true if commands were deleted. 586 */ 587 588 bool KUndo2QStack::checkUndoLimit() 589 { 590 if (m_undo_limit <= 0 || !m_macro_stack.isEmpty() || m_undo_limit >= m_command_list.count()) 591 return false; 592 593 int del_count = m_command_list.count() - m_undo_limit; 594 595 for (int i = 0; i < del_count; ++i) 596 delete m_command_list.takeFirst(); 597 598 m_index -= del_count; 599 if (m_clean_index != -1) { 600 if (m_clean_index < del_count) 601 m_clean_index = -1; // we've deleted the clean command 602 else 603 m_clean_index -= del_count; 604 } 605 return true; 606 } 607 608 /*! 609 Constructs an empty undo stack with the parent \a parent. The 610 stack will initially be in the clean state. If \a parent is a 611 KUndo2Group object, the stack is automatically added to the group. 612 613 \sa push() 614 */ 615 616 KUndo2QStack::KUndo2QStack(QObject *parent) 617 : QObject(parent), m_index(0), m_clean_index(0), m_group(0), m_undo_limit(0), m_useCumulativeUndoRedo(false), m_lastMergedSetCount(0), m_lastMergedIndex(0) 618 { 619 setTimeT1(5); 620 setTimeT2(1); 621 setStrokesN(2); 622 #ifndef QT_NO_UNDOGROUP 623 if (KUndo2Group *group = qobject_cast<KUndo2Group*>(parent)) 624 group->addStack(this); 625 #endif 626 } 627 628 /*! 629 Destroys the undo stack, deleting any commands that are on it. If the 630 stack is in a KUndo2Group, the stack is automatically removed from the group. 631 632 \sa KUndo2QStack() 633 */ 634 635 KUndo2QStack::~KUndo2QStack() 636 { 637 #ifndef QT_NO_UNDOGROUP 638 if (m_group != 0) 639 m_group->removeStack(this); 640 #endif 641 clear(); 642 } 643 644 /*! 645 Clears the command stack by deleting all commands on it, and returns the stack 646 to the clean state.{ 647 648 } 649 650 Commands are not undone or redone; the state of the edited object remains 651 unchanged. 652 653 This function is usually used when the contents of the document are 654 abandoned. 655 656 \sa KUndo2QStack() 657 */ 658 659 void KUndo2QStack::clear() 660 { 661 if (m_command_list.isEmpty()) 662 return; 663 664 bool was_clean = isClean(); 665 666 m_macro_stack.clear(); 667 qDeleteAll(m_command_list); 668 m_command_list.clear(); 669 670 m_index = 0; 671 m_clean_index = 0; 672 673 emit indexChanged(0); 674 emit canUndoChanged(false); 675 emit undoTextChanged(QString()); 676 emit canRedoChanged(false); 677 emit redoTextChanged(QString()); 678 679 if (!was_clean) 680 emit cleanChanged(true); 681 } 682 683 /*! 684 Pushes \a cmd on the stack or merges it with the most recently executed command. 685 In either case, executes \a cmd by calling its redo() function. 686 687 If \a cmd's id is not -1, and if the id is the same as that of the 688 most recently executed command, KUndo2QStack will attempt to merge the two 689 commands by calling KUndo2Command::mergeWith() on the most recently executed 690 command. If KUndo2Command::mergeWith() returns true, \a cmd is deleted and false 691 is returned. 692 693 In all other cases \a cmd is simply pushed on the stack and true is returned. 694 695 If commands were undone before \a cmd was pushed, the current command and 696 all commands above it are deleted. Hence \a cmd always ends up being the 697 top-most on the stack. 698 699 Once a command is pushed, the stack takes ownership of it. There 700 are no getters to return the command, since modifying it after it has 701 been executed will almost always lead to corruption of the document's 702 state. 703 704 \sa KUndo2Command::id() KUndo2Command::mergeWith() 705 */ 706 707 bool KUndo2QStack::push(KUndo2Command *cmd) 708 { 709 cmd->redoMergedCommands(); 710 cmd->setEndTime(); 711 712 bool macro = !m_macro_stack.isEmpty(); 713 714 KUndo2Command *cur = 0; 715 if (macro) { 716 KUndo2Command *macro_cmd = m_macro_stack.last(); 717 if (!macro_cmd->d->child_list.isEmpty()) 718 cur = macro_cmd->d->child_list.last(); 719 } else { 720 if (m_index > 0) 721 cur = m_command_list.at(m_index - 1); 722 while (m_index < m_command_list.size()) 723 delete m_command_list.takeLast(); 724 if (m_clean_index > m_index) 725 m_clean_index = -1; // we've deleted the clean state 726 } 727 728 bool try_merge = cur != 0 729 && cur->id() != -1 730 && cur->id() == cmd->id() 731 && (macro || m_index != m_clean_index); 732 733 /*! 734 *Here we are going to try to merge several commands together using the QVector field in the commands using 735 *3 parameters. N : Number of commands that should remain individual at the top of the stack. T1 : Time lapsed between current command and previously merged command -- signal to 736 *merge throughout the stack. T2 : Time lapsed between two commands signalling both commands belong to the same set 737 *Whenever a KUndo2Command is initialized -- it consists of a start-time and when it is pushed --an end time. 738 *Every time a command is pushed -- it checks whether the command pushed was pushed after T1 seconds of the last merged command 739 *Then the merging begins with each group depending on the time in between each command (T2). 740 * 741 *@TODO : Currently it is not able to merge two merged commands together. 742 */ 743 if (!macro && m_command_list.size() > 1 && cmd->timedId() != -1 && m_useCumulativeUndoRedo) { 744 KUndo2Command* lastcmd = m_command_list.last(); 745 if (qAbs(cmd->time().msecsTo(lastcmd->endTime())) < m_timeT2 * 1000) { 746 m_lastMergedSetCount++; 747 } else { 748 m_lastMergedSetCount = 0; 749 m_lastMergedIndex = m_index-1; 750 } 751 if (lastcmd->timedId() == -1){ 752 m_lastMergedSetCount = 0; 753 m_lastMergedIndex = m_index; 754 } 755 if (m_lastMergedSetCount > m_strokesN) { 756 KUndo2Command* toMerge = m_command_list.at(m_lastMergedIndex); 757 if (toMerge && m_command_list.size() >= m_lastMergedIndex + 1 && m_command_list.at(m_lastMergedIndex + 1)) { 758 if(toMerge->timedMergeWith(m_command_list.at(m_lastMergedIndex + 1))){ 759 m_command_list.removeAt(m_lastMergedIndex + 1); 760 } 761 m_lastMergedSetCount--; 762 m_lastMergedIndex = m_command_list.indexOf(toMerge); 763 } 764 765 } 766 m_index = m_command_list.size(); 767 if(m_lastMergedIndex<m_index){ 768 if (cmd->time().msecsTo(m_command_list.at(m_lastMergedIndex)->endTime()) < -m_timeT1 * 1000) { //T1 time elapsed 769 QListIterator<KUndo2Command*> it(m_command_list); 770 it.toBack(); 771 m_lastMergedSetCount = 1; 772 773 while (it.hasPrevious()) { 774 KUndo2Command* curr = it.previous(); 775 KUndo2Command* lastCmdInCurrent = curr; 776 777 if (!lastcmd->mergeCommandsVector().isEmpty()) { 778 if (qAbs(lastcmd->mergeCommandsVector().last()->time().msecsTo(lastCmdInCurrent->endTime())) < int(m_timeT2 * 1000) && lastcmd != lastCmdInCurrent && lastcmd != curr) { 779 if(lastcmd->timedMergeWith(curr)){ 780 if (m_command_list.contains(curr)) { 781 m_command_list.removeOne(curr); 782 } 783 } 784 } else { 785 lastcmd = curr; //end of a merge set 786 } 787 } else { 788 if (qAbs(lastcmd->time().msecsTo(lastCmdInCurrent->endTime())) < int(m_timeT2 * 1000) && lastcmd != lastCmdInCurrent &&lastcmd!=curr) { 789 if(lastcmd->timedMergeWith(curr)){ 790 if (m_command_list.contains(curr)){ 791 m_command_list.removeOne(curr); 792 } 793 } 794 } else { 795 lastcmd = curr; //end of a merge set 796 } 797 } 798 } 799 m_lastMergedIndex = m_command_list.size()-1; 800 } 801 } 802 m_index = m_command_list.size(); 803 } 804 if (try_merge && cur->mergeWith(cmd)) { 805 delete cmd; 806 cmd = 0; 807 if (!macro) { 808 emit indexChanged(m_index); 809 emit canUndoChanged(canUndo()); 810 emit undoTextChanged(undoText()); 811 emit canRedoChanged(canRedo()); 812 emit redoTextChanged(redoText()); 813 } 814 } else { 815 if (macro) { 816 m_macro_stack.last()->d->child_list.append(cmd); 817 } else { 818 m_command_list.append(cmd); 819 if(checkUndoLimit()) 820 { 821 m_lastMergedIndex = m_index - m_strokesN; 822 } 823 setIndex(m_index + 1, false); 824 } 825 } 826 return cmd; 827 } 828 829 /*! 830 Marks the stack as clean and emits cleanChanged() if the stack was 831 not already clean. 832 833 Whenever the stack returns to this state through the use of undo/redo 834 commands, it emits the signal cleanChanged(). This signal is also 835 emitted when the stack leaves the clean state. 836 837 \sa isClean(), cleanIndex() 838 */ 839 840 void KUndo2QStack::setClean() 841 { 842 if (!m_macro_stack.isEmpty()) { 843 qWarning("KUndo2QStack::setClean(): cannot set clean in the middle of a macro"); 844 return; 845 } 846 847 setIndex(m_index, true); 848 } 849 850 /*! 851 If the stack is in the clean state, returns true; otherwise returns false. 852 853 \sa setClean() cleanIndex() 854 */ 855 856 bool KUndo2QStack::isClean() const 857 { 858 if (!m_macro_stack.isEmpty()) 859 return false; 860 return m_clean_index == m_index; 861 } 862 863 /*! 864 Returns the clean index. This is the index at which setClean() was called. 865 866 A stack may not have a clean index. This happens if a document is saved, 867 some commands are undone, then a new command is pushed. Since 868 push() deletes all the undone commands before pushing the new command, the stack 869 can't return to the clean state again. In this case, this function returns -1. 870 871 \sa isClean() setClean() 872 */ 873 874 int KUndo2QStack::cleanIndex() const 875 { 876 return m_clean_index; 877 } 878 879 /*! 880 Undoes the command below the current command by calling KUndo2Command::undo(). 881 Decrements the current command index. 882 883 If the stack is empty, or if the bottom command on the stack has already been 884 undone, this function does nothing. 885 886 \sa redo() index() 887 */ 888 889 void KUndo2QStack::undo() 890 { 891 if (m_index == 0) 892 return; 893 894 if (!m_macro_stack.isEmpty()) { 895 qWarning("KUndo2QStack::undo(): cannot undo in the middle of a macro"); 896 return; 897 } 898 899 int idx = m_index - 1; 900 m_command_list.at(idx)->undoMergedCommands(); 901 setIndex(idx, false); 902 } 903 904 /*! 905 Redoes the current command by calling KUndo2Command::redo(). Increments the current 906 command index. 907 908 If the stack is empty, or if the top command on the stack has already been 909 redone, this function does nothing. 910 911 \sa undo() index() 912 */ 913 914 void KUndo2QStack::redo() 915 { 916 if (m_index == m_command_list.size()) 917 return; 918 919 if (!m_macro_stack.isEmpty()) { 920 qWarning("KUndo2QStack::redo(): cannot redo in the middle of a macro"); 921 return; 922 } 923 924 m_command_list.at(m_index)->redoMergedCommands(); 925 setIndex(m_index + 1, false); 926 } 927 928 /*! 929 Returns the number of commands on the stack. Macro commands are counted as 930 one command. 931 932 \sa index() setIndex() command() 933 */ 934 935 int KUndo2QStack::count() const 936 { 937 return m_command_list.size(); 938 } 939 940 /*! 941 Returns the index of the current command. This is the command that will be 942 executed on the next call to redo(). It is not always the top-most command 943 on the stack, since a number of commands may have been undone. 944 945 \sa undo() redo() count() 946 */ 947 948 int KUndo2QStack::index() const 949 { 950 return m_index; 951 } 952 953 /*! 954 Repeatedly calls undo() or redo() until the current command index reaches 955 \a idx. This function can be used to roll the state of the document forwards 956 of backwards. indexChanged() is emitted only once. 957 958 \sa index() count() undo() redo() 959 */ 960 961 void KUndo2QStack::setIndex(int idx) 962 { 963 if (!m_macro_stack.isEmpty()) { 964 qWarning("KUndo2QStack::setIndex(): cannot set index in the middle of a macro"); 965 return; 966 } 967 968 if (idx < 0) 969 idx = 0; 970 else if (idx > m_command_list.size()) 971 idx = m_command_list.size(); 972 973 int i = m_index; 974 while (i < idx) { 975 m_command_list.at(i++)->redoMergedCommands(); 976 notifySetIndexChangedOneCommand(); 977 } 978 while (i > idx) { 979 m_command_list.at(--i)->undoMergedCommands(); 980 notifySetIndexChangedOneCommand(); 981 } 982 983 setIndex(idx, false); 984 } 985 986 987 /** 988 * Called by setIndex after every command execution. It is needed by 989 * Krita to insert barriers between different kind of commands 990 */ 991 void KUndo2QStack::notifySetIndexChangedOneCommand() 992 { 993 } 994 995 /*! 996 Returns true if there is a command available for undo; otherwise returns false. 997 998 This function returns false if the stack is empty, or if the bottom command 999 on the stack has already been undone. 1000 1001 Synonymous with index() == 0. 1002 1003 \sa index() canRedo() 1004 */ 1005 1006 bool KUndo2QStack::canUndo() const 1007 { 1008 if (!m_macro_stack.isEmpty()) 1009 return false; 1010 return m_index > 0; 1011 } 1012 1013 /*! 1014 Returns true if there is a command available for redo; otherwise returns false. 1015 1016 This function returns false if the stack is empty or if the top command 1017 on the stack has already been redone. 1018 1019 Synonymous with index() == count(). 1020 1021 \sa index() canUndo() 1022 */ 1023 1024 bool KUndo2QStack::canRedo() const 1025 { 1026 if (!m_macro_stack.isEmpty()) 1027 return false; 1028 return m_index < m_command_list.size(); 1029 } 1030 1031 /*! 1032 Returns the text of the command which will be undone in the next call to undo(). 1033 1034 \sa KUndo2Command::text() redoActionText() undoItemText() 1035 */ 1036 1037 QString KUndo2QStack::undoText() const 1038 { 1039 if (!m_macro_stack.isEmpty()) 1040 return QString(); 1041 if (m_index > 0 && m_command_list.at(m_index-1)!=NULL) 1042 1043 return m_command_list.at(m_index - 1)->actionText(); 1044 return QString(); 1045 } 1046 1047 /*! 1048 Returns the text of the command which will be redone in the next call to redo(). 1049 1050 \sa KUndo2Command::text() undoActionText() redoItemText() 1051 */ 1052 1053 QString KUndo2QStack::redoText() const 1054 { 1055 if (!m_macro_stack.isEmpty()) 1056 return QString(); 1057 if (m_index < m_command_list.size()) 1058 return m_command_list.at(m_index)->actionText(); 1059 return QString(); 1060 } 1061 1062 #ifndef QT_NO_ACTION 1063 1064 /*! 1065 Creates an undo QAction object with the given \a parent. 1066 1067 Triggering this action will cause a call to undo(). The text of this action 1068 is the text of the command which will be undone in the next call to undo(), 1069 prefixed by the specified \a prefix. If there is no command available for undo, 1070 this action will be disabled. 1071 1072 If \a prefix is empty, the default prefix "Undo" is used. 1073 1074 \sa createRedoAction(), canUndo(), KUndo2Command::text() 1075 */ 1076 1077 QAction *KUndo2QStack::createUndoAction(QObject *parent) const 1078 { 1079 KUndo2Action *result = new KUndo2Action(i18n("Undo %1"), i18nc("Default text for undo action", "Undo"), parent); 1080 result->setEnabled(canUndo()); 1081 result->setPrefixedText(undoText()); 1082 connect(this, SIGNAL(canUndoChanged(bool)), 1083 result, SLOT(setEnabled(bool))); 1084 connect(this, SIGNAL(undoTextChanged(QString)), 1085 result, SLOT(setPrefixedText(QString))); 1086 connect(result, SIGNAL(triggered()), this, SLOT(undo())); 1087 return result; 1088 } 1089 1090 /*! 1091 Creates an redo QAction object with the given \a parent. 1092 1093 Triggering this action will cause a call to redo(). The text of this action 1094 is the text of the command which will be redone in the next call to redo(), 1095 prefixed by the specified \a prefix. If there is no command available for redo, 1096 this action will be disabled. 1097 1098 If \a prefix is empty, the default prefix "Redo" is used. 1099 1100 \sa createUndoAction(), canRedo(), KUndo2Command::text() 1101 */ 1102 1103 QAction *KUndo2QStack::createRedoAction(QObject *parent) const 1104 { 1105 KUndo2Action *result = new KUndo2Action(i18n("Redo %1"), i18nc("Default text for redo action", "Redo"), parent); 1106 result->setEnabled(canRedo()); 1107 result->setPrefixedText(redoText()); 1108 connect(this, SIGNAL(canRedoChanged(bool)), 1109 result, SLOT(setEnabled(bool))); 1110 connect(this, SIGNAL(redoTextChanged(QString)), 1111 result, SLOT(setPrefixedText(QString))); 1112 connect(result, SIGNAL(triggered()), this, SLOT(redo())); 1113 return result; 1114 } 1115 1116 #endif // QT_NO_ACTION 1117 1118 /*! 1119 Begins composition of a macro command with the given \a text description. 1120 1121 An empty command described by the specified \a text is pushed on the stack. 1122 Any subsequent commands pushed on the stack will be appended to the empty 1123 command's children until endMacro() is called. 1124 1125 Calls to beginMacro() and endMacro() may be nested, but every call to 1126 beginMacro() must have a matching call to endMacro(). 1127 1128 While a macro is composed, the stack is disabled. This means that: 1129 \list 1130 \i indexChanged() and cleanChanged() are not emitted, 1131 \i canUndo() and canRedo() return false, 1132 \i calling undo() or redo() has no effect, 1133 \i the undo/redo actions are disabled. 1134 \endlist 1135 1136 The stack becomes enabled and appropriate signals are emitted when endMacro() 1137 is called for the outermost macro. 1138 1139 \snippet doc/src/snippets/code/src_gui_util_qundostack.cpp 4 1140 1141 This code is equivalent to: 1142 1143 \snippet doc/src/snippets/code/src_gui_util_qundostack.cpp 5 1144 1145 \sa endMacro() 1146 */ 1147 1148 void KUndo2QStack::beginMacro(const KUndo2MagicString &text) 1149 { 1150 KUndo2Command *cmd = new KUndo2Command(); 1151 cmd->setText(text); 1152 1153 if (m_macro_stack.isEmpty()) { 1154 while (m_index < m_command_list.size()) 1155 delete m_command_list.takeLast(); 1156 if (m_clean_index > m_index) 1157 m_clean_index = -1; // we've deleted the clean state 1158 m_command_list.append(cmd); 1159 } else { 1160 m_macro_stack.last()->d->child_list.append(cmd); 1161 } 1162 m_macro_stack.append(cmd); 1163 1164 if (m_macro_stack.count() == 1) { 1165 emit canUndoChanged(false); 1166 emit undoTextChanged(QString()); 1167 emit canRedoChanged(false); 1168 emit redoTextChanged(QString()); 1169 } 1170 } 1171 1172 /*! 1173 Ends composition of a macro command. 1174 1175 If this is the outermost macro in a set nested macros, this function emits 1176 indexChanged() once for the entire macro command. 1177 1178 \sa beginMacro() 1179 */ 1180 1181 void KUndo2QStack::endMacro() 1182 { 1183 if (m_macro_stack.isEmpty()) { 1184 qWarning("KUndo2QStack::endMacro(): no matching beginMacro()"); 1185 return; 1186 } 1187 1188 m_macro_stack.removeLast(); 1189 1190 if (m_macro_stack.isEmpty()) { 1191 checkUndoLimit(); 1192 setIndex(m_index + 1, false); 1193 } 1194 } 1195 1196 /*! 1197 Returns a const pointer to the command at \a index. 1198 1199 This function returns a const pointer, because modifying a command, 1200 once it has been pushed onto the stack and executed, almost always 1201 causes corruption of the state of the document, if the command is 1202 later undone or redone. 1203 1204 \sa KUndo2Command::child() 1205 */ 1206 const KUndo2Command *KUndo2QStack::command(int index) const 1207 { 1208 if (index < 0 || index >= m_command_list.count()) 1209 return 0; 1210 return m_command_list.at(index); 1211 } 1212 1213 /*! 1214 Returns the text of the command at index \a idx. 1215 1216 \sa beginMacro() 1217 */ 1218 1219 QString KUndo2QStack::text(int idx) const 1220 { 1221 if (idx < 0 || idx >= m_command_list.size()) 1222 return QString(); 1223 return m_command_list.at(idx)->text().toString(); 1224 } 1225 1226 /*! 1227 \property KUndo2QStack::undoLimit 1228 \brief the maximum number of commands on this stack. 1229 1230 When the number of commands on a stack exceedes the stack's undoLimit, commands are 1231 deleted from the bottom of the stack. Macro commands (commands with child commands) 1232 are treated as one command. The default value is 0, which means that there is no 1233 limit. 1234 1235 This property may only be set when the undo stack is empty, since setting it on a 1236 non-empty stack might delete the command at the current index. Calling setUndoLimit() 1237 on a non-empty stack prints a warning and does nothing. 1238 */ 1239 1240 void KUndo2QStack::setUndoLimit(int limit) 1241 { 1242 if (!m_command_list.isEmpty()) { 1243 qWarning("KUndo2QStack::setUndoLimit(): an undo limit can only be set when the stack is empty"); 1244 return; 1245 } 1246 1247 if (limit == m_undo_limit) 1248 return; 1249 m_undo_limit = limit; 1250 checkUndoLimit(); 1251 } 1252 1253 int KUndo2QStack::undoLimit() const 1254 { 1255 return m_undo_limit; 1256 } 1257 1258 /*! 1259 \property KUndo2QStack::active 1260 \brief the active status of this stack. 1261 1262 An application often has multiple undo stacks, one for each opened document. The active 1263 stack is the one associated with the currently active document. If the stack belongs 1264 to a KUndo2Group, calls to KUndo2Group::undo() or KUndo2Group::redo() will be forwarded 1265 to this stack when it is active. If the KUndo2Group is watched by a KUndo2View, the view 1266 will display the contents of this stack when it is active. If the stack does not belong to 1267 a KUndo2Group, making it active has no effect. 1268 1269 It is the programmer's responsibility to specify which stack is active by 1270 calling setActive(), usually when the associated document window receives focus. 1271 1272 \sa KUndo2Group 1273 */ 1274 1275 void KUndo2QStack::setActive(bool active) 1276 { 1277 #ifdef QT_NO_UNDOGROUP 1278 Q_UNUSED(active); 1279 #else 1280 if (m_group != 0) { 1281 if (active) 1282 m_group->setActiveStack(this); 1283 else if (m_group->activeStack() == this) 1284 m_group->setActiveStack(0); 1285 } 1286 #endif 1287 } 1288 1289 bool KUndo2QStack::isActive() const 1290 { 1291 #ifdef QT_NO_UNDOGROUP 1292 return true; 1293 #else 1294 return m_group == 0 || m_group->activeStack() == this; 1295 #endif 1296 } 1297 void KUndo2QStack::setUseCumulativeUndoRedo(bool value) 1298 { 1299 m_useCumulativeUndoRedo = value; 1300 } 1301 1302 bool KUndo2QStack::useCumulativeUndoRedo() 1303 { 1304 return m_useCumulativeUndoRedo; 1305 } 1306 void KUndo2QStack::setTimeT1(double value) 1307 { 1308 m_timeT1 = value; 1309 } 1310 1311 double KUndo2QStack::timeT1() 1312 { 1313 return m_timeT1; 1314 } 1315 1316 void KUndo2QStack::setTimeT2(double value) 1317 { 1318 m_timeT2 = value; 1319 } 1320 1321 double KUndo2QStack::timeT2() 1322 { 1323 return m_timeT2; 1324 } 1325 int KUndo2QStack::strokesN() 1326 { 1327 return m_strokesN; 1328 } 1329 void KUndo2QStack::setStrokesN(int value) 1330 { 1331 m_strokesN = value; 1332 } 1333 1334 1335 1336 QAction* KUndo2Stack::createRedoAction(KActionCollection* actionCollection, const QString& actionName) 1337 { 1338 QAction* action = KUndo2QStack::createRedoAction(actionCollection); 1339 1340 if (actionName.isEmpty()) { 1341 action->setObjectName(KStandardAction::name(KStandardAction::Redo)); 1342 } else { 1343 action->setObjectName(actionName); 1344 } 1345 1346 action->setIcon(KexiIcon("edit-redo")); 1347 action->setIconText(i18n("Redo")); 1348 action->setShortcuts(KStandardShortcut::redo()); 1349 1350 actionCollection->addAction(action->objectName(), action); 1351 1352 return action; 1353 } 1354 1355 QAction* KUndo2Stack::createUndoAction(KActionCollection* actionCollection, const QString& actionName) 1356 { 1357 QAction* action = KUndo2QStack::createUndoAction(actionCollection); 1358 1359 if (actionName.isEmpty()) { 1360 action->setObjectName(KStandardAction::name(KStandardAction::Undo)); 1361 } else { 1362 action->setObjectName(actionName); 1363 } 1364 1365 action->setIcon(koIcon("edit-undo")); 1366 action->setIconText(i18n("Undo")); 1367 action->setShortcuts(KStandardShortcut::undo()); 1368 1369 actionCollection->addAction(action->objectName(), action); 1370 1371 return action; 1372 } 1373 1374 /*! 1375 \fn void KUndo2QStack::indexChanged(int idx) 1376 1377 This signal is emitted whenever a command modifies the state of the document. 1378 This happens when a command is undone or redone. When a macro 1379 command is undone or redone, or setIndex() is called, this signal 1380 is emitted only once. 1381 1382 \a idx specifies the index of the current command, ie. the command which will be 1383 executed on the next call to redo(). 1384 1385 \sa index() setIndex() 1386 */ 1387 1388 /*! 1389 \fn void KUndo2QStack::cleanChanged(bool clean) 1390 1391 This signal is emitted whenever the stack enters or leaves the clean state. 1392 If \a clean is true, the stack is in a clean state; otherwise this signal 1393 indicates that it has left the clean state. 1394 1395 \sa isClean() setClean() 1396 */ 1397 1398 /*! 1399 \fn void KUndo2QStack::undoTextChanged(const QString &undoText) 1400 1401 This signal is emitted whenever the value of undoText() changes. It is 1402 used to update the text property of the undo action returned by createUndoAction(). 1403 \a undoText specifies the new text. 1404 */ 1405 1406 /*! 1407 \fn void KUndo2QStack::canUndoChanged(bool canUndo) 1408 1409 This signal is emitted whenever the value of canUndo() changes. It is 1410 used to enable or disable the undo action returned by createUndoAction(). 1411 \a canUndo specifies the new value. 1412 */ 1413 1414 /*! 1415 \fn void KUndo2QStack::redoTextChanged(const QString &redoText) 1416 1417 This signal is emitted whenever the value of redoText() changes. It is 1418 used to update the text property of the redo action returned by createRedoAction(). 1419 \a redoText specifies the new text. 1420 */ 1421 1422 /*! 1423 \fn void KUndo2QStack::canRedoChanged(bool canRedo) 1424 1425 This signal is emitted whenever the value of canRedo() changes. It is 1426 used to enable or disable the redo action returned by createRedoAction(). 1427 \a canRedo specifies the new value. 1428 */ 1429 1430 KUndo2Stack::KUndo2Stack(QObject *parent): 1431 KUndo2QStack(parent) 1432 { 1433 } 1434 1435 #endif // QT_NO_UNDOSTACK 1436