]> git.saurik.com Git - wxWidgets.git/commitdiff
another file I added on the wxUniv branch and forgot to merge
authorVadim Zeitlin <vadim@wxwidgets.org>
Wed, 27 Jun 2001 12:04:21 +0000 (12:04 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Wed, 27 Jun 2001 12:04:21 +0000 (12:04 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@10680 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

src/common/cmdproc.cpp [new file with mode: 0644]

diff --git a/src/common/cmdproc.cpp b/src/common/cmdproc.cpp
new file mode 100644 (file)
index 0000000..c2d44c8
--- /dev/null
@@ -0,0 +1,286 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name:        src/common/cmdproc.cpp
+// Purpose:     wxCommand and wxCommandProcessor classes
+// Author:      Julian Smart (extracted from docview.h by VZ)
+// Modified by:
+// Created:     05.11.00
+// RCS-ID:      $Id$
+// Copyright:   (c) wxWindows team
+// Licence:     wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#ifdef __GNUG__
+    #pragma implementation "cmdproc.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+    #include "wx/intl.h"
+    #include "wx/string.h"
+    #include "wx/menu.h"
+#endif //WX_PRECOMP
+
+#include "wx/cmdproc.h"
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+IMPLEMENT_CLASS(wxCommand, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxCommandProcessor, wxObject)
+
+// ----------------------------------------------------------------------------
+// wxCommand
+// ----------------------------------------------------------------------------
+
+wxCommand::wxCommand(bool canUndoIt, const wxString& name)
+{
+    m_canUndo = canUndoIt;
+    m_commandName = name;
+}
+
+wxCommand::~wxCommand()
+{
+}
+
+// ----------------------------------------------------------------------------
+// Command processor
+// ----------------------------------------------------------------------------
+
+wxCommandProcessor::wxCommandProcessor(int maxCommands)
+{
+    m_maxNoCommands = maxCommands;
+    m_currentCommand = (wxNode *) NULL;
+#if wxUSE_MENUS
+    m_commandEditMenu = (wxMenu *) NULL;
+#endif // wxUSE_MENUS
+}
+
+wxCommandProcessor::~wxCommandProcessor()
+{
+    ClearCommands();
+}
+
+bool wxCommandProcessor::DoCommand(wxCommand& cmd)
+{
+    return cmd.Do();
+}
+
+bool wxCommandProcessor::UndoCommand(wxCommand& cmd)
+{
+    return cmd.Undo();
+}
+
+// Pass a command to the processor. The processor calls Do();
+// if successful, is appended to the command history unless
+// storeIt is FALSE.
+bool wxCommandProcessor::Submit(wxCommand *command, bool storeIt)
+{
+    wxCHECK_MSG( command, FALSE, _T("no command in wxCommandProcessor::Submit") );
+
+    if ( !DoCommand(*command) )
+        return FALSE;
+
+    if ( storeIt )
+        Store(command);
+
+    return TRUE;
+}
+
+void wxCommandProcessor::Store(wxCommand *command)
+{
+    wxCHECK_RET( command, _T("no command in wxCommandProcessor::Store") );
+
+    if (m_commands.Number() == m_maxNoCommands)
+    {
+        wxNode *firstNode = m_commands.First();
+        wxCommand *firstCommand = (wxCommand *)firstNode->Data();
+        delete firstCommand;
+        delete firstNode;
+    }
+
+    // Correct a bug: we must chop off the current 'branch'
+    // so that we're at the end of the command list.
+    if (!m_currentCommand)
+        ClearCommands();
+    else
+    {
+        wxNode *node = m_currentCommand->Next();
+        while (node)
+        {
+            wxNode *next = node->Next();
+            delete (wxCommand *)node->Data();
+            delete node;
+            node = next;
+        }
+    }
+
+    m_commands.Append(command);
+    m_currentCommand = m_commands.Last();
+    SetMenuStrings();
+}
+
+bool wxCommandProcessor::Undo()
+{
+    wxCommand *command = GetCurrentCommand();
+    if ( command && command->CanUndo() )
+    {
+        if ( UndoCommand(*command) )
+        {
+            m_currentCommand = m_currentCommand->Previous();
+            SetMenuStrings();
+            return TRUE;
+        }
+    }
+
+    return FALSE;
+}
+
+bool wxCommandProcessor::Redo()
+{
+    wxCommand *redoCommand = (wxCommand *) NULL;
+    wxNode *redoNode = (wxNode *) NULL;
+    if (m_currentCommand && m_currentCommand->Next())
+    {
+        redoCommand = (wxCommand *)m_currentCommand->Next()->Data();
+        redoNode = m_currentCommand->Next();
+    }
+    else
+    {
+        if (m_commands.Number() > 0)
+        {
+            redoCommand = (wxCommand *)m_commands.First()->Data();
+            redoNode = m_commands.First();
+        }
+    }
+
+    if (redoCommand)
+    {
+        bool success = DoCommand(*redoCommand);
+        if (success)
+        {
+            m_currentCommand = redoNode;
+            SetMenuStrings();
+            return TRUE;
+        }
+    }
+    return FALSE;
+}
+
+bool wxCommandProcessor::CanUndo() const
+{
+    wxCommand *command = GetCurrentCommand();
+
+    return command && command->CanUndo();
+}
+
+bool wxCommandProcessor::CanRedo() const
+{
+    if ((m_currentCommand != (wxNode*) NULL) && (m_currentCommand->Next() == (wxNode*) NULL))
+        return FALSE;
+
+    if ((m_currentCommand != (wxNode*) NULL) && (m_currentCommand->Next() != (wxNode*) NULL))
+        return TRUE;
+
+    if ((m_currentCommand == (wxNode*) NULL) && (m_commands.Number() > 0))
+        return TRUE;
+
+    return FALSE;
+}
+
+void wxCommandProcessor::Initialize()
+{
+    m_currentCommand = m_commands.Last();
+    SetMenuStrings();
+}
+
+void wxCommandProcessor::SetMenuStrings()
+{
+#if wxUSE_MENUS
+    if (m_commandEditMenu)
+    {
+        wxString buf;
+        if (m_currentCommand)
+        {
+            wxCommand *command = (wxCommand *)m_currentCommand->Data();
+            wxString commandName(command->GetName());
+            if (commandName == wxT("")) commandName = _("Unnamed command");
+            bool canUndo = command->CanUndo();
+            if (canUndo)
+                buf = wxString(_("&Undo ")) + commandName;
+            else
+                buf = wxString(_("Can't &Undo ")) + commandName;
+
+            m_commandEditMenu->SetLabel(wxID_UNDO, buf);
+            m_commandEditMenu->Enable(wxID_UNDO, canUndo);
+
+            // We can redo, if we're not at the end of the history.
+            if (m_currentCommand->Next())
+            {
+                wxCommand *redoCommand = (wxCommand *)m_currentCommand->Next()->Data();
+                wxString redoCommandName(redoCommand->GetName());
+                if (redoCommandName == wxT("")) redoCommandName = _("Unnamed command");
+                buf = wxString(_("&Redo ")) + redoCommandName;
+                m_commandEditMenu->SetLabel(wxID_REDO, buf);
+                m_commandEditMenu->Enable(wxID_REDO, TRUE);
+            }
+            else
+            {
+                m_commandEditMenu->SetLabel(wxID_REDO, _("&Redo"));
+                m_commandEditMenu->Enable(wxID_REDO, FALSE);
+            }
+        }
+        else
+        {
+            m_commandEditMenu->SetLabel(wxID_UNDO, _("&Undo"));
+            m_commandEditMenu->Enable(wxID_UNDO, FALSE);
+
+            if (m_commands.Number() == 0)
+            {
+                m_commandEditMenu->SetLabel(wxID_REDO, _("&Redo"));
+                m_commandEditMenu->Enable(wxID_REDO, FALSE);
+            }
+            else
+            {
+                // currentCommand is NULL but there are commands: this means that
+                // we've undone to the start of the list, but can redo the first.
+                wxCommand *redoCommand = (wxCommand *)m_commands.First()->Data();
+                wxString redoCommandName(redoCommand->GetName());
+                if (redoCommandName == wxT("")) redoCommandName = _("Unnamed command");
+                buf = wxString(_("&Redo ")) + redoCommandName;
+                m_commandEditMenu->SetLabel(wxID_REDO, buf);
+                m_commandEditMenu->Enable(wxID_REDO, TRUE);
+            }
+        }
+    }
+#endif // wxUSE_MENUS
+}
+
+void wxCommandProcessor::ClearCommands()
+{
+    wxNode *node = m_commands.First();
+    while (node)
+    {
+        wxCommand *command = (wxCommand *)node->Data();
+        delete command;
+        delete node;
+        node = m_commands.First();
+    }
+    m_currentCommand = (wxNode *) NULL;
+}
+
+