Commit 2889b888 authored by Claes Sjofors's avatar Claes Sjofors

SevHist, several sevhist curves in one window, sev plotgroups and plotgroup menu items in sev_xtt

parent 60dd39e9
...@@ -202,19 +202,13 @@ void XttTblGtk::activate_list_layout( GtkWidget *w, gpointer data) ...@@ -202,19 +202,13 @@ void XttTblGtk::activate_list_layout( GtkWidget *w, gpointer data)
xtt->tblnav->show_list(); xtt->tblnav->show_list();
} }
XttSevHist *XttTblGtk::sevhist_new( pwr_tOid oid, char *aname, bool sevhistobject) XttSevHist *XttTblGtk::sevhist_new( pwr_tOid *oidv, pwr_tOName *anamev, pwr_tOName *onamev, bool *sevhistobjectv)
{ {
GtkWidget *w; GtkWidget *w;
pwr_tStatus sts; pwr_tStatus sts;
pwr_tOid oidv[2];
pwr_tOName anamev[2];
oidv[0] = oid; return new XttSevHistGtk( (void *)this, toplevel, "SevHist", &w, oidv, anamev, onamev,
oidv[1] = pwr_cNOid; sevhistobjectv, sevcli, &sts);
strncpy( anamev[0], aname, sizeof(anamev[0]));
return new XttSevHistGtk( (void *)this, toplevel, "SevHist", &w, oidv, anamev,
sevcli, &sts, sevhistobject);
} }
CoLogin *XttTblGtk::login_new( const char *name, CoLogin *XttTblGtk::login_new( const char *name,
...@@ -487,6 +481,7 @@ XttTblGtk::XttTblGtk( GtkWidget *a_parent_wid, ...@@ -487,6 +481,7 @@ XttTblGtk::XttTblGtk( GtkWidget *a_parent_wid,
itemlist, item_cnt, &brow_widget, &sts); itemlist, item_cnt, &brow_widget, &sts);
tblnav->message_cb = &XttTbl::message; tblnav->message_cb = &XttTbl::message;
tblnav->is_authorized_cb = &XttTbl::is_authorized; tblnav->is_authorized_cb = &XttTbl::is_authorized;
tblnav->command_cb = &XttTbl::command_cb;
gtk_box_pack_start( GTK_BOX(vbox), GTK_WIDGET(menu_bar), FALSE, FALSE, 0); gtk_box_pack_start( GTK_BOX(vbox), GTK_WIDGET(menu_bar), FALSE, FALSE, 0);
gtk_box_pack_start( GTK_BOX(vbox), GTK_WIDGET(tools), FALSE, FALSE, 0); gtk_box_pack_start( GTK_BOX(vbox), GTK_WIDGET(tools), FALSE, FALSE, 0);
......
...@@ -49,7 +49,7 @@ class XttTblGtk : public XttTbl { ...@@ -49,7 +49,7 @@ class XttTblGtk : public XttTbl {
CoWowEntryGtk *cmd_entry; CoWowEntryGtk *cmd_entry;
void message( char severity, char *message); void message( char severity, char *message);
XttSevHist *sevhist_new( pwr_tOid oid, char *aname, bool sevhistobject); XttSevHist *sevhist_new( pwr_tOid *oidv, pwr_tOName *anamev, pwr_tOName *onamev, bool *sevhistobjectv);
CoLogin *login_new( const char *wl_name, CoLogin *login_new( const char *wl_name,
const char *wl_groupname, const char *wl_groupname,
void (* wl_bc_success)( void *), void (* wl_bc_success)( void *),
......
...@@ -77,6 +77,11 @@ void XttTbl::message( void *xtttbl, char severity, const char *message) ...@@ -77,6 +77,11 @@ void XttTbl::message( void *xtttbl, char severity, const char *message)
((XttTbl *)xtttbl)->message( severity, message); ((XttTbl *)xtttbl)->message( severity, message);
} }
int XttTbl::command_cb( void *ctx, char *cmd)
{
return ((XttTbl *)ctx)->command( cmd);
}
int XttTbl::is_authorized( void *ctx, unsigned int access, int msg) int XttTbl::is_authorized( void *ctx, unsigned int access, int msg)
{ {
return ((XttTbl *)ctx)->is_authorized( access, msg); return ((XttTbl *)ctx)->is_authorized( access, msg);
...@@ -120,29 +125,48 @@ void XttTbl::activate_print() ...@@ -120,29 +125,48 @@ void XttTbl::activate_print()
void XttTbl::activate_opensevhist() void XttTbl::activate_opensevhist()
{ {
// sevcli_sHistItem *hi; ItemBase *item;
TblNav_sevhistobject *hi;
if ( !tblnav->get_select( &hi)) { if ( !tblnav->get_select( &item)) {
message( 'E', "Select an storage item"); message( 'E', "Select an storage item");
return; return;
} }
bool sevhistobject = hi->attrnum > 1; switch ( item->type) {
if( !sevhistobject ) { case tblnav_eItemType_Local:
sevhist_new( hi->oid, hi->objectattrlist[0].aname, sevhistobject); case tblnav_eItemType_TreeLocal: {
} TblNav_sevhistobject *hi = &((ItemLocal *)item)->item;
else { pwr_tOid oidv[2] = { hi->oid, pwr_cNOid};
char *s; pwr_tOName anamev[2];
pwr_tAName aname; pwr_tOName onamev[2] = {"", ""};
s = strchr( hi->oname, '.'); bool sevhistobjectv[2] = {hi->attrnum > 1, false};
if ( !s) { if( !sevhistobjectv[0] ) {
//It is a complete object strcpy( anamev[0], hi->objectattrlist[0].aname);
aname[0] = '\0'; sevhist_new( oidv, anamev, onamev, sevhistobjectv);
} }
else { else {
strcpy( aname, s+1); char *s;
pwr_tAName aname;
s = strchr( hi->oname, '.');
if ( !s) {
//It is a complete object
aname[0] = '\0';
}
else {
strcpy( aname, s+1);
}
strcpy( anamev[0], aname);
sevhist_new( oidv, anamev, onamev, sevhistobjectv);
} }
sevhist_new( hi->oid, aname, sevhistobject); break;
}
case tblnav_eItemType_TreeCommand: {
ItemTreeCommand *ci = (ItemTreeCommand *)item;
command( ci->item.command);
break;
}
default: ;
} }
} }
...@@ -167,13 +191,20 @@ void XttTbl::delete_item_yes( void *ctx, void *data) ...@@ -167,13 +191,20 @@ void XttTbl::delete_item_yes( void *ctx, void *data)
void XttTbl::activate_delete_item() void XttTbl::activate_delete_item()
{ {
//sevcli_sHistItem *hi; //sevcli_sHistItem *hi;
ItemBase *item;
TblNav_sevhistobject *hi; TblNav_sevhistobject *hi;
char msg[300]; char msg[300];
if ( !tblnav->get_select( &hi)) { if ( !tblnav->get_select( &item)) {
message( 'E', "Select an storage item");
return;
}
if ( !(item->type == tblnav_eItemType_Local ||
item->type == tblnav_eItemType_TreeLocal)) {
message( 'E', "Select an storage item"); message( 'E', "Select an storage item");
return; return;
} }
hi = &((ItemLocal *)item)->item;
sprintf( msg, "Do you really wan't to delete all stored data for item\n\n%s.%s\n", hi->oname, hi->objectattrlist[0].aname); sprintf( msg, "Do you really wan't to delete all stored data for item\n\n%s.%s\n", hi->oname, hi->objectattrlist[0].aname);
......
...@@ -55,7 +55,8 @@ class XttTbl { ...@@ -55,7 +55,8 @@ class XttTbl {
int quiet; int quiet;
virtual void message( char severity, const char *message) {} virtual void message( char severity, const char *message) {}
virtual XttSevHist *sevhist_new( pwr_tOid oid, char *aname, bool sevhistobject) { return 0;} virtual XttSevHist *sevhist_new( pwr_tOid *oidv, pwr_tOName *anamev, pwr_tOName *onamev,
bool *sevhistobjectv) { return 0;}
virtual CoLogin *login_new( const char *wl_name, virtual CoLogin *login_new( const char *wl_name,
const char *wl_groupname, const char *wl_groupname,
void (* wl_bc_success)( void *), void (* wl_bc_success)( void *),
...@@ -78,6 +79,7 @@ class XttTbl { ...@@ -78,6 +79,7 @@ class XttTbl {
static void message( void *attr, char severity, const char *message); static void message( void *attr, char severity, const char *message);
static int is_authorized( void *ctx, unsigned int access, int msg); static int is_authorized( void *ctx, unsigned int access, int msg);
static int command_cb( void *ctx, char *cmd);
static void delete_item_yes( void *ctx, void *data); static void delete_item_yes( void *ctx, void *data);
virtual ~XttTbl(); virtual ~XttTbl();
......
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
#include "co_error.h" #include "co_error.h"
#include "cow_wow.h" #include "cow_wow.h"
#include "xtt_tbl.h" #include "xtt_tbl.h"
#include "xtt_tblnav.h"
#include "co_dcli_msg.h" #include "co_dcli_msg.h"
#include "cow_xhelp.h" #include "cow_xhelp.h"
#include "cow_login.h" #include "cow_login.h"
...@@ -72,18 +73,25 @@ static int xtttbl_open_func( void *client_data, ...@@ -72,18 +73,25 @@ static int xtttbl_open_func( void *client_data,
void *client_flag); void *client_flag);
static int xtttbl_show_func( void *client_data, static int xtttbl_show_func( void *client_data,
void *client_flag); void *client_flag);
static int xtttbl_create_func( void *client_data,
void *client_flag);
dcli_tCmdTable xtttbl_command_table[] = { dcli_tCmdTable xtttbl_command_table[] = {
{ {
"OPEN", "OPEN",
&xtttbl_open_func, &xtttbl_open_func,
{ "dcli_arg1", ""} { "dcli_arg1", "dcli_arg2", "/NAME", ""}
}, },
{ {
"SHOW", "SHOW",
&xtttbl_show_func, &xtttbl_show_func,
{ "dcli_arg1", ""} { "dcli_arg1", ""}
}, },
{
"CREATE",
&xtttbl_create_func,
{ "dcli_arg1", "/NAME", "/COMMAND", ""}
},
{ {
"EXIT", "EXIT",
&xtttbl_exit_func, &xtttbl_exit_func,
...@@ -360,6 +368,116 @@ static int xtttbl_open_func( void *client_data, ...@@ -360,6 +368,116 @@ static int xtttbl_open_func( void *client_data,
if ( strncmp( arg1_str, "GRAPH", strlen( arg1_str)) == 0) if ( strncmp( arg1_str, "GRAPH", strlen( arg1_str)) == 0)
{ {
} }
else if ( cdh_NoCaseStrncmp( arg1_str, "HISTORY", strlen( arg1_str)) == 0)
{
pwr_tAName name_str;
char *name_ptr;
pwr_tAName name_array[10];
int i, names;
pwr_tOid oidv[11];
pwr_tOName anamev[11];
pwr_tOName onamev[11];
bool sevhistobjectv[11];
int sts;
// Command is "OPEN HISTORY"
/* Get the name qualifier */
if ( ODD( dcli_get_qualifier( "dcli_arg2", name_str, sizeof(name_str)))) {
if ( name_str[0] != '/')
/* Assume that this is the namestring */
name_ptr = name_str;
else {
xtttbl->message('E', "Syntax error");
return XTTTBL__HOLDCOMMAND;
}
}
else {
if ( ODD( dcli_get_qualifier( "/NAME", name_str, sizeof(name_str))))
name_ptr = name_str;
else {
/* Get the selected object */
ItemBase *item;
if ( !xtttbl->tblnav->get_select( &item)) {
xtttbl->message('E', "Enter name or select an object");
return XTTTBL__SUCCESS;
}
xtttbl->activate_opensevhist();
}
}
// The name string can contain several hists separated by ','
names = dcli_parse( name_str, ",", "",
(char *) name_array, sizeof( name_array)/sizeof( name_array[0]),
sizeof( name_array[0]), 0);
for ( i = 0; i < names; i++) {
TblNav_sevhistobject *hi;
if ( i == 10)
break;
sts = xtttbl->tblnav->get_item( name_array[i], &hi);
if ( EVEN(sts)) {
xtttbl->message('E', "Name object not found");
return XTTTBL__SUCCESS;
}
oidv[i] = hi->oid;
if ( hi->attrnum == 1) {
strcpy( anamev[i], hi->objectattrlist[0].aname);
sevhistobjectv[i] = false;
strcpy( onamev[i], hi->oname);
}
else {
strcpy( anamev[i], "");
sevhistobjectv[i] = true;
strcpy( onamev[i], hi->oname);
}
}
oidv[i] = pwr_cNOid;
xtttbl->sevhist_new( oidv, anamev, onamev, sevhistobjectv);
}
else
xtttbl->message('E',"Syntax error");
return XTTTBL__SUCCESS;
}
static int xtttbl_create_func( void *client_data,
void *client_flag)
{
XttTbl *xtttbl = (XttTbl *)client_data;
char arg1_str[80];
int arg1_sts;
arg1_sts = dcli_get_qualifier( "dcli_arg1", arg1_str, sizeof(arg1_str));
if ( strncmp( arg1_str, "ITEM", strlen( arg1_str)) == 0)
{
pwr_tOName name_str;
pwr_tCmd command_str;
// Command is "CREATE ITEM"
if ( EVEN( dcli_get_qualifier( "/NAME", name_str, sizeof(name_str)))) {
xtttbl->message('E', "Enter name");
return XTTTBL__SUCCESS;
}
if ( EVEN( dcli_get_qualifier( "/COMMAND", command_str, sizeof(command_str)))) {
xtttbl->message('E', "Enter command");
return XTTTBL__SUCCESS;
}
xtttbl->tblnav->add_item_command( name_str, command_str);
}
else else
xtttbl->message('E',"Syntax error"); xtttbl->message('E',"Syntax error");
......
This diff is collapsed.
...@@ -49,12 +49,15 @@ ...@@ -49,12 +49,15 @@
#include "rt_sevcli.h" #include "rt_sevcli.h"
#endif #endif
class ItemBase;
typedef enum { typedef enum {
tblnav_eItemType_Local, tblnav_eItemType_Local,
tblnav_eItemType_LocalAttr, tblnav_eItemType_LocalAttr,
tblnav_eItemType_TreeLocal, tblnav_eItemType_TreeLocal,
tblnav_eItemType_TreeNode tblnav_eItemType_TreeNode,
tblnav_eItemType_TreeCommand
} tblnav_eItemType; } tblnav_eItemType;
typedef enum { typedef enum {
...@@ -87,17 +90,30 @@ class TblNav_sevhistobject { ...@@ -87,17 +90,30 @@ class TblNav_sevhistobject {
vector<TblNav_sevhistobjectattr> objectattrlist; vector<TblNav_sevhistobjectattr> objectattrlist;
}; };
class TblNav_command {
public:
pwr_tAName oname;
pwr_tCmd command;
};
typedef enum {
tblnav_eTreeItemType_No,
tblnav_eTreeItemType_SevHist,
tblnav_eTreeItemType_Command
} tblnav_eTreeItemType;
class TblTreeNode { class TblTreeNode {
public: public:
TblTreeNode() : fth(0), fch(0), fws(0), bws(0), item(0), deleted(0) TblTreeNode() : fth(0), fch(0), fws(0), bws(0), type(tblnav_eTreeItemType_No), idx(0), deleted(0)
{ strcpy( sname, "");} { strcpy( sname, "");}
int fth; int fth;
int fch; int fch;
int fws; int fws;
int bws; int bws;
char sname[80]; char sname[80];
TblNav_sevhistobject *item; tblnav_eTreeItemType type;
int idx;
int deleted; int deleted;
}; };
...@@ -138,9 +154,11 @@ class TblNav { ...@@ -138,9 +154,11 @@ class TblNav {
TblNavBrow *brow; TblNavBrow *brow;
sevcli_sHistItem *itemlist; sevcli_sHistItem *itemlist;
vector<TblNav_sevhistobject> sevhistobjectlist; vector<TblNav_sevhistobject> sevhistobjectlist;
vector<TblNav_command> commandlist;
int item_cnt; int item_cnt;
void (*message_cb)( void *, char, const char *); void (*message_cb)( void *, char, const char *);
int (*is_authorized_cb)( void *, unsigned int, int); int (*is_authorized_cb)( void *, unsigned int, int);
int (*command_cb)( void *, char *cmd);
vector<TblTreeNode> tree; vector<TblTreeNode> tree;
int list_layout; int list_layout;
...@@ -148,7 +166,9 @@ class TblNav { ...@@ -148,7 +166,9 @@ class TblNav {
int is_authorized( unsigned int access = pwr_mAccess_AllSev, int msg = 1); int is_authorized( unsigned int access = pwr_mAccess_AllSev, int msg = 1);
int create_items(); int create_items();
void build_tree(); void build_tree();
int get_select( TblNav_sevhistobject **hi); void tree_add( char *name, int list_index, tblnav_eTreeItemType type);
int get_select( ItemBase **item);
int get_item( char *oname, TblNav_sevhistobject **hi);
void get_zoom( double *zoom_factor); void get_zoom( double *zoom_factor);
void zoom( double zoom_factor); void zoom( double zoom_factor);
void unzoom(); void unzoom();
...@@ -158,6 +178,8 @@ class TblNav { ...@@ -158,6 +178,8 @@ class TblNav {
void create_objectlist( sevcli_sHistItem *xn_itemlist, void create_objectlist( sevcli_sHistItem *xn_itemlist,
int xn_item_cnt, int xn_item_cnt,
pwr_tStatus *status); pwr_tStatus *status);
void add_item_command( char *name, char *command);
virtual void message( char sev, const char *text); virtual void message( char sev, const char *text);
virtual void set_inputfocus() {} virtual void set_inputfocus() {}
static int init_brow_cb( FlowCtx *fctx, void *client_data); static int init_brow_cb( FlowCtx *fctx, void *client_data);
...@@ -220,5 +242,17 @@ class ItemTreeNode : public ItemBase { ...@@ -220,5 +242,17 @@ class ItemTreeNode : public ItemBase {
}; };
//! Item for a command object.
class ItemTreeCommand : public ItemBase {
public:
ItemTreeCommand( TblNav *tblnav, TblNav_command *xitem, int index, brow_tNode dest, flow_eDest dest_code);
virtual ~ItemTreeCommand() {}
TblNav_command item;
int idx;
brow_tNode node;
};
#endif #endif
...@@ -348,7 +348,7 @@ int sevcli_get_itemdata( pwr_tStatus *sts, sevcli_tCtx ctx, pwr_tOid oid, ...@@ -348,7 +348,7 @@ int sevcli_get_itemdata( pwr_tStatus *sts, sevcli_tCtx ctx, pwr_tOid oid,
*sts = rmsg->Status; *sts = rmsg->Status;
if ( EVEN(*sts)) { if ( EVEN(*sts)) {
qcom_Free( sts, rmsg); qcom_Free( &lsts, rmsg);
return 0; return 0;
} }
...@@ -363,7 +363,7 @@ int sevcli_get_itemdata( pwr_tStatus *sts, sevcli_tCtx ctx, pwr_tOid oid, ...@@ -363,7 +363,7 @@ int sevcli_get_itemdata( pwr_tStatus *sts, sevcli_tCtx ctx, pwr_tOid oid,
*vtype = rmsg->VType; *vtype = rmsg->VType;
*vsize = rmsg->VSize; *vsize = rmsg->VSize;
qcom_Free( sts, rmsg); qcom_Free( &lsts, rmsg);
*sts = SEV__SUCCESS; *sts = SEV__SUCCESS;
return 1; return 1;
......
...@@ -134,6 +134,7 @@ static pwr_tStatus SyntaxCheck ( ...@@ -134,6 +134,7 @@ static pwr_tStatus SyntaxCheck (
pwr_tOid thread_oid; pwr_tOid thread_oid;
wb_session *sp = (wb_session *)Session; wb_session *sp = (wb_session *)Session;
pwr_tAttrRef dataname_aref; pwr_tAttrRef dataname_aref;
pwr_tDeltaTime storagetime;
wb_attribute a = sp->attribute( &Object); wb_attribute a = sp->attribute( &Object);
if ( !a) return a.sts(); if ( !a) return a.sts();
...@@ -151,6 +152,16 @@ static pwr_tStatus SyntaxCheck ( ...@@ -151,6 +152,16 @@ static pwr_tStatus SyntaxCheck (
else if ( othread.cid() != pwr_cClass_SevHistThread) else if ( othread.cid() != pwr_cClass_SevHistThread)
wsx_error_msg_str( Session, "Bad thread object class", Object, 'E', ErrorCount, WarningCount); wsx_error_msg_str( Session, "Bad thread object class", Object, 'E', ErrorCount, WarningCount);
// Check StorageTime
wb_attribute storagetime_a( a, 0, "StorageTime");
if (!storagetime_a) return storagetime_a.sts();
storagetime_a.value( &storagetime);
if ( !storagetime_a) return storagetime_a.sts();
if ( storagetime.tv_sec == 0 && storagetime.tv_nsec == 0)
wsx_error_msg_str( Session, "Bad StorageTime", Object, 'E', ErrorCount, WarningCount);
// Check Attribute // Check Attribute
wb_attribute dataname_a( a, 0, "Attribute"); wb_attribute dataname_a( a, 0, "Attribute");
if (!dataname_a) return dataname_a.sts(); if (!dataname_a) return dataname_a.sts();
......
...@@ -71,6 +71,8 @@ static pwr_tStatus SyntaxCheck ( ...@@ -71,6 +71,8 @@ static pwr_tStatus SyntaxCheck (
) { ) {
pwr_tOid thread_oid; pwr_tOid thread_oid;
wb_session *sp = (wb_session *)Session; wb_session *sp = (wb_session *)Session;
pwr_tAttrRef dataname_aref;
pwr_tDeltaTime storagetime;
wb_attribute a = sp->attribute( &Object); wb_attribute a = sp->attribute( &Object);
if ( !a) return a.sts(); if ( !a) return a.sts();
...@@ -88,6 +90,28 @@ static pwr_tStatus SyntaxCheck ( ...@@ -88,6 +90,28 @@ static pwr_tStatus SyntaxCheck (
else if ( othread.cid() != pwr_cClass_SevHistThread) else if ( othread.cid() != pwr_cClass_SevHistThread)
wsx_error_msg_str( Session, "Bad thread object class", Object, 'E', ErrorCount, WarningCount); wsx_error_msg_str( Session, "Bad thread object class", Object, 'E', ErrorCount, WarningCount);
// Check StorageTime
wb_attribute storagetime_a( a, 0, "StorageTime");
if (!storagetime_a) return storagetime_a.sts();
storagetime_a.value( &storagetime);
if ( !storagetime_a) return storagetime_a.sts();
if ( storagetime.tv_sec == 0 && storagetime.tv_nsec == 0)
wsx_error_msg_str( Session, "Bad StorageTime", Object, 'E', ErrorCount, WarningCount);
// Check Attribute
wb_attribute dataname_a( a, 0, "Attribute");
if (!dataname_a) return dataname_a.sts();
dataname_a.value( &dataname_aref);
if ( !dataname_a) return dataname_a.sts();
wb_attribute data_a = sp->attribute( &dataname_aref);
if ( !data_a) {
wsx_error_msg_str( Session, "Bad Attribute reference", Object, 'E', ErrorCount, WarningCount);
return PWRB__SUCCESS;
}
return PWRB__SUCCESS; return PWRB__SUCCESS;
} }
......
...@@ -527,8 +527,8 @@ GeCurveGtk::GeCurveGtk( void *gc_parent_ctx, ...@@ -527,8 +527,8 @@ GeCurveGtk::GeCurveGtk( void *gc_parent_ctx,
gtk_paned_add2( GTK_PANED(vpaned1), vpaned2); gtk_paned_add2( GTK_PANED(vpaned1), vpaned2);
gtk_widget_show_all( vpaned1); gtk_widget_show_all( vpaned1);
gtk_paned_add1( GTK_PANED(vpaned2), hbox); gtk_paned_pack1( GTK_PANED(vpaned2), hbox, TRUE, TRUE);
gtk_paned_add2( GTK_PANED(vpaned2), nav_widget); gtk_paned_pack2( GTK_PANED(vpaned2), nav_widget, FALSE, TRUE);
gtk_widget_show_all( vpaned2); gtk_widget_show_all( vpaned2);
GtkWidget *vbox = gtk_vbox_new( FALSE, 0); GtkWidget *vbox = gtk_vbox_new( FALSE, 0);
......
This diff is collapsed.
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
typedef enum { typedef enum {
curve_eDataType_LogFile, curve_eDataType_LogFile,
curve_eDataType_DsTrend, curve_eDataType_DsTrend,
curve_eDataType_MultiTrend,
curve_eDataType_ODBC curve_eDataType_ODBC
} curve_eDataType; } curve_eDataType;
...@@ -56,7 +57,7 @@ class GeCurveData { ...@@ -56,7 +57,7 @@ class GeCurveData {
public: public:
GeCurveData( curve_eDataType datatype); GeCurveData( curve_eDataType datatype);
curve_eDataType type; curve_eDataType type;
int rows; int rows[CURVE_MAX_COLS];
int cols; int cols;
pwr_tAName y_name[CURVE_MAX_COLS]; pwr_tAName y_name[CURVE_MAX_COLS];
pwr_tAName x_name; pwr_tAName x_name;
......
...@@ -1979,7 +1979,7 @@ typedef enum { ...@@ -1979,7 +1979,7 @@ typedef enum {
typedef struct { typedef struct {
glow_eCurveDataType type; glow_eCurveDataType type;
int curves; //!< Number of curves int curves; //!< Number of curves
int rows; //!< Number of points int rows[TREND_MAX_CURVES]; //!< Number of points
int x_reverse; //!< Reverse the curves when drawing them int x_reverse; //!< Reverse the curves when drawing them
double y_max_value[TREND_MAX_CURVES]; //!< Max value for every curve double y_max_value[TREND_MAX_CURVES]; //!< Max value for every curve
double x_max_value[TREND_MAX_CURVES]; //!< Max value for every curve double x_max_value[TREND_MAX_CURVES]; //!< Max value for every curve
......
...@@ -65,7 +65,7 @@ void GrowCurve::configure_curves( glow_sCurveData *data) ...@@ -65,7 +65,7 @@ void GrowCurve::configure_curves( glow_sCurveData *data)
if ( data->type == glow_eCurveDataType_CommonX) { if ( data->type == glow_eCurveDataType_CommonX) {
curve_cnt = data->curves; curve_cnt = data->curves;
no_of_points = data->rows; no_of_points = data->rows[0];
for ( i = 0; i < curve_cnt; i++) { for ( i = 0; i < curve_cnt; i++) {
y_max_value[i] = data->y_max_value[i]; y_max_value[i] = data->y_max_value[i];
...@@ -162,6 +162,111 @@ void GrowCurve::configure_curves( glow_sCurveData *data) ...@@ -162,6 +162,111 @@ void GrowCurve::configure_curves( glow_sCurveData *data)
} }
free( (char *) pointarray); free( (char *) pointarray);
draw();
}
else if ( data->type == glow_eCurveDataType_SeparateX) {
curve_cnt = data->curves;
no_of_points = data->rows[0];
for ( i = 0; i < curve_cnt; i++) {
y_max_value[i] = data->y_max_value[i];
y_min_value[i] = data->y_min_value[i];
curve_drawtype[i] = data->color[i];
curve_fill_drawtype[i] = data->fillcolor[i];
}
curve_width = min( DRAW_TYPE_SIZE, max( 1, curve_width));
for ( idx = 0; idx < curve_cnt; idx++) {
points = data->rows[idx];
if ( fill_curve)
points += 2;
pointarray = (glow_sPoint *) calloc( points, sizeof(glow_sPoint));
point_p = pointarray;
for ( i = 0; i < points; i++) {
if ( !fill_curve) {
if ( data->x_reverse)
x_value = ur.x - (data->x_data[idx][i] - data->x_min_value[idx]) /
(data->x_max_value[idx] - data->x_min_value[idx]) * (ur.x - ll.x);
else
x_value = ll.x + (data->x_data[idx][i] - data->x_min_value[idx]) /
(data->x_max_value[idx] - data->x_min_value[idx]) * (ur.x - ll.x);
x_value = max( ll.x, min( x_value, ur.x));
y_value = ur.y - (data->y_data[idx][i] - y_min_value[idx]) /
(y_max_value[idx] - y_min_value[idx]) * (ur.y - ll.y);
y_value = max( ll.y, min( y_value, ur.y));
point_p->y = y_value;
point_p->x = x_value;
}
else {
if ( i == 0) {
point_p->y = ur.y;
// point_p->x = ur.x;
if ( data->x_reverse)
point_p->x = ur.x - (data->x_data[idx][i] - data->x_min_value[idx]) /
(data->x_max_value[idx] - data->x_min_value[idx]) * (ur.x - ll.x);
else
point_p->x = ll.x + (data->x_data[0][i] - data->x_min_value[0]) /
(data->x_max_value[idx] - data->x_min_value[idx]) * (ur.x - ll.x);
}
else if ( i == points - 1) {
point_p->y = ur.y;
if ( data->x_reverse)
point_p->x = ur.x - (data->x_data[0][i-2] - data->x_min_value[0]) /
(data->x_max_value[idx] - data->x_min_value[idx]) * (ur.x - ll.x);
else
point_p->x = ll.x + (data->x_data[0][i-2] - data->x_min_value[0]) /
(data->x_max_value[idx] - data->x_min_value[idx]) * (ur.x - ll.x);
// point_p->x = ll.x;
}
else {
if ( data->x_reverse)
x_value = ur.x - (data->x_data[idx][i-1] - data->x_min_value[idx]) /
(data->x_max_value[idx] - data->x_min_value[idx]) * (ur.x - ll.x);
else
x_value = ll.x + (data->x_data[idx][i-1] - data->x_min_value[idx]) /
(data->x_max_value[idx] - data->x_min_value[idx]) * (ur.x - ll.x);
x_value = max( ll.x, min( x_value, ur.x));
y_value = ur.y - (data->y_data[idx][i-1] - y_min_value[idx]) /
(y_max_value[idx] - y_min_value[idx]) * (ur.y - ll.y);
y_value = max( ll.y, min( y_value, ur.y));
point_p->y = y_value;
point_p->x = x_value;
}
}
point_p++;
}
if ( curve_drawtype[idx] != glow_eDrawType_Inherit)
dt = curve_drawtype[idx];
else
dt = draw_type;
if ( curve_fill_drawtype[idx] != glow_eDrawType_Inherit)
dt_fill = curve_fill_drawtype[idx];
else
dt_fill = draw_type;
ctx->nodraw++;
curve[idx] = new GrowPolyLine( ctx, "", pointarray, points, dt,
curve_width,
0, fill_curve, 1, 0, dt_fill);
ctx->nodraw--;
free( (char *) pointarray);
}
draw(); draw();
} }
} }
......
...@@ -45,14 +45,17 @@ ...@@ -45,14 +45,17 @@
XttSevHistGtk::XttSevHistGtk( void *parent_ctx, XttSevHistGtk::XttSevHistGtk( void *parent_ctx,
GtkWidget *parent_wid, GtkWidget *parent_wid,
const char *name, const char *name,
GtkWidget **w, GtkWidget **w,
pwr_tOid *xn_oid, pwr_tOid *xn_oidv,
pwr_tOName *xn_aname, pwr_tOName *xn_anamev,
sevcli_tCtx xn_scctx, pwr_tOName *xn_onamev,
int *sts, bool sevhistobject) : bool *sevhistobjectv,
XttSevHist( parent_ctx, name, xn_oid, xn_aname, xn_scctx, sts, sevhistobject), parent_widget(parent_wid) sevcli_tCtx xn_scctx,
int *sts) :
XttSevHist( parent_ctx, name, xn_oidv, xn_anamev, xn_onamev, sevhistobjectv, xn_scctx, sts),
parent_widget(parent_wid)
{ {
char title[250]; char title[250];
strncpy(title, name, sizeof(title)); strncpy(title, name, sizeof(title));
......
...@@ -31,14 +31,15 @@ class XttSevHistGtk : public XttSevHist { ...@@ -31,14 +31,15 @@ class XttSevHistGtk : public XttSevHist {
GtkWidget *parent_widget; //!< Parent widget. GtkWidget *parent_widget; //!< Parent widget.
XttSevHistGtk( void *xn_parent_ctx, XttSevHistGtk( void *xn_parent_ctx,
GtkWidget *xn_parent_wid, GtkWidget *xn_parent_wid,
const char *xn_name, const char *xn_name,
GtkWidget **w, GtkWidget **w,
pwr_tOid *xn_oid, pwr_tOid *xn_oidv,
pwr_tOName *xn_aname, pwr_tOName *xn_anamev,
sevcli_tCtx xn_scctx, pwr_tOName *xn_onamev,
int *sts, bool *sevhistobjectv,
bool sevhistobject); sevcli_tCtx xn_scctx,
int *sts);
~XttSevHistGtk(); ~XttSevHistGtk();
}; };
......
...@@ -223,12 +223,12 @@ XttTrend *XNavGtk::xtttrend_new( char *name, pwr_tAttrRef *objar, pwr_tAttrRef * ...@@ -223,12 +223,12 @@ XttTrend *XNavGtk::xtttrend_new( char *name, pwr_tAttrRef *objar, pwr_tAttrRef *
return new XttTrendGtk( this, parent_wid, name, &w, objar, plotgroup, sts); return new XttTrendGtk( this, parent_wid, name, &w, objar, plotgroup, sts);
} }
XttSevHist *XNavGtk::xttsevhist_new( char *name, pwr_tOid *oid, pwr_tOName *aname, XttSevHist *XNavGtk::xttsevhist_new( char *name, pwr_tOid *oidv, pwr_tOName *anamev, pwr_tOName *onamev,
sevcli_tCtx scctx, pwr_tStatus *sts, bool sevhistobject) bool *sevhistobjectv, sevcli_tCtx scctx, pwr_tStatus *sts)
{ {
GtkWidget *w; GtkWidget *w;
return new XttSevHistGtk( this, parent_wid, name, &w, oid, aname, scctx, sts, sevhistobject); return new XttSevHistGtk( this, parent_wid, name, &w, oidv, anamev, onamev, sevhistobjectv, scctx, sts);
} }
XttFast *XNavGtk::xttfast_new( char *name, pwr_tAttrRef *objar, pwr_tStatus *sts) XttFast *XNavGtk::xttfast_new( char *name, pwr_tAttrRef *objar, pwr_tStatus *sts)
......
...@@ -58,8 +58,9 @@ class XNavGtk : public XNav { ...@@ -58,8 +58,9 @@ class XNavGtk : public XNav {
Op *op_new( char *opplace, pwr_tStatus *sts); Op *op_new( char *opplace, pwr_tStatus *sts);
XttTrend *xtttrend_new( char *name, pwr_tAttrRef *objar, pwr_tAttrRef *plotgroup, XttTrend *xtttrend_new( char *name, pwr_tAttrRef *objar, pwr_tAttrRef *plotgroup,
pwr_tStatus *sts); pwr_tStatus *sts);
XttSevHist *xttsevhist_new( char *name, pwr_tOid *oid, pwr_tOName *aname, XttSevHist *xttsevhist_new( char *name, pwr_tOid *oidv, pwr_tOName *anamev,
sevcli_tCtx scctx, pwr_tStatus *sts, bool sevhistobject=false); pwr_tOName *onamev, bool *sevhistobjectv, sevcli_tCtx scctx,
pwr_tStatus *sts);
XttFast *xttfast_new( char *name, pwr_tAttrRef *objar, pwr_tStatus *sts); XttFast *xttfast_new( char *name, pwr_tAttrRef *objar, pwr_tStatus *sts);
XAttOne *xattone_new( pwr_tAttrRef *objar, char *title, unsigned int priv, XAttOne *xattone_new( pwr_tAttrRef *objar, char *title, unsigned int priv,
pwr_tStatus *sts); pwr_tStatus *sts);
......
...@@ -152,9 +152,9 @@ XttFast::XttFast( void *parent_ctx, ...@@ -152,9 +152,9 @@ XttFast::XttFast( void *parent_ctx,
default: default:
element_size[i] = 4; element_size[i] = 4;
} }
gcd->rows[i] = max_points;
} }
gcd->cols = fast_cnt; gcd->cols = fast_cnt;
gcd->rows = max_points;
axis_configured = true; axis_configured = true;
for ( i = 0; i < FAST_CURVES; i++) { for ( i = 0; i < FAST_CURVES; i++) {
......
This diff is collapsed.
...@@ -66,22 +66,26 @@ class XttSevHist { ...@@ -66,22 +66,26 @@ class XttSevHist {
void (*close_cb)( void *, XttSevHist *); //!< Close callback to parent. void (*close_cb)( void *, XttSevHist *); //!< Close callback to parent.
void (*help_cb)( void *, const char *); //!< Open help window. void (*help_cb)( void *, const char *); //!< Open help window.
bool first_scan; //!< Indicates that this is the first scan. bool first_scan; //!< Indicates that this is the first scan.
char title[250]; //!< Window title char title[250]; //!< Window title
sevcli_tCtx scctx; sevcli_tCtx scctx;
pwr_tOName aname; pwr_tOName anamev[XTT_SEVHIST_MAX];
pwr_tOid oid; pwr_tOName onamev[XTT_SEVHIST_MAX];
pwr_tOid oidv[XTT_SEVHIST_MAX];
int oid_cnt;
CoWow *wow; CoWow *wow;
long int time_low_old; long int time_low_old;
long int time_high_old; long int time_high_old;
bool sevhistobject; //!< Indicates that it is a SevHistObject bool sevhistobjectv[XTT_SEVHIST_MAX]; //!< Indicates that it is a SevHistObject
//! Constructor //! Constructor
XttSevHist( void *xn_parent_ctx, XttSevHist( void *xn_parent_ctx,
const char *xn_name, const char *xn_name,
pwr_tOid* xn_oid, pwr_tOid* xn_oidv,
pwr_tOName *xn_aname, pwr_tOName *xn_aname,
pwr_tOName *xn_oname,
bool *sevhistobjectv,
sevcli_tCtx xn_scctx, sevcli_tCtx xn_scctx,
int *sts, bool sevhistobject); int *sts);
//! Destructor //! Destructor
virtual ~XttSevHist(); virtual ~XttSevHist();
...@@ -90,6 +94,7 @@ class XttSevHist { ...@@ -90,6 +94,7 @@ class XttSevHist {
void pop(); void pop();
int get_data( pwr_tStatus *sts, pwr_tTime from, pwr_tTime to); int get_data( pwr_tStatus *sts, pwr_tTime from, pwr_tTime to);
int get_objectdata( pwr_tStatus *sts, pwr_tTime from, pwr_tTime to); int get_objectdata( pwr_tStatus *sts, pwr_tTime from, pwr_tTime to);
int get_multidata( pwr_tStatus *sts, pwr_tTime from, pwr_tTime to);
static void sevhist_close_cb( void *ctx); static void sevhist_close_cb( void *ctx);
static void sevhist_higher_res_cb( void *ctx); static void sevhist_higher_res_cb( void *ctx);
......
...@@ -227,9 +227,9 @@ XttTrend::XttTrend( void *parent_ctx, ...@@ -227,9 +227,9 @@ XttTrend::XttTrend( void *parent_ctx,
default: default:
element_size[i] = 4; element_size[i] = 4;
} }
gcd->rows[i] = max_points;
} }
gcd->cols = trend_cnt; gcd->cols = trend_cnt;
gcd->rows = max_points;
gcd->x_reverse = 1; gcd->x_reverse = 1;
gcd->get_borders(); gcd->get_borders();
gcd->get_default_axis(); gcd->get_default_axis();
......
...@@ -341,8 +341,9 @@ class XNav { ...@@ -341,8 +341,9 @@ class XNav {
virtual Op *op_new( char *opplace, pwr_tStatus *sts) {return 0;} virtual Op *op_new( char *opplace, pwr_tStatus *sts) {return 0;}
virtual XttTrend *xtttrend_new( char *name, pwr_tAttrRef *objar, pwr_tAttrRef *plotgroup, virtual XttTrend *xtttrend_new( char *name, pwr_tAttrRef *objar, pwr_tAttrRef *plotgroup,
pwr_tStatus *sts) {return 0;} pwr_tStatus *sts) {return 0;}
virtual XttSevHist *xttsevhist_new( char *name, pwr_tOid *oid, pwr_tOName *aname, virtual XttSevHist *xttsevhist_new( char *name, pwr_tOid *oidv, pwr_tOName *aname,
sevcli_tCtx scctx, pwr_tStatus *sts, bool sevhistobject=false) {return 0;} pwr_tOName *oname, bool *sevhistobjectv, sevcli_tCtx scctx,
pwr_tStatus *sts) {return 0;}
virtual XttFast *xttfast_new( char *name, pwr_tAttrRef *objar, pwr_tStatus *sts) {return 0;} virtual XttFast *xttfast_new( char *name, pwr_tAttrRef *objar, pwr_tStatus *sts) {return 0;}
virtual XAttOne *xattone_new( pwr_tAttrRef *objar, char *title, unsigned int priv, virtual XAttOne *xattone_new( pwr_tAttrRef *objar, char *title, unsigned int priv,
pwr_tStatus *sts) {return 0;} pwr_tStatus *sts) {return 0;}
......
...@@ -3109,6 +3109,9 @@ static int xnav_open_func( void *client_data, ...@@ -3109,6 +3109,9 @@ static int xnav_open_func( void *client_data,
char server_node[40]; char server_node[40];
pwr_tOid oidv[11]; pwr_tOid oidv[11];
pwr_tOName anamev[11]; pwr_tOName anamev[11];
pwr_tOName onamev[11];
bool sevhistobjectv[11];
int oid_cnt = 0;
int sts; int sts;
pwr_tAName name_array[10]; pwr_tAName name_array[10];
int i, names; int i, names;
...@@ -3177,22 +3180,100 @@ static int xnav_open_func( void *client_data, ...@@ -3177,22 +3180,100 @@ static int xnav_open_func( void *client_data,
if (EVEN(sts)) return sts; if (EVEN(sts)) return sts;
switch ( classid) { switch ( classid) {
case pwr_cClass_SevHist: case pwr_cClass_SevHist:
break; break;
case pwr_cClass_SevHistObject: case pwr_cClass_SevHistObject:
sevHistObjectFound = true; sevHistObjectFound = true;
break; break;
case pwr_cClass_PlotGroup: case pwr_cClass_PlotGroup:
xnav->message('E', "Not yet implemented"); plotgroup = sevhist_aref;
return XNAV__HOLDCOMMAND; plotgroup_found = 1;
default: break;
xnav->message('E', "Error in object class"); default:
return XNAV__HOLDCOMMAND; xnav->message('E', "Error in object class");
return XNAV__HOLDCOMMAND;
} }
if ( plotgroup_found)
break;
if( sevHistObjectFound ) { if ( plotgroup_found) {
pwr_sClass_PlotGroup plot;
pwr_tCid cid;
int j;
sts = gdh_GetObjectInfo( hist_name, &plot, sizeof(plot));
if ( EVEN(sts)) return sts;
for ( j = 0; j < 20; j++) {
if ( cdh_ObjidIsNull( plot.YObjectName[j].Objid))
break;
sevhist_aref = plot.YObjectName[j];
sts = gdh_GetAttrRefTid( &sevhist_aref, &cid);
if ( EVEN(sts)) return sts;
switch ( cid) {
case pwr_cClass_SevHist: {
sts = gdh_ArefANameToAref( &sevhist_aref, "Attribute", &attr_aref);
if ( EVEN(sts)) return sts;
sts = gdh_GetObjectInfoAttrref( &attr_aref, &aref, sizeof(aref));
if ( EVEN(sts)) return sts;
sts = gdh_AttrrefToName( &aref, aname, sizeof(aname), cdh_mNName);
if ( EVEN(sts)) {
xnav->message('E', "Error in SevHist configuration");
return XNAV__HOLDCOMMAND;
}
s = strchr( aname, '.');
if ( !s) {
xnav->message('E', "Error in SevHist configuration");
return XNAV__HOLDCOMMAND;
}
*s = 0;
strcpy( onamev[oid_cnt], aname);
strcpy( anamev[oid_cnt], s+1);
oidv[oid_cnt] = aref.Objid;
sevhistobjectv[oid_cnt] = false;
oid_cnt++;
break;
}
case pwr_cClass_SevHistObject: {
sts = gdh_ArefANameToAref( &sevhist_aref, "Object", &attr_aref);
if ( EVEN(sts)) return sts;
sts = gdh_GetObjectInfoAttrref( &attr_aref, &aref, sizeof(aref));
if ( EVEN(sts)) return sts;
sts = gdh_AttrrefToName( &aref, aname, sizeof(aname), cdh_mNName);
if ( EVEN(sts)) {
xnav->message('E', "Error in SevHist configuration");
return XNAV__HOLDCOMMAND;
}
s = strchr( aname, '.');
if ( !s) {
//It is a complete object
anamev[oid_cnt][0] = '\0';
}
else {
strcpy( anamev[oid_cnt], s+1);
*s = 0;
}
strcpy( onamev[oid_cnt], aname);
oidv[oid_cnt] = aref.Objid;
sevhistobjectv[oid_cnt] = true;
oid_cnt++;
break;
}
default: ;
}
}
if ( oid_cnt == 0) {
xnav->message('E', "History objects in PlotGroup not found");
return XNAV__SUCCESS;
}
}
else if ( sevHistObjectFound ) {
sts = gdh_ArefANameToAref( &sevhist_aref, "Object", &attr_aref); sts = gdh_ArefANameToAref( &sevhist_aref, "Object", &attr_aref);
if ( EVEN(sts)) return sts; if ( EVEN(sts)) return sts;
...@@ -3207,12 +3288,15 @@ static int xnav_open_func( void *client_data, ...@@ -3207,12 +3288,15 @@ static int xnav_open_func( void *client_data,
s = strchr( aname, '.'); s = strchr( aname, '.');
if ( !s) { if ( !s) {
//It is a complete object //It is a complete object
anamev[i][0] = '\0'; anamev[oid_cnt][0] = '\0';
} }
else { else {
strcpy( anamev[i], s+1); strcpy( anamev[oid_cnt], s+1);
} }
oidv[i] = aref.Objid; oidv[oid_cnt] = aref.Objid;
sevhistobjectv[oid_cnt] = true;
strcpy( onamev[oid_cnt], "");
oid_cnt++;
} }
else { else {
sts = gdh_ArefANameToAref( &sevhist_aref, "Attribute", &attr_aref); sts = gdh_ArefANameToAref( &sevhist_aref, "Attribute", &attr_aref);
...@@ -3232,8 +3316,11 @@ static int xnav_open_func( void *client_data, ...@@ -3232,8 +3316,11 @@ static int xnav_open_func( void *client_data,
return XNAV__HOLDCOMMAND; return XNAV__HOLDCOMMAND;
} }
strcpy( anamev[i], s+1); strcpy( anamev[oid_cnt], s+1);
oidv[i] = aref.Objid; oidv[oid_cnt] = aref.Objid;
sevhistobjectv[oid_cnt] = false;
strcpy( onamev[oid_cnt], "");
oid_cnt++;
} }
// Get server and connect to server // Get server and connect to server
...@@ -3260,7 +3347,7 @@ static int xnav_open_func( void *client_data, ...@@ -3260,7 +3347,7 @@ static int xnav_open_func( void *client_data,
sevcli_set_servernode( &sts, xnav->scctx, server_node); sevcli_set_servernode( &sts, xnav->scctx, server_node);
if ( EVEN(sts)) return sts; if ( EVEN(sts)) return sts;
} }
oidv[i] = pwr_cNOid; oidv[oid_cnt] = pwr_cNOid;
if ( EVEN( dcli_get_qualifier( "/TITLE", title_str, sizeof(title_str)))) { if ( EVEN( dcli_get_qualifier( "/TITLE", title_str, sizeof(title_str)))) {
if ( plotgroup_found) { if ( plotgroup_found) {
...@@ -3277,17 +3364,19 @@ static int xnav_open_func( void *client_data, ...@@ -3277,17 +3364,19 @@ static int xnav_open_func( void *client_data,
} }
if ( plotgroup_found) { if ( plotgroup_found) {
xnav->message('E', "Not yet implemented"); hist = xnav->xttsevhist_new( title_str, oidv, anamev, onamev, sevhistobjectv, xnav->scctx, &sts);
return XNAV__HOLDCOMMAND; if ( ODD(sts)) {
hist->help_cb = xnav_sevhist_help_cb;
}
} }
else if( sevHistObjectFound ) { else if( sevHistObjectFound ) {
hist = xnav->xttsevhist_new( title_str, oidv, anamev, xnav->scctx, &sts, true); hist = xnav->xttsevhist_new( title_str, oidv, anamev, onamev, sevhistobjectv, xnav->scctx, &sts);
if ( ODD(sts)) { if ( ODD(sts)) {
hist->help_cb = xnav_sevhist_help_cb; hist->help_cb = xnav_sevhist_help_cb;
} }
} }
else { else {
hist = xnav->xttsevhist_new( title_str, oidv, anamev, xnav->scctx, &sts); hist = xnav->xttsevhist_new( title_str, oidv, anamev, onamev, sevhistobjectv, xnav->scctx, &sts);
if ( ODD(sts)) { if ( ODD(sts)) {
hist->help_cb = xnav_sevhist_help_cb; hist->help_cb = xnav_sevhist_help_cb;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment