Check if undo/redo stack has items



  • Hi,

    I am working on a text editor with tabs. When a tab changes I need to check if a undo or redo action is available and set my buttons accordingly. I could not find a bool value in QPlainTextEdit that would tell me if there is something that I can undo.
    I added a variable that holds if the text in the tab has been changed for other reasons and I can use that to detect if undo is available but this does not help with redo. Do I need to add my own variable to capture the redo state or is there something build in?
    Also I noticed that the undoAvailable signal is not fired when I start typing in my QPlainTextEdit. The standard short cuts cmd/crl+z work as expected. Is this a "feature" or am I doing something wrong when I connect undoAvailable with my undo action?

    Thanks.



  • Hello @Sikarjan

    What about :

    redoAvailable, and undoAvailable signals:

    According to Qt doc

    void QPlainTextEdit::redoAvailable ( bool available ) [signal]
    This signal is emitted whenever redo operations become available (available is true) or unavailable (available is false).

    void QPlainTextEdit::undoAvailable ( bool available ) [signal]
    This signal is emitted whenever undo operations become available (available is true) or unavailable (available is false).

    You can do something like this:

    connect(yourPlainTextEdit,SIGNAL(redoAvailable(bool),this,SLOT(onRedoAvailable(bool));
    

    and then implement onRedoAvailable(bool) slots:

    void onRedoAvailable(bool isRedoAvailable)
    {
          if(isRedoAvailable)
          {
                //change your ui as you need
          }
    }
    


  • Hi mostefa,

    this is exactly what I did but
    a) the first undoAvailable is not fired when I edit the text. I need to set it manually or do a redo action
    b) when I change my tab the undo/redo state could be different from the last tab. I need to check for the current QPlainTextEdit if there is a undo/redo item in the stack.



  • Is it possible to share your code with us ?



  • @Sikarjan

    I made a test code with :

    One QPlainTextEdit,Two QPushButton (mUndoButton,mRedoButton) , and it seems to work without any problem , here is my code if this can help:

    Header file

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
    private slots:
        void onUndoAvailable(bool isUndoAvailable);
        void onRedoAvailable(bool isRedoAvailable);
    
    private:
        Ui::MainWindow *ui;
    };
    
    #endif // MAINWINDOW_H
    

    Source File

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    #include <QDebug>
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
    
        connect(ui->plainTextEdit,SIGNAL(undoAvailable(bool)),this,SLOT(onUndoAvailable(bool)));
        connect(ui->plainTextEdit,SIGNAL(redoAvailable(bool)),this,SLOT(onRedoAvailable(bool)));
    
        ui->mRedoBUtton->setEnabled(false);
        ui->mUndoButton->setEnabled(false);
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::onUndoAvailable(bool isUndoAvailable)
    {
        qDebug() << Q_FUNC_INFO << "isUndoAvailable" << isUndoAvailable;
        if(isUndoAvailable)
        {
            ui->mUndoButton->setEnabled(true);
        }
        else
        {
            ui->mUndoButton->setEnabled(false);
        }
    }
    
    void MainWindow::onRedoAvailable(bool isRedoAvailable)
    {
        qDebug() << Q_FUNC_INFO << "isRedoAvailable" << isRedoAvailable;
        if(isRedoAvailable)
        {
            ui->mRedoBUtton->setEnabled(true);
        }
        else
        {
            ui->mRedoBUtton->setEnabled(false);
        }
    }
    

    Hope this can help !



  • Hi mostefa,

    Thanks for the example! I have a QTabView each tab holds a QPlainTextEdit. As long as I am in one tab everything works fine. I have connected the signals and slots and they work as intended (besides the first undo signal). My issue is that if I change the tab I need to change my icons as well. By changing the tab the current QPlainTextEdit will not fire undo/redoAvailable.

    How could I make it fire or how can I check the current state?

    Other than by storing the current state in new variable.


  • Moderators

    @Sikarjan When you change the tab disconnect the previous textEdit and connect the new one



  • Not sure how I would do the disconnect. The tab changed signal only gives me the new index and I do not see a onFocusLost signal I could connect to. So how would you do the disconnect?


  • Moderators

    @Sikarjan You can store the pointer to currently active textEdit. If you switch to another tab you disconnect from the old textEdit using that stored pointer (use disconnect() function), connect the new one and store the pointer to the new textEdit.



  • @jsulm Okay I see. And with connecting all signals will be fired, right?

    Thanks for the suggestion.


  • Moderators

    @Sikarjan said in Check if undo/redo stack has items:

    And with connecting all signals will be fired, right?

    What do you mean? Connected signals will be fired, that's why you connect them.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.