svn merge ^/trunk/blender -r49573:49601
[blender.git] / source / blender / editors / space_node / node_relationships.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2005 Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): David Millan Escriva, Juho Vepsäläinen, Nathan Letwory
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/editors/space_node/node_relationships.c
29  *  \ingroup spnode
30  */
31
32 #include "MEM_guardedalloc.h"
33
34 #include "DNA_node_types.h"
35 #include "DNA_object_types.h"
36
37 #include "BLI_math.h"
38 #include "BLI_blenlib.h"
39
40 #include "BKE_context.h"
41 #include "BKE_main.h"
42 #include "BKE_node.h"
43
44 #include "ED_node.h"  /* own include */
45 #include "ED_screen.h"
46 #include "ED_render.h"
47
48 #include "RNA_access.h"
49 #include "RNA_define.h"
50
51 #include "WM_api.h"
52 #include "WM_types.h"
53
54 #include "UI_view2d.h"
55
56 #include "node_intern.h"  /* own include */
57
58 /* ****************** Add *********************** */
59
60
61 typedef struct bNodeListItem {
62         struct bNodeListItem *next, *prev;
63         struct bNode *node;
64 } bNodeListItem;
65
66 static int sort_nodes_locx(void *a, void *b)
67 {
68         bNodeListItem *nli1 = (bNodeListItem *)a;
69         bNodeListItem *nli2 = (bNodeListItem *)b;
70         bNode *node1 = nli1->node;
71         bNode *node2 = nli2->node;
72
73         if (node1->locx > node2->locx)
74                 return 1;
75         else
76                 return 0;
77 }
78
79 static int socket_is_available(bNodeTree *UNUSED(ntree), bNodeSocket *sock, int allow_used)
80 {
81         if (nodeSocketIsHidden(sock))
82                 return 0;
83
84         if (!allow_used && (sock->flag & SOCK_IN_USE))
85                 return 0;
86
87         return 1;
88 }
89
90 static bNodeSocket *best_socket_output(bNodeTree *ntree, bNode *node, bNodeSocket *sock_target, int allow_multiple)
91 {
92         bNodeSocket *sock;
93
94         /* first look for selected output */
95         for (sock = node->outputs.first; sock; sock = sock->next) {
96                 if (!socket_is_available(ntree, sock, allow_multiple))
97                         continue;
98
99                 if (sock->flag & SELECT)
100                         return sock;
101         }
102
103         /* try to find a socket with a matching name */
104         for (sock = node->outputs.first; sock; sock = sock->next) {
105                 if (!socket_is_available(ntree, sock, allow_multiple))
106                         continue;
107
108                 /* check for same types */
109                 if (sock->type == sock_target->type) {
110                         if (strcmp(sock->name, sock_target->name) == 0)
111                                 return sock;
112                 }
113         }
114
115         /* otherwise settle for the first available socket of the right type */
116         for (sock = node->outputs.first; sock; sock = sock->next) {
117
118                 if (!socket_is_available(ntree, sock, allow_multiple))
119                         continue;
120
121                 /* check for same types */
122                 if (sock->type == sock_target->type) {
123                         return sock;
124                 }
125         }
126
127         return NULL;
128 }
129
130 /* this is a bit complicated, but designed to prioritize finding
131  * sockets of higher types, such as image, first */
132 static bNodeSocket *best_socket_input(bNodeTree *ntree, bNode *node, int num, int replace)
133 {
134         bNodeSocket *sock;
135         int socktype, maxtype = 0;
136         int a = 0;
137
138         for (sock = node->inputs.first; sock; sock = sock->next) {
139                 maxtype = MAX2(sock->type, maxtype);
140         }
141
142         /* find sockets of higher 'types' first (i.e. image) */
143         for (socktype = maxtype; socktype >= 0; socktype--) {
144                 for (sock = node->inputs.first; sock; sock = sock->next) {
145
146                         if (!socket_is_available(ntree, sock, replace)) {
147                                 a++;
148                                 continue;
149                         }
150
151                         if (sock->type == socktype) {
152                                 /* increment to make sure we don't keep finding
153                                  * the same socket on every attempt running this function */
154                                 a++;
155                                 if (a > num)
156                                         return sock;
157                         }
158                 }
159         }
160
161         return NULL;
162 }
163
164 static int snode_autoconnect_input(SpaceNode *snode, bNode *node_fr, bNodeSocket *sock_fr, bNode *node_to, bNodeSocket *sock_to, int replace)
165 {
166         bNodeTree *ntree = snode->edittree;
167         bNodeLink *link;
168
169         /* then we can connect */
170         if (replace)
171                 nodeRemSocketLinks(ntree, sock_to);
172
173         link = nodeAddLink(ntree, node_fr, sock_fr, node_to, sock_to);
174         /* validate the new link */
175         ntreeUpdateTree(ntree);
176         if (!(link->flag & NODE_LINK_VALID)) {
177                 nodeRemLink(ntree, link);
178                 return 0;
179         }
180
181         snode_update(snode, node_to);
182         return 1;
183 }
184
185 static void snode_autoconnect(SpaceNode *snode, int allow_multiple, int replace)
186 {
187         bNodeTree *ntree = snode->edittree;
188         ListBase *nodelist = MEM_callocN(sizeof(ListBase), "items_list");
189         bNodeListItem *nli;
190         bNode *node;
191         int i, numlinks = 0;
192
193         for (node = ntree->nodes.first; node; node = node->next) {
194                 if (node->flag & NODE_SELECT) {
195                         nli = MEM_mallocN(sizeof(bNodeListItem), "temporary node list item");
196                         nli->node = node;
197                         BLI_addtail(nodelist, nli);
198                 }
199         }
200
201         /* sort nodes left to right */
202         BLI_sortlist(nodelist, sort_nodes_locx);
203
204         for (nli = nodelist->first; nli; nli = nli->next) {
205                 bNode *node_fr, *node_to;
206                 bNodeSocket *sock_fr, *sock_to;
207                 int has_selected_inputs = 0;
208
209                 if (nli->next == NULL) break;
210
211                 node_fr = nli->node;
212                 node_to = nli->next->node;
213
214                 /* if there are selected sockets, connect those */
215                 for (sock_to = node_to->inputs.first; sock_to; sock_to = sock_to->next) {
216                         if (sock_to->flag & SELECT) {
217                                 has_selected_inputs = 1;
218
219                                 if (!socket_is_available(ntree, sock_to, replace))
220                                         continue;
221
222                                 /* check for an appropriate output socket to connect from */
223                                 sock_fr = best_socket_output(ntree, node_fr, sock_to, allow_multiple);
224                                 if (!sock_fr)
225                                         continue;
226
227                                 if (snode_autoconnect_input(snode, node_fr, sock_fr, node_to, sock_to, replace))
228                                         ++numlinks;
229                         }
230                 }
231
232                 if (!has_selected_inputs) {
233                         /* no selected inputs, connect by finding suitable match */
234                         int num_inputs = BLI_countlist(&node_to->inputs);
235
236                         for (i = 0; i < num_inputs; i++) {
237
238                                 /* find the best guess input socket */
239                                 sock_to = best_socket_input(ntree, node_to, i, replace);
240                                 if (!sock_to)
241                                         continue;
242
243                                 /* check for an appropriate output socket to connect from */
244                                 sock_fr = best_socket_output(ntree, node_fr, sock_to, allow_multiple);
245                                 if (!sock_fr)
246                                         continue;
247
248                                 if (snode_autoconnect_input(snode, node_fr, sock_fr, node_to, sock_to, replace)) {
249                                         ++numlinks;
250                                         break;
251                                 }
252                         }
253                 }
254         }
255
256         if (numlinks > 0) {
257                 ntreeUpdateTree(ntree);
258         }
259
260         BLI_freelistN(nodelist);
261         MEM_freeN(nodelist);
262 }
263
264 /* *************************** link viewer op ******************** */
265
266 static int node_link_viewer(const bContext *C, bNode *tonode)
267 {
268         SpaceNode *snode = CTX_wm_space_node(C);
269         bNode *node;
270         bNodeLink *link;
271         bNodeSocket *sock;
272
273         /* context check */
274         if (tonode == NULL || tonode->outputs.first == NULL)
275                 return OPERATOR_CANCELLED;
276         if (ELEM(tonode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))
277                 return OPERATOR_CANCELLED;
278
279         /* get viewer */
280         for (node = snode->edittree->nodes.first; node; node = node->next)
281                 if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))
282                         if (node->flag & NODE_DO_OUTPUT)
283                                 break;
284         /* no viewer, we make one active */
285         if (node == NULL) {
286                 for (node = snode->edittree->nodes.first; node; node = node->next) {
287                         if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
288                                 node->flag |= NODE_DO_OUTPUT;
289                                 break;
290                         }
291                 }
292         }
293
294         sock = NULL;
295
296         /* try to find an already connected socket to cycle to the next */
297         if (node) {
298                 link = NULL;
299                 for (link = snode->edittree->links.first; link; link = link->next)
300                         if (link->tonode == node && link->fromnode == tonode)
301                                 if (link->tosock == node->inputs.first)
302                                         break;
303                 if (link) {
304                         /* unlink existing connection */
305                         sock = link->fromsock;
306                         nodeRemLink(snode->edittree, link);
307
308                         /* find a socket after the previously connected socket */
309                         for (sock = sock->next; sock; sock = sock->next)
310                                 if (!nodeSocketIsHidden(sock))
311                                         break;
312                 }
313         }
314
315         /* find a socket starting from the first socket */
316         if (!sock) {
317                 for (sock = tonode->outputs.first; sock; sock = sock->next)
318                         if (!nodeSocketIsHidden(sock))
319                                 break;
320         }
321
322         if (sock) {
323                 /* add a new viewer if none exists yet */
324                 if (!node) {
325                         Main *bmain = CTX_data_main(C);
326                         Scene *scene = CTX_data_scene(C);
327                         bNodeTemplate ntemp;
328
329                         ntemp.type = CMP_NODE_VIEWER;
330                         /* XXX location is a quick hack, just place it next to the linked socket */
331                         node = node_add_node(snode, bmain, scene, &ntemp, sock->locx + 100, sock->locy);
332                         if (!node)
333                                 return OPERATOR_CANCELLED;
334
335                         link = NULL;
336                 }
337                 else {
338                         /* get link to viewer */
339                         for (link = snode->edittree->links.first; link; link = link->next)
340                                 if (link->tonode == node && link->tosock == node->inputs.first)
341                                         break;
342                 }
343
344                 if (link == NULL) {
345                         nodeAddLink(snode->edittree, tonode, sock, node, node->inputs.first);
346                 }
347                 else {
348                         link->fromnode = tonode;
349                         link->fromsock = sock;
350                         /* make sure the dependency sorting is updated */
351                         snode->edittree->update |= NTREE_UPDATE_LINKS;
352                 }
353                 ntreeUpdateTree(snode->edittree);
354                 snode_update(snode, node);
355         }
356
357         return OPERATOR_FINISHED;
358 }
359
360
361 static int node_active_link_viewer(bContext *C, wmOperator *UNUSED(op))
362 {
363         SpaceNode *snode = CTX_wm_space_node(C);
364         bNode *node;
365
366         node = editnode_get_active(snode->edittree);
367
368         if (!node)
369                 return OPERATOR_CANCELLED;
370
371         ED_preview_kill_jobs(C);
372
373         if (node_link_viewer(C, node) == OPERATOR_CANCELLED)
374                 return OPERATOR_CANCELLED;
375
376         snode_notify(C, snode);
377
378         return OPERATOR_FINISHED;
379 }
380
381
382 void NODE_OT_link_viewer(wmOperatorType *ot)
383 {
384         /* identifiers */
385         ot->name = "Link to Viewer Node";
386         ot->description = "Link to viewer node";
387         ot->idname = "NODE_OT_link_viewer";
388
389         /* api callbacks */
390         ot->exec = node_active_link_viewer;
391         ot->poll = composite_node_active;
392
393         /* flags */
394         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
395 }
396
397
398 /* *************************** add link op ******************** */
399
400 static void node_remove_extra_links(SpaceNode *snode, bNodeSocket *tsock, bNodeLink *link)
401 {
402         bNodeLink *tlink;
403         bNodeSocket *sock;
404
405         if (tsock && nodeCountSocketLinks(snode->edittree, link->tosock) > tsock->limit) {
406
407                 for (tlink = snode->edittree->links.first; tlink; tlink = tlink->next) {
408                         if (link != tlink && tlink->tosock == link->tosock)
409                                 break;
410                 }
411                 if (tlink) {
412                         /* try to move the existing link to the next available socket */
413                         if (tlink->tonode) {
414                                 /* is there a free input socket with the target type? */
415                                 for (sock = tlink->tonode->inputs.first; sock; sock = sock->next) {
416                                         if (sock->type == tlink->tosock->type)
417                                                 if (nodeCountSocketLinks(snode->edittree, sock) < sock->limit)
418                                                         break;
419                                 }
420                                 if (sock) {
421                                         tlink->tosock = sock;
422                                         sock->flag &= ~SOCK_HIDDEN;
423                                 }
424                                 else {
425                                         nodeRemLink(snode->edittree, tlink);
426                                 }
427                         }
428                         else
429                                 nodeRemLink(snode->edittree, tlink);
430
431                         snode->edittree->update |= NTREE_UPDATE_LINKS;
432                 }
433         }
434 }
435
436 static int outside_group_rect(SpaceNode *snode)
437 {
438         bNode *gnode = node_tree_get_editgroup(snode->nodetree);
439         if (gnode) {
440                 return (snode->mx <  gnode->totr.xmin ||
441                         snode->mx >= gnode->totr.xmax ||
442                         snode->my <  gnode->totr.ymin ||
443                         snode->my >= gnode->totr.ymax);
444         }
445         return 0;
446 }
447
448 /* loop that adds a nodelink, called by function below  */
449 /* in_out = starting socket */
450 static int node_link_modal(bContext *C, wmOperator *op, wmEvent *event)
451 {
452         SpaceNode *snode = CTX_wm_space_node(C);
453         ARegion *ar = CTX_wm_region(C);
454         bNodeLinkDrag *nldrag = op->customdata;
455         bNodeTree *ntree = snode->edittree;
456         bNode *tnode;
457         bNodeSocket *tsock = NULL;
458         bNodeLink *link;
459         LinkData *linkdata;
460         int in_out;
461
462         in_out = nldrag->in_out;
463
464         UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1],
465                                  &snode->mx, &snode->my);
466
467         switch (event->type) {
468                 case MOUSEMOVE:
469
470                         if (in_out == SOCK_OUT) {
471                                 if (node_find_indicated_socket(snode, &tnode, &tsock, SOCK_IN)) {
472                                         for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) {
473                                                 link = linkdata->data;
474
475                                                 /* skip if this is already the target socket */
476                                                 if (link->tosock == tsock)
477                                                         continue;
478                                                 /* skip if socket is on the same node as the fromsock */
479                                                 if (tnode && link->fromnode == tnode)
480                                                         continue;
481
482                                                 /* attach links to the socket */
483                                                 link->tonode = tnode;
484                                                 link->tosock = tsock;
485                                                 /* add it to the node tree temporarily */
486                                                 if (BLI_findindex(&ntree->links, link) < 0)
487                                                         BLI_addtail(&ntree->links, link);
488
489                                                 ntree->update |= NTREE_UPDATE_LINKS;
490                                         }
491                                         ntreeUpdateTree(ntree);
492                                 }
493                                 else {
494                                         int do_update = FALSE;
495                                         for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) {
496                                                 link = linkdata->data;
497
498                                                 if (link->tonode || link->tosock) {
499                                                         BLI_remlink(&ntree->links, link);
500                                                         link->prev = link->next = NULL;
501                                                         link->tonode = NULL;
502                                                         link->tosock = NULL;
503
504                                                         ntree->update |= NTREE_UPDATE_LINKS;
505                                                         do_update = TRUE;
506                                                 }
507                                         }
508                                         if (do_update) {
509                                                 ntreeUpdateTree(ntree);
510                                         }
511                                 }
512                         }
513                         else {
514                                 if (node_find_indicated_socket(snode, &tnode, &tsock, SOCK_OUT)) {
515                                         for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) {
516                                                 link = linkdata->data;
517
518                                                 /* skip if this is already the target socket */
519                                                 if (link->fromsock == tsock)
520                                                         continue;
521                                                 /* skip if socket is on the same node as the fromsock */
522                                                 if (tnode && link->tonode == tnode)
523                                                         continue;
524
525                                                 /* attach links to the socket */
526                                                 link->fromnode = tnode;
527                                                 link->fromsock = tsock;
528                                                 /* add it to the node tree temporarily */
529                                                 if (BLI_findindex(&ntree->links, link) < 0)
530                                                         BLI_addtail(&ntree->links, link);
531
532                                                 ntree->update |= NTREE_UPDATE_LINKS;
533                                         }
534                                         ntreeUpdateTree(ntree);
535                                 }
536                                 else {
537                                         int do_update = FALSE;
538                                         for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) {
539                                                 link = linkdata->data;
540
541                                                 if (link->fromnode || link->fromsock) {
542                                                         BLI_remlink(&ntree->links, link);
543                                                         link->prev = link->next = NULL;
544                                                         link->fromnode = NULL;
545                                                         link->fromsock = NULL;
546
547                                                         ntree->update |= NTREE_UPDATE_LINKS;
548                                                         do_update = TRUE;
549                                                 }
550                                         }
551                                         if (do_update) {
552                                                 ntreeUpdateTree(ntree);
553                                         }
554                                 }
555                         }
556
557                         ED_region_tag_redraw(ar);
558                         break;
559
560                 case LEFTMOUSE:
561                 case RIGHTMOUSE:
562                 case MIDDLEMOUSE: {
563                         for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) {
564                                 link = linkdata->data;
565
566                                 if (link->tosock && link->fromsock) {
567                                         /* send changed events for original tonode and new */
568                                         if (link->tonode)
569                                                 snode_update(snode, link->tonode);
570
571                                         /* we might need to remove a link */
572                                         if (in_out == SOCK_OUT)
573                                                 node_remove_extra_links(snode, link->tosock, link);
574
575                                         /* when linking to group outputs, update the socket type */
576                                         /* XXX this should all be part of a generic update system */
577                                         if (!link->tonode) {
578                                                 if (link->tosock->type != link->fromsock->type)
579                                                         nodeSocketSetType(link->tosock, link->fromsock->type);
580                                         }
581                                 }
582                                 else if (outside_group_rect(snode) && (link->tonode || link->fromnode)) {
583                                         /* automatically add new group socket */
584                                         if (link->tonode && link->tosock) {
585                                                 link->fromsock = node_group_expose_socket(ntree, link->tosock, SOCK_IN);
586                                                 link->fromnode = NULL;
587                                                 if (BLI_findindex(&ntree->links, link) < 0)
588                                                         BLI_addtail(&ntree->links, link);
589
590                                                 ntree->update |= NTREE_UPDATE_GROUP_IN | NTREE_UPDATE_LINKS;
591                                         }
592                                         else if (link->fromnode && link->fromsock) {
593                                                 link->tosock = node_group_expose_socket(ntree, link->fromsock, SOCK_OUT);
594                                                 link->tonode = NULL;
595                                                 if (BLI_findindex(&ntree->links, link) < 0)
596                                                         BLI_addtail(&ntree->links, link);
597
598                                                 ntree->update |= NTREE_UPDATE_GROUP_OUT | NTREE_UPDATE_LINKS;
599                                         }
600                                 }
601                                 else
602                                         nodeRemLink(ntree, link);
603                         }
604
605                         ntreeUpdateTree(ntree);
606                         snode_notify(C, snode);
607                         snode_dag_update(C, snode);
608
609                         BLI_remlink(&snode->linkdrag, nldrag);
610                         /* links->data pointers are either held by the tree or freed already */
611                         BLI_freelistN(&nldrag->links);
612                         MEM_freeN(nldrag);
613
614                         return OPERATOR_FINISHED;
615                 }
616         }
617
618         return OPERATOR_RUNNING_MODAL;
619 }
620
621 /* return 1 when socket clicked */
622 static bNodeLinkDrag *node_link_init(SpaceNode *snode, int detach)
623 {
624         bNode *node;
625         bNodeSocket *sock;
626         bNodeLink *link, *link_next, *oplink;
627         bNodeLinkDrag *nldrag = NULL;
628         LinkData *linkdata;
629         int num_links;
630
631         /* output indicated? */
632         if (node_find_indicated_socket(snode, &node, &sock, SOCK_OUT)) {
633                 nldrag = MEM_callocN(sizeof(bNodeLinkDrag), "drag link op customdata");
634
635                 num_links = nodeCountSocketLinks(snode->edittree, sock);
636                 if (num_links > 0 && (num_links >= sock->limit || detach)) {
637                         /* dragged links are fixed on input side */
638                         nldrag->in_out = SOCK_IN;
639                         /* detach current links and store them in the operator data */
640                         for (link = snode->edittree->links.first; link; link = link_next) {
641                                 link_next = link->next;
642                                 if (link->fromsock == sock) {
643                                         linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data");
644                                         linkdata->data = oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link");
645                                         *oplink = *link;
646                                         oplink->next = oplink->prev = NULL;
647                                         BLI_addtail(&nldrag->links, linkdata);
648                                         nodeRemLink(snode->edittree, link);
649                                 }
650                         }
651                 }
652                 else {
653                         /* dragged links are fixed on output side */
654                         nldrag->in_out = SOCK_OUT;
655                         /* create a new link */
656                         linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data");
657                         linkdata->data = oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link");
658                         oplink->fromnode = node;
659                         oplink->fromsock = sock;
660                         BLI_addtail(&nldrag->links, linkdata);
661                 }
662         }
663         /* or an input? */
664         else if (node_find_indicated_socket(snode, &node, &sock, SOCK_IN)) {
665                 nldrag = MEM_callocN(sizeof(bNodeLinkDrag), "drag link op customdata");
666
667                 num_links = nodeCountSocketLinks(snode->edittree, sock);
668                 if (num_links > 0 && (num_links >= sock->limit || detach)) {
669                         /* dragged links are fixed on output side */
670                         nldrag->in_out = SOCK_OUT;
671                         /* detach current links and store them in the operator data */
672                         for (link = snode->edittree->links.first; link; link = link_next) {
673                                 link_next = link->next;
674                                 if (link->tosock == sock) {
675                                         linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data");
676                                         linkdata->data = oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link");
677                                         *oplink = *link;
678                                         oplink->next = oplink->prev = NULL;
679                                         BLI_addtail(&nldrag->links, linkdata);
680                                         nodeRemLink(snode->edittree, link);
681
682                                         /* send changed event to original link->tonode */
683                                         if (node)
684                                                 snode_update(snode, node);
685                                 }
686                         }
687                 }
688                 else {
689                         /* dragged links are fixed on input side */
690                         nldrag->in_out = SOCK_IN;
691                         /* create a new link */
692                         linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data");
693                         linkdata->data = oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link");
694                         oplink->tonode = node;
695                         oplink->tosock = sock;
696                         BLI_addtail(&nldrag->links, linkdata);
697                 }
698         }
699
700         return nldrag;
701 }
702
703 static int node_link_invoke(bContext *C, wmOperator *op, wmEvent *event)
704 {
705         SpaceNode *snode = CTX_wm_space_node(C);
706         ARegion *ar = CTX_wm_region(C);
707         bNodeLinkDrag *nldrag;
708         int detach = RNA_boolean_get(op->ptr, "detach");
709
710         UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1],
711                                  &snode->mx, &snode->my);
712
713         ED_preview_kill_jobs(C);
714
715         nldrag = node_link_init(snode, detach);
716
717         if (nldrag) {
718                 op->customdata = nldrag;
719                 BLI_addtail(&snode->linkdrag, nldrag);
720
721                 /* add modal handler */
722                 WM_event_add_modal_handler(C, op);
723
724                 return OPERATOR_RUNNING_MODAL;
725         }
726         else
727                 return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
728 }
729
730 static int node_link_cancel(bContext *C, wmOperator *op)
731 {
732         SpaceNode *snode = CTX_wm_space_node(C);
733         bNodeLinkDrag *nldrag = op->customdata;
734
735         BLI_remlink(&snode->linkdrag, nldrag);
736
737         BLI_freelistN(&nldrag->links);
738         MEM_freeN(nldrag);
739
740         return OPERATOR_CANCELLED;
741 }
742
743 void NODE_OT_link(wmOperatorType *ot)
744 {
745         /* identifiers */
746         ot->name = "Link Nodes";
747         ot->idname = "NODE_OT_link";
748         ot->description = "Use the mouse to create a link between two nodes";
749
750         /* api callbacks */
751         ot->invoke = node_link_invoke;
752         ot->modal = node_link_modal;
753 //      ot->exec = node_link_exec;
754         ot->poll = ED_operator_node_active;
755         ot->cancel = node_link_cancel;
756
757         /* flags */
758         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
759
760         RNA_def_boolean(ot->srna, "detach", FALSE, "Detach", "Detach and redirect existing links");
761 }
762
763 /* ********************** Make Link operator ***************** */
764
765 /* makes a link between selected output and input sockets */
766 static int node_make_link_exec(bContext *C, wmOperator *op)
767 {
768         SpaceNode *snode = CTX_wm_space_node(C);
769         int replace = RNA_boolean_get(op->ptr, "replace");
770
771         ED_preview_kill_jobs(C);
772
773         snode_autoconnect(snode, 1, replace);
774
775         /* deselect sockets after linking */
776         node_deselect_all_input_sockets(snode, 0);
777         node_deselect_all_output_sockets(snode, 0);
778
779         ntreeUpdateTree(snode->edittree);
780         snode_notify(C, snode);
781         snode_dag_update(C, snode);
782
783         return OPERATOR_FINISHED;
784 }
785
786 void NODE_OT_link_make(wmOperatorType *ot)
787 {
788         /* identifiers */
789         ot->name = "Make Links";
790         ot->description = "Makes a link between selected output in input sockets";
791         ot->idname = "NODE_OT_link_make";
792
793         /* callbacks */
794         ot->exec = node_make_link_exec;
795         ot->poll = ED_operator_node_active; // XXX we need a special poll which checks that there are selected input/output sockets
796
797         /* flags */
798         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
799
800         RNA_def_boolean(ot->srna, "replace", 0, "Replace", "Replace socket connections with the new links");
801 }
802
803 /* ********************** Cut Link operator ***************** */
804 static int cut_links_intersect(bNodeLink *link, float mcoords[][2], int tot)
805 {
806         float coord_array[NODE_LINK_RESOL + 1][2];
807         int i, b;
808
809         if (node_link_bezier_points(NULL, NULL, link, coord_array, NODE_LINK_RESOL)) {
810
811                 for (i = 0; i < tot - 1; i++)
812                         for (b = 0; b < NODE_LINK_RESOL; b++)
813                                 if (isect_line_line_v2(mcoords[i], mcoords[i + 1], coord_array[b], coord_array[b + 1]) > 0)
814                                         return 1;
815         }
816         return 0;
817 }
818
819 static int cut_links_exec(bContext *C, wmOperator *op)
820 {
821         SpaceNode *snode = CTX_wm_space_node(C);
822         ARegion *ar = CTX_wm_region(C);
823         float mcoords[256][2];
824         int i = 0;
825
826         RNA_BEGIN(op->ptr, itemptr, "path")
827         {
828                 float loc[2];
829
830                 RNA_float_get_array(&itemptr, "loc", loc);
831                 UI_view2d_region_to_view(&ar->v2d, (int)loc[0], (int)loc[1],
832                                          &mcoords[i][0], &mcoords[i][1]);
833                 i++;
834                 if (i >= 256) break;
835         }
836         RNA_END;
837
838         if (i > 1) {
839                 int found = FALSE;
840                 bNodeLink *link, *next;
841
842                 for (link = snode->edittree->links.first; link; link = next) {
843                         next = link->next;
844
845                         if (cut_links_intersect(link, mcoords, i)) {
846
847                                 if (found == FALSE) {
848                                         ED_preview_kill_jobs(C);
849                                         found = TRUE;
850                                 }
851
852                                 snode_update(snode, link->tonode);
853                                 nodeRemLink(snode->edittree, link);
854                         }
855                 }
856
857                 if (found) {
858                         ntreeUpdateTree(snode->edittree);
859                         snode_notify(C, snode);
860                         snode_dag_update(C, snode);
861
862                         return OPERATOR_FINISHED;
863                 }
864                 else {
865                         return OPERATOR_CANCELLED;
866                 }
867
868         }
869
870         return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
871 }
872
873 void NODE_OT_links_cut(wmOperatorType *ot)
874 {
875         PropertyRNA *prop;
876
877         ot->name = "Cut links";
878         ot->idname = "NODE_OT_links_cut";
879         ot->description = "Use the mouse to cut (remove) some links";
880
881         ot->invoke = WM_gesture_lines_invoke;
882         ot->modal = WM_gesture_lines_modal;
883         ot->exec = cut_links_exec;
884         ot->cancel = WM_gesture_lines_cancel;
885
886         ot->poll = ED_operator_node_active;
887
888         /* flags */
889         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
890
891         prop = RNA_def_property(ot->srna, "path", PROP_COLLECTION, PROP_NONE);
892         RNA_def_property_struct_runtime(prop, &RNA_OperatorMousePath);
893         /* internal */
894         RNA_def_int(ot->srna, "cursor", BC_KNIFECURSOR, 0, INT_MAX, "Cursor", "", 0, INT_MAX);
895 }
896
897 /* ********************** Detach links operator ***************** */
898
899 static int detach_links_exec(bContext *C, wmOperator *UNUSED(op))
900 {
901         SpaceNode *snode = CTX_wm_space_node(C);
902         bNodeTree *ntree = snode->edittree;
903         bNode *node;
904
905         ED_preview_kill_jobs(C);
906
907         for (node = ntree->nodes.first; node; node = node->next) {
908                 if (node->flag & SELECT) {
909                         nodeInternalRelink(ntree, node);
910                 }
911         }
912
913         ntreeUpdateTree(ntree);
914
915         snode_notify(C, snode);
916         snode_dag_update(C, snode);
917
918         return OPERATOR_FINISHED;
919 }
920
921 void NODE_OT_links_detach(wmOperatorType *ot)
922 {
923         ot->name = "Detach Links";
924         ot->idname = "NODE_OT_links_detach";
925         ot->description = "Remove all links to selected nodes, and try to connect neighbor nodes together";
926
927         ot->exec = detach_links_exec;
928         ot->poll = ED_operator_node_active;
929
930         /* flags */
931         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
932 }
933
934
935 /* ****************** Show Cyclic Dependencies Operator  ******************* */
936
937 static int node_show_cycles_exec(bContext *C, wmOperator *UNUSED(op))
938 {
939         SpaceNode *snode = CTX_wm_space_node(C);
940
941         /* this is just a wrapper around this call... */
942         ntreeUpdateTree(snode->nodetree);
943         snode_notify(C, snode);
944
945         return OPERATOR_FINISHED;
946 }
947
948 void NODE_OT_show_cyclic_dependencies(wmOperatorType *ot)
949 {
950         /* identifiers */
951         ot->name = "Show Cyclic Dependencies";
952         ot->description = "Sort the nodes and show the cyclic dependencies between the nodes";
953         ot->idname = "NODE_OT_show_cyclic_dependencies";
954
955         /* callbacks */
956         ot->exec = node_show_cycles_exec;
957         ot->poll = ED_operator_node_active;
958
959         /* flags */
960         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
961 }
962
963 /* ****************** Set Parent ******************* */
964
965 static int node_parent_set_exec(bContext *C, wmOperator *UNUSED(op))
966 {
967         SpaceNode *snode = CTX_wm_space_node(C);
968         bNodeTree *ntree = snode->edittree;
969         bNode *frame = nodeGetActive(ntree), *node;
970         if (!frame || frame->type != NODE_FRAME)
971                 return OPERATOR_CANCELLED;
972
973         for (node = ntree->nodes.first; node; node = node->next) {
974                 if (node == frame)
975                         continue;
976                 if (node->flag & NODE_SELECT) {
977                         nodeDetachNode(node);
978                         nodeAttachNode(node, frame);
979                 }
980         }
981
982         ED_node_sort(ntree);
983         WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
984
985         return OPERATOR_FINISHED;
986 }
987
988 void NODE_OT_parent_set(wmOperatorType *ot)
989 {
990         /* identifiers */
991         ot->name = "Make Parent";
992         ot->description = "Attach selected nodes";
993         ot->idname = "NODE_OT_parent_set";
994
995         /* api callbacks */
996         ot->exec = node_parent_set_exec;
997         ot->poll = ED_operator_node_active;
998
999         /* flags */
1000         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1001 }
1002
1003 /* ****************** Clear Parent ******************* */
1004
1005 static int node_parent_clear_exec(bContext *C, wmOperator *UNUSED(op))
1006 {
1007         SpaceNode *snode = CTX_wm_space_node(C);
1008         bNodeTree *ntree = snode->edittree;
1009         bNode *node;
1010
1011         for (node = ntree->nodes.first; node; node = node->next) {
1012                 if (node->flag & NODE_SELECT) {
1013                         nodeDetachNode(node);
1014                 }
1015         }
1016
1017         WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
1018
1019         return OPERATOR_FINISHED;
1020 }
1021
1022 void NODE_OT_parent_clear(wmOperatorType *ot)
1023 {
1024         /* identifiers */
1025         ot->name = "Clear Parent";
1026         ot->description = "Detach selected nodes";
1027         ot->idname = "NODE_OT_parent_clear";
1028
1029         /* api callbacks */
1030         ot->exec = node_parent_clear_exec;
1031         ot->poll = ED_operator_node_active;
1032
1033         /* flags */
1034         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1035 }
1036
1037 /* ****************** Join Nodes ******************* */
1038
1039 /* tags for depth-first search */
1040 #define NODE_JOIN_DONE          1
1041 #define NODE_JOIN_IS_DESCENDANT 2
1042
1043 static void node_join_attach_recursive(bNode *node, bNode *frame)
1044 {
1045         node->done |= NODE_JOIN_DONE;
1046
1047         if (node == frame) {
1048                 node->done |= NODE_JOIN_IS_DESCENDANT;
1049         }
1050         else if (node->parent) {
1051                 /* call recursively */
1052                 if (!(node->parent->done & NODE_JOIN_DONE))
1053                         node_join_attach_recursive(node->parent, frame);
1054
1055                 /* in any case: if the parent is a descendant, so is the child */
1056                 if (node->parent->done & NODE_JOIN_IS_DESCENDANT)
1057                         node->done |= NODE_JOIN_IS_DESCENDANT;
1058                 else if (node->flag & NODE_TEST) {
1059                         /* if parent is not an decendant of the frame, reattach the node */
1060                         nodeDetachNode(node);
1061                         nodeAttachNode(node, frame);
1062                         node->done |= NODE_JOIN_IS_DESCENDANT;
1063                 }
1064         }
1065         else if (node->flag & NODE_TEST) {
1066                 nodeAttachNode(node, frame);
1067                 node->done |= NODE_JOIN_IS_DESCENDANT;
1068         }
1069 }
1070
1071 static int node_join_exec(bContext *C, wmOperator *UNUSED(op))
1072 {
1073         SpaceNode *snode = CTX_wm_space_node(C);
1074         Main *bmain = CTX_data_main(C);
1075         Scene *scene = CTX_data_scene(C);
1076         bNodeTree *ntree = snode->edittree;
1077         bNode *node, *frame;
1078         bNodeTemplate ntemp;
1079
1080         /* XXX save selection: node_add_node call below sets the new frame as single active+selected node */
1081         for (node = ntree->nodes.first; node; node = node->next) {
1082                 if (node->flag & NODE_SELECT)
1083                         node->flag |= NODE_TEST;
1084                 else
1085                         node->flag &= ~NODE_TEST;
1086         }
1087
1088         ntemp.main = bmain;
1089         ntemp.scene = scene;
1090         ntemp.type = NODE_FRAME;
1091         frame = node_add_node(snode, bmain, scene, &ntemp, 0.0f, 0.0f);
1092
1093         /* reset tags */
1094         for (node = ntree->nodes.first; node; node = node->next)
1095                 node->done = 0;
1096
1097         for (node = ntree->nodes.first; node; node = node->next) {
1098                 if (!(node->done & NODE_JOIN_DONE))
1099                         node_join_attach_recursive(node, frame);
1100         }
1101
1102         /* restore selection */
1103         for (node = ntree->nodes.first; node; node = node->next) {
1104                 if (node->flag & NODE_TEST)
1105                         node->flag |= NODE_SELECT;
1106         }
1107
1108         ED_node_sort(ntree);
1109         WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
1110
1111         return OPERATOR_FINISHED;
1112 }
1113
1114 void NODE_OT_join(wmOperatorType *ot)
1115 {
1116         /* identifiers */
1117         ot->name = "Join Nodes";
1118         ot->description = "Attach selected nodes to a new common frame";
1119         ot->idname = "NODE_OT_join";
1120
1121         /* api callbacks */
1122         ot->exec = node_join_exec;
1123         ot->poll = ED_operator_node_active;
1124
1125         /* flags */
1126         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1127 }
1128
1129 /* ****************** Attach ******************* */
1130
1131 static int node_attach_exec(bContext *C, wmOperator *UNUSED(op))
1132 {
1133         SpaceNode *snode = CTX_wm_space_node(C);
1134         bNodeTree *ntree = snode->edittree;
1135         bNode *frame;
1136
1137         /* check nodes front to back */
1138         for (frame = ntree->nodes.last; frame; frame = frame->prev) {
1139                 /* skip selected, those are the nodes we want to attach */
1140                 if ((frame->type != NODE_FRAME) || (frame->flag & NODE_SELECT))
1141                         continue;
1142                 if (BLI_in_rctf(&frame->totr, snode->mx, snode->my))
1143                         break;
1144         }
1145         if (frame) {
1146                 bNode *node, *parent;
1147                 for (node = ntree->nodes.last; node; node = node->prev) {
1148                         if (node->flag & NODE_SELECT) {
1149                                 if (node->parent == NULL) {
1150                                         /* disallow moving a parent into its child */
1151                                         if (nodeAttachNodeCheck(frame, node) == FALSE) {
1152                                                 /* attach all unparented nodes */
1153                                                 nodeAttachNode(node, frame);
1154                                         }
1155                                 }
1156                                 else {
1157                                         /* attach nodes which share parent with the frame */
1158                                         for (parent = frame->parent; parent; parent = parent->parent) {
1159                                                 if (parent == node->parent) {
1160                                                         break;
1161                                                 }
1162                                         }
1163
1164                                         if (parent) {
1165                                                 /* disallow moving a parent into its child */
1166                                                 if (nodeAttachNodeCheck(frame, node) == FALSE) {
1167                                                         nodeDetachNode(node);
1168                                                         nodeAttachNode(node, frame);
1169                                                 }
1170                                         }
1171                                 }
1172                         }
1173                 }
1174         }
1175
1176         ED_node_sort(ntree);
1177         WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
1178
1179         return OPERATOR_FINISHED;
1180 }
1181
1182 static int node_attach_invoke(bContext *C, wmOperator *op, wmEvent *event)
1183 {
1184         ARegion *ar = CTX_wm_region(C);
1185         SpaceNode *snode = CTX_wm_space_node(C);
1186
1187         /* convert mouse coordinates to v2d space */
1188         UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &snode->mx, &snode->my);
1189
1190         return node_attach_exec(C, op);
1191 }
1192
1193 void NODE_OT_attach(wmOperatorType *ot)
1194 {
1195         /* identifiers */
1196         ot->name = "Attach Nodes";
1197         ot->description = "Attach active node to a frame";
1198         ot->idname = "NODE_OT_attach";
1199
1200         /* api callbacks */
1201         ot->exec = node_attach_exec;
1202         ot->invoke = node_attach_invoke;
1203         ot->poll = ED_operator_node_active;
1204
1205         /* flags */
1206         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1207 }
1208
1209 /* ****************** Detach ******************* */
1210
1211 /* tags for depth-first search */
1212 #define NODE_DETACH_DONE            1
1213 #define NODE_DETACH_IS_DESCENDANT   2
1214
1215 static void node_detach_recursive(bNode *node)
1216 {
1217         node->done |= NODE_DETACH_DONE;
1218
1219         if (node->parent) {
1220                 /* call recursively */
1221                 if (!(node->parent->done & NODE_DETACH_DONE))
1222                         node_detach_recursive(node->parent);
1223
1224                 /* in any case: if the parent is a descendant, so is the child */
1225                 if (node->parent->done & NODE_DETACH_IS_DESCENDANT)
1226                         node->done |= NODE_DETACH_IS_DESCENDANT;
1227                 else if (node->flag & NODE_SELECT) {
1228                         /* if parent is not a decendant of a selected node, detach */
1229                         nodeDetachNode(node);
1230                         node->done |= NODE_DETACH_IS_DESCENDANT;
1231                 }
1232         }
1233         else if (node->flag & NODE_SELECT) {
1234                 node->done |= NODE_DETACH_IS_DESCENDANT;
1235         }
1236 }
1237
1238
1239 /* detach the root nodes in the current selection */
1240 static int node_detach_exec(bContext *C, wmOperator *UNUSED(op))
1241 {
1242         SpaceNode *snode = CTX_wm_space_node(C);
1243         bNodeTree *ntree = snode->edittree;
1244         bNode *node;
1245
1246         /* reset tags */
1247         for (node = ntree->nodes.first; node; node = node->next)
1248                 node->done = 0;
1249         /* detach nodes recursively
1250          * relative order is preserved here!
1251          */
1252         for (node = ntree->nodes.first; node; node = node->next) {
1253                 if (!(node->done & NODE_DETACH_DONE))
1254                         node_detach_recursive(node);
1255         }
1256
1257         ED_node_sort(ntree);
1258         WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
1259
1260         return OPERATOR_FINISHED;
1261 }
1262
1263 void NODE_OT_detach(wmOperatorType *ot)
1264 {
1265         /* identifiers */
1266         ot->name = "Detach Nodes";
1267         ot->description = "Detach selected nodes from parents";
1268         ot->idname = "NODE_OT_detach";
1269
1270         /* api callbacks */
1271         ot->exec = node_detach_exec;
1272         ot->poll = ED_operator_node_active;
1273
1274         /* flags */
1275         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1276 }
1277
1278 /* *********************  automatic node insert on dragging ******************* */
1279
1280
1281 /* prevent duplicate testing code below */
1282 static SpaceNode *ed_node_link_conditions(ScrArea *sa, bNode **select)
1283 {
1284         SpaceNode *snode = sa ? sa->spacedata.first : NULL;
1285         bNode *node;
1286         bNodeLink *link;
1287
1288         /* no unlucky accidents */
1289         if (sa == NULL || sa->spacetype != SPACE_NODE) return NULL;
1290
1291         *select = NULL;
1292
1293         for (node = snode->edittree->nodes.first; node; node = node->next) {
1294                 if (node->flag & SELECT) {
1295                         if (*select)
1296                                 break;
1297                         else
1298                                 *select = node;
1299                 }
1300         }
1301         /* only one selected */
1302         if (node || *select == NULL) return NULL;
1303
1304         /* correct node */
1305         if ((*select)->inputs.first == NULL || (*select)->outputs.first == NULL) return NULL;
1306
1307         /* test node for links */
1308         for (link = snode->edittree->links.first; link; link = link->next) {
1309                 if (link->tonode == *select || link->fromnode == *select)
1310                         return NULL;
1311         }
1312
1313         return snode;
1314 }
1315
1316 /* test == 0, clear all intersect flags */
1317 void ED_node_link_intersect_test(ScrArea *sa, int test)
1318 {
1319         bNode *select;
1320         SpaceNode *snode = ed_node_link_conditions(sa, &select);
1321         bNodeLink *link, *selink = NULL;
1322         float mcoords[6][2];
1323
1324         if (snode == NULL) return;
1325
1326         /* clear flags */
1327         for (link = snode->edittree->links.first; link; link = link->next)
1328                 link->flag &= ~NODE_LINKFLAG_HILITE;
1329
1330         if (test == 0) return;
1331
1332         /* okay, there's 1 node, without links, now intersect */
1333         mcoords[0][0] = select->totr.xmin;
1334         mcoords[0][1] = select->totr.ymin;
1335         mcoords[1][0] = select->totr.xmax;
1336         mcoords[1][1] = select->totr.ymin;
1337         mcoords[2][0] = select->totr.xmax;
1338         mcoords[2][1] = select->totr.ymax;
1339         mcoords[3][0] = select->totr.xmin;
1340         mcoords[3][1] = select->totr.ymax;
1341         mcoords[4][0] = select->totr.xmin;
1342         mcoords[4][1] = select->totr.ymin;
1343         mcoords[5][0] = select->totr.xmax;
1344         mcoords[5][1] = select->totr.ymax;
1345
1346         /* we only tag a single link for intersect now */
1347         /* idea; use header dist when more? */
1348         for (link = snode->edittree->links.first; link; link = link->next) {
1349
1350                 if (cut_links_intersect(link, mcoords, 5)) { /* intersect code wants edges */
1351                         if (selink)
1352                                 break;
1353                         selink = link;
1354                 }
1355         }
1356
1357         if (link == NULL && selink)
1358                 selink->flag |= NODE_LINKFLAG_HILITE;
1359 }
1360
1361 /* assumes sockets in list */
1362 static bNodeSocket *socket_best_match(ListBase *sockets)
1363 {
1364         bNodeSocket *sock;
1365         int type, maxtype = 0;
1366
1367         /* find type range */
1368         for (sock = sockets->first; sock; sock = sock->next)
1369                 maxtype = MAX2(sock->type, maxtype);
1370
1371         /* try all types, starting from 'highest' (i.e. colors, vectors, values) */
1372         for (type = maxtype; type >= 0; --type) {
1373                 for (sock = sockets->first; sock; sock = sock->next) {
1374                         if (!nodeSocketIsHidden(sock) && type == sock->type) {
1375                                 return sock;
1376                         }
1377                 }
1378         }
1379
1380         /* no visible sockets, unhide first of highest type */
1381         for (type = maxtype; type >= 0; --type) {
1382                 for (sock = sockets->first; sock; sock = sock->next) {
1383                         if (type == sock->type) {
1384                                 sock->flag &= ~SOCK_HIDDEN;
1385                                 return sock;
1386                         }
1387                 }
1388         }
1389
1390         return NULL;
1391 }
1392
1393 /* assumes link with NODE_LINKFLAG_HILITE set */
1394 void ED_node_link_insert(ScrArea *sa)
1395 {
1396         bNode *node, *select;
1397         SpaceNode *snode = ed_node_link_conditions(sa, &select);
1398         bNodeLink *link;
1399         bNodeSocket *sockto;
1400
1401         if (snode == NULL) return;
1402
1403         /* get the link */
1404         for (link = snode->edittree->links.first; link; link = link->next)
1405                 if (link->flag & NODE_LINKFLAG_HILITE)
1406                         break;
1407
1408         if (link) {
1409                 node = link->tonode;
1410                 sockto = link->tosock;
1411
1412                 link->tonode = select;
1413                 link->tosock = socket_best_match(&select->inputs);
1414                 link->flag &= ~NODE_LINKFLAG_HILITE;
1415
1416                 nodeAddLink(snode->edittree, select, socket_best_match(&select->outputs), node, sockto);
1417                 ntreeUpdateTree(snode->edittree);   /* needed for pointers */
1418                 snode_update(snode, select);
1419                 ED_node_changed_update(snode->id, select);
1420         }
1421 }