Esempio n. 1
0
bool
Container::eventFilter(QObject *s, QEvent *e)
{
//	kdDebug() << e->type() << endl;
	switch(e->type())
	{
		case QEvent::MouseButtonPress:
		{
			m_insertBegin = QPoint(-1, -1);
			m_mousePressEventReceived = true;

			kdDebug() << "QEvent::MouseButtonPress sender object = " << s->name()
				<< "of type " << s->className() << endl;
			kdDebug() << "QEvent::MouseButtonPress this          = " << name() << endl;

			m_moving = static_cast<QWidget*>(s);
			QMouseEvent *mev = static_cast<QMouseEvent*>(e);
			m_grab = QPoint(mev->x(), mev->y());

			// we are drawing a connection
			if(FormManager::self()->isCreatingConnection())  {
				drawConnection(mev);
				return true;
			}

			if(((mev->state() == ControlButton) || (mev->state() == ShiftButton)) 
				&& (!FormManager::self()->isInserting())) // multiple selection mode
			{
				if(m_form->selectedWidgets()->findRef(m_moving) != -1) // widget is already selected
				{
					if(m_form->selectedWidgets()->count() > 1) // we remove it from selection
						unSelectWidget(m_moving);
					else // the widget is the only selected, so it means we want to copy it
					{
						//m_copyRect = m_moving->geometry();
						m_state = CopyingWidget;
						if(m_form->formWidget())
							m_form->formWidget()->initBuffer();
					}
				}
				else // the widget is not yet selected, we add it
					setSelectedWidget(m_moving, true, (mev->button() == RightButton));
			}
			else if((m_form->selectedWidgets()->count() > 1))//&& (!m_form->manager()->isInserting())) // more than one widget selected
			{
				if(m_form->selectedWidgets()->findRef(m_moving) == -1) // widget is not selected, it becomes the only selected widget
					setSelectedWidget(m_moving, false, (mev->button() == RightButton));
				// If the widget is already selected, we do nothing (to ease widget moving, etc.)
			}
			else// if(!m_form->manager()->isInserting())
				setSelectedWidget(m_moving, false, (mev->button() == RightButton));

			// we are inserting a widget or drawing a selection rect in the form
			if((/*s == m_container &&*/ FormManager::self()->isInserting()) || ((s == m_container) && !m_toplevel))
			{
				int tmpx,tmpy;
				if(!FormManager::self()->snapWidgetsToGrid() || (mev->state() == (LeftButton|ControlButton|AltButton)))
				{
					tmpx = mev->x();
					tmpy = mev->y();
				}
				else
				{
					int gridX = m_form->gridSize();
					int gridY = m_form->gridSize();
					tmpx = int( (float)mev->x() / ((float)gridX) + 0.5 ); // snap to grid
					tmpx *= gridX;
					tmpy = int( (float)mev->y() / ((float)gridY) + 0.5 );
					tmpy *= gridX;
				}

				m_insertBegin = (static_cast<QWidget*>(s))->mapTo(m_container, QPoint(tmpx, tmpy));
				if(m_form->formWidget())
					m_form->formWidget()->initBuffer();

				if(!FormManager::self()->isInserting())
					m_state = DrawingSelectionRect;
			}
			else {
				if(s->inherits("QTabWidget")) // to allow changing page by clicking tab
					return false;
			}

			if (m_objectForMouseReleaseEvent) {
				const bool res = handleMouseReleaseEvent(m_objectForMouseReleaseEvent, &m_mouseReleaseEvent);
				m_objectForMouseReleaseEvent = 0;
				return res;
			}
			return true;
		}

		case QEvent::MouseButtonRelease:
		{
			QMouseEvent *mev = static_cast<QMouseEvent*>(e);
			if (!m_mousePressEventReceived) {
				m_mouseReleaseEvent = *mev;
				m_objectForMouseReleaseEvent = s;
				return true;
			}
			m_mousePressEventReceived = false;
			m_objectForMouseReleaseEvent = 0;
			return handleMouseReleaseEvent(s, mev);
		}

		case QEvent::MouseMove:
		{
			QMouseEvent *mev = static_cast<QMouseEvent*>(e);
			if(m_insertBegin!=QPoint(-1,-1) && FormManager::self()->isInserting() && ((mev->state() == LeftButton) || (mev->state() == (LeftButton|ControlButton)) ||
			(mev->state() == (LeftButton|ControlButton|AltButton)) || (mev->state() == (LeftButton|ShiftButton)) ) )
			// draw the insert rect
			{
				drawInsertRect(mev, s);
				return true;
			}
			// Creating a connection, we highlight sender and receiver, and we draw a link between them
			else if(FormManager::self()->isCreatingConnection() && !FormManager::self()->createdConnection()->sender().isNull())
			{
				ObjectTreeItem *tree = m_form->objectTree()->lookup(FormManager::self()->createdConnection()->sender());
				if(!tree || !tree->widget())
					return true;

				if(m_form->formWidget() && (tree->widget() != s))
					m_form->formWidget()->highlightWidgets(tree->widget(), static_cast<QWidget*>(s));
			}
			else if(m_insertBegin!=QPoint(-1,-1) && s == m_container && !m_toplevel && (mev->state() != ControlButton) && !FormManager::self()->isCreatingConnection()) // draw the selection rect
			{
				if((mev->state() != LeftButton) || /*m_inlineEditing*/ m_state == InlineEditing)
					return true;
				int topx = (m_insertBegin.x() < mev->x()) ? m_insertBegin.x() :  mev->x();
				int topy = (m_insertBegin.y() < mev->y()) ? m_insertBegin.y() : mev->y();
				int botx = (m_insertBegin.x() > mev->x()) ? m_insertBegin.x() :  mev->x();
				int boty = (m_insertBegin.y() > mev->y()) ? m_insertBegin.y() : mev->y();
				QRect r = QRect(QPoint(topx, topy), QPoint(botx, boty));
				m_insertRect = r;

				if(m_form->formWidget())
					m_form->formWidget()->drawRect(r, 1);

				m_state = DoingNothing;
				return true;
			}
			else if(mev->state() == (LeftButton|ControlButton)) // draw the insert rect for the copied widget
			{
				if(s == m_container)// || (m_form->selectedWidgets()->count() > 1))
					return true;
				drawCopiedWidgetRect(mev);
				return true;
			}
			else if( ( (mev->state() == Qt::LeftButton) || (mev->state() == (LeftButton|ControlButton|AltButton)) )
			  && !FormManager::self()->isInserting() && (m_state != CopyingWidget)) // we are dragging the widget(s) to move it
			{
				if(!m_toplevel && m_moving == m_container) // no effect for form
					return false;
				if((!m_moving) || (!m_moving->parentWidget()))// || (m_moving->parentWidget()->inherits("QWidgetStack")))
						return true;

				moveSelectedWidgetsBy(mev->x() - m_grab.x(), mev->y() - m_grab.y());
				m_state = MovingWidget;
			}

			return true; // eat
		}

		case QEvent::Paint: // Draw the dotted background
		{
			if(s != m_container)
				return false;
			int gridX = m_form->gridSize();
			int gridY = m_form->gridSize();

			QPainter p(m_container);
			p.setPen(QPen(white, 2));
			p.setRasterOp(XorROP);
			int cols = m_container->width() / gridX;
			int rows = m_container->height() / gridY;

			for(int rowcursor = 1; rowcursor <= rows; ++rowcursor)
			{
				for(int colcursor = 1; colcursor <= cols; ++colcursor)
				{
					p.drawPoint(-1 + colcursor *gridX, -1 + rowcursor *gridY);
				}
			}

			return false;
		}

		case QEvent::Resize: // we are resizing a widget, so we set m_move to true -> the layout will be reloaded when releasing mouse
		{
			if(m_form->interactiveMode())
				m_state = MovingWidget;
			break;
		}

		//case QEvent::AccelOverride:
		case QEvent::KeyPress:
		{
			QKeyEvent *kev = static_cast<QKeyEvent*>(e);

			if(kev->key() == Key_F2) // pressing F2 == double-clicking
			{
				m_state = InlineEditing;
				QWidget *w;

				// try to find the widget which was clicked last and should be edited
				if(m_form->selectedWidgets()->count() == 1)
					w = m_form->selectedWidgets()->first();
				else if(m_form->selectedWidgets()->findRef(m_moving) != -1)
					w = m_moving;
				else
					w = m_form->selectedWidgets()->last();
				m_form->library()->startEditing(w->className(), w, this);
			}
			else if(kev->key() == Key_Escape)
			{
				if(FormManager::self()->isCreatingConnection())
					FormManager::self()->stopCreatingConnection();
				else if(FormManager::self()->isInserting())
					FormManager::self()->stopInsert();
				return true;
			}
			else if((kev->key() == Key_Control) && (m_state == MovingWidget))
			{
				if(!m_moving)
					return true;
				// we simulate a mouse move event to update screen
				QMouseEvent *mev = new QMouseEvent(QEvent::MouseMove, m_moving->mapFromGlobal(QCursor::pos()), NoButton,
				LeftButton|ControlButton );
				eventFilter(m_moving, mev);
				delete mev;
			}
			else if(kev->key() == FormManager::self()->contextMenuKey())
			{
					FormManager::self()->createContextMenu(static_cast<QWidget*>(s), this, false);
					return true;
			}
			else if (kev->key() == Key_Delete)
			{
				FormManager::self()->deleteWidget();
				return true;
			}
			// directional buttons move the widget
			else if(kev->key() == Key_Left){ // move the widget of gridX to the left
				moveSelectedWidgetsBy(-form()->gridSize(), 0);
				return true;
			}
			else if(kev->key() == Key_Right){ // move the widget of gridX to the right
				moveSelectedWidgetsBy(form()->gridSize(), 0);
				return true;
			}
			else if(kev->key() == Key_Up){ // move the widget of gridY to the top
				moveSelectedWidgetsBy(0, - form()->gridSize());
				return true;
			}
			else if(kev->key() == Key_Down){ // move the widget of gridX to the bottom
				moveSelectedWidgetsBy(0, form()->gridSize());
				return true;
			}
			else if((kev->key() == Key_Tab) || (kev->key() == Key_BackTab)){
				ObjectTreeItem *item = form()->objectTree()->lookup(form()->selectedWidgets()->first()->name());
				if(!item || !item->parent())
					return true;
				ObjectTreeList *list = item->parent()->children();
				if(list->count() == 1)
					return true;
				int index = list->findRef(item);

				if(kev->key() == Key_BackTab){
					if(index == 0) // go back to the last item
						index = list->count() - 1;
					else
						index = index - 1;
				}
				else  {
					if(index == int(list->count() - 1)) // go back to the first item
						index = 0;
					else
						index = index + 1;
				}

				ObjectTreeItem *nextItem = list->at(index);
				if(nextItem && nextItem->widget())
					form()->setSelectedWidget(nextItem->widget(), false);
			}
			return true;
		}

		case QEvent::KeyRelease:
		{
			QKeyEvent *kev = static_cast<QKeyEvent*>(e);
			if((kev->key() == Key_Control) && (m_state == CopyingWidget)) {
				// cancel copying
				//m_copyRect = QRect();
				if(m_form->formWidget())
					m_form->formWidget()->clearForm();
			}
			return true;
		}

		case QEvent::MouseButtonDblClick: // editing
		{
			kdDebug() << "Container: Mouse dbl click for widget " << s->name() << endl;
			QWidget *w = static_cast<QWidget*>(s);
			if(!w)
				return false;

			//m_inlineEditing = true;
			m_state = InlineEditing;
			m_form->library()->startEditing(w->className(), w, this);
			return true;
		}

		case QEvent::ContextMenu:
		case QEvent::Enter:
		case QEvent::Leave:
		case QEvent::FocusIn:
		case QEvent::FocusOut:
//		case QEvent::DragEnter:
//		case QEvent::DragMove:
//		case QEvent::DragLeave:
			return true; // eat them

		default:
			return false; // let the widget do the rest ...
	}
	return false;
}