| 
							- /*
 -  * Patchbay Canvas engine using QGraphicsView/Scene
 -  * Copyright (C) 2010-2012 Filipe Coelho <falktx@falktx.com>
 -  *
 -  * 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
 -  * any later version.
 -  *
 -  * This program is distributed in the hope that it will be useful,
 -  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 -  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 -  * GNU General Public License for more details.
 -  *
 -  * For a full copy of the GNU General Public License see the COPYING file
 -  */
 - 
 - #include "canvasbox.h"
 - 
 - #include <QtCore/QTimer>
 - #include <QtGui/QCursor>
 - #include <QtGui/QInputDialog>
 - #include <QtGui/QMenu>
 - #include <QtGui/QGraphicsSceneContextMenuEvent>
 - #include <QtGui/QGraphicsSceneMouseEvent>
 - #include <QtGui/QPainter>
 - 
 - #include "canvasline.h"
 - #include "canvasbezierline.h"
 - #include "canvasport.h"
 - #include "canvasboxshadow.h"
 - #include "canvasicon.h"
 - 
 - START_NAMESPACE_PATCHCANVAS
 - 
 - CanvasBox::CanvasBox(int group_id, QString group_name, Icon icon, QGraphicsItem* parent) :
 -     QGraphicsItem(parent, canvas.scene)
 - {
 -     // Save Variables, useful for later
 -     m_group_id   = group_id;
 -     m_group_name = group_name;
 - 
 -     // Base Variables
 -     p_width  = 50;
 -     p_height = 25;
 - 
 -     m_last_pos = QPointF();
 -     m_splitted = false;
 -     m_splitted_mode = PORT_MODE_NULL;
 - 
 -     m_cursor_moving = false;
 -     m_forced_split  = false;
 -     m_mouse_down    = false;
 - 
 -     m_port_list_ids.clear();
 -     m_connection_lines.clear();
 - 
 -     // Set Font
 -     m_font_name = QFont(canvas.theme->box_font_name, canvas.theme->box_font_size, canvas.theme->box_font_state);
 -     m_font_port = QFont(canvas.theme->port_font_name, canvas.theme->port_font_size, canvas.theme->port_font_state);
 - 
 -     // Icon
 -     icon_svg = new CanvasIcon(icon, group_name, this);
 - 
 -     // Shadow
 -     if (options.eyecandy)
 -     {
 -         shadow = new CanvasBoxShadow(toGraphicsObject());
 -         shadow->setFakeParent(this);
 -         setGraphicsEffect(shadow);
 -     }
 -     else
 -         shadow = 0;
 - 
 -     // Final touches
 -     setFlags(QGraphicsItem::ItemIsMovable|QGraphicsItem::ItemIsSelectable);
 - 
 -     // Wait for at least 1 port
 -     if (options.auto_hide_groups)
 -         setVisible(false);
 - 
 -     updatePositions();
 - }
 - 
 - CanvasBox::~CanvasBox()
 - {
 -     if (shadow)
 -         delete shadow;
 -     delete icon_svg;
 - }
 - 
 - int CanvasBox::getGroupId()
 - {
 -     return m_group_id;
 - }
 - 
 - QString CanvasBox::getGroupName()
 - {
 -     return m_group_name;
 - }
 - 
 - bool CanvasBox::isSplitted()
 - {
 -     return m_splitted;
 - }
 - 
 - PortMode CanvasBox::getSplittedMode()
 - {
 -     return m_splitted_mode;
 - }
 - 
 - int CanvasBox::getPortCount()
 - {
 -     return m_port_list_ids.count();
 - }
 - 
 - QList<int> CanvasBox::getPortList()
 - {
 -     return m_port_list_ids;
 - }
 - 
 - void CanvasBox::setIcon(Icon icon)
 - {
 -     icon_svg->setIcon(icon, m_group_name);
 - }
 - 
 - void CanvasBox::setSplit(bool split, PortMode mode)
 - {
 -     m_splitted = split;
 -     m_splitted_mode = mode;
 - }
 - 
 - void CanvasBox::setGroupName(QString group_name)
 - {
 -     m_group_name = group_name;
 -     updatePositions();
 - }
 - 
 - void CanvasBox::setShadowOpacity(float opacity)
 - {
 -     if (shadow)
 -         shadow->setOpacity(opacity);
 - }
 - 
 - CanvasPort* CanvasBox::addPortFromGroup(int port_id, QString port_name, PortMode port_mode, PortType port_type)
 - {
 -     if (m_port_list_ids.count() == 0)
 -     {
 -         if (options.auto_hide_groups)
 -         {
 -             if (options.eyecandy == EYECANDY_FULL)
 -                 CanvasItemFX(this, true);
 -             setVisible(true);
 -         }
 -     }
 - 
 -     CanvasPort* new_widget = new CanvasPort(port_id, port_name, port_mode, port_type, this);
 - 
 -     port_dict_t port_dict;
 -     port_dict.group_id  = m_group_id;
 -     port_dict.port_id   = port_id;
 -     port_dict.port_name = port_name;
 -     port_dict.port_mode = port_mode;
 -     port_dict.port_type = port_type;
 -     port_dict.widget    = new_widget;
 - 
 -     m_port_list_ids.append(port_id);
 - 
 -     return new_widget;
 - }
 - 
 - void CanvasBox::removePortFromGroup(int port_id)
 - {
 -     if (m_port_list_ids.contains(port_id))
 -     {
 -         m_port_list_ids.removeOne(port_id);
 -     }
 -     else
 -     {
 -         qCritical("PatchCanvas::CanvasBox->removePort(%i) - unable to find port to remove", port_id);
 -         return;
 -     }
 - 
 -     if (m_port_list_ids.count() > 0)
 -     {
 -         updatePositions();
 -     }
 -     else if (isVisible())
 -     {
 -         if (options.auto_hide_groups)
 -         {
 -             if (options.eyecandy == EYECANDY_FULL)
 -                 CanvasItemFX(this, false);
 -             else
 -                 setVisible(false);
 -         }
 -     }
 - }
 - 
 - void CanvasBox::addLineFromGroup(AbstractCanvasLine* line, int connection_id)
 - {
 -     cb_line_t new_cbline;
 -     new_cbline.line = line;
 -     new_cbline.connection_id = connection_id;
 -     m_connection_lines.append(new_cbline);
 - }
 - 
 - void CanvasBox::removeLineFromGroup(int connection_id)
 - {
 -     foreach2 (const cb_line_t& connection, m_connection_lines)
 -         if (connection.connection_id == connection_id)
 -         {
 -             m_connection_lines.takeAt(i);
 -             return;
 -         }
 -     }
 - 
 -     qCritical("PatchCanvas::CanvasBox->removeLineFromGroup(%i) - unable to find line to remove", connection_id);
 - }
 - 
 - void CanvasBox::checkItemPos()
 - {
 -     if (canvas.size_rect.isNull() == false)
 -     {
 -         QPointF pos = scenePos();
 -         if (canvas.size_rect.contains(pos) == false || canvas.size_rect.contains(pos+QPointF(p_width, p_height)) == false)
 -         {
 -             if (pos.x() < canvas.size_rect.x())
 -                 setPos(canvas.size_rect.x(), pos.y());
 -             else if (pos.x()+p_width > canvas.size_rect.width())
 -                 setPos(canvas.size_rect.width()-p_width, pos.y());
 - 
 -             pos = scenePos();
 -             if (pos.y() < canvas.size_rect.y())
 -                 setPos(pos.x(), canvas.size_rect.y());
 -             else if (pos.y()+p_height > canvas.size_rect.height())
 -                 setPos(pos.x(), canvas.size_rect.height()-p_height);
 -         }
 -     }
 - }
 - 
 - void CanvasBox::removeIconFromScene()
 - {
 -     canvas.scene->removeItem(icon_svg);
 - }
 - 
 - void CanvasBox::updatePositions()
 - {
 -     prepareGeometryChange();
 - 
 -     int max_in_width   = 0;
 -     int max_in_height  = 24;
 -     int max_out_width  = 0;
 -     int max_out_height = 24;
 -     bool have_audio_jack_in, have_audio_jack_out, have_midi_jack_in, have_midi_jack_out;
 -     bool have_midi_a2j_in,  have_midi_a2j_out, have_midi_alsa_in,  have_midi_alsa_out;
 -     have_audio_jack_in  = have_midi_jack_in  = have_midi_a2j_in  = have_midi_alsa_in  = false;
 -     have_audio_jack_out = have_midi_jack_out = have_midi_a2j_out = have_midi_alsa_out = false;
 - 
 -     // reset box size
 -     p_width  = 50;
 -     p_height = 25;
 - 
 -     // Check Text Name size
 -     int app_name_size = QFontMetrics(m_font_name).width(m_group_name)+30;
 -     if (app_name_size > p_width)
 -         p_width = app_name_size;
 - 
 -     // Get Port List
 -     QList<port_dict_t> port_list;
 -     foreach (const port_dict_t& port, canvas.port_list)
 -     {
 -         if (m_port_list_ids.contains(port.port_id))
 -             port_list.append(port);
 -     }
 - 
 -     // Get Max Box Width/Height
 -     foreach (const port_dict_t& port, port_list)
 -     {
 -         if (port.port_mode == PORT_MODE_INPUT)
 -         {
 -             max_in_height += 18;
 - 
 -             int size = QFontMetrics(m_font_port).width(port.port_name);
 -             if (size > max_in_width)
 -                 max_in_width = size;
 - 
 -             if (port.port_type == PORT_TYPE_AUDIO_JACK && have_audio_jack_in == false)
 -             {
 -                 have_audio_jack_in = true;
 -                 max_in_height += 2;
 -             }
 -             else if (port.port_type == PORT_TYPE_MIDI_JACK && have_midi_jack_in == false)
 -             {
 -                 have_midi_jack_in = true;
 -                 max_in_height += 2;
 -             }
 -             else if (port.port_type == PORT_TYPE_MIDI_A2J && have_midi_a2j_in == false)
 -             {
 -                 have_midi_a2j_in = true;
 -                 max_in_height += 2;
 -             }
 -             else if (port.port_type == PORT_TYPE_MIDI_ALSA && have_midi_alsa_in == false)
 -             {
 -                 have_midi_alsa_in = true;
 -                 max_in_height += 2;
 -             }
 -         }
 -         else if (port.port_mode == PORT_MODE_OUTPUT)
 -         {
 -             max_out_height += 18;
 - 
 -             int size = QFontMetrics(m_font_port).width(port.port_name);
 -             if (size > max_out_width)
 -                 max_out_width = size;
 - 
 -             if (port.port_type == PORT_TYPE_AUDIO_JACK && have_audio_jack_out == false)
 -             {
 -                 have_audio_jack_out = true;
 -                 max_out_height += 2;
 -             }
 -             else if (port.port_type == PORT_TYPE_MIDI_JACK && have_midi_jack_out == false)
 -             {
 -                 have_midi_jack_out = true;
 -                 max_out_height += 2;
 -             }
 -             else if (port.port_type == PORT_TYPE_MIDI_A2J && have_midi_a2j_out == false)
 -             {
 -                 have_midi_a2j_out = true;
 -                 max_out_height += 2;
 -             }
 -             else if (port.port_type == PORT_TYPE_MIDI_ALSA && have_midi_alsa_out == false)
 -             {
 -                 have_midi_alsa_out = true;
 -                 max_out_height += 2;
 -             }
 -         }
 -     }
 - 
 -     int final_width = 30 + max_in_width + max_out_width;
 -     if (final_width > p_width)
 -         p_width = final_width;
 - 
 -     if (max_in_height > p_height)
 -         p_height = max_in_height;
 - 
 -     if (max_out_height > p_height)
 -         p_height = max_out_height;
 - 
 -     // Remove bottom space
 -     p_height -= 2;
 - 
 -     int last_in_pos  = 24;
 -     int last_out_pos = 24;
 -     PortType last_in_type  = PORT_TYPE_NULL;
 -     PortType last_out_type = PORT_TYPE_NULL;
 - 
 -     // Re-position ports, AUDIO_JACK
 -     foreach (const port_dict_t& port, port_list)
 -     {
 -         if (port.port_type == PORT_TYPE_AUDIO_JACK)
 -         {
 -             if (port.port_mode == PORT_MODE_INPUT)
 -             {
 -                 port.widget->setPos(QPointF(1, last_in_pos));
 -                 port.widget->setPortWidth(max_in_width);
 - 
 -                 last_in_pos += 18;
 -                 last_in_type = port.port_type;
 -             }
 -             else if (port.port_mode == PORT_MODE_OUTPUT)
 -             {
 -                 port.widget->setPos(QPointF(p_width-max_out_width-13, last_out_pos));
 -                 port.widget->setPortWidth(max_out_width);
 - 
 -                 last_out_pos += 18;
 -                 last_out_type = port.port_type;
 -             }
 -         }
 -     }
 - 
 -     // Re-position ports, MIDI_JACK
 -     foreach (const port_dict_t& port, port_list)
 -     {
 -         if (port.port_type == PORT_TYPE_MIDI_JACK)
 -         {
 -             if (port.port_mode == PORT_MODE_INPUT)
 -             {
 -                 if (last_in_type != PORT_TYPE_NULL && port.port_type != last_in_type)
 -                     last_in_pos += 2;
 - 
 -                 port.widget->setPos(QPointF(1, last_in_pos));
 -                 port.widget->setPortWidth(max_in_width);
 - 
 -                 last_in_pos += 18;
 -                 last_in_type = port.port_type;
 -             }
 -             else if (port.port_mode == PORT_MODE_OUTPUT)
 -             {
 -                 if (last_out_type != PORT_TYPE_NULL && port.port_type != last_out_type)
 -                     last_out_pos += 2;
 - 
 -                 port.widget->setPos(QPointF(p_width-max_out_width-13, last_out_pos));
 -                 port.widget->setPortWidth(max_out_width);
 - 
 -                 last_out_pos += 18;
 -                 last_out_type = port.port_type;
 -             }
 -         }
 -     }
 - 
 -     // Re-position ports, MIDI_A2J
 -     foreach (const port_dict_t& port, port_list)
 -     {
 -         if (port.port_type == PORT_TYPE_MIDI_A2J)
 -         {
 -             if (port.port_mode == PORT_MODE_INPUT)
 -             {
 -                 if (last_in_type != PORT_TYPE_NULL && port.port_type != last_in_type)
 -                     last_in_pos += 2;
 - 
 -                 port.widget->setPos(QPointF(1, last_in_pos));
 -                 port.widget->setPortWidth(max_in_width);
 - 
 -                 last_in_pos += 18;
 -                 last_in_type = port.port_type;
 -             }
 -             else if (port.port_mode == PORT_MODE_OUTPUT)
 -             {
 -                 if (last_out_type != PORT_TYPE_NULL && port.port_type != last_out_type)
 -                     last_out_pos += 2;
 - 
 -                 port.widget->setPos(QPointF(p_width-max_out_width-13, last_out_pos));
 -                 port.widget->setPortWidth(max_out_width);
 - 
 -                 last_out_pos += 18;
 -                 last_out_type = port.port_type;
 -             }
 -         }
 -     }
 - 
 -     // Re-position ports, MIDI_ALSA
 -     foreach (const port_dict_t& port, port_list)
 -     {
 -         if (port.port_type == PORT_TYPE_MIDI_ALSA)
 -         {
 -             if (port.port_mode == PORT_MODE_INPUT)
 -             {
 -                 if (last_in_type != PORT_TYPE_NULL && port.port_type != last_in_type)
 -                     last_in_pos += 2;
 - 
 -                 port.widget->setPos(QPointF(1, last_in_pos));
 -                 port.widget->setPortWidth(max_in_width);
 - 
 -                 last_in_pos += 18;
 -                 last_in_type = port.port_type;
 -             }
 -             else if (port.port_mode == PORT_MODE_OUTPUT)
 -             {
 -                 if (last_out_type != PORT_TYPE_NULL && port.port_type != last_out_type)
 -                     last_out_pos += 2;
 - 
 -                 port.widget->setPos(QPointF(p_width-max_out_width-13, last_out_pos));
 -                 port.widget->setPortWidth(max_out_width);
 - 
 -                 last_out_pos += 18;
 -                 last_out_type = port.port_type;
 -             }
 -         }
 -     }
 - 
 -     repaintLines(true);
 -     update();
 - }
 - 
 - void CanvasBox::repaintLines(bool forced)
 - {
 -     if (pos() != m_last_pos || forced)
 -     {
 -         foreach (const cb_line_t& connection, m_connection_lines)
 -             connection.line->updateLinePos();
 -     }
 - 
 -     m_last_pos = pos();
 - }
 - 
 - void CanvasBox::resetLinesZValue()
 - {
 -     foreach (const connection_dict_t& connection, canvas.connection_list)
 -     {
 -         int z_value;
 -         if (m_port_list_ids.contains(connection.port_out_id) && m_port_list_ids.contains(connection.port_in_id))
 -             z_value = canvas.last_z_value;
 -         else
 -             z_value = canvas.last_z_value-1;
 - 
 -         connection.widget->setZValue(z_value);
 -     }
 - }
 - 
 - int CanvasBox::type() const
 - {
 -     return CanvasBoxType;
 - }
 - 
 - void CanvasBox::contextMenuEvent(QGraphicsSceneContextMenuEvent* event)
 - {
 -     QMenu menu;
 -     QMenu discMenu("Disconnect", &menu);
 - 
 -     QList<int> port_con_list;
 -     QList<int> port_con_list_ids;
 - 
 -     foreach (const int& port_id, m_port_list_ids)
 -     {
 -         QList<int> tmp_port_con_list = CanvasGetPortConnectionList(port_id);
 -         foreach (const int& port_con_id, tmp_port_con_list)
 -         {
 -             if (port_con_list.contains(port_con_id) == false)
 -             {
 -                 port_con_list.append(port_con_id);
 -                 port_con_list_ids.append(port_id);
 -             }
 -         }
 -     }
 - 
 -     if (port_con_list.count() > 0)
 -     {
 -         for (int i=0; i < port_con_list.count(); i++)
 -         {
 -             int port_con_id = CanvasGetConnectedPort(port_con_list[i], port_con_list_ids[i]);
 -             QAction* act_x_disc = discMenu.addAction(CanvasGetFullPortName(port_con_id));
 -             act_x_disc->setData(port_con_list[i]);
 -             QObject::connect(act_x_disc, SIGNAL(triggered()), canvas.qobject, SLOT(PortContextMenuDisconnect()));
 -         }
 -     }
 -     else
 -     {
 -         QAction* act_x_disc = discMenu.addAction("No connections");
 -         act_x_disc->setEnabled(false);
 -     }
 - 
 -     menu.addMenu(&discMenu);
 -     QAction* act_x_disc_all   = menu.addAction("Disconnect &All");
 -     QAction* act_x_sep1       = menu.addSeparator();
 -     QAction* act_x_info       = menu.addAction("&Info");
 -     QAction* act_x_rename     = menu.addAction("&Rename");
 -     QAction* act_x_sep2       = menu.addSeparator();
 -     QAction* act_x_split_join = menu.addAction(m_splitted ? "Join" : "Split");
 - 
 -     if (features.group_info == false)
 -         act_x_info->setVisible(false);
 - 
 -     if (features.group_rename == false)
 -         act_x_rename->setVisible(false);
 - 
 -     if (features.group_info == false && features.group_rename == false)
 -         act_x_sep1->setVisible(false);
 - 
 -     bool haveIns, haveOuts;
 -     haveIns = haveOuts = false;
 -     foreach (const port_dict_t& port, canvas.port_list)
 -     {
 -         if (m_port_list_ids.contains(port.port_id))
 -         {
 -             if (port.port_mode == PORT_MODE_INPUT)
 -                 haveIns = true;
 -             else if (port.port_mode == PORT_MODE_OUTPUT)
 -                 haveOuts = true;
 -         }
 -     }
 - 
 -     if (m_splitted == false && (haveIns && haveOuts) == false)
 -     {
 -         act_x_sep2->setVisible(false);
 -         act_x_split_join->setVisible(false);
 -     }
 - 
 -     QAction* act_selected = menu.exec(event->screenPos());
 - 
 -     if (act_selected == act_x_disc_all)
 -     {
 -         foreach (const int& port_id, port_con_list)
 -             canvas.callback(ACTION_PORTS_DISCONNECT, port_id, 0, "");
 -     }
 -     else if (act_selected == act_x_info)
 -     {
 -         canvas.callback(ACTION_GROUP_INFO, m_group_id, 0, "");
 -     }
 -     else if (act_selected == act_x_rename)
 -     {
 -         bool ok_check;
 -         QString new_name = QInputDialog::getText(0, "Rename Group", "New name:", QLineEdit::Normal, m_group_name, &ok_check);
 -         if (ok_check and !new_name.isEmpty())
 -         {
 -             canvas.callback(ACTION_GROUP_RENAME, m_group_id, 0, new_name);
 -         }
 -     }
 -     else if (act_selected == act_x_split_join)
 -     {
 -         if (m_splitted)
 -             canvas.callback(ACTION_GROUP_JOIN, m_group_id, 0, "");
 -         else
 -             canvas.callback(ACTION_GROUP_SPLIT, m_group_id, 0, "");
 - 
 -     }
 - 
 -     event->accept();
 - }
 - 
 - void CanvasBox::mousePressEvent(QGraphicsSceneMouseEvent* event)
 - {
 -     canvas.last_z_value += 1;
 -     setZValue(canvas.last_z_value);
 -     resetLinesZValue();
 -     m_cursor_moving = false;
 - 
 -     if (event->button() == Qt::RightButton)
 -     {
 -         canvas.scene->clearSelection();
 -         setSelected(true);
 -         m_mouse_down = false;
 -         return event->accept();
 -     }
 -     else if (event->button() == Qt::LeftButton)
 -     {
 -         if (sceneBoundingRect().contains(event->scenePos()))
 -             m_mouse_down = true;
 -         else
 -         {
 -             // Fixes a weird Qt behaviour with right-click mouseMove
 -             m_mouse_down = false;
 -             return event->ignore();
 -         }
 -     }
 -     else
 -         m_mouse_down = false;
 - 
 -     QGraphicsItem::mousePressEvent(event);
 - }
 - 
 - void CanvasBox::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
 - {
 -     if (m_mouse_down)
 -     {
 -         if (m_cursor_moving == false)
 -         {
 -             setCursor(QCursor(Qt::SizeAllCursor));
 -             m_cursor_moving = true;
 -         }
 -         repaintLines();
 -     }
 -     QGraphicsItem::mouseMoveEvent(event);
 - }
 - 
 - void CanvasBox::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
 - {
 -     if (m_cursor_moving)
 -         setCursor(QCursor(Qt::ArrowCursor));
 -     m_mouse_down = false;
 -     m_cursor_moving = false;
 -     QGraphicsItem::mouseReleaseEvent(event);
 - }
 - 
 - QRectF CanvasBox::boundingRect() const
 - {
 -     return QRectF(0, 0, p_width, p_height);
 - }
 - 
 - void CanvasBox::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
 - {
 -     painter->setRenderHint(QPainter::Antialiasing, false);
 - 
 -     if (isSelected())
 -         painter->setPen(canvas.theme->box_pen_sel);
 -     else
 -         painter->setPen(canvas.theme->box_pen);
 - 
 -     QLinearGradient box_gradient(0, 0, 0, p_height);
 -     box_gradient.setColorAt(0, canvas.theme->box_bg_1);
 -     box_gradient.setColorAt(1, canvas.theme->box_bg_2);
 - 
 -     painter->setBrush(box_gradient);
 -     painter->drawRect(0, 0, p_width, p_height);
 - 
 -     QPointF text_pos(25, 16);
 - 
 -     painter->setFont(m_font_name);
 -     painter->setPen(canvas.theme->box_text);
 -     painter->drawText(text_pos, m_group_name);
 - 
 -     repaintLines();
 - }
 - 
 - END_NAMESPACE_PATCHCANVAS
 
 
  |