File indexing completed on 2024-04-28 04:20:11

0001 
0002 /*
0003    Copyright (c) 2003-2007 Clarence Dang <dang@kde.org>
0004    All rights reserved.
0005 
0006    Redistribution and use in source and binary forms, with or without
0007    modification, are permitted provided that the following conditions
0008    are met:
0009 
0010    1. Redistributions of source code must retain the above copyright
0011       notice, this list of conditions and the following disclaimer.
0012    2. Redistributions in binary form must reproduce the above copyright
0013       notice, this list of conditions and the following disclaimer in the
0014       documentation and/or other materials provided with the distribution.
0015 
0016    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
0017    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0018    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
0019    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
0020    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
0021    NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0022    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0023    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0024    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
0025    THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0026 */
0027 
0028 
0029 #define DEBUG_KP_COMMAND_HISTORY 0
0030 
0031 
0032 #include "kpCommandHistoryBase.h"
0033 
0034 #include <climits>
0035 
0036 #include <QMenu>
0037 
0038 #include <KSharedConfig>
0039 #include <KConfigGroup>
0040 #include <KStandardShortcut>
0041 #include <KStandardAction>
0042 #include <KToolBarPopupAction>
0043 #include <KActionCollection>
0044 #include <KLocalizedString>
0045 
0046 #include "kpCommand.h"
0047 #include "kpLogCategories.h"
0048 #include "environments/commands/kpCommandEnvironment.h"
0049 #include "kpDefs.h"
0050 #include "document/kpDocument.h"
0051 #include "mainWindow/kpMainWindow.h"
0052 #include "tools/kpTool.h"
0053 
0054 //---------------------------------------------------------------------
0055 
0056 static void ClearPointerList(QList<kpCommand *> &list)
0057 {
0058     qDeleteAll(list);
0059     list.clear();
0060 }
0061 
0062 //--------------------------------------------------------------------------------
0063 
0064 kpCommandHistoryBase::kpCommandHistoryBase (bool doReadConfig,
0065                                             KActionCollection *ac)
0066 {
0067     m_actionUndo = new KToolBarPopupAction(QIcon::fromTheme(QStringLiteral("edit-undo")), undoActionText (), this);
0068 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0069     ac->addAction (QString::fromLatin1(KStandardAction::name (KStandardAction::Undo)), m_actionUndo);
0070 #else
0071     ac->addAction (KStandardAction::name (KStandardAction::Undo), m_actionUndo);
0072 #endif
0073     ac->setDefaultShortcuts (m_actionUndo, KStandardShortcut::shortcut (KStandardShortcut::Undo));
0074     connect (m_actionUndo, &KToolBarPopupAction::triggered, this, &kpCommandHistoryBase::undo);
0075 
0076     m_actionRedo = new KToolBarPopupAction(QIcon::fromTheme(QStringLiteral("edit-redo")), redoActionText (), this);
0077 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0078     ac->addAction (QString::fromLatin1(KStandardAction::name (KStandardAction::Redo)), m_actionRedo);
0079 #else
0080     ac->addAction (KStandardAction::name (KStandardAction::Redo), m_actionRedo);
0081 #endif
0082     ac->setDefaultShortcuts (m_actionRedo, KStandardShortcut::shortcut (KStandardShortcut::Redo));
0083     connect (m_actionRedo, &KToolBarPopupAction::triggered, this, &kpCommandHistoryBase::redo );
0084 
0085 
0086     m_actionUndo->setEnabled (false);
0087     m_actionRedo->setEnabled (false);
0088 
0089 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0090     connect (m_actionUndo->menu(), &QMenu::triggered,
0091 #else
0092     connect (m_actionUndo->popupMenu(), &QMenu::triggered,
0093 #endif
0094              this, &kpCommandHistoryBase::undoUpToNumber);
0095 
0096 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0097     connect (m_actionRedo->menu(), &QMenu::triggered,
0098 #else
0099     connect (m_actionRedo->popupMenu(), &QMenu::triggered,
0100 #endif
0101              this, &kpCommandHistoryBase::redoUpToNumber);
0102 
0103 
0104     m_undoMinLimit = 10;
0105     m_undoMaxLimit = 500;
0106     m_undoMaxLimitSizeLimit = 16 * 1048576;
0107 
0108 
0109     m_documentRestoredPosition = 0;
0110 
0111 
0112     if (doReadConfig) {
0113         readConfig ();
0114     }
0115 }
0116 
0117 //--------------------------------------------------------------------------------
0118 
0119 kpCommandHistoryBase::~kpCommandHistoryBase ()
0120 {
0121     ::ClearPointerList(m_undoCommandList);
0122     ::ClearPointerList(m_redoCommandList);
0123 }
0124 
0125 //--------------------------------------------------------------------------------
0126 
0127 // public
0128 int kpCommandHistoryBase::undoLimit () const
0129 {
0130     return undoMinLimit ();
0131 }
0132 
0133 // public
0134 void kpCommandHistoryBase::setUndoLimit (int limit)
0135 {
0136     setUndoMinLimit (limit);
0137 }
0138 
0139 
0140 // public
0141 int kpCommandHistoryBase::undoMinLimit () const
0142 {
0143     return m_undoMinLimit;
0144 }
0145 
0146 // public
0147 void kpCommandHistoryBase::setUndoMinLimit (int limit)
0148 {
0149 #if DEBUG_KP_COMMAND_HISTORY
0150     qCDebug(kpLogCommands) << "kpCommandHistoryBase::setUndoMinLimit("
0151                << limit << ")";
0152 #endif
0153 
0154     if (limit < 1 || limit > 5000/*"ought to be enough for anybody"*/)
0155     {
0156         qCCritical(kpLogCommands) << "kpCommandHistoryBase::setUndoMinLimit("
0157                    << limit << ")";
0158         return;
0159     }
0160 
0161     if (limit == m_undoMinLimit) {
0162         return;
0163     }
0164 
0165     m_undoMinLimit = limit;
0166     trimCommandListsUpdateActions ();
0167 }
0168 
0169 
0170 // public
0171 int kpCommandHistoryBase::undoMaxLimit () const
0172 {
0173     return m_undoMaxLimit;
0174 }
0175 
0176 // public
0177 void kpCommandHistoryBase::setUndoMaxLimit (int limit)
0178 {
0179 #if DEBUG_KP_COMMAND_HISTORY
0180     qCDebug(kpLogCommands) << "kpCommandHistoryBase::setUndoMaxLimit("
0181                << limit << ")";
0182 #endif
0183 
0184     if (limit < 1 || limit > 5000/*"ought to be enough for anybody"*/)
0185     {
0186         qCCritical(kpLogCommands) << "kpCommandHistoryBase::setUndoMaxLimit("
0187                    << limit << ")";
0188         return;
0189     }
0190 
0191     if (limit == m_undoMaxLimit) {
0192         return;
0193     }
0194 
0195     m_undoMaxLimit = limit;
0196     trimCommandListsUpdateActions ();
0197 }
0198 
0199 
0200 // public
0201 kpCommandSize::SizeType kpCommandHistoryBase::undoMaxLimitSizeLimit () const
0202 {
0203     return m_undoMaxLimitSizeLimit;
0204 }
0205 
0206 // public
0207 void kpCommandHistoryBase::setUndoMaxLimitSizeLimit (kpCommandSize::SizeType sizeLimit)
0208 {
0209 #if DEBUG_KP_COMMAND_HISTORY
0210     qCDebug(kpLogCommands) << "kpCommandHistoryBase::setUndoMaxLimitSizeLimit("
0211                << sizeLimit << ")";
0212 #endif
0213 
0214     if (sizeLimit < 0 ||
0215         sizeLimit > (500 * 1048576)/*"ought to be enough for anybody"*/)
0216     {
0217         qCCritical(kpLogCommands) << "kpCommandHistoryBase::setUndoMaxLimitSizeLimit("
0218                    << sizeLimit << ")";
0219         return;
0220     }
0221 
0222     if (sizeLimit == m_undoMaxLimitSizeLimit) {
0223         return;
0224     }
0225 
0226     m_undoMaxLimitSizeLimit = sizeLimit;
0227     trimCommandListsUpdateActions ();
0228 }
0229 
0230 
0231 // public
0232 void kpCommandHistoryBase::readConfig ()
0233 {
0234 #if DEBUG_KP_COMMAND_HISTORY
0235     qCDebug(kpLogCommands) << "kpCommandHistoryBase::readConfig()";
0236 #endif
0237     KConfigGroup cfg (KSharedConfig::openConfig (), QStringLiteral(kpSettingsGroupUndoRedo));
0238 
0239     setUndoMinLimit (cfg.readEntry (kpSettingUndoMinLimit, undoMinLimit ()));
0240     setUndoMaxLimit (cfg.readEntry (kpSettingUndoMaxLimit, undoMaxLimit ()));
0241     setUndoMaxLimitSizeLimit (
0242         cfg.readEntry <kpCommandSize::SizeType> (kpSettingUndoMaxLimitSizeLimit,
0243                                                  undoMaxLimitSizeLimit ()));
0244 
0245     trimCommandListsUpdateActions ();
0246 }
0247 
0248 // public
0249 void kpCommandHistoryBase::writeConfig ()
0250 {
0251 #if DEBUG_KP_COMMAND_HISTORY
0252     qCDebug(kpLogCommands) << "kpCommandHistoryBase::writeConfig()";
0253 #endif
0254     KConfigGroup cfg (KSharedConfig::openConfig (), QStringLiteral(kpSettingsGroupUndoRedo));
0255 
0256     cfg.writeEntry (kpSettingUndoMinLimit, undoMinLimit ());
0257     cfg.writeEntry (kpSettingUndoMaxLimit, undoMaxLimit ());
0258     cfg.writeEntry <kpCommandSize::SizeType> (
0259         kpSettingUndoMaxLimitSizeLimit, undoMaxLimitSizeLimit ());
0260 
0261     cfg.sync ();
0262 }
0263 
0264 
0265 // public
0266 void kpCommandHistoryBase::addCommand (kpCommand *command, bool execute)
0267 {
0268 #if DEBUG_KP_COMMAND_HISTORY
0269     qCDebug(kpLogCommands) << "kpCommandHistoryBase::addCommand("
0270                << command
0271                << ",execute=" << execute << ")"
0272 #endif
0273 
0274     if (execute) {
0275         command->execute ();
0276     }
0277 
0278     m_undoCommandList.push_front (command);
0279     ::ClearPointerList(m_redoCommandList);
0280 
0281 #if DEBUG_KP_COMMAND_HISTORY
0282     qCDebug(kpLogCommands) << "\tdocumentRestoredPosition=" << m_documentRestoredPosition;
0283 #endif
0284     if (m_documentRestoredPosition != INT_MAX)
0285     {
0286         if (m_documentRestoredPosition > 0) {
0287             m_documentRestoredPosition = INT_MAX;
0288         }
0289         else {
0290             m_documentRestoredPosition--;
0291         }
0292     #if DEBUG_KP_COMMAND_HISTORY
0293         qCDebug(kpLogCommands) << "\t\tdocumentRestoredPosition=" << m_documentRestoredPosition;
0294     #endif
0295     }
0296 
0297     trimCommandListsUpdateActions ();
0298 }
0299 
0300 // public
0301 void kpCommandHistoryBase::clear ()
0302 {
0303 #if DEBUG_KP_COMMAND_HISTORY
0304     qCDebug(kpLogCommands) << "kpCommandHistoryBase::clear()";
0305 #endif
0306 
0307     ::ClearPointerList(m_undoCommandList);
0308     ::ClearPointerList(m_redoCommandList);
0309 
0310     m_documentRestoredPosition = 0;
0311 
0312     updateActions ();
0313 }
0314 
0315 //---------------------------------------------------------------------
0316 
0317 // protected slot
0318 void kpCommandHistoryBase::undoInternal ()
0319 {
0320 #if DEBUG_KP_COMMAND_HISTORY
0321     qCDebug(kpLogCommands) << "kpCommandHistoryBase::undoInternal()";
0322 #endif
0323 
0324     kpCommand *undoCommand = nextUndoCommand ();
0325     if (!undoCommand) {
0326         return;
0327     }
0328 
0329     undoCommand->unexecute ();
0330 
0331 
0332     m_undoCommandList.erase (m_undoCommandList.begin ());
0333     m_redoCommandList.push_front (undoCommand);
0334 
0335 #if DEBUG_KP_COMMAND_HISTORY
0336     qCDebug(kpLogCommands) << "\tdocumentRestoredPosition=" << m_documentRestoredPosition;
0337 #endif
0338     if (m_documentRestoredPosition != INT_MAX)
0339     {
0340         m_documentRestoredPosition++;
0341         if (m_documentRestoredPosition == 0)
0342             Q_EMIT documentRestored ();
0343     #if DEBUG_KP_COMMAND_HISTORY
0344         qCDebug(kpLogCommands) << "\t\tdocumentRestoredPosition=" << m_documentRestoredPosition;
0345     #endif
0346     }
0347 }
0348 
0349 //---------------------------------------------------------------------
0350 
0351 // protected slot
0352 void kpCommandHistoryBase::redoInternal ()
0353 {
0354 #if DEBUG_KP_COMMAND_HISTORY
0355     qCDebug(kpLogCommands) << "kpCommandHistoryBase::redoInternal()";
0356 #endif
0357 
0358     kpCommand *redoCommand = nextRedoCommand ();
0359     if (!redoCommand) {
0360         return;
0361     }
0362 
0363     redoCommand->execute ();
0364 
0365 
0366     m_redoCommandList.erase (m_redoCommandList.begin ());
0367     m_undoCommandList.push_front (redoCommand);
0368 
0369 #if DEBUG_KP_COMMAND_HISTORY
0370     qCDebug(kpLogCommands) << "\tdocumentRestoredPosition=" << m_documentRestoredPosition;
0371 #endif
0372     if (m_documentRestoredPosition != INT_MAX)
0373     {
0374         m_documentRestoredPosition--;
0375         if (m_documentRestoredPosition == 0) {
0376             Q_EMIT documentRestored ();
0377         }
0378     #if DEBUG_KP_COMMAND_HISTORY
0379         qCDebug(kpLogCommands) << "\t\tdocumentRestoredPosition=" << m_documentRestoredPosition;
0380     #endif
0381     }
0382 }
0383 
0384 //---------------------------------------------------------------------
0385 
0386 // public slot virtual
0387 void kpCommandHistoryBase::undo ()
0388 {
0389 #if DEBUG_KP_COMMAND_HISTORY
0390     qCDebug(kpLogCommands) << "kpCommandHistoryBase::undo()";
0391 #endif
0392 
0393     undoInternal ();
0394     trimCommandListsUpdateActions ();
0395 }
0396 
0397 //---------------------------------------------------------------------
0398 
0399 // public slot virtual
0400 void kpCommandHistoryBase::redo ()
0401 {
0402 #if DEBUG_KP_COMMAND_HISTORY
0403     qCDebug(kpLogCommands) << "kpCommandHistoryBase::redo()";
0404 #endif
0405 
0406     redoInternal ();
0407     trimCommandListsUpdateActions ();
0408 }
0409 
0410 //---------------------------------------------------------------------
0411 
0412 // public slot virtual
0413 void kpCommandHistoryBase::undoUpToNumber (QAction *which)
0414 {
0415 #if DEBUG_KP_COMMAND_HISTORY
0416     qCDebug(kpLogCommands) << "kpCommandHistoryBase::undoUpToNumber(" << which << ")";
0417 #endif
0418 
0419     for (int i = 0;
0420          i <= which->data().toInt() && !m_undoCommandList.isEmpty ();
0421          i++)
0422     {
0423         undoInternal ();
0424     }
0425 
0426     trimCommandListsUpdateActions ();
0427 }
0428 
0429 // public slot virtual
0430 void kpCommandHistoryBase::redoUpToNumber (QAction *which)
0431 {
0432 #if DEBUG_KP_COMMAND_HISTORY
0433     qCDebug(kpLogCommands) << "kpCommandHistoryBase::redoUpToNumber(" << which << ")";
0434 #endif
0435 
0436     for (int i = 0;
0437          i <= which->data().toInt() && !m_redoCommandList.isEmpty ();
0438          i++)
0439     {
0440         redoInternal ();
0441     }
0442 
0443     trimCommandListsUpdateActions ();
0444 }
0445 
0446 
0447 // protected
0448 QString kpCommandHistoryBase::undoActionText () const
0449 {
0450     kpCommand *undoCommand = nextUndoCommand ();
0451 
0452     return (undoCommand) ? i18n ("&Undo: %1", undoCommand->name ()) : i18n ("&Undo");
0453 }
0454 
0455 // protected
0456 QString kpCommandHistoryBase::redoActionText () const
0457 {
0458     kpCommand *redoCommand = nextRedoCommand ();
0459 
0460     return (redoCommand) ? i18n ("&Redo: %1", redoCommand->name ()) : i18n ("&Redo");
0461 }
0462 
0463 
0464 // protected
0465 QString kpCommandHistoryBase::undoActionToolTip () const
0466 {
0467     kpCommand *undoCommand = nextUndoCommand ();
0468 
0469     return (undoCommand) ? i18n ("Undo: %1", undoCommand->name ()) : i18n ("Undo");
0470 }
0471 
0472 // protected
0473 QString kpCommandHistoryBase::redoActionToolTip () const
0474 {
0475     kpCommand *redoCommand = nextRedoCommand ();
0476 
0477     return (redoCommand) ? i18n ("Redo: %1", redoCommand->name ()) : i18n ("Redo");
0478 }
0479 
0480 
0481 // protected
0482 void kpCommandHistoryBase::trimCommandListsUpdateActions ()
0483 {
0484 #if DEBUG_KP_COMMAND_HISTORY
0485     qCDebug(kpLogCommands) << "kpCommandHistoryBase::trimCommandListsUpdateActions()";
0486 #endif
0487 
0488     trimCommandLists ();
0489     updateActions ();
0490 }
0491 
0492 //--------------------------------------------------------------------------------
0493 
0494 // protected
0495 void kpCommandHistoryBase::trimCommandList(QList<kpCommand *> &commandList)
0496 {
0497 #if DEBUG_KP_COMMAND_HISTORY
0498     qCDebug(kpLogCommands) << "kpCommandHistoryBase::trimCommandList()";
0499     QTime timer; timer.start ();
0500 
0501     qCDebug(kpLogCommands) << "\tsize=" << commandList.size()
0502                << "    undoMinLimit=" << m_undoMinLimit
0503                << " undoMaxLimit=" << m_undoMaxLimit
0504                << " undoMaxLimitSizeLimit=" << m_undoMaxLimitSizeLimit;
0505 #endif
0506     if ( commandList.size() <= m_undoMinLimit )
0507     {
0508     #if DEBUG_KP_COMMAND_HISTORY
0509         qCDebug(kpLogCommands) << "\t\tsize under undoMinLimit - done";
0510     #endif
0511         return;
0512     }
0513 
0514 
0515 #if DEBUG_KP_COMMAND_HISTORY && 0
0516     qCDebug(kpLogCommands) << "\tsize over undoMinLimit - iterating thru cmds:";
0517 #endif
0518 
0519     QList <kpCommand *>::iterator it = commandList.begin ();
0520     int upto = 0;
0521 
0522     kpCommandSize::SizeType sizeSoFar = 0;
0523 
0524     while (it != commandList.end ())
0525     {
0526         bool advanceIt = true;
0527 
0528         if (sizeSoFar <= m_undoMaxLimitSizeLimit)
0529         {
0530             sizeSoFar += (*it)->size ();
0531         }
0532 
0533     #if DEBUG_KP_COMMAND_HISTORY && 0
0534         qCDebug(kpLogCommands) << "\t\t" << upto << ":"
0535                    << " name='" << (*it)->name ()
0536                    << "' size=" << (*it)->size ()
0537                    << "    sizeSoFar=" << sizeSoFar;
0538     #endif
0539 
0540         if (upto >= m_undoMinLimit)
0541         {
0542             if (upto >= m_undoMaxLimit ||
0543                 sizeSoFar > m_undoMaxLimitSizeLimit)
0544             {
0545             #if DEBUG_KP_COMMAND_HISTORY && 0
0546                 qCDebug(kpLogCommands) << "\t\t\tkill";
0547             #endif
0548                 delete (*it);
0549                 it = commandList.erase (it);
0550                 advanceIt = false;
0551             }
0552         }
0553 
0554         if (advanceIt) {
0555             it++;
0556         }
0557         upto++;
0558     }
0559 
0560 #if DEBUG_KP_COMMAND_HISTORY
0561     qCDebug(kpLogCommands) << "\ttook " << timer.elapsed () << "ms";
0562 #endif
0563 }
0564 
0565 //--------------------------------------------------------------------------------
0566 
0567 // protected
0568 void kpCommandHistoryBase::trimCommandLists ()
0569 {
0570 #if DEBUG_KP_COMMAND_HISTORY
0571     qCDebug(kpLogCommands) << "kpCommandHistoryBase::trimCommandLists()";
0572 #endif
0573 
0574     trimCommandList(m_undoCommandList);
0575     trimCommandList(m_redoCommandList);
0576 
0577 #if DEBUG_KP_COMMAND_HISTORY
0578     qCDebug(kpLogCommands) << "\tdocumentRestoredPosition=" << m_documentRestoredPosition
0579 #endif
0580     if (m_documentRestoredPosition != INT_MAX)
0581     {
0582     #if DEBUG_KP_COMMAND_HISTORY
0583         qCDebug(kpLogCommands) << "\t\tundoCmdList.size=" << m_undoCommandList.size ()
0584                    << " redoCmdList.size=" << m_redoCommandList.size ();
0585     #endif
0586         if (m_documentRestoredPosition > static_cast<int> (m_redoCommandList.size ()) ||
0587             -m_documentRestoredPosition > static_cast<int> (m_undoCommandList.size ()))
0588         {
0589         #if DEBUG_KP_COMMAND_HISTORY
0590             qCDebug(kpLogCommands) << "\t\t\tinvalidate documentRestoredPosition";
0591         #endif
0592             m_documentRestoredPosition = INT_MAX;
0593         }
0594     }
0595 }
0596 
0597 
0598 static void populatePopupMenu (QMenu *popupMenu,
0599                                const QString &undoOrRedo,
0600                                const QList <kpCommand *> &commandList)
0601 {
0602     if (!popupMenu) {
0603         return;
0604     }
0605 
0606     popupMenu->clear ();
0607 
0608     QList <kpCommand *>::const_iterator it = commandList.begin ();
0609     int i = 0;
0610     while (i < 10 && it != commandList.end ())
0611     {
0612         QAction *action = new QAction(i18n ("%1: %2", undoOrRedo, (*it)->name ()), popupMenu);
0613         action->setData(i);
0614         popupMenu->addAction (action);
0615         i++;
0616         it++;
0617     }
0618 
0619     if (it != commandList.end ())
0620     {
0621         // TODO: maybe have a scrollview show all the items instead, like KOffice in KDE 3
0622         // LOCOMPAT: should be centered text.
0623         popupMenu->addSection (i18np ("%1 more item", "%1 more items",
0624                                     commandList.size () - i));
0625     }
0626 }
0627 
0628 
0629 // protected
0630 void kpCommandHistoryBase::updateActions ()
0631 {
0632 #if DEBUG_KP_COMMAND_HISTORY
0633     qCDebug(kpLogCommands) << "kpCommandHistoryBase::updateActions()";
0634 #endif
0635 
0636     m_actionUndo->setEnabled (static_cast<bool> (nextUndoCommand ()));
0637     // Don't want to keep changing toolbar text.
0638     // TODO: As a bad side-effect, the menu doesn't have "Undo: <action>"
0639     //       anymore.  In any case, the KDE4 KToolBarPopupAction
0640     //       sucks in menus as it forces the clicking of a submenu.  IMO,
0641     //       there should be no submenu in the menu.
0642     //m_actionUndo->setText (undoActionText ());
0643 
0644     // But in icon mode, a tooltip with context is useful.
0645     m_actionUndo->setToolTip (undoActionToolTip ());
0646 #if DEBUG_KP_COMMAND_HISTORY
0647     QTime timer; timer.start ();
0648 #endif
0649 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0650     populatePopupMenu (m_actionUndo->menu (),
0651 #else
0652     populatePopupMenu (m_actionUndo->popupMenu (),
0653 #endif
0654                        i18n ("Undo"),
0655                        m_undoCommandList);
0656 #if DEBUG_KP_COMMAND_HISTORY
0657     qCDebug(kpLogCommands) << "\tpopuplatePopupMenu undo=" << timer.elapsed ()
0658                << "ms";
0659 #endif
0660 
0661     m_actionRedo->setEnabled (static_cast<bool> (nextRedoCommand ()));
0662     // Don't want to keep changing toolbar text.
0663     // TODO: As a bad side-effect, the menu doesn't have "Undo: <action>"
0664     //       anymore.  In any case, the KDE4 KToolBarPopupAction
0665     //       sucks in menus as it forces the clicking of a submenu.  IMO,
0666     //       there should be no submenu in the menu.
0667     //m_actionRedo->setText (redoActionText ());
0668 
0669     // But in icon mode, a tooltip with context is useful.
0670     m_actionRedo->setToolTip (redoActionToolTip ());
0671 #if DEBUG_KP_COMMAND_HISTORY
0672     timer.restart ();
0673 #endif
0674 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0675     populatePopupMenu (m_actionRedo->menu (),
0676 #else
0677     populatePopupMenu (m_actionRedo->popupMenu (),
0678 #endif
0679                        i18n ("Redo"),
0680                        m_redoCommandList);
0681 #if DEBUG_KP_COMMAND_HISTORY
0682     qCDebug(kpLogCommands) << "\tpopuplatePopupMenu redo=" << timer.elapsed ()
0683                << "ms";
0684 #endif
0685 }
0686 
0687 
0688 // public
0689 kpCommand *kpCommandHistoryBase::nextUndoCommand () const
0690 {
0691     if (m_undoCommandList.isEmpty ()) {
0692         return nullptr;
0693     }
0694 
0695     return m_undoCommandList.first ();
0696 }
0697 
0698 // public
0699 kpCommand *kpCommandHistoryBase::nextRedoCommand () const
0700 {
0701     if (m_redoCommandList.isEmpty ()) {
0702         return nullptr;
0703     }
0704 
0705     return m_redoCommandList.first ();
0706 }
0707 
0708 
0709 // public
0710 void kpCommandHistoryBase::setNextUndoCommand (kpCommand *command)
0711 {
0712 #if DEBUG_KP_COMMAND_HISTORY
0713     qCDebug(kpLogCommands) << "kpCommandHistoryBase::setNextUndoCommand("<< command << ")";
0714 #endif
0715 
0716     if (m_undoCommandList.isEmpty ()) {
0717         return;
0718     }
0719 
0720     delete *m_undoCommandList.begin ();
0721     *m_undoCommandList.begin () = command;
0722 
0723     trimCommandListsUpdateActions ();
0724 }
0725 
0726 
0727 // public slot virtual
0728 void kpCommandHistoryBase::documentSaved ()
0729 {
0730 #if DEBUG_KP_COMMAND_HISTORY
0731     qCDebug(kpLogCommands) << "kpCommandHistoryBase::documentSaved()";
0732 #endif
0733 
0734     m_documentRestoredPosition = 0;
0735 }
0736 
0737 #include "moc_kpCommandHistoryBase.cpp"