Project

General

Profile

Statistics
| Branch: | Revision:

root / src / tkenv / inspector.cc @ e1750c09

History | View | Annotate | Download (10.5 KB)

1 01873262 Georg Kunz
//==========================================================================
2
//  INSPECTOR.CC - part of
3
//
4
//                     OMNeT++/OMNEST
5
//            Discrete System Simulation in C++
6
//
7
//  Implementation of
8
//    inspectors
9
//
10
//==========================================================================
11
12
/*--------------------------------------------------------------*
13
  Copyright (C) 1992-2008 Andras Varga
14
  Copyright (C) 2006-2008 OpenSim Ltd.
15

16
  This file is distributed WITHOUT ANY WARRANTY. See the file
17
  `license' for details on this and other legal matters.
18
*--------------------------------------------------------------*/
19
20
#include <string.h>
21
#include <math.h>
22
#include <assert.h>
23
24
#include "omnetpp.h"
25
#include "tkenv.h"
26
#include "tklib.h"
27
#include "inspector.h"
28
29
USING_NAMESPACE
30
31
//
32
// Inspector type code <--> string conversions
33
//
34
struct InspTypeName {int code; const char *namestr;} insp_typenames[] =
35
{
36
     { INSP_DEFAULT,          "(default)"     },
37
     { INSP_OBJECT,           "As Object"     },
38
     { INSP_GRAPHICAL,        "As Graphics"   },
39
     { INSP_MODULEOUTPUT,     "Module output" },
40
     { -1,                     NULL           }
41
};
42
43
const char *insptypeNameFromCode(int code)
44
{
45
   for (int i=0; insp_typenames[i].namestr!=NULL; i++)
46
      if (insp_typenames[i].code == code)
47
         return insp_typenames[i].namestr;
48
   return NULL;
49
}
50
51
int insptypeCodeFromName(const char *namestr)
52
{
53
   for (int i=0; insp_typenames[i].namestr!=NULL; i++)
54
      if (strcmp(insp_typenames[i].namestr, namestr)==0)
55
         return insp_typenames[i].code;
56
   return -1;
57
}
58
59
//=================================================================
60
// a utility function:
61
62
void splitInspectorName(const char *namestr, cObject *&object, int& type)
63
{
64
   // namestr is the window path name, sth like ".ptr80005a31-2"
65
   // split it into pointer string ("ptr80005a31") and inspector type ("2")
66
   assert(namestr!=0); // must exist
67
   assert(namestr[0]=='.');  // must begin with a '.'
68
69
   // find '-' and temporarily replace it with EOS
70
   char *s;
71
   for (s=const_cast<char *>(namestr); *s!='-' && *s!='\0'; s++);
72
   assert(*s=='-');  // there must be a '-' in the string
73
   *s = '\0';
74
75
   object = strToPtr(namestr+1);
76
   type = atoi(s+1);
77
   *s = '-';  // restore '-'
78
}
79
80
//=======================================================================
81
// TInspector: base class for all inspector types
82
//             member functions
83
84
TInspector::TInspector(cObject *obj, int typ, const char *geom, void *dat)
85
{
86
   object = obj;
87
   type = typ;
88
   data = dat;
89
   toBeDeleted = false;
90
91
   windowname[0] = '\0'; // no window exists
92
   windowtitle[0] = '\0';
93
   geometry[0] = '\0';
94
   if (geom) strcpy(geometry, geom);
95
}
96
97
TInspector::~TInspector()
98
{
99
   if (windowname[0])
100
   {
101
      Tcl_Interp *interp = getTkenv()->getInterp();
102
      CHK(Tcl_VarEval(interp, "destroy_inspector_toplevel ", windowname, NULL ));
103
   }
104
}
105
106
void TInspector::createWindow()
107
{
108
   windowname[0] = '.';
109
   ptrToStr(object, windowname+1 );
110
   sprintf(windowname+strlen(windowname), "-%d",type);
111
112
   // derived classes will also call Tcl_Eval() to actually create the
113
   // Tk window by invoking a procedure in inspect.tcl
114
}
115
116
bool TInspector::windowExists()
117
{
118
   Tcl_Interp *interp = getTkenv()->getInterp();
119
   CHK(Tcl_VarEval(interp, "winfo exists ", windowname, NULL ));
120
   return Tcl_GetStringResult(interp)[0]=='1';
121
}
122
123
void TInspector::showWindow()
124
{
125
   Tcl_Interp *interp = getTkenv()->getInterp();
126
   CHK(Tcl_VarEval(interp, "inspector_show ", windowname, NULL ));
127
}
128
129
void TInspector::hostObjectDeleted()
130
{
131
   Tcl_Interp *interp = getTkenv()->getInterp();
132
   CHK(Tcl_VarEval(interp, "inspector_hostobjectdeleted ", windowname, NULL ));
133
}
134
135
void TInspector::update()
136
{
137
   Tcl_Interp *interp = getTkenv()->getInterp();
138
139
   // update window title (only if changed)
140
   //  (always updating the title produces many unnecessary redraws under some window mgrs)
141
   char newtitle[128];
142
   const char *prefix = getTkenv()->getWindowTitlePrefix();
143
   char fullpath[300];
144
   strncpy(fullpath, object->getFullPath().c_str(), 300);
145
   fullpath[299] = 0;
146
   int len = strlen(fullpath);
147
   if (len<=45)
148
       sprintf(newtitle, "%s(%.40s) %s", prefix, getObjectShortTypeName(object), fullpath);
149
   else
150
       sprintf(newtitle, "%s(%.40s) ...%s", prefix, getObjectShortTypeName(object), fullpath+len-40);
151
152
   if (strcmp(newtitle, windowtitle)!=0)
153
   {
154
       strcpy(windowtitle, newtitle);
155
       CHK(Tcl_VarEval(interp, "wm title ",windowname," {",windowtitle,"}",NULL));
156
   }
157
158
   // update object type and name info
159
   char newname[MAX_OBJECTFULLPATH+MAX_CLASSNAME+40];
160
   char buf[30];
161
   cModule *mod = dynamic_cast<cModule *>(object);
162
   if (mod)
163
       sprintf(newname, "(%s) %s  (id=%d)  (%s)", getObjectFullTypeName(object),
164
                        object->getFullPath().c_str(), mod->getId(), ptrToStr(object,buf));
165
   else
166
       sprintf(newname, "(%s) %s  (%s)", getObjectFullTypeName(object),
167
                        object->getFullPath().c_str(), ptrToStr(object,buf));
168
   CHK(Tcl_VarEval(interp, windowname,".infobar.name config -text {",newname,"}",NULL));
169
170
   // owner button on toolbar
171
   setToolbarInspectButton(".toolbar.owner", mod ? mod->getParentModule() : object->getOwner(), INSP_DEFAULT);
172
}
173
174
void TInspector::setEntry(const char *entry, const char *val)
175
{
176
   Tcl_Interp *interp = getTkenv()->getInterp();
177
   if (!val) val="";
178
   CHK(Tcl_VarEval(interp, windowname,entry," delete 0 end;",
179
                           windowname,entry," insert 0 {",val,"}",NULL));
180
}
181
182
void TInspector::setEntry( const char *entry, long l )
183
{
184
   Tcl_Interp *interp = getTkenv()->getInterp();
185
   char buf[16];
186
   sprintf(buf, "%ld", l );
187
   CHK(Tcl_VarEval(interp, windowname,entry," delete 0 end;",
188
                           windowname,entry," insert 0 {",buf,"}",NULL));
189
}
190
191
void TInspector::setEntry( const char *entry, double d )
192
{
193
   Tcl_Interp *interp = getTkenv()->getInterp();
194
   char buf[24];
195
   sprintf(buf, "%g", d );
196
   CHK(Tcl_VarEval(interp, windowname,entry," delete 0 end;",
197
                           windowname,entry," insert 0 {",buf,"}",NULL));
198
}
199
200
void TInspector::setLabel( const char *label, const char *val )
201
{
202
   Tcl_Interp *interp = getTkenv()->getInterp();
203
   if (!val) val="";
204
   CHK(Tcl_VarEval(interp, windowname,label," config -text {",val,"}",NULL));
205
}
206
207
void TInspector::setLabel( const char *label, long l )
208
{
209
   Tcl_Interp *interp = getTkenv()->getInterp();
210
   char buf[16];
211
   sprintf(buf, "%ld", l );
212
   CHK(Tcl_VarEval(interp, windowname,label," config -text {",buf,"}",NULL));
213
}
214
215
void TInspector::setLabel( const char *label, double d )
216
{
217
   Tcl_Interp *interp = getTkenv()->getInterp();
218
   char buf[16];
219
   sprintf(buf, "%g", d );
220
   CHK(Tcl_VarEval(interp, windowname,label," config -text {",buf,"}",NULL));
221
}
222
223
void TInspector::setText(const char *entry, const char *val)
224
{
225
   Tcl_Interp *interp = getTkenv()->getInterp();
226
   if (!val) val="";
227
   CHK(Tcl_VarEval(interp, windowname,entry," delete 1.0 end", NULL));
228
   CHK(Tcl_VarEval(interp, windowname,entry," insert 1.0 {",val,"}",NULL));
229
}
230
231
void TInspector::setReadonlyText(const char *entry, const char *val)
232
{
233
   Tcl_Interp *interp = getTkenv()->getInterp();
234
   CHK(Tcl_VarEval(interp, windowname,entry," config -state normal", NULL));
235
   setText(entry, val);
236
   CHK(Tcl_VarEval(interp, windowname,entry," config -state disabled", NULL));
237
}
238
239
const char *TInspector::getEntry( const char *entry )
240
{
241
   Tcl_Interp *interp = getTkenv()->getInterp();
242
   CHK(Tcl_VarEval(interp, windowname,entry," get",NULL));
243
   return Tcl_GetStringResult(interp);
244
}
245
246
void TInspector::setInspectButton(const char *button, cObject *object, bool displayfullpath, int inspectortype)
247
{
248
   Tcl_Interp *interp = getTkenv()->getInterp();
249
   if (object)
250
   {
251
      char buf[16];
252
      sprintf(buf, "%d", inspectortype);
253
      char idtext[30] = "";
254
      if (dynamic_cast<cModule *>(object))
255
      {
256
          sprintf(idtext, " (id=%d)", static_cast<cModule *>(object)->getId());
257
      }
258
      CHK(Tcl_VarEval(interp, windowname, button,".e config -state normal ",
259
                              "-text {(", getObjectShortTypeName(object), ") ",
260
                              (displayfullpath ? object->getFullPath().c_str() : object->getFullName()),
261
                              idtext, "} ",
262
                              "-command {opp_inspect ",ptrToStr(object)," ",buf,"}",
263
                              NULL));
264
   }
265
   else
266
   {
267
      CHK(Tcl_VarEval(interp, windowname,button,".e config -state disabled -text {n/a}",NULL));
268
   }
269
}
270
271
void TInspector::setToolbarInspectButton(const char *button, cObject *object, int type)
272
{
273
   Tcl_Interp *interp = getTkenv()->getInterp();
274
   if (object)
275
   {
276
      char buf[16];
277
      sprintf(buf, "%d", type );
278
      CHK(Tcl_VarEval(interp, windowname,button," config -state normal -command"
279
                              " {opp_inspect ",ptrToStr(object)," ",buf,"}",NULL));
280
   }
281
   else
282
   {
283
      CHK(Tcl_VarEval(interp, windowname,button," config -state disabled",NULL));
284
   }
285
}
286
287
void TInspector::deleteInspectorListbox(const char *listbox)
288
{
289
   Tcl_Interp *interp = getTkenv()->getInterp();
290
   CHK(Tcl_VarEval(interp, "multicolumnlistbox_deleteall ", windowname,listbox,".main.list",NULL));
291
}
292
293
void TInspector::fillInspectorListbox(const char *listbox, cObject *object, bool deep)
294
{
295
   Tcl_Interp *interp = getTkenv()->getInterp();
296
   char w[256], buf[256];
297
   sprintf(w, "%s%s.main.list", windowname,listbox);
298
   int n = fillListboxWithChildObjects(object, interp, w, deep);
299
300
   // The following is needed because BLT tends to crash when item count goes
301
   // from 3 to 0 (e.g. in samples/fifo, Fast mode). Adding a dummy line when
302
   // listbox is empty solves the problem...
303
   if (n==0)
304
       CHK(Tcl_VarEval(interp, "multicolumnlistbox_adddummyline ", w, NULL));
305
306
   // set "number of items" display
307
   sprintf(w, "%s.label", listbox);
308
   sprintf(buf,"%d objects", n);
309
   setLabel(w, buf);
310
}
311
312
void TInspector::fillListboxWithSubmodules(const char *listbox, cModule *parent)
313
{
314
   Tcl_Interp *interp = getTkenv()->getInterp();
315
   char w[256], buf[256];
316
   sprintf(w, "%s%s.main.list", windowname,listbox);
317
318
   // feed into listbox
319
   int n = 0;
320
   for (cModule::SubmoduleIterator submod(parent); !submod.end(); submod++, n++)
321
        insertIntoInspectorListbox(interp, w, submod(), false);
322
323
   // set "number of items" display
324
   sprintf(w, "%s.label", listbox);
325
   sprintf(buf,"%d modules", n);
326
   setLabel(w, buf);
327
}
328
329
//=======================================================================
330
331
TInspectorPanel::TInspectorPanel(const char *widgetname, cObject *obj)
332
{
333
   strcpy(this->widgetname, widgetname);
334
   object = obj;
335
}
336
337
void TInspectorPanel::setObject(cObject *obj)
338
{
339
   object=obj;
340
}
341