/* * Proview Open Source Process Control. * Copyright (C) 2005-2017 SSAB EMEA AB. * * This file is part of Proview. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * 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. * * You should have received a copy of the GNU General Public License * along with Proview. If not, see <http://www.gnu.org/licenses/> * * Linking Proview statically or dynamically with other modules is * making a combined work based on Proview. Thus, the terms and * conditions of the GNU General Public License cover the whole * combination. * * In addition, as a special exception, the copyright holders of * Proview give you permission to, from the build function in the * Proview Configurator, combine Proview with modules generated by the * Proview PLC Editor to a PLC program, regardless of the license * terms of these modules. You may copy and distribute the resulting * combined work under the terms of your choice, provided that every * copy of the combined work is accompanied by a complete copy of * the source code of Proview (the version used to produce the * combined work), being distributed under the terms of the GNU * General Public License plus this exception. **/ #include "glow_std.h" #include <iostream> #include <float.h> #include <math.h> #include <stdlib.h> #include "glow_node.h" #include "glow_draw.h" #include "glow_conpoint.h" #include "glow_browctx.h" #include "glow_growctx.h" #include "glow_tracedata.h" #include "glow_grownode.h" #include "glow_msg.h" GlowNode::GlowNode( GrowCtx *glow_ctx, const char *name, GlowNodeClass *node_class, double x1, double y1, int nodraw, int rel_annot_pos) : x_right(x1), x_left(x1), y_high(y1), y_low(y1), obst_x_right(x1), obst_x_left(x1), obst_y_high(y1), obst_y_low(y1), hot(0), ctx(glow_ctx), nc(node_class), nc_root(node_class), pos(glow_ctx, x1,y1), stored_pos(glow_ctx, x1, y1), highlight(0), inverse(0), local_nc(0), user_data(0), level(0), node_open(0), relative_annot_pos(rel_annot_pos), relative_annot_x(0), input_active(0), input_focus(0) { double x_grid, y_grid; strncpy( n_name, name, sizeof(n_name)); n_name[sizeof(n_name)-1] = 0; memset( refcon_cnt, 0, sizeof(refcon_cnt)); memset( annotv, 0, sizeof(annotv)); memset( annotsize, 0, sizeof(annotsize)); memset( annotv_inputmode, 0, sizeof(annotv_inputmode)); memset( annotv_input, 0, sizeof(annotv_input)); memset( rbuttonv, 0, sizeof(rbuttonv)); memset( rel_annot_x, 0, sizeof(rel_annot_x)); if ( !nc) return; if ( ctx->grid_on) { ctx->find_grid( x1, y1, &x_grid, &y_grid); pos.posit( x_grid, y_grid); } x_left = y_low = 1e37; x_right = y_high = -1e37; get_node_borders(); if ( nc->group == glow_eNodeGroup_Document) { obst_x_left = obst_y_low = 1e37; obst_x_right = obst_y_high = -1e37; get_node_obstacle_borders(); } else { obst_x_left = x_left; obst_x_right = x_right; obst_y_low = y_low; obst_y_high = y_high; } zoom(); } GlowNode::~GlowNode() { if ( !nc) return; ctx->object_deleted( this); if ( ctx->nodraw) return; if ( ctx->type() == glow_eCtxType_Grow) return; erase(); nav_erase(); ctx->set_defered_redraw(); ctx->delete_node_cons( this); ctx->draw( &ctx->mw, x_left * ctx->mw.zoom_factor_x - ctx->mw.offset_x - DRAW_MP, y_low * ctx->mw.zoom_factor_y - ctx->mw.offset_y - DRAW_MP, x_right * ctx->mw.zoom_factor_x - ctx->mw.offset_x + DRAW_MP, y_high * ctx->mw.zoom_factor_y - ctx->mw.offset_y + DRAW_MP); ctx->nav_draw( &ctx->navw, x_left * ctx->navw.zoom_factor_x - ctx->navw.offset_x - 1, y_low * ctx->navw.zoom_factor_y - ctx->navw.offset_y - 1, x_right * ctx->navw.zoom_factor_x - ctx->navw.offset_x + 1, y_high * ctx->navw.zoom_factor_y - ctx->navw.offset_y + 1); ctx->redraw_defered(); if ( hot) ctx->gdraw->set_cursor( &ctx->mw, glow_eDrawCursor_Normal); } int GlowNode::get_conpoint( int num, double *x, double *y, glow_eDirection *dir) { int sts; sts = nc->get_conpoint( num, x, y, dir); if ( ODD(sts)) { *x += pos.x; *y += pos.y; } return sts; } void GlowNode::save( ofstream& fp, glow_eSaveMode mode) { int i; char *s; if ( (mode == glow_eSaveMode_Trace && nc->group != glow_eNodeGroup_Trace) || (mode == glow_eSaveMode_Edit && nc->group == glow_eNodeGroup_Trace) ) return; fp << int(glow_eSave_Node) << endl; fp << int(glow_eSave_Node_nc) << FSPACE << nc->nc_name << endl; fp << int(glow_eSave_Node_n_name) << FSPACE << n_name << endl; fp << int(glow_eSave_Node_refcon_cnt) << endl; for ( i = 0; i < MAX_CONPOINTS; i++) fp << refcon_cnt[i] << endl; fp << int(glow_eSave_Node_x_right) << FSPACE << x_right << endl; fp << int(glow_eSave_Node_x_left) << FSPACE << x_left << endl; fp << int(glow_eSave_Node_y_high) << FSPACE << y_high << endl; fp << int(glow_eSave_Node_y_low) << FSPACE << y_low << endl; fp << int(glow_eSave_Node_obst_x_right) << FSPACE << obst_x_right << endl; fp << int(glow_eSave_Node_obst_x_left) << FSPACE << obst_x_left << endl; fp << int(glow_eSave_Node_obst_y_high) << FSPACE << obst_y_high << endl; fp << int(glow_eSave_Node_obst_y_low) << FSPACE << obst_y_low << endl; fp << int(glow_eSave_Node_annotsize) << endl; for ( i = 0; i < 10; i++) fp << annotsize[i] << endl; fp << int(glow_eSave_Node_annotv) << endl; for ( i = 0; i < 10; i++) { if( annotsize[i]) { fp << "\""; for ( s = annotv[i]; *s; s++) { if ( *s == '"') fp << "\\"; fp << *s; } fp << "\"" << endl; } } fp << int(glow_eSave_Node_pos) << endl; pos.save( fp, mode); fp << int(glow_eSave_Node_trace_data1) << FSPACE << trace.data[0] << endl; fp << int(glow_eSave_Node_trace_data2) << FSPACE << trace.data[1] << endl; fp << int(glow_eSave_Node_trace_data3) << FSPACE << trace.data[2] << endl; fp << int(glow_eSave_Node_trace_data4) << FSPACE << trace.data[3] << endl; fp << int(glow_eSave_Node_trace_data5) << FSPACE << trace.data[4] << endl; fp << int(glow_eSave_Node_trace_data6) << FSPACE << trace.data[5] << endl; fp << int(glow_eSave_Node_trace_data7) << FSPACE << trace.data[6] << endl; fp << int(glow_eSave_Node_trace_data8) << FSPACE << trace.data[7] << endl; fp << int(glow_eSave_Node_trace_data9) << FSPACE << trace.data[8] << endl; fp << int(glow_eSave_Node_trace_data10) << FSPACE << trace.data[9] << endl; fp << int(glow_eSave_Node_trace_attr_type) << FSPACE << int(trace.attr_type) << endl; fp << int(glow_eSave_Node_trace_color) << FSPACE << int(trace.color) << endl; fp << int(glow_eSave_Node_trace_color2) << FSPACE << int(trace.color2) << endl; fp << int(glow_eSave_Node_access) << FSPACE << (unsigned int)(trace.access) << endl; fp << int(glow_eSave_Node_cycle) << FSPACE << (unsigned int)(trace.cycle) << endl; fp << int(glow_eSave_Node_ref_object) << FSPACE << trace.ref_object << endl; fp << int(glow_eSave_End) << endl; } void GlowNode::open( ifstream& fp) { int type; int end_found = 0; char dummy[40]; char nc_name[80]; int i, j; char c; int tmp; unsigned int utmp; int sts; for (;;) { if ( !fp.good()) { fp.clear(); fp.getline( dummy, sizeof(dummy)); printf( "** Read error GlowNode: \"%d %s\"\n", type, dummy); } fp >> type; switch( type) { case glow_eSave_Node: break; case glow_eSave_Node_nc: fp.get(); fp.getline( nc_name, sizeof(nc_name)); if ( ctx->type() != glow_eCtxType_Grow || ((GrowNode *)this)->type() != glow_eObjectType_GrowGroup) { nc = (GlowNodeClass *) ctx->get_nodeclass_from_name( nc_name); if ( !nc && ctx->type() == glow_eCtxType_Grow) { // If grow, load subgraph sts = ctx->open_subgraph_from_name( nc_name, glow_eSaveMode_SubGraph); if ( ODD(sts)) { nc = (GlowNodeClass *) ctx->get_nodeclass_from_name( nc_name); if ( nc) nc->nc_extern = 1; } } if ( !nc) cout << "GlowNode:nodeclass not found: " << nc_name << endl; if ( nc && ctx->environment == glow_eEnv_Runtime && nc->recursive_trace) { // Create local copy of nodeclass nc = new GlowNodeClass(*nc); local_nc = 1; } nc_root = nc; } break; case glow_eSave_Node_n_name: fp.get(); fp.getline( n_name, sizeof(n_name)); break; case glow_eSave_Node_refcon_cnt: for ( i = 0; i < MAX_CONPOINTS; i++) fp >> refcon_cnt[i]; break; case glow_eSave_Node_x_right: fp >> x_right; break; case glow_eSave_Node_x_left: fp >> x_left; break; case glow_eSave_Node_y_high: fp >> y_high; break; case glow_eSave_Node_y_low: fp >> y_low; break; case glow_eSave_Node_obst_x_right: fp >> obst_x_right; break; case glow_eSave_Node_obst_x_left: fp >> obst_x_left; break; case glow_eSave_Node_obst_y_high: fp >> obst_y_high; break; case glow_eSave_Node_obst_y_low: fp >> obst_y_low; break; case glow_eSave_Node_annotsize: for ( i = 0; i < 10; i++) fp >> annotsize[i]; break; case glow_eSave_Node_annotv: fp.getline( dummy, sizeof(dummy)); for ( i = 0; i < 10; i++) { if ( annotsize[i]) { annotv[i] = (char *) calloc( 1, annotsize[i]); fp.get(); for ( j = 0; j < annotsize[i]; j++) { if ((c = fp.get()) == '"') { if ( j > 0 && annotv[i][j-1] == '\\') j--; else { annotv[i][j] = 0; break; } } annotv[i][j] = c; } fp.getline( dummy, sizeof(dummy)); } } break; case glow_eSave_Node_pos: pos.open( fp); break; case glow_eSave_Node_trace_data1: fp.get(); fp.getline( trace.data[0], sizeof(trace.data[0])); break; case glow_eSave_Node_trace_data2: fp.get(); fp.getline( trace.data[1], sizeof(trace.data[0])); break; case glow_eSave_Node_trace_data3: fp.get(); fp.getline( trace.data[2], sizeof(trace.data[0])); break; case glow_eSave_Node_trace_data4: fp.get(); fp.getline( trace.data[3], sizeof(trace.data[0])); break; case glow_eSave_Node_trace_data5: fp.get(); fp.getline( trace.data[4], sizeof(trace.data[0])); break; case glow_eSave_Node_trace_data6: fp.get(); fp.getline( trace.data[5], sizeof(trace.data[0])); break; case glow_eSave_Node_trace_data7: fp.get(); fp.getline( trace.data[6], sizeof(trace.data[0])); break; case glow_eSave_Node_trace_data8: fp.get(); fp.getline( trace.data[7], sizeof(trace.data[0])); break; case glow_eSave_Node_trace_data9: fp.get(); fp.getline( trace.data[8], sizeof(trace.data[0])); break; case glow_eSave_Node_trace_data10: fp.get(); fp.getline( trace.data[9], sizeof(trace.data[0])); break; case glow_eSave_Node_trace_attr_type: fp >> tmp; trace.attr_type = (glow_eTraceType)tmp; break; case glow_eSave_Node_trace_color: fp >> tmp; trace.color = (glow_eDrawType)tmp; break; case glow_eSave_Node_trace_color2: fp >> tmp; trace.color2 = (glow_eDrawType)tmp; break; case glow_eSave_Node_access: fp >> utmp; trace.access = (glow_mAccess)utmp; break; case glow_eSave_Node_cycle: fp >> tmp; trace.cycle = (glow_eCycle)tmp; break; case glow_eSave_Node_ref_object: fp.get(); fp.getline( trace.ref_object, sizeof(trace.ref_object)); break; case glow_eSave_End: end_found = 1; break; default: cout << "GlowNode:open syntax error" << endl; fp.getline( dummy, sizeof(dummy)); } if ( end_found) break; } if ( ctx->trace_started) trace_init(); } void GlowNode::select_region_insert( double ll_x, double ll_y, double ur_x, double ur_y, glow_eSelectPolicy select_policy) { if ( select_policy == glow_eSelectPolicy_Surround || nc->group == glow_eNodeGroup_Document) { if ( x_left > ll_x && x_right < ur_x && y_high < ur_y && y_low > ll_y) ctx->select_insert( this); } else { if ( x_right > ll_x && x_left < ur_x && y_low < ur_y && y_high > ll_y) ctx->select_insert( this); } } void GlowNode::get_annotation( int num, char *text, int size) { if ( !annotv[num]) strcpy( text, ""); else { strncpy( text, annotv[num], size); text[size-1] = 0; } } void GlowNode::conpoint_refcon_reconfig( int conpoint) { // ctx->conpoint_refcon_erase( this, conpoint); refcon_cnt[conpoint] = 0; ctx->conpoint_refcon_redraw( this, conpoint); } void GlowNode::remove_notify() { ctx->delete_node_cons( this); } void GlowNode::set_trace_attr( GlowTraceData *attr) { memcpy( &trace, attr, sizeof(trace)); if ( ctx->trace_started /* && strcmp( trace.data[0], "") != 0 */) ctx->trace_connect_func( (void *) this, &trace); } void GlowNode::get_trace_attr( GlowTraceData **attr) { *attr = &trace; } int GlowNode::trace_scan() { int sts; if ( ctx->trace_scan_func && trace.p) { sts = ctx->trace_scan_func( (void *) this, trace.p); if ( sts == GLOW__TERMINATED || sts == GLOW__SUBTERMINATED || sts == GLOW__SWAPTERMINATED) return sts; } if ( nc->recursive_trace) nc->a.trace_scan(); return 1; } int GlowNode::trace_init() { int sts; // if ( strcmp( trace.data[0], "") == 0) // return 1; sts = ctx->trace_connect_func( (void *) this, &trace); if ( nc->recursive_trace) nc->a.trace_init(); return sts; } void GlowNode::trace_close() { // if ( strcmp( trace.data[0], "") == 0) // return; if ( trace.p) ctx->trace_disconnect_func( (void *) this); if ( nc->recursive_trace) nc->a.trace_close(); }