/*************************************************************************** mycanvasview.cpp - description ------------------- begin : Die Apr 23 2002 copyright : (C) 2002 by Dominik Seichter email : domseichter@web.de ***************************************************************************/ /*************************************************************************** * * * 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 "mycanvasview.h" #include "commands.h" #include "definition.h" #include "measurements.h" #include "kbarcodesettings.h" // TQt includes #include #include #include // KDE includes #include #include MyCanvas::MyCanvas( TQObject* parent, const char* name ) : TQCanvas( parent, name ) { m_grid = false; setBackgroundColor( TQt::lightGray ); resize( 0, 0 ); } MyCanvas::~MyCanvas() { } void MyCanvas::drawBackground( TQPainter & painter, const TQRect & clip ) { TQCanvas::drawBackground( painter, clip ); TQRect shadow1( int(m_rect.x() + m_rect.width()), m_rect.y() + 5, 5, m_rect.height() ); TQRect shadow2( m_rect.x()+ 5, int(m_rect.y() + m_rect.height()), m_rect.width(), 5 ); // draw background shadow if( clip.intersects( shadow1 ) ) painter.fillRect( shadow1, TQt::black ); if( clip.intersects( shadow2 ) ) painter.fillRect( shadow2, TQt::black ); if( clip.intersects( m_rect ) ) { painter.fillRect( m_rect, TQt::white ); if( m_grid ) { painter.translate( m_rect.x(), m_rect.y() ); painter.setPen( TQPen( KBarcodeSettings::getInstance()->gridColor(), 0 ) ); for( int y = 0; y <= m_rect.height(); y += KBarcodeSettings::getInstance()->gridSize() ) for( int x = 0; x <= m_rect.width(); x += KBarcodeSettings::getInstance()->gridSize() ) painter.drawPoint( x, y ); painter.translate( -m_rect.x(), -m_rect.y() ); } } } MyCanvasView::MyCanvasView( Definition* d, MyCanvas* c, TQWidget* parent, const char* name, WFlags f) : TQCanvasView(c,parent,name,f) { statusbar = 0; m_commov = 0; canv = c; rulerv = new KRuler( Qt::Vertical, this ); rulerh = new KRuler( Qt::Horizontal, this ); if( Measurements::measurementSystem() == Measurements::Metric ) { rulerv->setRulerMetricStyle( KRuler::Millimetres ); rulerh->setRulerMetricStyle( KRuler::Millimetres ); } else { rulerv->setRulerMetricStyle( KRuler::Inch ); rulerh->setRulerMetricStyle( KRuler::Inch ); } rulerv->setMaxValue( 0 ); rulerh->setMaxValue( 0 ); viewport()->setMouseTracking( true ); setDefinition( d ); } MyCanvasView::~MyCanvasView() { } void MyCanvasView::snapPoint(TQPoint * point, TCanvasItem* item ) { // move item to next grid position // TODO: align the top left to the grid not the current mouse position! /* */ if( item ) { int difx = point->x() - (int)item->x(); int dify = point->y() - (int)item->y(); int x = (int)item->x(); int y = (int)item->y(); int grid = KBarcodeSettings::getInstance()->gridSize(); int modx = x % grid; int mody = y % grid; x -= modx; y -= mody; if(modx >= grid / 2) x += grid; if(mody >= grid / 2) y += grid; point->setX( x + difx ); point->setY( y + dify ); } else { point->setX(point->x() - point->x() % KBarcodeSettings::getInstance()->gridSize()); point->setY(point->y() - point->y() % KBarcodeSettings::getInstance()->gridSize()); } } void MyCanvasView::contentsMouseMoveEvent(TQMouseEvent* e) { rulerh->slotNewValue( e->x() ); rulerv->slotNewValue( e->y() ); if( statusbar ) { LabelUtils l; int x = (int)l.pixelToMm( e->x(), TQT_TQPAINTDEVICE(this), LabelUtils::DpiX ); int y = (int)l.pixelToMm( e->y(), TQT_TQPAINTDEVICE(this), LabelUtils::DpiY ); statusbar->changeItem( i18n("Position: ") + TQString( "%1%2 x %3%4" ).arg( x ) .arg( Measurements::system() ).arg( y ).arg( Measurements::system()), mouseid ); } updateCursor( e->pos() ); // if no mouse button is pressed bail out now if( !(e->state() & Qt::LeftButton ) ) { (void)updateCursor( e->pos(), true ); return; } bool shift_pressed = e->state() & TQt::ShiftButton; TCanvasItem* moving = getActive(); if( moving && !moving->item()->locked() ) { TQPoint p = inverseWorldMatrix().map(e->pos()); if( m_mode == Barcode || m_mode == Inside ) { TCanvasItemList list = getSelected(); for( unsigned int i = 0; i < list.count(); i++ ) { TCanvasItem* moving = list[i]; TQPoint new_pt = TQPoint(p.x() - delta_pt.x(),p.y() - delta_pt.y()); if( canv->grid() ) { snapPoint(&new_pt, moving) ; } LabelUtils l; TQPoint pmm; pmm.setX( (int)l.pixelToMm( new_pt.x() - getTranslation().x(), TQT_TQPAINTDEVICE(this), LabelUtils::DpiX ) * 1000 ); pmm.setY( (int)l.pixelToMm( new_pt.y() - getTranslation().y(), TQT_TQPAINTDEVICE(this), LabelUtils::DpiY ) * 1000 ); // Move the item MoveCommand* mv = new MoveCommand( pmm.x() - moving->item()->rectMM().x(), pmm.y() - moving->item()->rectMM().y(), moving ); mv->execute(); getMoveCommand()->addCommand( mv ); } } else { if( canv->grid() ) { snapPoint(&p, NULL ) ; } LabelUtils l; TQPoint pmm; pmm.setX( (int)l.pixelToMm( p.x() - getTranslation().x(), TQT_TQPAINTDEVICE(this), LabelUtils::DpiX ) * 1000 ); pmm.setY( (int)l.pixelToMm( p.y() - getTranslation().y(), TQT_TQPAINTDEVICE(this), LabelUtils::DpiY ) * 1000 ); TQRect rmm = moving->item()->rectMM(); ResizeCommand* mv = new ResizeCommand( moving, shift_pressed ); switch( m_mode ) { case RightMiddle: mv->setRect( rmm.x(), rmm.y(), pmm.x() - rmm.x(), rmm.height() ); break; case LeftMiddle: mv->setRect( pmm.x(), rmm.y(), rmm.width()+ (rmm.x() - pmm.x()), rmm.height() ); break; case BottomMiddle: mv->setRect( rmm.x(), rmm.y(), rmm.width(), pmm.y() - rmm.y()); break; case TopMiddle: mv->setRect( rmm.x(), pmm.y(), rmm.width(), rmm.height()+ (rmm.y() - pmm.y())); break; case BottomLeft: mv->setRect( pmm.x(), rmm.y(), rmm.width()+ (rmm.x() - pmm.x()), pmm.y() - rmm.y() ); break; case BottomRight: mv->setRect( rmm.x(), rmm.y(), pmm.x() - rmm.x(), pmm.y() - rmm.y() ); break; case TopLeft: mv->setRect( pmm.x(), pmm.y(), rmm.width()+ (rmm.x() - pmm.x()), rmm.height()+ (rmm.y() - pmm.y())); break; case TopRight: mv->setRect( rmm.x(), pmm.y(), pmm.x() - rmm.x(),rmm.height()+ (rmm.y() - pmm.y()) ); break; default: break; } mv->execute(); getMoveCommand()->addCommand( mv ); } moving_start = p; emit movedSomething(); } } void MyCanvasView::contentsMousePressEvent(TQMouseEvent* e) { setActive( 0, e->state() & TQt::ControlButton ); TQCanvasItemList list = canvas()->allItems(); for( int z = MyCanvasView::getLowestZ( list ); z <= MyCanvasView::getHighestZ( list ); z++ ) for( unsigned int i = 0; i < list.count(); i++ ) if( list[i]->z() == z && isInside( e->pos(), list[i] ) ) setActive( list[i], (e->state() & TQt::ControlButton) ); if( getActive() ) { moving_start = inverseWorldMatrix().map(e->pos()); m_mode = updateCursor( e->pos() ); old = getActive()->boundingRect(); delta_pt=TQPoint(e->x() - old.x(),e->y() - old.y()); } if( e->button() == Qt::RightButton && getActive() ) emit showContextMenu( e->globalPos() ); } void MyCanvasView::contentsMouseReleaseEvent(TQMouseEvent* e) { if( e->button() != Qt::LeftButton || getSelected().isEmpty() ) return; if( m_commov ) { history->addCommand( getMoveCommand(), false ); m_commov = 0; } updateCursor( e->pos() ); } KMacroCommand* MyCanvasView::getMoveCommand() { if( !m_commov ) m_commov = new KMacroCommand( i18n("Item Moved") ); return m_commov; } void MyCanvasView::contentsMouseDoubleClickEvent(TQMouseEvent* e) { setActive( 0 ); TQCanvasItemList list = canvas()->allItems(); for( int z = MyCanvasView::getHighestZ( list ); z >= MyCanvasView::getLowestZ( list ); z-- ) for( unsigned int i = 0; i < list.count(); i++ ) if( list[i]->z() == z && isInside( e->pos(), list[i] ) ) { setActive( list[i] ); emit doubleClickedItem( getActive() ); return; } } bool MyCanvasView::isInside( TQPoint p, TQCanvasItem* item ) { if( !item->isVisible() ) return false; return item->boundingRect().contains( p ); } int MyCanvasView::isEdge( TQPoint p, TQCanvasItem* item ) { if( !isInside( p, item ) ) return Outside; TQRect r = item->boundingRect(); int rh = r.y() + r.height(); int rw = r.x() + r.width(); if( p.x() > r.x() && p.x() < r.x() + SPOTSIZE ) { // Left if( p.y() > r.y() && p.y() < r.y() + SPOTSIZE ) return TopLeft; if( p.y() > rh - SPOTSIZE && p.y() < rh ) return BottomLeft; if( (r.height() - 2 * SPOTSIZE ) / 2 > SPOTSIZE ) { // Middle int start = ( r.y() + (r.height() - SPOTSIZE)/2 ); if( p.y() > start && p.y() < start + SPOTSIZE ) return LeftMiddle; } } if( p.y() > r.y() && p.y() < r.y() + SPOTSIZE ) { // Top if( (r.width() - 2 * SPOTSIZE ) / 2 > SPOTSIZE ) { // Middle int start = ( r.x() + (r.width() - SPOTSIZE)/2 ); if( p.x() > start && p.x() < start + SPOTSIZE ) return TopMiddle; } } if( p.y() > rh - SPOTSIZE && p.y() < rh ) { // Bottom if( (r.width() - 2 * SPOTSIZE ) / 2 > SPOTSIZE ) { // Middle int start = ( r.x() + (r.width() - SPOTSIZE)/2 ); if( p.x() > start && p.x() < start + SPOTSIZE ) return BottomMiddle; } } if( p.x() > rw - SPOTSIZE && p.x() < rw ) { // Right if( p.y() > r.y() && p.y() < r.y() + SPOTSIZE ) return TopRight; if( p.y() > rh - SPOTSIZE && p.y() < rh ) return BottomRight; if( (r.height() - 2 * SPOTSIZE ) / 2 > SPOTSIZE ) { // Middle int start = ( r.y() + (r.height() - SPOTSIZE)/2 ); if( p.y() > start && p.y() < start + SPOTSIZE ) return RightMiddle; } } return Inside; } void MyCanvasView::deleteCurrent() { TCanvasItemList list = getSelected(); if( !list.isEmpty() ) { KMacroCommand* mc = new KMacroCommand( i18n("Delete") ); for( unsigned int i = 0; i < list.count(); i++ ) { DeleteCommand* dc = new DeleteCommand( list[i] ); dc->execute(); mc->addCommand( dc ); } history->addCommand( mc, false ); setActive( 0 ); canvas()->update(); } } void MyCanvasView::setCurrent( TQCanvasItem* item ) { setSelected( item ); setActive( item ); } void MyCanvasView::updateRuler() { rulerh->setGeometry( 20, 0, width() - 20, 20 ); rulerv->setGeometry( 0, 20, 20, height() - 20 ); if( def ) { canv->setRect( TQRect( translation.x(), translation.y(), (int)def->getMeasurements().width( TQT_TQPAINTDEVICE(this) ), (int)def->getMeasurements().height( TQT_TQPAINTDEVICE(this) )) ); rulerv->setMaxValue( height() ); rulerh->setMaxValue( width() ); TQPaintDeviceMetrics pdm( this ); if( Measurements::measurementSystem() == Measurements::Metric ) { rulerh->setPixelPerMark( (1/ 25.4)* pdm.logicalDpiX() ); rulerv->setPixelPerMark( (1/25.4)* pdm.logicalDpiY() ); } } } void MyCanvasView::resizeEvent( TQResizeEvent * r ) { setUpdatesEnabled( false ); TQPoint old = translation; TQCanvasView::resizeEvent( r ); reposition(); updateRuler(); repaintContents(); old = translation - old; TQCanvasItemList list = canvas()->allItems(); for( unsigned int i = 0; i < list.count(); i++ ) list[i]->moveBy( old.x(), old.y() ); setUpdatesEnabled( true ); } void MyCanvasView::reposition() { /* * it is difficult to handle the repositioning * when a new scaling factor has been set. * Therefore we divide by the old factor * and multiply with the new one. * As a result we have the correct width. */ int x = int((width() - (def->getMeasurements().width( TQT_TQPAINTDEVICE(this) )) ) / 2); int y = int((height() - (def->getMeasurements().height( TQT_TQPAINTDEVICE(this) )) ) / 2); // move label 30 pixels away from top/left if necessary x = x > 0 ? x : 30; y = y > 0 ? y : 30; // make sure that there is some space around the label, therefore at 60 pixel int w = ( this->width() - 2 > def->getMeasurements().width( TQT_TQPAINTDEVICE(this) ) ? this->width() - 2 : int(def->getMeasurements().width( TQT_TQPAINTDEVICE(this) ) + 60) ); int h = ( this->height() - 2 > def->getMeasurements().height( TQT_TQPAINTDEVICE(this) ) ? this->height() - 2 : int(def->getMeasurements().height( TQT_TQPAINTDEVICE(this) ) + 60) ); canvas()->resize( w, h ); translation = TQPoint( x, y ); } void MyCanvasView::setDefinition( Definition* d ) { def = d; reposition(); updateRuler(); repaintContents( true ); } void MyCanvasView::selectAll() { TQCanvasItemList list = canvas()->allItems(); for( unsigned int i = 0; i < list.count(); i++ ) setSelected( list[i], true ); } void MyCanvasView::deSelectAll() { setSelected( 0 ); } int MyCanvasView::getLowestZ( TQCanvasItemList list ) { int v = 0; for( unsigned int i = 0; i < list.count(); i++ ) if( list[i]->z() < v ) v = (int)list[i]->z(); return v; } int MyCanvasView::getHighestZ( TQCanvasItemList list ) { int v = 0; for( unsigned int i = 0; i < list.count(); i++ ) if( list[i]->z() > v ) v = (int)list[i]->z(); return v; } TCanvasItem* MyCanvasView::getActive() { TQCanvasItemList list = canvas()->allItems(); for( unsigned int i = 0; i < list.count(); i++ ) if( list[i]->isActive() ) return (TCanvasItem*)list[i]; return 0; } void MyCanvasView::setActive( TQCanvasItem* item, bool control ) { emit selectionChanged(); TQCanvasItemList list = canvas()->allItems(); for( unsigned int i = 0; i < list.count(); i++ ) list[i]->setActive( false ); if( item ) item->setActive( true ); setSelected( item, control ); } DocumentItemList MyCanvasView::getAllItems() { DocumentItemList l; TQCanvasItemList list = canvas()->allItems(); for( unsigned int i = 0; i < list.count(); i++ ) l.append( ((TCanvasItem*)list[i])->item() ); return l; } TCanvasItemList MyCanvasView::getSelected() { TCanvasItemList l; TQCanvasItemList list = canvas()->allItems(); for( unsigned int i = 0; i < list.count(); i++ ) if( list[i]->isSelected() ) l.append( (TCanvasItem*)list[i] ); return l; } void MyCanvasView::setSelected( TQCanvasItem* item, bool control ) { if( !control ) { TQCanvasItemList list = canvas()->allItems(); for( unsigned int i = 0; i < list.count(); i++ ) list[i]->setSelected( false ); } if( item ) item->setSelected( true ); } int MyCanvasView::updateCursor( TQPoint pos, bool pressed ) { if( !getActive() ) { this->setCursor( TQCursor::ArrowCursor ); return -1; } int mode = isEdge( pos, getActive() ); if( getActive()->item()->locked() ) { pressed && mode != Outside ? setCursor( TQt::ForbiddenCursor ) : setCursor( TQCursor::ArrowCursor ); return mode; } if( getActive()->rtti() == eRtti_Barcode ) { pressed && mode != Outside ? setCursor( TQCursor::SizeAllCursor ) : setCursor( TQCursor::ArrowCursor ); mode = Barcode; return mode; } switch( mode ) { case TopLeft: case BottomRight: this->setCursor( TQCursor::SizeFDiagCursor ); break; case TopMiddle: case BottomMiddle: this->setCursor( TQCursor::SizeVerCursor ); break; case TopRight: case BottomLeft: this->setCursor( TQCursor::SizeBDiagCursor ); break; case RightMiddle: case LeftMiddle: this->setCursor( TQCursor::SizeHorCursor ); break; case Inside: pressed ? setCursor( TQCursor::SizeAllCursor ) : setCursor( TQCursor::ArrowCursor ); break; case Outside: default: this->setCursor( TQCursor::ArrowCursor ); break; }; return mode; } #include "mycanvasview.moc"