Code for Undo Framework Example
/****************************************************************************
**
** Copyright (C) 1992-2008 Nokia. All rights reserved.
**
** This file is part of Qt Jambi.
**
** * Commercial Usage
* Licensees holding valid Qt Commercial licenses may use this file in
* accordance with the Qt Commercial License Agreement provided with the
* Software or, alternatively, in accordance with the terms contained in
* a written agreement between you and Nokia.
*
*
* GNU General Public License Usage
* Alternatively, this file may be used under the terms of the GNU
* General Public License versions 2.0 or 3.0 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included in
* the packaging of this file. Please review the following information
* to ensure GNU General Public Licensing requirements will be met:
* http://www.fsf.org/licensing/licenses/info/GPLv2.html and
* http://www.gnu.org/copyleft/gpl.html. In addition, as a special
* exception, Nokia gives you certain additional rights. These rights
* are described in the Nokia Qt GPL Exception version 1.2, included in
* the file GPL_EXCEPTION.txt in this package.
*
* Qt for Windows(R) Licensees
* As a special exception, Nokia, as the sole copyright holder for Qt
* Designer, grants users of the Qt/Eclipse Integration plug-in the
* right for the Qt/Eclipse Integration to link to functionality
* provided by Qt Designer and its related libraries.
*
*
* If you are unsure which license is appropriate for your use, please
* contact the sales department at qt-sales@nokia.com.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
package com.trolltech.examples;
import com.trolltech.qt.gui.*;
import com.trolltech.qt.core.*;
import java.util.*;
@QtJambiExample(name = "Undo Framework")
public class UndoFramework extends QMainWindow
{
private QAction deleteAction;
private QAction addBoxAction;
private QAction addTriangleAction;
private QAction undoAction;
private QAction redoAction;
private QAction exitAction;
private QAction aboutAction;
private QMenu fileMenu;
private QMenu editMenu;
private QMenu itemMenu;
private QMenu helpMenu;
private DiagramScene diagramScene;
private QUndoStack undoStack;
private QUndoView undoView;
public static int itemCount = 0;
public enum DiagramType { Box, Triangle }
public UndoFramework()
{
undoStack = new QUndoStack();
createActions();
createMenus();
undoStack.canRedoChanged.connect(redoAction, "setEnabled(boolean)");
undoStack.canUndoChanged.connect(undoAction, "setEnabled(boolean)");
createUndoView();
diagramScene = new DiagramScene();
diagramScene.setSceneRect(new QRectF(0, 0, 500, 500));
diagramScene.itemMoved.connect(this, "itemMoved(UndoFramework$DiagramItem,QPointF)");
setWindowTitle("Undo Framework");
QGraphicsView view = new QGraphicsView(diagramScene);
setCentralWidget(view);
resize(700, 500);
}
private void createUndoView()
{
undoView = new QUndoView(undoStack);
undoView.setWindowTitle(tr("Command List"));
undoView.setAttribute(Qt.WidgetAttribute.WA_QuitOnClose, false);
QDialog dialog = new QDialog(this);
QVBoxLayout layout = new QVBoxLayout(dialog);
layout.setContentsMargins(0, 0, 0, 0);
layout.addWidget(undoView);
dialog.show();
}
private void createActions()
{
deleteAction = new QAction(tr("&Delete Item"), this);
deleteAction.setShortcut(tr("Del"));
deleteAction.triggered.connect(this, "deleteItem()");
addBoxAction = new QAction(tr("Add &Box"), this);
addBoxAction.setShortcut(tr("Ctrl+O"));
addBoxAction.triggered.connect(this, "addBox()");
addTriangleAction = new QAction(tr("Add &Triangle"), this);
addTriangleAction.setShortcut(tr("Ctrl+T"));
addTriangleAction.triggered.connect(this, "addTriangle()");
undoAction = new QAction(tr("&Undo"), this);
undoAction.setShortcut(tr("Ctrl+Z"));
undoAction.setEnabled(false);
undoAction.triggered.connect(undoStack, "undo()");
redoAction = new QAction(tr("&Redo"), this);
List<QKeySequence> redoShortcuts = new LinkedList<QKeySequence>();
redoShortcuts.add(new QKeySequence(tr("Ctrl+Y")));
redoShortcuts.add(new QKeySequence(tr("Shift+Ctrl+Z")));
redoAction.setShortcuts(redoShortcuts);
redoAction.setEnabled(false);
redoAction.triggered.connect(undoStack, "redo()");
exitAction = new QAction(tr("E&xit"), this);
exitAction.setShortcut(tr("Ctrl+Q"));
exitAction.triggered.connect(this, "close()");
aboutAction = new QAction(tr("&About"), this);
List<QKeySequence> aboutShortcuts = new LinkedList<QKeySequence>();
aboutShortcuts.add(new QKeySequence(tr("Ctrl+A")));
aboutShortcuts.add(new QKeySequence(tr("Ctrl+B")));
aboutAction.setShortcuts(aboutShortcuts);
aboutAction.triggered.connect(this, "about()");
}
private void createMenus()
{
fileMenu = menuBar().addMenu(tr("&File"));
fileMenu.addAction(exitAction);
editMenu = menuBar().addMenu(tr("&Edit"));
editMenu.addAction(undoAction);
editMenu.addAction(redoAction);
editMenu.addSeparator();
editMenu.addAction(deleteAction);
editMenu.aboutToShow.connect(this, "itemMenuAboutToShow()");
editMenu.aboutToHide.connect(this, "itemMenuAboutToHide()");
itemMenu = menuBar().addMenu(tr("&Item"));
itemMenu.addAction(addBoxAction);
itemMenu.addAction(addTriangleAction);
helpMenu = menuBar().addMenu(tr("&About"));
helpMenu.addAction(aboutAction);
}
public void itemMoved(DiagramItem movedItem, QPointF oldPosition)
{
undoStack.push(new MoveCommand(movedItem, oldPosition));
}
private void deleteItem()
{
if (diagramScene.selectedItems().isEmpty())
return;
QUndoCommand deleteCommand = new DeleteCommand(diagramScene);
undoStack.push(deleteCommand);
}
private void itemMenuAboutToHide()
{
deleteAction.setEnabled(true);
}
private void itemMenuAboutToShow()
{
undoAction.setText(tr("Undo ") + undoStack.undoText());
redoAction.setText(tr("Redo ") + undoStack.redoText());
deleteAction.setEnabled(!diagramScene.selectedItems().isEmpty());
}
private void addBox()
{
QUndoCommand addCommand = new AddCommand(DiagramType.Box, diagramScene);
undoStack.push(addCommand);
}
private void addTriangle()
{
QUndoCommand addCommand = new AddCommand(DiagramType.Triangle,
diagramScene);
undoStack.push(addCommand);
}
private void about()
{
QMessageBox.about(this, tr("About Undo"),
tr("The <b>Undo</b> example demonstrates how to " +
"use Qt's undo framework."));
}
class DiagramItem extends QGraphicsPolygonItem
{
private QPolygonF boxPolygon;
private QPolygonF trianglePolygon;
public DiagramItem(DiagramType diagramType)
{
boxPolygon = new QPolygonF();
trianglePolygon = new QPolygonF();
if (diagramType == DiagramType.Box) {
boxPolygon.add(new QPointF(0, 0));
boxPolygon.add(new QPointF(0, 30));
boxPolygon.add(new QPointF(30, 30));
boxPolygon.add(new QPointF(30, 0));
boxPolygon.add(new QPointF(0, 0));
setPolygon(boxPolygon);
} else {
trianglePolygon.add(new QPointF(15, 0));
trianglePolygon.add(new QPointF(30, 30));
trianglePolygon.add(new QPointF(0, 30));
trianglePolygon.add(new QPointF(15, 0));
setPolygon(trianglePolygon);
}
Random random = new Random();
QColor color = new QColor(random.nextInt(256), random.nextInt(256), random.nextInt(256));
QBrush brush = new QBrush(color);
setBrush(brush);
setFlag(QGraphicsItem.GraphicsItemFlag.ItemIsSelectable, true);
setFlag(QGraphicsItem.GraphicsItemFlag.ItemIsMovable, true);
}
public DiagramType diagramType() {
return polygon().subtracted(boxPolygon).isEmpty() ? DiagramType.Box : DiagramType.Triangle;
}
}
class DiagramScene extends QGraphicsScene
{
public Signal2<DiagramItem,QPointF> itemMoved =
new Signal2<DiagramItem,QPointF>();
private DiagramItem movingItem;
private QPointF oldPos;
public DiagramScene()
{
movingItem = null;
}
@Override
public void mousePressEvent(QGraphicsSceneMouseEvent event)
{
QPointF mousePos = new QPointF(event.buttonDownScenePos(Qt.MouseButton.LeftButton).x(),
event.buttonDownScenePos(Qt.MouseButton.LeftButton).y());
movingItem = (DiagramItem) itemAt(mousePos.x(), mousePos.y());
if (movingItem != null && event.button() == Qt.MouseButton.LeftButton) {
oldPos = movingItem.pos();
}
super.mousePressEvent(event);
}
@Override
public void mouseReleaseEvent(QGraphicsSceneMouseEvent event)
{
if (movingItem != null && event.button() == Qt.MouseButton.LeftButton) {
if (oldPos != movingItem.pos()) {
itemMoved.emit(movingItem, oldPos);
}
movingItem = null;
}
super.mouseReleaseEvent(event);
}
@Override
protected void drawBackground(QPainter painter, QRectF rect)
{
double startY = rect.top() - Math.IEEEremainder(rect.top(), 30.0);
for (; startY < rect.bottom(); startY += 30.0)
painter.drawLine(new QPointF(rect.left(), startY),
new QPointF(rect.right(), startY));
double startX = rect.left() - Math.IEEEremainder(rect.left(), 30.0);
for (; startX < rect.right(); startX += 30.0)
painter.drawLine(new QPointF(startX, rect.top()),
new QPointF(startX, rect.bottom()));
}
}
class DeleteCommand extends QUndoCommand
{
private DiagramItem myDiagramItem;
private QGraphicsScene myGraphicsScene;
public DeleteCommand(QGraphicsScene scene)
{
myGraphicsScene = scene;
List<QGraphicsItemInterface> list = myGraphicsScene.selectedItems();
list.get(0).setSelected(false);
myDiagramItem = (DiagramItem) list.get(0);
setText("Delete " + UndoFramework.createCommandString(myDiagramItem, myDiagramItem.pos()));
}
@Override
public void redo()
{
myGraphicsScene.removeItem(myDiagramItem);
}
@Override
public void undo()
{
myGraphicsScene.addItem(myDiagramItem);
myGraphicsScene.update();
}
}
class MoveCommand extends QUndoCommand
{
private DiagramItem myDiagramItem;
private QPointF myOldPos;
private QPointF newPos;
public MoveCommand(DiagramItem diagramItem, QPointF oldPos)
{
myDiagramItem = diagramItem;
newPos = diagramItem.pos();
myOldPos = oldPos;
}
@Override
public int id() { return 1; }
@Override
public void undo()
{
myDiagramItem.setPos(myOldPos);
myDiagramItem.scene().update();
setText(tr("Move " + UndoFramework.createCommandString(myDiagramItem, newPos)));
}
@Override
public void redo()
{
myDiagramItem.setPos(newPos);
setText(tr("Move " + UndoFramework.createCommandString(myDiagramItem, newPos)));
}
@Override
public boolean mergeWith(QUndoCommand other)
{
MoveCommand moveCommand = (MoveCommand) other;
DiagramItem item = moveCommand.myDiagramItem;
if (!myDiagramItem.equals(item))
return false;
newPos = item.pos();
setText(tr("Move " + UndoFramework.createCommandString(myDiagramItem, newPos)));
return true;
}
}
class AddCommand extends QUndoCommand
{
private DiagramItem myDiagramItem;
private QGraphicsScene myGraphicsScene;
private QPointF initialPosition;
public AddCommand(DiagramType addType, QGraphicsScene scene)
{
myGraphicsScene = scene;
myDiagramItem = new DiagramItem(addType);
initialPosition = new QPointF((UndoFramework.itemCount * 15) % (int) scene.width(),
(UndoFramework.itemCount * 15) % (int) scene.height());
scene.update();
++UndoFramework.itemCount;
setText(tr("Add " + UndoFramework.createCommandString(myDiagramItem, initialPosition)));
}
@Override
public void redo()
{
myGraphicsScene.addItem(myDiagramItem);
myDiagramItem.setPos(initialPosition);
myGraphicsScene.clearSelection();
myGraphicsScene.update();
}
@Override
public void undo()
{
myGraphicsScene.removeItem(myDiagramItem);
myGraphicsScene.update();
}
}
public static String createCommandString(DiagramItem item, QPointF pos)
{
return QCoreApplication.translate("DiagramItem", (item.diagramType() == DiagramType.Box ? "Box" : "Triangle") +
" at (" + pos.x() + ", " + pos.y() + ")");
}
public static void main(String args[])
{
QApplication.initialize(args);
UndoFramework mainWindow = new UndoFramework();
mainWindow.show();
QApplication.exec();
}
}
Copyright © 2008 Nokia |
Trademarks |
Qt Jambi 4.4.3_01 |