void CircuitWidget::on_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& context, int x, int y, const Gtk::SelectionData& selection_data, guint info, guint time) { (void)info; //placate compiler... (void)selection_data; //placate compiler... if (!circuit) { context->drag_finish(false, false, time); return; } selections.clear(); static_cast<QCViewer*>(win)->set_selection (selections); Gtk::Widget* widget = drag_get_source_widget(context); Gtk::Button* button = dynamic_cast<Gtk::Button*>(widget); if (button == NULL) { context->drag_finish(false, false, time); return; } shared_ptr<Gate> newgate; unsigned int target = 0; switch (static_cast<GateIcon*>(button->get_image())->type) { case GateIcon::NOT: newgate = shared_ptr<Gate>(new UGate ("X")); newgate->drawType = Gate::NOT; break; case GateIcon::R: newgate = shared_ptr<Gate>(new RGate (1.0, RGate::Z)); break; case GateIcon::SWAP: newgate = shared_ptr<Gate>(new UGate ("F")); newgate->drawType = Gate::FRED; newgate->targets.push_back (target++); break; case GateIcon::MEASURE: newgate = shared_ptr<Gate>(new UGate("MEASURE","")); newgate->drawType = Gate::MEASURE; break; default: newgate = shared_ptr<Gate>(new UGate(static_cast<GateIcon*>(button->get_image ())->symbol)); break; } if (newgate->targets.size () > circuit->numLines ()) { context->drag_finish (false, false, time); return; } newgate->targets.push_back(target++); Gtk::Allocation allocation = get_allocation(); const int width = allocation.get_width(); const int height = allocation.get_height(); // translate mouse click coords into circuit diagram coords double xx = (x - width/2.0 + ext.width/2.0)/scale + cx; double yy = (y - height/2.0 + ext.height/2.0)/scale + cy; vector<int> select_ids; string name; int pos = -1; getCircuitAndColPosition (xx, yy, circuit, rects, name, pos); if (name.compare("Main")==0||pos==-1||name.compare("")==0) { //If the click is not in a subcircuit vector<unsigned int> para = circuit->getGreedyParallel(); unsigned int wire = getFirstWire (yy); if (wire + newgate->targets.size () - 1 >= circuit->numLines ()) { wire = circuit->numLines () - newgate->targets.size (); } for (unsigned int i = 0; i < newgate->targets.size(); i++) { newgate->targets[i] += wire; } if (columns.empty()||pos==-1) { insert_gate_at_front (newgate); } else if (pos >= (int)para.size()) { insert_gate_in_new_column (newgate, circuit->numGates(),circuit); } else { insert_gate_in_new_column (newgate, para.at(pos),circuit); } circuit->getGreedyParallel(); } else { insert_gate_in_new_column (newgate, pos,circuit->subcircuits[name]); unsigned int wire = getFirstWire (yy); for (unsigned int i = 0; i < newgate->targets.size(); i++) newgate->targets[i] += wire; } context->drag_finish(true, false, time); }