You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1272 lines
40 KiB
1272 lines
40 KiB
/***************************************************************************
|
|
qsctools.cpp
|
|
-------------------
|
|
begin : Sun Jan 30 2000
|
|
copyright : (C) 2000 by Kamil Dobkowski
|
|
email : kamildbk@friko.onet.pl
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* *
|
|
* 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. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
|
|
#include"qsctools.h"
|
|
#include"qscobjects.h"
|
|
#include"kspanelmanager.h"
|
|
#include"ksworkbook.h"
|
|
#include"kscommands.h"
|
|
#include"widgets/qsdrvqt.h"
|
|
#include"widgets/qsdrvhittest.h"
|
|
#include"widgets/qsplotview.h"
|
|
#include"widgets/qsaxes2d.h"
|
|
#include"widgets/qsaxes3d.h"
|
|
#include"widgets/qsaxis.h"
|
|
#include"dialogs/kstextedit.h"
|
|
#include<qcursor.h>
|
|
#include<qlabel.h>
|
|
#include<qpainter.h>
|
|
#include<qpopupmenu.h>
|
|
#include<qpen.h>
|
|
#include<math.h>
|
|
#include"kmatplotshell.h"
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QSToolLabel::QSToolLabel( QObject *parent )
|
|
: QSTool( parent )
|
|
{
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QSToolLabel::~QSToolLabel()
|
|
{
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolLabel::activate( QSPlotView *p )
|
|
{
|
|
QSTool::activate( p );
|
|
m_view->showUserMessage( tr("Label tool\n"
|
|
"Click on a canvas to create a new label. "
|
|
"If the axis object is currently selected the "
|
|
"newly created label will became its child object "
|
|
"and can be positioned relative to its parents position. "
|
|
"Click on a existing label to edit it. ") );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolLabel::deactivate()
|
|
{
|
|
// WE CANT set selection in deactivate.
|
|
// selection get first sigPageRemoved - it clear itself, next PlotView gets page removed,
|
|
// calls deactivate, and in deactivate we select an object which was removed with this page.
|
|
//m_view->selection()->set( active );
|
|
QSTool::deactivate();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolLabel::canvasClicked( const QPoint& pos, int )
|
|
{
|
|
QSCLabel *clicked = dynamic_cast<QSCLabel*>(m_view->objectAt(pos,true));
|
|
|
|
QSCLabel *edited_label;
|
|
if ( !clicked ) {
|
|
edited_label = new QSCLabel();
|
|
edited_label->setBox( QSRectf( pos.x(), pos.y(), 10, 10 ), driver() );
|
|
} else {
|
|
edited_label = clicked;
|
|
}
|
|
|
|
KSTextEditDlg dlg(m_view,edited_label->text(),edited_label->font());
|
|
if ( dlg.exec() ) edited_label->setText( dlg.text() );
|
|
|
|
if ( !clicked ) {
|
|
if ( edited_label->text().isEmpty() ) {
|
|
delete edited_label;
|
|
} else {
|
|
QSRectf box = edited_label->box(driver());
|
|
if ( dynamic_cast<KSWorkbook*>(m_view->workbook())->execute( new KSCmdAddCObject(edited_label,m_view->activeCollection()) ) )
|
|
edited_label->setBox( box, driver() );
|
|
}
|
|
} else {
|
|
if ( edited_label->text().isEmpty() ) {
|
|
dynamic_cast<KSWorkbook*>(m_view->workbook())->execute( new KSCmdRemoveCObject(edited_label) );
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
|
|
|
|
|
|
class QSToolSelect::Handle {
|
|
public:
|
|
enum Type {
|
|
Selected,
|
|
Resize,
|
|
Rotate,
|
|
RCenter,
|
|
Special
|
|
};
|
|
enum AlignFlags {
|
|
HCenter = 1U<<0,
|
|
VCenter = 1U<<1,
|
|
Left = 1U<<2,
|
|
Right = 1U<<3,
|
|
Top = 1U<<4,
|
|
Bottom = 1U<<5
|
|
};
|
|
Type m_type;
|
|
int m_align;
|
|
QSCObject *m_object;
|
|
QPoint m_pos;
|
|
QRect m_rect;
|
|
int m_number;
|
|
QCursor m_cursor;
|
|
|
|
//----------------------------------------------//
|
|
|
|
Handle( const QPoint& pos, QSCObject *object, Type type, int align=HCenter|VCenter, int number=-1 ) {
|
|
m_pos = pos;
|
|
m_object = object;
|
|
m_type = type;
|
|
m_align = align;
|
|
m_number = number;
|
|
switch( m_type ) {
|
|
case Special: m_rect = QRect( 0, 0, 5, 5 ); break;
|
|
default: m_rect = QRect( 0, 0, 7, 7 ); break;
|
|
}
|
|
m_rect.moveCenter( m_pos );
|
|
if ( align & Left ) m_rect.moveTopRight( QPoint(m_pos.x(),m_rect.top()) );
|
|
if ( align & Right ) m_rect.moveTopLeft( QPoint(m_pos.x(),m_rect.top()) );
|
|
if ( align & Top ) m_rect.moveBottomLeft( QPoint(m_rect.left(),m_pos.y()) );
|
|
if ( align & Bottom ) m_rect.moveTopLeft( QPoint(m_rect.left(),m_pos.y()) );
|
|
}
|
|
|
|
~Handle() {
|
|
}
|
|
|
|
//--------------------------------------------//
|
|
|
|
void paint( QPainter *p ) {
|
|
p->setPen( Qt::SolidLine );
|
|
p->setBrush( Qt::NoBrush );
|
|
switch( m_type ) {
|
|
case Resize: p->fillRect( m_rect, black ); break;
|
|
case Selected: p->drawRect( m_rect ); break;
|
|
case Rotate: p->drawEllipse( m_rect ); break;
|
|
case Special: p->drawEllipse( m_rect ); break;
|
|
case RCenter: p->drawEllipse( m_rect );
|
|
p->drawPoint( m_pos ); break;
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------//
|
|
|
|
QCursor cursor() {
|
|
if ( m_type == Rotate ) {
|
|
return QCursor(Qt::crossCursor);
|
|
}
|
|
if ( m_type == Resize ) {
|
|
if ( m_align & HCenter ) return QCursor(Qt::sizeVerCursor);
|
|
if ( m_align & VCenter ) return QCursor(Qt::sizeHorCursor);
|
|
if ( m_align & Top ) {
|
|
if ( m_align & Left ) return QCursor(Qt::sizeFDiagCursor);
|
|
if ( m_align & Right ) return QCursor(Qt::sizeBDiagCursor);
|
|
}
|
|
if ( m_align & Bottom ) {
|
|
if ( m_align & Left ) return QCursor(Qt::sizeBDiagCursor);
|
|
if ( m_align & Right ) return QCursor(Qt::sizeFDiagCursor);
|
|
}
|
|
}
|
|
|
|
return QCursor(Qt::arrowCursor);
|
|
}
|
|
};
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QSToolSelect::QSToolSelect( KMatplotShell *shell, QObject *parent )
|
|
: QSTool( parent )
|
|
{
|
|
m_state = StateNormal;
|
|
m_shell = shell;
|
|
m_handles.setAutoDelete( TRUE );
|
|
m_handles_visible = false;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QSToolSelect::~QSToolSelect()
|
|
{
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolSelect::make_new_handles()
|
|
{
|
|
m_handles.clear();
|
|
QSSelection *curr_sel = m_view->selection();
|
|
for( int object_nr=0; object_nr<curr_sel->count(); object_nr++ ) {
|
|
QSCObject *curr_obj = curr_sel->object(object_nr);
|
|
QSRectf curr_box = curr_obj->box(driver()).normalize();
|
|
QSPt2f curr_rcenter = curr_obj->rCenter(driver());
|
|
QRect rect = curr_box.rect();
|
|
QPoint rcenter = curr_rcenter.point();
|
|
bool is_resizeable = curr_obj->style() & QSCObject::Resizeable;
|
|
bool is_rotateable = curr_obj->style() & QSCObject::Rotateable;
|
|
if ( m_state == StateNormal || !is_rotateable ) {
|
|
Handle::Type type = is_resizeable ? Handle::Resize : Handle::Selected;
|
|
m_handles.append( new Handle( QPoint(rect.center().x(),rect.top()), curr_obj, type, Handle::HCenter|Handle::Top ) );
|
|
m_handles.append( new Handle( QPoint(rect.center().x(),rect.bottom()), curr_obj, type, Handle::HCenter|Handle::Bottom ) );
|
|
m_handles.append( new Handle( QPoint(rect.left(),rect.center().y()), curr_obj, type, Handle::VCenter|Handle::Left ) );
|
|
m_handles.append( new Handle( QPoint(rect.right(),rect.center().y()), curr_obj, type, Handle::VCenter|Handle::Right ) );
|
|
|
|
m_handles.append( new Handle( rect.topLeft(), curr_obj, type, Handle::Top|Handle::Left ) );
|
|
m_handles.append( new Handle( rect.topRight(), curr_obj, type, Handle::Top|Handle::Right ) );
|
|
m_handles.append( new Handle( rect.bottomLeft(), curr_obj, type, Handle::Bottom|Handle::Left ) );
|
|
m_handles.append( new Handle( rect.bottomRight(), curr_obj, type, Handle::Bottom|Handle::Right ) );
|
|
}
|
|
else
|
|
if ( m_state == StateRotate ) {
|
|
m_handles.append( new Handle( rect.topLeft(), curr_obj, Handle::Rotate, Handle::Top|Handle::Left ) );
|
|
m_handles.append( new Handle( rect.topRight(), curr_obj, Handle::Rotate, Handle::Top|Handle::Right ) );
|
|
m_handles.append( new Handle( rect.bottomLeft(), curr_obj, Handle::Rotate, Handle::Bottom|Handle::Left ) );
|
|
m_handles.append( new Handle( rect.bottomRight(), curr_obj, Handle::Rotate, Handle::Bottom|Handle::Right ) );
|
|
m_handles.append( new Handle( rcenter, curr_obj, Handle::RCenter ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolSelect::paint_handles()
|
|
{
|
|
if ( m_view->fullPage() ) {
|
|
QPainter p(m_view->canvasWidget());
|
|
p.setRasterOp( Qt::NotXorROP );
|
|
for( unsigned int i=0; i<m_handles.count(); i++ ) m_handles.at(i)->paint(&p);
|
|
m_handles_visible = !m_handles_visible;
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolSelect::show_handles()
|
|
{
|
|
if ( !m_handles_visible ) paint_handles();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolSelect::hide_handles()
|
|
{
|
|
if ( m_handles_visible ) paint_handles();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QSToolSelect::Handle *QSToolSelect::handle_at( const QPoint& pos )
|
|
{
|
|
if ( m_handles_visible && m_view->currentPage() && m_view->selection()->rootCollection() == m_view->currentPage()->objects() )
|
|
for ( unsigned int i=0; i<m_handles.count(); i++ )
|
|
if ( m_handles.at(i)->m_rect.contains(pos) ) return m_handles.at(i);
|
|
return NULL;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QSCObject *QSToolSelect::selected_at( const QPoint& pos )
|
|
{
|
|
if ( m_view->currentPage() && m_view->selection()->rootCollection() == m_view->currentPage()->objects() ) {
|
|
return m_view->selection()->objectAt( QSPt2f(pos.x(),pos.y()), driver() );
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolSelect::activate( QSPlotView *p )
|
|
{
|
|
QSTool::activate( p );
|
|
m_state = StateNormal;
|
|
connect( m_view->selection(), SIGNAL(sigListChanged()), this, SLOT(slot_selection_changed()) );
|
|
m_view->showUserMessage(tr("Select tool\n"
|
|
"Click to select an object pointed by cursor. "
|
|
"CTRL+Click selects an object inside a group. "
|
|
"SHIFT+Click adds/removes an object from the selection. "
|
|
"Drag with SHIFT button pressed to move smoothly. "
|
|
"Click again on the selected object to turn on a rotate mode. "
|
|
"Right-button click shows menu. "
|
|
"Middle-button click selects a property panel of the element under mouse pointer.") );
|
|
make_new_handles();
|
|
show_handles();
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolSelect::deactivate()
|
|
{
|
|
disconnect( m_view->selection(), SIGNAL(sigListChanged()), this, SLOT(slot_selection_changed()) );
|
|
hide_handles();
|
|
m_handles.clear();
|
|
QSTool::deactivate();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolSelect::slot_selection_changed()
|
|
{
|
|
hide_handles();
|
|
make_new_handles();
|
|
show_handles();
|
|
m_view->showUserMessage( QString(tr(" %1 objects selected.")).arg(m_view->selection()->count()) );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolSelect::draw()
|
|
{
|
|
m_handles_visible = false;
|
|
if ( m_view->fullPage() && m_view->currentPage() && m_view->selection()->rootCollection() == m_view->currentPage()->objects() ) {
|
|
make_new_handles();
|
|
show_handles();
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolSelect::canvasMove( const QPoint& pos )
|
|
{
|
|
if ( !m_view->fullPage() ) return;
|
|
Handle *handle = handle_at(pos);
|
|
if ( handle ) {
|
|
m_view->canvasWidget()->setCursor( handle->cursor() );
|
|
return;
|
|
}
|
|
/*
|
|
QSCObject *object = selected_at(pos);
|
|
if ( object ) {
|
|
m_view->canvasWidget()->setCursor( sizeAllCursor );
|
|
return;
|
|
}
|
|
*/
|
|
m_view->canvasWidget()->setCursor( arrowCursor );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolSelect::canvasMiddleButtonClicked( const QPoint& pos, int )
|
|
{
|
|
if ( m_view->activeObject() && m_view->activeObject()->busy() ) m_view->activeObject()->stop();
|
|
if ( m_view->activeObject() && !m_view->activeObject()->busy() ) {
|
|
KSPanelManager *panel_manager = dynamic_cast<KSPanelManager*>(m_shell->propertyContainer()->widget());
|
|
// test hit - select panel
|
|
if ( panel_manager ) {
|
|
QSDrvHitTest drv( QSPt2f(pos.x(),pos.y()) );
|
|
drv.setDC(new QPainter(m_view->canvasWidget()),m_view->dpi(),true);
|
|
connect(&drv,SIGNAL(hitDetected(int,int)),panel_manager,SLOT(selectPanel(int,int)));
|
|
// hack - axes can be in a single view mode and redrawing axes object
|
|
// redraw object on page, not zoomed in a single view...
|
|
// Driver is not created on the stack ( why ? ) so do blocking redraw
|
|
if ( m_view->activeObject()->isAxesShadow() ) {
|
|
m_view->activeObject()->parentAxes()->drawPlot( &drv, true, true );
|
|
} else {
|
|
m_view->activeObject()->draw( &drv, true, true );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolSelect::canvasClicked( const QPoint& pos, int keyState )
|
|
{
|
|
if ( m_view->fullPage() ) {
|
|
QSCObject *clicked_object = selected_at(pos);
|
|
if ( clicked_object == NULL || (keyState&ControlButton) ) clicked_object = m_view->objectAt(pos,(keyState&ControlButton));
|
|
// user clicked on a new object with Shift pressed - add/remove object from selection
|
|
if ( keyState & Qt::ShiftButton ) {
|
|
m_state = StateNormal;
|
|
m_view->selection()->turn( clicked_object );
|
|
}
|
|
// user clicked on selected object - turn on/off rotation mode
|
|
else if ( m_view->selection()->contains(clicked_object) ) {
|
|
m_state = m_state==StateNormal?StateRotate:StateNormal;
|
|
m_view->selection()->set( clicked_object );
|
|
}
|
|
// user clicked on some object - select it
|
|
else {
|
|
m_state = StateNormal;
|
|
m_view->selection()->set( clicked_object );
|
|
}
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
bool QSToolSelect::canvasDragStart( const QPoint& pos, int keyState )
|
|
{
|
|
m_view->currentPage()->objects()->stop();
|
|
m_drag_handle = NULL;
|
|
m_drag_object = NULL;
|
|
m_move_prev_d = QSPt2f();
|
|
// check if handle clicked
|
|
if ( handle_at(pos) ) {
|
|
m_drag_handle = handle_at(pos);
|
|
create_transform_cmd();
|
|
paint_selected_objects();
|
|
}
|
|
// check if selected object clicked - moving objects
|
|
else if ( selected_at(pos) ) {
|
|
m_drag_object = selected_at(pos);
|
|
create_transform_cmd();
|
|
paint_selected_objects();
|
|
}
|
|
// check if other object was clicked
|
|
else if ( m_view->objectAt(pos,(keyState&ControlButton)) ) {
|
|
QSCObject *clicked_object = m_view->objectAt(pos,(keyState&ControlButton));
|
|
m_view->selection()->set(clicked_object);
|
|
m_drag_object = clicked_object;
|
|
create_transform_cmd();
|
|
paint_selected_objects();
|
|
}
|
|
// selecting using bounding frame
|
|
else if ( keyState & Qt::ShiftButton ) {
|
|
paint_frame( pos, pos );
|
|
}
|
|
// selecting using bounding frame
|
|
else {
|
|
m_view->selection()->clear();
|
|
paint_frame( pos, pos );
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolSelect::canvasDragMove( const QPoint& pos, const QPoint& prevPos, const QPoint& startPos, int keyState, int, int )
|
|
{
|
|
// draging some handle
|
|
if ( m_drag_handle ) {
|
|
switch( m_drag_handle->m_type ) {
|
|
case Handle::Resize: drag_resize_handle_by( pos-startPos, keyState, m_drag_handle ); break;
|
|
case Handle::Rotate: drag_rotate_handle( startPos, pos, keyState, m_drag_handle ); break;
|
|
}
|
|
}
|
|
// moving a group of objects
|
|
else if ( m_drag_object ) {
|
|
move_selected_by( pos-startPos, keyState );
|
|
}
|
|
// selecting using bounding frame
|
|
else {
|
|
paint_frame( prevPos, startPos );
|
|
paint_frame( pos, startPos );
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolSelect::canvasDragEnd( const QPoint& pos, const QPoint& startPos, int, int )
|
|
{
|
|
// dragging some handle
|
|
if ( m_drag_handle ) {
|
|
paint_selected_objects();
|
|
m_transform_cmd->commit();
|
|
dynamic_cast<KSWorkbook*>(m_view->workbook())->execute( m_transform_cmd );
|
|
m_transform_cmd = NULL;
|
|
}
|
|
// moving a group of objects
|
|
else if ( m_drag_object ) {
|
|
paint_selected_objects();
|
|
m_transform_cmd->commit();
|
|
dynamic_cast<KSWorkbook*>(m_view->workbook())->execute( m_transform_cmd );
|
|
m_transform_cmd = NULL;
|
|
}
|
|
// selecting using bounding frame
|
|
else {
|
|
paint_frame( pos, startPos );
|
|
QSRectf bounding_rect = QSRectf( QSPt2f(startPos), QSPt2f(pos), true );
|
|
for( int i=0; i<m_view->currentPage()->objects()->count(); i++ ) {
|
|
QSCObject *object = m_view->currentPage()->objects()->object(i);
|
|
QSRectf curr_rect = object->box(driver());
|
|
if ( bounding_rect.contains(curr_rect.pos) &&
|
|
bounding_rect.contains(curr_rect.pos+curr_rect.size) ) {
|
|
m_view->selection()->add(object);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
bool QSToolSelect::eventMousePress( QMouseEvent* e )
|
|
{
|
|
if ( e->button() == Qt::RightButton ) {
|
|
m_shell->doAction( m_shell->m_object_menu );
|
|
return TRUE;
|
|
}
|
|
return QSTool::eventMousePress( e );
|
|
}
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolSelect::drag_rotate_handle( const QPoint& startPos, const QPoint& currPos, int keyState, Handle *handle )
|
|
{
|
|
QSCObject *object = handle->m_object;
|
|
if ( handle->m_type == Handle::Rotate ) {
|
|
QSPt2f center = object->rCenter(driver());
|
|
int new_angle = snapAngle( int(angle( center, startPos, currPos )) + m_transform_cmd->objectAngle(object), keyState );
|
|
if ( new_angle != object->angle() ) {
|
|
paint_selected_objects();
|
|
object->setAutoUpdates(false);
|
|
object->setAngle(new_angle);
|
|
object->setAutoUpdates(true);
|
|
paint_selected_objects();
|
|
}
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolSelect::drag_resize_handle_by( const QPoint& mouseShift, int keyState, Handle *handle )
|
|
{
|
|
QSCObject *object = handle->m_object;
|
|
if ( handle->m_type == Handle::Resize ) {
|
|
QSRectf rect = m_transform_cmd->objectRect( object );
|
|
if ( handle->m_align & Handle::Top ) {
|
|
rect.setTopLeft( QSPt2f( rect.topLeft().x, snapToGridY( rect.topLeft().y + mouseShift.y(), keyState ) ) );
|
|
}
|
|
if ( handle->m_align & Handle::Bottom ) {
|
|
rect.setBottomRight( QSPt2f( rect.bottomRight().x, snapToGridY( rect.bottomRight().y + mouseShift.y(), keyState ) ) );
|
|
}
|
|
if ( handle->m_align & Handle::Left ) {
|
|
rect.setTopLeft( QSPt2f( snapToGridX( rect.topLeft().x + mouseShift.x(), keyState ), rect.topLeft().y ) );
|
|
}
|
|
if ( handle->m_align & Handle::Right ) {
|
|
rect.setBottomRight( QSPt2f( snapToGridX( rect.bottomRight().x + mouseShift.x(), keyState ), rect.bottomRight().y ) );
|
|
}
|
|
|
|
if ( rect.normalize() != object->box(driver()).normalize() ) {
|
|
paint_selected_objects();
|
|
object->setAutoUpdates(false);
|
|
object->setBox(rect,driver());
|
|
object->setAutoUpdates(true);
|
|
paint_selected_objects();
|
|
}
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolSelect::move_selected_by( const QPoint& mouseShift, int keyState )
|
|
{
|
|
// find top-left corner of selection
|
|
QSPt2f selection_pos;
|
|
for( int i=0; i<m_view->selection()->count(); i++ ) {
|
|
QSCObject *object = m_view->selection()->object(i);
|
|
QSPt2f pos = m_transform_cmd->objectRect( object ).normalize().pos;
|
|
if ( i==0 ) selection_pos = pos;
|
|
selection_pos.x = QMIN( pos.x, selection_pos.x );
|
|
selection_pos.y = QMIN( pos.y, selection_pos.y );
|
|
}
|
|
|
|
// shift the corner, snap to grid, and calculate resulting move distance
|
|
QSPt2f new_pos = snapToGrid( selection_pos+QSPt2f(mouseShift), keyState );
|
|
QSPt2f d = new_pos-selection_pos;
|
|
// move all object by this distance
|
|
if ( m_move_prev_d != d ) {
|
|
paint_selected_objects();
|
|
for( int i=0; i<m_view->selection()->count(); i++ ) {
|
|
QSCObject *object = m_view->selection()->object(i);
|
|
QSRectf box = m_transform_cmd->objectRect( object );
|
|
box.pos = box.pos + d;
|
|
object->setAutoUpdates(false);
|
|
object->setBox(box,driver());
|
|
object->setAutoUpdates(true);
|
|
}
|
|
m_move_prev_d = d;
|
|
paint_selected_objects();
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolSelect::create_transform_cmd()
|
|
{
|
|
QSDrvQt *drv = new QSDrvQt();
|
|
drv->setDC(new QPainter(m_view->canvasWidget()),m_view->dpi(),true);
|
|
m_transform_cmd = new KSCmdTransformCObjects( drv );
|
|
for( int i=0; i<m_view->selection()->count(); i++ ) {
|
|
QSCObject *object = m_view->selection()->object(i);
|
|
m_transform_cmd->addObject( object );
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
int QSToolSelect::angle( const QSPt2f& rcenter, const QPoint& click_pos, const QPoint& mouse_pos )
|
|
{
|
|
double A2 = mouse_pos.y() - rcenter.y;
|
|
double B2 = rcenter.x - mouse_pos.x();
|
|
|
|
double A1 = click_pos.y() - rcenter.y;
|
|
double B1 = rcenter.x - click_pos.x();
|
|
|
|
return int( atan2(A1*B2-A2*B1,A1*A2+B1*B2)*180.0/3.141592 + 0.5 );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolSelect::paint_object( QSCObject* object )
|
|
{
|
|
object->stop();
|
|
QPainter p ( m_view->canvasWidget() );
|
|
p.setRasterOp( Qt::NotXorROP );
|
|
//QSRectf r = object->box(driver());
|
|
object->paintSkeleton( &p, driver()->dpi );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolSelect::paint_selected_objects()
|
|
{
|
|
m_view->selection()->stop();
|
|
QPainter p ( m_view->canvasWidget() );
|
|
p.setRasterOp( Qt::NotXorROP );
|
|
m_view->selection()->paintSkeleton( &p, driver()->dpi );
|
|
/*
|
|
for( int i=0; i<m_view->selection()->objectCount(); i++ ) {
|
|
paint_object( m_view->selection()->object(i) );
|
|
}
|
|
*/
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolSelect::paint_frame( const QPoint& p1, const QPoint& p2 )
|
|
{
|
|
QRect r( p1, p2 );
|
|
QPainter p ( m_view->canvasWidget() );
|
|
p.setRasterOp( Qt::NotXorROP );
|
|
p.setPen( Qt::DotLine );
|
|
p.setBrush( Qt::NoBrush );
|
|
p.drawRect( r );
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
|
|
|
|
QSToolZoom::QSToolZoom( QObject *parent )
|
|
:QSTool( parent )
|
|
{
|
|
m_active_axes = NULL;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QSToolZoom::~QSToolZoom()
|
|
{
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolZoom::activate( QSPlotView *init_view )
|
|
{
|
|
QSTool::activate( init_view );
|
|
erase_crossmark = false;
|
|
|
|
// is the selected object on the current page ?
|
|
if ( m_view->currentPage() &&
|
|
m_view->currentPage()->objects()->find( m_view->activeObject()) >= 0 )
|
|
m_active_axes = m_view->activeObject()->parentAxes();
|
|
|
|
m_view->showUserMessage(tr("Zoom tool\n"
|
|
"Click and drag over selected axes to set a new range."
|
|
"Press a right button to zoom out. "
|
|
"Double click to set a default zoom. "
|
|
"Only scrollable axes are zoomed. ") );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolZoom::deactivate()
|
|
{
|
|
if ( erase_crossmark ) draw_crossmark(p1);
|
|
m_active_axes = NULL;
|
|
QSTool::deactivate();
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolZoom::draw()
|
|
{
|
|
erase_crossmark = false;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolZoom::canvasRightButtonClicked( const QPoint& pos, int )
|
|
{
|
|
bool busy = ( m_active_axes && m_active_axes->state() == QSAxes::Busy );
|
|
if ( erase_crossmark && !busy ) draw_crossmark(p1);
|
|
erase_crossmark = false;
|
|
zoom_out(pos);
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
bool QSToolZoom::canvasDragStart( const QPoint& pos, int )
|
|
{
|
|
if ( find_plane(pos) ) {
|
|
p1 = p2 = world_point( pos );
|
|
if ( erase_crossmark ) draw_crossmark(p1);
|
|
draw_frame();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolZoom::canvasDragMove( const QPoint& pos, const QPoint&, const QPoint&, int, int, int )
|
|
{
|
|
draw_frame();
|
|
p2 = world_point( pos );
|
|
draw_frame();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolZoom::canvasDragEnd( const QPoint&, const QPoint&, int, int )
|
|
{
|
|
draw_frame();
|
|
erase_crossmark = false;
|
|
if ( p1 != p2 ) zoom_in( p1, p2 );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolZoom::canvasMove( const QPoint& pos )
|
|
{
|
|
bool busy = ( m_active_axes && m_active_axes->state() == QSAxes::Busy );
|
|
if ( erase_crossmark && !busy ) draw_crossmark(p1);
|
|
erase_crossmark = false;
|
|
if ( find_plane(pos) ) {
|
|
p1=world_point(pos);
|
|
if ( !busy ) { draw_crossmark(p1); erase_crossmark = true; }
|
|
m_view->showUserMessage(message(p1));
|
|
} else {
|
|
m_view->showUserMessage( QString(tr("OUT OF AREA ")) );
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolZoom::canvasDoubleClicked( const QPoint&, int )
|
|
{
|
|
p1 = p2 = QSPt3f( 0.0, 0.0, 0.0 );
|
|
zoom_in( p1, p2 );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QSPt3f QSToolZoom::world_point( const QPoint& click_pos )
|
|
// returns point in world coordinates
|
|
{
|
|
QSPt3f result;
|
|
QSPt2 canvas_pos( click_pos.x(), click_pos.y() );
|
|
QSAxes *axes = m_active_axes;
|
|
QSAxes3D *axes3d = dynamic_cast<QSAxes3D*>(axes);
|
|
if ( axes3d ) {
|
|
|
|
// find a straight line crossing focuspoint
|
|
// and point on the plane of the screen
|
|
QSPt3f pos1 = axes->proj()->canvas3ToWorld3D(QSPt3f(canvas_pos.x,canvas_pos.y,0.0));
|
|
QSPt3f pos2 = axes->proj()->canvas3ToWorld3D(QSPt3f(canvas_pos.x,canvas_pos.y,1.0));
|
|
|
|
// focuspoint
|
|
if ( axes3d->perspective() ) pos2 = axes3d->p3D()->eye;
|
|
|
|
// 'f' - it is a point where all three planes cross.
|
|
QSPt3f f = axes3d->proj()->furthest();
|
|
|
|
// Inf will be good for other functions to mark that the point is invalid
|
|
QSPt3f inf(-1.0,-1.0,-1.0);
|
|
if ( plane == PlaneYZ && pos1.x == pos2.x ) return inf;
|
|
if ( plane == PlaneXZ && pos1.y == pos2.y ) return inf;
|
|
if ( plane == PlaneXY && pos1.z == pos2.z ) return inf;
|
|
|
|
// Where our straightline crosses the choosen plane ?
|
|
double t = 0.0;
|
|
if ( plane == PlaneYZ ) t = ( f.x - pos1.x ) / ( pos2.x - pos1.x );
|
|
if ( plane == PlaneXZ ) t = ( f.y - pos1.y ) / ( pos2.y - pos1.y );
|
|
if ( plane == PlaneXY ) t = ( f.z - pos1.z ) / ( pos2.z - pos1.z );
|
|
|
|
// Calculate x,y,z from t
|
|
result = f;
|
|
if ( plane != PlaneYZ ) result.x = pos1.x + t * ( pos2.x - pos1.x );
|
|
if ( plane != PlaneXZ ) result.y = pos1.y + t * ( pos2.y - pos1.y );
|
|
if ( plane != PlaneXY ) result.z = pos1.z + t * ( pos2.z - pos1.z );
|
|
} else {
|
|
result = axes->proj()->canvas3ToWorld3D( QSPt3f(canvas_pos.x,canvas_pos.y,0.0) );
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolZoom::draw_frame()
|
|
{
|
|
QSPt3f p[4];
|
|
QSPt2 cp[4];
|
|
p[0] = p1;
|
|
p[1] = (plane == PlaneXY) ? QSPt3f( p1.x, p2.y, p1.z ) : QSPt3f( p1.x, p1.y, p2.z );
|
|
p[2] = p2;
|
|
p[3] = (plane == PlaneXY) ? QSPt3f( p2.x, p1.y, p1.z ) : QSPt3f( p2.x, p2.y, p1.z );
|
|
for( int i=0; i<4; i++ ) {
|
|
QSPt3f curr_p = m_active_axes->proj()->world3DToCanvas3(p[i]);
|
|
cp[i].x = int(curr_p.x+0.5);
|
|
cp[i].y = int(curr_p.y+0.5);
|
|
}
|
|
|
|
QPainter paint( m_view->canvasWidget() );
|
|
paint.setRasterOp( Qt::NotXorROP ); paint.setPen( Qt::DotLine );
|
|
for ( int i=0; i<4; i++ ) paint.drawLine(cp[i].x,cp[i].y,cp[(i+1)%4].x,cp[(i+1)%4].y);
|
|
draw_crossmark( p1 );
|
|
draw_crossmark( p2 );
|
|
QString info = QString(tr("From: \n"))+message(p1)+QString("\n")+QString(tr("To: \n"))+message(p2);
|
|
m_view->showUserMessage(info);
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolZoom::zoom_out( const QPoint& click_pos )
|
|
{
|
|
if ( find_plane(click_pos) ) {
|
|
QSPt3f pos = world_point( click_pos );
|
|
QSPt3f min( pos.x-1.0, pos.y-1.0, pos.z-1.0);
|
|
QSPt3f max( pos.x+1.0, pos.y+1.0, pos.z+1.0);
|
|
zoom_in(min,max);
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolZoom::zoom_in( const QSPt3f& p1, const QSPt3f& p2 )
|
|
// zoom all axes
|
|
{
|
|
QSAxes *axes = m_active_axes;
|
|
if ( axes ) {
|
|
KSCmdSetRanges *cmd = new KSCmdSetRanges( axes );
|
|
for( int axis_nr=0; axis_nr<axes->axisCount(); axis_nr++ ) {
|
|
QSAxis *axis = axes->axis(axis_nr);
|
|
if ( axis->scrollable() ) {
|
|
if ( plane != PlaneYZ && axis->type() == QSAxis::XAxisType ) axis->setRange( axis->worldToData(p1.x), axis->worldToData(p2.x) );
|
|
if ( plane != PlaneXZ && axis->type() == QSAxis::YAxisType ) axis->setRange( axis->worldToData(p1.y), axis->worldToData(p2.y) );
|
|
if ( plane != PlaneXY && axis->type() == QSAxis::ZAxisType ) axis->setRange( axis->worldToData(p1.z), axis->worldToData(p2.z) );
|
|
}
|
|
}
|
|
cmd->commit();
|
|
KSWorkbook *workbook = dynamic_cast<KSWorkbook*>(m_view->workbook());
|
|
workbook->execute( cmd );
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
bool QSToolZoom::find_plane( const QPoint& canvas_pos )
|
|
// sets an internal variable plane;
|
|
{
|
|
if ( m_active_axes )
|
|
if (dynamic_cast<QSAxes3D*>(m_active_axes)) {
|
|
for( int i=0; i<3; i++ ) {
|
|
plane = (Plane )i;
|
|
QSPt3f pos = world_point( canvas_pos );
|
|
switch( plane ) {
|
|
case PlaneXY: if ( pos.x>0.0 && pos.x<1.0 && pos.y>0.0 && pos.y<1.0 ) return true;
|
|
case PlaneXZ: if ( pos.x>0.0 && pos.x<1.0 && pos.z>0.0 && pos.z<1.0 ) return true;
|
|
case PlaneYZ: if ( pos.y>0.0 && pos.y<1.0 && pos.z>0.0 && pos.z<1.0 ) return true;
|
|
}
|
|
}
|
|
} else {
|
|
QSPt3f pos = world_point( canvas_pos );
|
|
plane = PlaneXY;
|
|
//if ( pos.x>0.0 && pos.x<1.0 && pos.y>0.0 && pos.y<1.0 ) return true;
|
|
//return false;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolZoom::draw_crossmark( const QSPt3f& pos )
|
|
{
|
|
if ( !m_active_axes ) return;
|
|
|
|
QSPt3f f;
|
|
QSPt3f min[2];
|
|
QSPt3f max[2];
|
|
|
|
min[0] = min[1] = QSPt3f(-0.02,-0.02,-0.02);
|
|
max[0] = max[1] = QSPt3f( 1.02, 1.02, 1.02);
|
|
QSAxes3D *axes3d = dynamic_cast<QSAxes3D*>(m_active_axes);
|
|
if ( axes3d ) f=axes3d->proj()->furthest();
|
|
switch( plane ) {
|
|
case PlaneXY: min[0].z=min[1].z=max[0].z=max[1].z=f.z;
|
|
min[0].x=max[0].x=pos.x;
|
|
min[1].y=max[1].y=pos.y;
|
|
break;
|
|
case PlaneXZ: min[0].y=min[1].y=max[0].y=max[1].y=f.y;
|
|
min[0].x=max[0].x=pos.x;
|
|
min[1].z=max[1].z=pos.z;
|
|
break;
|
|
case PlaneYZ: min[0].x=min[1].x=max[0].x=max[1].x=f.x;
|
|
min[0].y=max[0].y=pos.y;
|
|
min[1].z=max[1].z=pos.z;
|
|
break;
|
|
}
|
|
|
|
QSPt3f p[2];
|
|
QSPt3f q[2];
|
|
p[0] = m_active_axes->proj()->world3DToCanvas3(min[0]);
|
|
p[1] = m_active_axes->proj()->world3DToCanvas3(min[1]);
|
|
q[0] = m_active_axes->proj()->world3DToCanvas3(max[0]);
|
|
q[1] = m_active_axes->proj()->world3DToCanvas3(max[1]);
|
|
QPainter paint( m_view->canvasWidget() );
|
|
paint.setRasterOp( Qt::NotXorROP ); paint.setPen( Qt::SolidLine );
|
|
paint.drawLine( int(p[0].x+0.5), int(p[0].y+0.5), int(q[0].x+0.5), int(q[0].y+0.5) );
|
|
paint.drawLine( int(p[1].x+0.5), int(p[1].y+0.5), int(q[1].x+0.5), int(q[1].y+0.5) );
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QString QSToolZoom::message( const QSPt3f& p )
|
|
{
|
|
QString message;
|
|
//int x_nr = 1;
|
|
//int y_nr = 1;
|
|
//int z_nr = 1;
|
|
QSAxes *axes = m_active_axes;
|
|
|
|
if ( axes )
|
|
for ( int axis_nr=0; axis_nr<axes->axisCount(); axis_nr++ ) {
|
|
QSAxis *axis = axes->axis(axis_nr);
|
|
if ( axis->scrollable() )
|
|
switch(axis->type()) {
|
|
case QSAxis::XAxisType: message += QString("X \"")+axis->title()+QString("\" = ")+QString::number(axis->worldToData(p.x))+QString("\n");break;
|
|
case QSAxis::YAxisType: message += QString("Y \"")+axis->title()+QString("\" = ")+QString::number(axis->worldToData(p.y))+QString("\n");break;
|
|
case QSAxis::ZAxisType: message += QString("Z \"")+axis->title()+QString("\" = ")+QString::number(axis->worldToData(p.z))+QString("\n");break;
|
|
default: break;
|
|
}
|
|
}
|
|
return message;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
|
|
|
|
QSToolArrow::QSToolArrow( QObject *parent )
|
|
:QSTool( parent )
|
|
{
|
|
m_new_object = NULL;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QSToolArrow::~QSToolArrow()
|
|
{
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolArrow::activate( QSPlotView *init_view )
|
|
{
|
|
QSTool::activate( init_view );
|
|
m_view->showUserMessage(tr("Arrow tool. \n"
|
|
"If the axis object is currently selected the "
|
|
"newly created arrow will became its child object "
|
|
"and can be positioned relative to its parents position. ") );
|
|
m_view->canvasWidget()->setCursor( crossCursor );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolArrow::deactivate()
|
|
{
|
|
QSTool::deactivate();
|
|
delete m_new_object; m_new_object = NULL;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolArrow::draw()
|
|
{
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
bool QSToolArrow::canvasDragStart( const QPoint& pos, int keyState )
|
|
{
|
|
m_new_object = new QSCArrow();
|
|
m_new_object->setBox( QSRectf( snapToGrid(pos,keyState), snapToGrid(pos,keyState) ), driver() );
|
|
paint_object();
|
|
return true;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolArrow::canvasDragMove( const QPoint& pos, const QPoint&, const QPoint& startPos, int keyState, int, int startKeyState )
|
|
{
|
|
paint_object();
|
|
m_new_object->setBox( QSRectf( snapToGrid(pos,keyState), snapToGrid(startPos,startKeyState), false ), driver() );
|
|
paint_object();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolArrow::canvasDragEnd( const QPoint& pos, const QPoint& startPos, int keyState, int startKeyState )
|
|
{
|
|
paint_object();
|
|
if ( snapToGrid(pos,keyState) != snapToGrid(startPos,startKeyState) ) {
|
|
if ( dynamic_cast<KSWorkbook*>(m_view->workbook())->execute( new KSCmdAddCObject(m_new_object,m_view->activeCollection()) ) ) {
|
|
m_new_object->setBox( QSRectf( snapToGrid(pos,keyState), snapToGrid(startPos,startKeyState), false ), driver() );
|
|
}
|
|
} else {
|
|
delete m_new_object;
|
|
}
|
|
m_new_object = NULL;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolArrow::paint_object()
|
|
{
|
|
QPainter p ( m_view->canvasWidget() );
|
|
p.setRasterOp( Qt::NotXorROP );
|
|
m_new_object->paint( &p, driver()->dpi );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
|
|
QSToolRect::QSToolRect( QObject *parent )
|
|
:QSTool( parent )
|
|
{
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QSToolRect::~QSToolRect()
|
|
{
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolRect::activate( QSPlotView *init_view )
|
|
{
|
|
QSTool::activate( init_view );
|
|
m_view->showUserMessage(tr("Rectangle/Ellipse tool."
|
|
"If the axis object is currently selected the "
|
|
"newly created rectangle will became its child object "
|
|
"and can be positioned relative to its parents position. "));
|
|
m_view->canvasWidget()->setCursor( crossCursor );
|
|
m_new_object = NULL;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolRect::deactivate()
|
|
{
|
|
delete m_new_object; m_new_object = NULL;
|
|
QSTool::deactivate();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolRect::draw()
|
|
{
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
bool QSToolRect::canvasDragStart( const QPoint& pos, int keyState )
|
|
{
|
|
m_new_object = new QSCRect();
|
|
m_new_object->setBox( QSRectf(snapToGrid(pos,keyState),QSPt2f()), driver() );
|
|
paint_object();
|
|
return true;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolRect::canvasDragMove( const QPoint& pos, const QPoint&, const QPoint& startPos, int keyState, int, int startKeyState )
|
|
{
|
|
paint_object();
|
|
m_new_object->setBox( QSRectf(snapToGrid(pos,keyState),snapToGrid(startPos,startKeyState),false), driver() );
|
|
paint_object();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolRect::canvasDragEnd( const QPoint& pos, const QPoint& startPos, int keyState, int startKeyState )
|
|
{
|
|
paint_object();
|
|
if ( snapToGrid(pos,keyState) != snapToGrid(startPos,startKeyState) ) {
|
|
if ( dynamic_cast<KSWorkbook*>(m_view->workbook())->execute( new KSCmdAddCObject(m_new_object,m_view->activeCollection()) ) ) {
|
|
m_new_object->setBox( QSRectf(snapToGrid(pos,keyState),snapToGrid(startPos,startKeyState),false), driver() );
|
|
}
|
|
} else {
|
|
delete m_new_object;
|
|
}
|
|
m_new_object = NULL;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolRect::paint_object()
|
|
{
|
|
QPainter p ( m_view->canvasWidget() );
|
|
p.setRasterOp( Qt::NotXorROP );
|
|
if ( m_new_object ) m_new_object->paintSkeleton( &p, driver()->dpi );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
|
|
|
|
QSToolLocate::QSToolLocate( QObject *parent )
|
|
:QSTool( parent )
|
|
{
|
|
m_info = QString();
|
|
m_popup = NULL;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QSToolLocate::~QSToolLocate()
|
|
{
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolLocate::activate( QSPlotView *init_view )
|
|
{
|
|
QSTool::activate( init_view );
|
|
m_view->showUserMessage(tr("Locate tool\n"
|
|
"Click on a datapoint inside the active axes.."));
|
|
draw();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolLocate::deactivate()
|
|
{
|
|
draw_info( false );
|
|
QSTool::deactivate();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolLocate::draw()
|
|
{
|
|
m_info = QString();
|
|
delete m_popup; m_popup = NULL;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolLocate::canvasMove( const QPoint& pos )
|
|
{
|
|
if ( m_view->currentPage() &&
|
|
m_view->activeAxes() &&
|
|
m_view->activeAxes()->shadowObject()->box(driver()).contains(QSPt2f(pos.x(),pos.y())) &&
|
|
m_view->currentPage()->objects()->find(m_view->activeAxes()->shadowObject()) >= 0 ) {
|
|
m_view->canvasWidget()->setCursor( pointingHandCursor );
|
|
} else {
|
|
m_view->canvasWidget()->setCursor( arrowCursor );
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolLocate::canvasClicked( const QPoint& pos, int )
|
|
{
|
|
draw_info( false );
|
|
if ( m_view->activeAxes() ) {
|
|
QSPt2f p( pos.x(), pos.y() );
|
|
if ( (m_info=m_view->activeAxes()->posInfo(p)) == QString::null ) m_info = QString("?");
|
|
m_pos = QPoint( int(p.x+0.5), int(p.y+0.5) );
|
|
draw_info();
|
|
m_view->showUserMessage( m_info );
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolLocate::canvasRightButtonClicked( const QPoint&, int )
|
|
{
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSToolLocate::draw_info( bool show_popup )
|
|
{
|
|
if ( m_popup ) { delete m_popup; m_popup = NULL; }
|
|
if ( m_info.isEmpty() || m_view->activeAxes()->state() != QSAxes::Waiting ) return;
|
|
|
|
QWidget *canvas = m_view->canvasWidget();
|
|
|
|
QPainter p ( canvas ) ;
|
|
p.setRasterOp( Qt::NotXorROP );
|
|
p.drawLine( 0, m_pos.y(), canvas->width()-1, m_pos.y() );
|
|
p.drawLine( m_pos.x(), 0, m_pos.x(), canvas->height()-1 );
|
|
p.end();
|
|
|
|
if ( show_popup ) {
|
|
m_popup = new QLabel( m_info, canvas, "locate", Qt::WStyle_Customize | Qt::WType_Popup );
|
|
m_popup->setFrameStyle( QFrame::Panel | QFrame::Raised );
|
|
m_popup->setCursor( pointingHandCursor );
|
|
m_popup->move( canvas->mapToGlobal(QPoint(m_pos.x()+20,m_pos.y()+20)) );
|
|
m_popup->show();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|