F:/KPlato/koffice/libs/flake/KoInteractionStrategy.cpp

Aller à la documentation de ce fichier.
00001 /* This file is part of the KDE project
00002  * Copyright (C) 2006 Thomas Zander <zander@kde.org>
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Library General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Library General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Library General Public License
00015  * along with this library; see the file COPYING.LIB.  If not, write to
00016  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018  */
00019 
00020 #include "KoInteractionStrategy.h"
00021 #include "KoSelection.h"
00022 #include "KoShapeManager.h"
00023 #include "KoPointerEvent.h"
00024 #include "KoShapeRubberSelectStrategy.h"
00025 #include "KoShapeMoveStrategy.h"
00026 #include "KoShapeRotateStrategy.h"
00027 #include "KoShapeShearStrategy.h"
00028 #include "KoShapeResizeStrategy.h"
00029 #include "KoCreateShapeStrategy.h"
00030 #include "KoCreateShapesTool.h"
00031 #include "KoInteractionTool.h"
00032 #include "KoCanvasBase.h"
00033 #include "KoTool.h"
00034 
00035 #include <kcommand.h>
00036 
00037 #include <QMouseEvent>
00038 
00039 void KoInteractionStrategy::cancelInteraction() {
00040     KCommand *cmd = createCommand();
00041     if(cmd) {
00042         cmd->unexecute();
00043         delete cmd;
00044     }
00045 }
00046 
00047 KoInteractionStrategy::KoInteractionStrategy(KoTool *parent, KoCanvasBase *canvas)
00048 : m_parent(parent)
00049 , m_canvas(canvas)
00050 {
00051 }
00052 
00053 // static
00054 KoInteractionStrategy* KoInteractionStrategy::createStrategy(KoPointerEvent *event, KoInteractionTool *parent, KoCanvasBase *canvas) {
00055     if((event->buttons() & Qt::LeftButton) == 0)
00056         return 0;  // Nothing to do for middle/right mouse button
00057 
00058     KoCreateShapesTool *crs = dynamic_cast<KoCreateShapesTool*>(parent);
00059     if(crs)
00060         return new KoCreateShapeStrategy(crs, canvas, event->point);
00061 
00062     KoShapeManager *shapeManager = canvas->shapeManager();
00063     KoSelection *select = shapeManager->selection();
00064     bool insideSelection, editableShape=false;
00065     KoFlake::SelectionHandle handle = parent->handleAt(event->point, &insideSelection);
00066 
00067     foreach (KoShape* shape, select->selectedShapes()) {
00068         if (shape->isVisible() && !shape->isLocked()) {
00069             editableShape = true;
00070             break;
00071         }
00072     }
00073 
00074     if(editableShape && (event->modifiers() == Qt::NoModifier )) {
00075         // manipulation of selected shapes goes first
00076         if(handle != KoFlake::NoHandle) {
00077             if(insideSelection)
00078                 return new KoShapeResizeStrategy(parent, canvas, event->point, handle);
00079             if(handle == KoFlake::TopMiddleHandle || handle == KoFlake::RightMiddleHandle ||
00080                         handle == KoFlake::BottomMiddleHandle || handle == KoFlake::LeftMiddleHandle)
00081                 return new KoShapeShearStrategy(parent, canvas, event->point, handle);
00082             return new KoShapeRotateStrategy(parent, canvas, event->point);
00083         }
00084         // This is wrong now when there is a single rotated object as you get it also when pressing outside of the object
00085         if(select->boundingRect().contains(event->point))
00086             return new KoShapeMoveStrategy(parent, canvas, event->point);
00087     }
00088 
00089     KoShape * object( shapeManager->shapeAt( event->point, (event->modifiers() & Qt::ShiftButton) ? KoFlake::NextUnselected : KoFlake::ShapeOnTop, true  ) );
00090     if( !object && handle == KoFlake::NoHandle) {
00091         if ( ( event->modifiers() & Qt::ControlModifier ) == 0 )
00092         {
00093             parent->repaintDecorations();
00094             select->deselectAll();
00095         }
00096         return new KoShapeRubberSelectStrategy(parent, canvas, event->point);
00097     }
00098 
00099     if(select->isSelected(object)) {
00100         if ((event->modifiers() & Qt::ControlModifier) == Qt::ControlModifier ) {
00101             parent->repaintDecorations();
00102             select->deselect(object);
00103         }
00104     }
00105     else if(handle == KoFlake::NoHandle) { // clicked on object which is not selected
00106         parent->repaintDecorations();
00107         if ( ( event->modifiers() & Qt::ControlModifier ) == 0 )
00108             shapeManager->selection()->deselectAll();
00109         select->select(object);
00110         parent->repaintDecorations();
00111         return new KoShapeMoveStrategy(parent, canvas, event->point);
00112     }
00113     return 0;
00114 }
00115 
00116 void KoInteractionStrategy::applyGrid(QPointF &point) {
00117     // The 1e-10 here is a workaround for some weird division problem.
00118     // 360.00062366 / 2.83465058 gives 127 'exactly' when shown as a double,
00119     // but when casting into an int, we get 126. In fact it's 127 - 5.64e-15 !
00120     double gridX, gridY;
00121     m_canvas->gridSize(&gridX, &gridY);
00122 
00123     // This is a problem when calling applyGrid twice, we get 1 less than the time before.
00124     point.setX( static_cast<int>( point.x() / gridX + 1e-10 ) * gridX );
00125     point.setY( static_cast<int>( point.y() / gridY + 1e-10 ) * gridY );
00126 }

Généré le Wed Nov 22 23:40:59 2006 pour KPlato par  doxygen 1.5.1-p1