File: basiccommand.h

package info (click to toggle)
rosegarden4 1.0-1
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 22,344 kB
  • ctags: 14,022
  • sloc: cpp: 131,139; sh: 9,429; perl: 2,620; xml: 2,231; makefile: 607; python: 374; ansic: 339; ruby: 173; php: 2
file content (130 lines) | stat: -rw-r--r-- 4,027 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// -*- c-basic-offset: 4 -*-

/*
    Rosegarden-4
    A sequencer and musical notation editor.

    This program is Copyright 2000-2005
        Guillaume Laurent   <glaurent@telegraph-road.org>,
        Chris Cannam        <cannam@all-day-breakfast.com>,
        Richard Bown        <bownie@bownie.com>

    The moral right of the authors to claim authorship of this work
    has been asserted.

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
    published by the Free Software Foundation; either version 2 of the
    License, or (at your option) any later version.  See the file
    COPYING included with this distribution for more information.
*/

#ifndef _BASIC_COMMAND_H_
#define _BASIC_COMMAND_H_

/**
 * Command that handles undo on a single Segment by brute-force,
 * saving the affected area of the Segment before the execute() and
 * then restoring it on unexecute().  Subclass this with your own
 * implementation.
 *
 * This class implements execute() and unexecute(); in order to create
 * a working subclass, you should normally put the code you would
 * otherwise have put in execute() into modifySegment().
 */

#include <kcommand.h>
#include "Segment.h"

namespace Rosegarden { class EventSelection; }

/**
 * BasicCommand is an abstract subclass of Command that manages undo,
 * redo and notification of changes within a contiguous region of a
 * single Rosegarden Segment, by brute force.  When a subclass
 * of BasicCommand executes, it stores a copy of the events that are
 * modified by the command, ready to be restored verbatim on undo.
 */

class BasicCommand : public KNamedCommand
{
public:
    virtual ~BasicCommand();

    virtual void execute();
    virtual void unexecute();

    virtual Rosegarden::Segment &getSegment();

    Rosegarden::timeT getStartTime() { return m_startTime; }
    Rosegarden::timeT getEndTime() { return m_endTime; }
    virtual Rosegarden::timeT getRelayoutEndTime();

protected:
    /**
     * You should pass "bruteForceRedoRequired = true" if your
     * subclass's implementation of modifySegment uses discrete
     * event pointers or segment iterators to determine which
     * events to modify, in which case it won't work when
     * replayed for redo because the pointers may no longer be
     * valid.  In which case, BasicCommand will implement redo
     * much like undo, and will only call your modifySegment 
     * the very first time the command object is executed.
     *
     * It is always safe to pass bruteForceRedoRequired true,
     * it's just normally a waste of memory.
     */
    BasicCommand(const QString &name,
		 Rosegarden::Segment &segment,
		 Rosegarden::timeT start, Rosegarden::timeT end,
		 bool bruteForceRedoRequired = false);

    virtual void modifySegment() = 0;

    virtual void beginExecute();

private:
    //--------------- Data members ---------------------------------

    void copyTo(Rosegarden::Segment *);
    void copyFrom(Rosegarden::Segment *);

    Rosegarden::timeT calculateStartTime(Rosegarden::timeT given,
					 Rosegarden::Segment &segment);
    Rosegarden::timeT calculateEndTime(Rosegarden::timeT given,
				       Rosegarden::Segment &segment);

    Rosegarden::timeT m_startTime;
    Rosegarden::timeT m_endTime;

    Rosegarden::Segment &m_segment;
    Rosegarden::Segment m_savedEvents;

    bool m_doBruteForceRedo;
    Rosegarden::Segment *m_redoEvents;
};


/**
 * Subclass of BasicCommand that manages the brute-force undo and redo
 * extends based on a given selection.
 */

class BasicSelectionCommand : public BasicCommand
{
public:
    virtual ~BasicSelectionCommand();

protected:
    /// selection from segment
    BasicSelectionCommand(const QString &name,
			  Rosegarden::EventSelection &selection,
			  bool bruteForceRedoRequired = false);

    /// entire segment
    BasicSelectionCommand(const QString &name,
			  Rosegarden::Segment &segment,
			  bool bruteForceRedoRequired = false);
};

#endif