1
0
mirror of https://github.com/VDR4Arch/vdr.git synced 2023-10-10 13:36:52 +02:00

Implemented cStatusMonitor to allow plugins to set up a status monitor

This commit is contained in:
Klaus Schmidinger 2002-05-19 15:50:11 +02:00
parent 82725f53b5
commit 9f9d6a8a93
13 changed files with 311 additions and 21 deletions

View File

@ -1294,7 +1294,7 @@ Video Disk Recorder Revision History
- Fixed the cutting mechanism to make it re-sync in case a frame is larger than the
buffer (thanks to Sven Grothklags).
2002-05-18: Version 1.1.3
2002-05-19: Version 1.1.3
- Improved the VDR Makefile to avoid a warning if the '.dependencies' file does
not exist, and also using $(MAKE) to call recursive makes.
@ -1312,3 +1312,5 @@ Video Disk Recorder Revision History
accessed (suggested by Stefan Huelswitt).
- Rearranged OSD class names to make 'cOsd' available for the main OSD interface.
- Completely moved OSD handling out of the cDvbApi class, into the new cOsd.
- Implemented cStatusMonitor to allow plugins to set up a status monitor.
See PLUGINS.html for details.

View File

@ -4,7 +4,7 @@
# See the main source file 'vdr.c' for copyright information and
# how to reach the author.
#
# $Id: Makefile 1.36 2002/05/14 21:12:28 kls Exp $
# $Id: Makefile 1.37 2002/05/18 15:10:10 kls Exp $
.DELETE_ON_ERROR:
@ -23,7 +23,7 @@ DTVLIB = $(DTVDIR)/libdtv.a
OBJS = config.o dvbapi.o dvbosd.o eit.o font.o i18n.o interface.o menu.o\
menuitems.o osdbase.o osd.o plugin.o recording.o remote.o remux.o ringbuffer.o\
svdrp.o thread.o tools.o vdr.o videodir.o
status.o svdrp.o thread.o tools.o vdr.o videodir.o
OSDFONT = -adobe-helvetica-medium-r-normal--23-*-100-100-p-*-iso8859-1
FIXFONT = -adobe-courier-bold-r-normal--25-*-100-100-m-*-iso8859-1

View File

@ -4,7 +4,7 @@
</head>
<body bgcolor="white">
<h1>The VDR Plugin System</h1>
<center><h1>The VDR Plugin System</h1></center>
VDR provides an easy to use plugin interface that allows additional functionality
to be added to the program by implementing a dynamically loadable library file.
@ -12,9 +12,16 @@ This interface allows programmers to develop additional functionality for VDR co
separate from the core VDR source, without the need of patching the original
VDR code (and all the problems of correlating various patches).
<p>
This document describes the "outside" interface of the plugin system.
It handles everything necessary for a plugin to get hooked into the core
<!--X1.1.3--><table width=100%><tr><td bgcolor=red>&nbsp;</td><td width=100%>
This document is divided into two parts, the first one describing the
<a href="#Part I - The Outside Interface"><i>outside</i> interface</a>
of the plugin system, and the second one describing the
<a href="#Part II - The Inside Interface"><i>inside</i> interface</a>.
The <i>outside</i> interface handles everything necessary for a plugin to get hooked into the core
VDR program and present itself to the user.
The <i>inside</i> interface provides the plugin code access to VDR's internal data
structures and allows it to hook itself into specific areas to perform special actions.
<!--X1.1.3--></td></tr></table>
<p>
<!--X1.1.1--><table width=100%><tr><td bgcolor=lime>&nbsp;</td><td width=100%>
Important modifications introduced in version 1.1.1 are marked like this.
@ -27,6 +34,8 @@ Important modifications introduced in version 1.1.3 are marked like this.
<!--X1.1.3--></td></tr></table>
<!--<p>TODO: Link to the document about VDR base classes to use when implementing actual functionality (yet to be written).-->
<a name="Part I - The Outside Interface"><hr><center><h1>Part I - The Outside Interface</h1></center>
<hr><h2>Quick start</h2>
<center><i><b>Can't wait, can't wait!</b></i></center><p>
@ -840,5 +849,82 @@ vdr-hello-0.0.1.tgz
in your source directory, where <tt>hello</tt> will be replaced with your actual
plugin's name, and <tt>0.0.1</tt> will be your plugin's current version number.
<!--X1.1.3--><table width=100%><tr><td bgcolor=red>&nbsp;</td><td width=100%>
<a name="Part II - The Inside Interface"><hr><center><h1>Part II - The Inside Interface</h1></center>
<hr><h2>Status monitor</h2>
<center><i><b>A piece of the action</b></i></center><p>
If a plugin wants to get informed on various events in VDR, it can derive a class from
<tt>cStatusMonitor</tt>, as in
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
#include &lt;vdr/status.h&gt;
class cMyStatusMonitor : public cStatusMonitor {
protected:
virtual void ChannelSwitch(const cDvbApi *DvbApi, int ChannelNumber);
};
void cMyStatusMonitor::ChannelSwitch(const cDvbApi *DvbApi, int ChannelNumber)
{
if (ChannelNumber)
dsyslog("channel switched to %d on DVB %d", ChannelNumber, DvbApi-&gt;CardIndex());
else
dsyslog("about to switch channel on DVB %d", DvbApi-&gt;CardIndex());
}
</pre></td></tr></table><p>
An object of this class will be informed whenever the channel is switched on one of
the DVB devices. It could be used in a plugin like this:
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
#include &lt;vdr/plugin.h&gt;
class cPluginStatus : public cPlugin {
private:
cMyStatusMonitor *statusMonitor;
public:
cPluginStatus(void);
virtual ~cPluginStatus();
...
virtual bool Start(void);
...
};
cPluginStatus::cPluginStatus(void)
{
statusMonitor = NULL;
}
cPluginStatus::~cPluginStatus()
{
delete statusMonitor;
}
bool cPluginStatus::Start(void)
{
statusMonitor = new cMyStatusMonitor;
return true;
}
</pre></td></tr></table><p>
Note that the actual object is created in the <tt>Start()</tt> function, not in the
constructor! It is also important to delete the object in the destructor, in order to
avoid memory leaks.
<p>
A Plugin can implement any number of <tt>cStatusMonitor</tt> derived objects, and once
the plugin has been started it may create and delete them as necessary.
No further action apart from creating an object derived from <tt>cStatusMonitor</tt>
is necessary. VDR will automatically hook it into a list of status monitors, with
their individual virtual member functions being called in the same sequence as the
objects were created.
<p>
See the file <tt>status.h</tt> for detailed information on which status monitor
member functions are available in <tt>cStatusMonitor</tt>. You only need to implement
the functions you actually want to use.
<!--X1.1.3--></td></tr></table>
</body>
</html>

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: dvbapi.c 1.178 2002/05/18 14:26:08 kls Exp $
* $Id: dvbapi.c 1.179 2002/05/19 14:46:38 kls Exp $
*/
#include "dvbapi.h"
@ -25,6 +25,7 @@ extern "C" {
#include "recording.h"
#include "remux.h"
#include "ringbuffer.h"
#include "status.h"
#include "tools.h"
#include "videodir.h"
@ -2124,6 +2125,8 @@ eSetChannelResult cDvbApi::SetChannel(int ChannelNumber, int Frequency, char Pol
StopTransfer();
StopReplay();
cStatusMonitor::MsgChannelSwitch(this, 0);
// Must set this anyway to avoid getting stuck when switching through
// channels with 'Up' and 'Down' keys:
currentChannel = ChannelNumber;
@ -2303,6 +2306,8 @@ eSetChannelResult cDvbApi::SetChannel(int ChannelNumber, int Frequency, char Pol
if (Result == scrOk && siProcessor)
siProcessor->SetCurrentTransponder(Frequency);
cStatusMonitor::MsgChannelSwitch(this, ChannelNumber);
return Result;
}
@ -2546,6 +2551,7 @@ void cDvbApi::SetVolume(int Volume, bool Absolute)
audioMixer_t am;
am.volume_left = am.volume_right = volume;
CHECK(ioctl(fd_audio, AUDIO_SET_MIXER, &am));
cStatusMonitor::MsgSetVolume(volume, Absolute);
if (volume > 0)
mute = false;
}

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: dvbapi.h 1.70 2002/05/18 14:03:12 kls Exp $
* $Id: dvbapi.h 1.71 2002/05/19 10:13:34 kls Exp $
*/
#ifndef __DVBAPI_H
@ -119,7 +119,7 @@ public:
// will be returned.
// The caller must check whether the returned DVB device is actually
// recording and stop recording if necessary.
int CardIndex(void) { return cardIndex; }
int CardIndex(void) const { return cardIndex; }
// Returns the card index of this DvbApi (0 ... MAXDVBAPI - 1).
static void SetCaCaps(void);
// Sets the CaCaps of all DVB devices according to the Setup data.

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: interface.c 1.49 2002/05/18 13:08:20 kls Exp $
* $Id: interface.c 1.50 2002/05/19 12:02:57 kls Exp $
*/
#include "interface.h"
@ -12,6 +12,7 @@
#include <unistd.h>
#include "i18n.h"
#include "osd.h"
#include "status.h"
cInterface *Interface = NULL;
@ -127,6 +128,7 @@ void cInterface::Clear(void)
{
if (open)
cOsd::Clear();
cStatusMonitor::MsgOsdClear();
}
void cInterface::ClearEol(int x, int y, eDvbColor Color)
@ -287,6 +289,7 @@ void cInterface::Title(const char *s)
x = 0;
Write(x, 0, s, clrBlack, clrCyan);
}
cStatusMonitor::MsgOsdTitle(s);
}
void cInterface::Status(const char *s, eDvbColor FgColor, eDvbColor BgColor)
@ -299,6 +302,7 @@ void cInterface::Status(const char *s, eDvbColor FgColor, eDvbColor BgColor)
x = 0;
Write(x, Line, s, FgColor, BgColor);
}
cStatusMonitor::MsgOsdStatusMessage(s);
}
void cInterface::Info(const char *s)
@ -354,6 +358,7 @@ void cInterface::Help(const char *Red, const char *Green, const char *Yellow, co
HelpButton(1, Green, clrBlack, clrGreen);
HelpButton(2, Yellow, clrBlack, clrYellow);
HelpButton(3, Blue, clrWhite, clrBlue);
cStatusMonitor::MsgOsdHelpKeys(Red, Green, Yellow, Blue);
}
void cInterface::QueryKeys(void)

13
menu.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: menu.c 1.194 2002/05/18 13:08:42 kls Exp $
* $Id: menu.c 1.195 2002/05/19 14:55:22 kls Exp $
*/
#include "menu.h"
@ -18,6 +18,7 @@
#include "i18n.h"
#include "menuitems.h"
#include "plugin.h"
#include "status.h"
#include "videodir.h"
#define MENUTIMEOUT 120 // seconds
@ -2162,6 +2163,7 @@ void cDisplayChannel::DisplayChannel(const cChannel *Channel)
Interface->Write(0, 0, buffer);
const char *date = DayDateTime();
Interface->Write(-strlen(date), 0, date);
cStatusMonitor::MsgOsdChannel(buffer);
}
void cDisplayChannel::DisplayInfo(void)
@ -2215,6 +2217,7 @@ void cDisplayChannel::DisplayInfo(void)
Interface->Flush();
lines = Lines;
lastTime = time_ms();
cStatusMonitor::MsgOsdProgramme(Present ? Present->GetTime() : 0, PresentTitle, PresentSubtitle, Following ? Following->GetTime() : 0, FollowingTitle, FollowingSubtitle);
}
}
}
@ -2431,8 +2434,10 @@ cRecordControl::cRecordControl(cDvbApi *DvbApi, cTimer *Timer)
cRecording Recording(timer, Title, Subtitle, Summary);
fileName = strdup(Recording.FileName());
cRecordingUserCommand::InvokeCommand(RUC_BEFORERECORDING, fileName);
if (dvbApi->StartRecord(fileName, Channels.GetByNumber(timer->channel)->ca, timer->priority))
if (dvbApi->StartRecord(fileName, Channels.GetByNumber(timer->channel)->ca, timer->priority)) {
Recording.WriteSummary();
cStatusMonitor::MsgRecording(dvbApi, fileName);
}
Interface->DisplayRecording(dvbApi->CardIndex(), true);
}
else
@ -2479,6 +2484,7 @@ bool cRecordControl::GetEventInfo(void)
void cRecordControl::Stop(bool KeepInstant)
{
if (timer) {
cStatusMonitor::MsgRecording(dvbApi, NULL);
dvbApi->StopRecord();
timer->SetRecording(false);
if ((IsInstant() && !KeepInstant) || (timer->IsSingleEvent() && !timer->Matches())) {
@ -2667,12 +2673,15 @@ cReplayControl::cReplayControl(void)
marks.Load(fileName);
if (!dvbApi->StartReplay(fileName))
Interface->Error(tr("Channel locked (recording)!"));
else
cStatusMonitor::MsgReplaying(dvbApi, fileName);
}
}
cReplayControl::~cReplayControl()
{
Hide();
cStatusMonitor::MsgReplaying(dvbApi, NULL);
dvbApi->StopReplay();
}

View File

@ -4,13 +4,14 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: menuitems.c 1.4 2002/05/18 13:09:04 kls Exp $
* $Id: menuitems.c 1.5 2002/05/19 12:34:33 kls Exp $
*/
#include "menuitems.h"
#include <ctype.h>
#include "i18n.h"
#include "plugin.h"
#include "status.h"
// --- cMenuEditItem ---------------------------------------------------------
@ -397,6 +398,7 @@ void cMenuTextItem::Display(int Offset, eDvbColor FgColor, eDvbColor BgColor)
// scroll indicators use inverted color scheme!
if (CanScrollUp()) Interface->Write(x + w - 1, y, "^", bgColor, fgColor);
if (CanScrollDown()) Interface->Write(x + w - 1, y + h - 1, "v", bgColor, fgColor);
cStatusMonitor::MsgOsdTextItem(text);
}
void cMenuTextItem::ScrollUp(bool Page)
@ -406,6 +408,7 @@ void cMenuTextItem::ScrollUp(bool Page)
offset = max(offset - (Page ? h : 1), 0);
Display();
}
cStatusMonitor::MsgOsdTextItem(NULL, true);
}
void cMenuTextItem::ScrollDown(bool Page)
@ -415,6 +418,7 @@ void cMenuTextItem::ScrollDown(bool Page)
offset = min(offset + (Page ? h : 1), lines - h);
Display();
}
cStatusMonitor::MsgOsdTextItem(NULL, false);
}
eOSState cMenuTextItem::ProcessKey(eKeys Key)

13
osd.c
View File

@ -4,13 +4,14 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: osd.c 1.26 2002/05/18 14:00:21 kls Exp $
* $Id: osd.c 1.27 2002/05/19 12:56:57 kls Exp $
*/
#include "osd.h"
#include <string.h>
#include "dvbapi.h"
#include "i18n.h"
#include "status.h"
// --- cOsd ------------------------------------------------------------------
@ -430,8 +431,11 @@ void cOsdMenu::Display(void)
}
for (int i = first; i < count; i++) {
cOsdItem *item = Get(i);
if (item)
if (item) {
item->Display(i - first, i == current ? clrBlack : clrWhite, i == current ? clrCyan : clrBackground);
if (i == current)
cStatusMonitor::MsgOsdCurrentItem(item->Text());
}
if (++n == MAXOSDITEMS) //TODO get this from Interface!!!
break;
}
@ -455,8 +459,11 @@ void cOsdMenu::RefreshCurrent(void)
void cOsdMenu::DisplayCurrent(bool Current)
{
cOsdItem *item = Get(current);
if (item)
if (item) {
item->Display(current - first, Current ? clrBlack : clrWhite, Current ? clrCyan : clrBackground);
if (Current)
cStatusMonitor::MsgOsdCurrentItem(item->Text());
}
}
void cOsdMenu::Clear(void)

96
status.c Normal file
View File

@ -0,0 +1,96 @@
/*
* status.c: Status monitoring
*
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: status.c 1.1 2002/05/19 14:54:30 kls Exp $
*/
#include "status.h"
// --- cStatusMonitor --------------------------------------------------------
cList<cStatusMonitor> cStatusMonitor::statusMonitors;
cStatusMonitor::cStatusMonitor(void)
{
statusMonitors.Add(this);
}
cStatusMonitor::~cStatusMonitor()
{
statusMonitors.Del(this, false);
}
void cStatusMonitor::MsgChannelSwitch(const cDvbApi *DvbApi, int ChannelNumber)
{
for (cStatusMonitor *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
sm->ChannelSwitch(DvbApi, ChannelNumber);
}
void cStatusMonitor::MsgRecording(const cDvbApi *DvbApi, const char *Name)
{
for (cStatusMonitor *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
sm->Recording(DvbApi, Name);
}
void cStatusMonitor::MsgReplaying(const cDvbApi *DvbApi, const char *Name)
{
for (cStatusMonitor *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
sm->Replaying(DvbApi, Name);
}
void cStatusMonitor::MsgSetVolume(int Volume, bool Absolute)
{
for (cStatusMonitor *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
sm->SetVolume(Volume, Absolute);
}
void cStatusMonitor::MsgOsdClear(void)
{
for (cStatusMonitor *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
sm->OsdClear();
}
void cStatusMonitor::MsgOsdTitle(const char *Title)
{
for (cStatusMonitor *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
sm->OsdTitle(Title);
}
void cStatusMonitor::MsgOsdStatusMessage(const char *Message)
{
for (cStatusMonitor *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
sm->OsdStatusMessage(Message);
}
void cStatusMonitor::MsgOsdHelpKeys(const char *Red, const char *Green, const char *Yellow, const char *Blue)
{
for (cStatusMonitor *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
sm->OsdHelpKeys(Red, Green, Yellow, Blue);
}
void cStatusMonitor::MsgOsdCurrentItem(const char *Text)
{
for (cStatusMonitor *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
sm->OsdCurrentItem(Text);
}
void cStatusMonitor::MsgOsdTextItem(const char *Text, bool Scroll)
{
for (cStatusMonitor *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
sm->OsdTextItem(Text, Scroll);
}
void cStatusMonitor::MsgOsdChannel(const char *Text)
{
for (cStatusMonitor *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
sm->OsdChannel(Text);
}
void cStatusMonitor::MsgOsdProgramme(time_t PresentTime, const char *PresentTitle, const char *PresentSubtitle, time_t FollowingTime, const char *FollowingTitle, const char *FollowingSubtitle)
{
for (cStatusMonitor *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
sm->OsdProgramme(PresentTime, PresentTitle, PresentSubtitle, FollowingTime, FollowingTitle, FollowingSubtitle);
}

74
status.h Normal file
View File

@ -0,0 +1,74 @@
/*
* status.h: Status monitoring
*
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: status.h 1.1 2002/05/19 14:54:15 kls Exp $
*/
#ifndef __STATUS_H
#define __STATUS_H
#include "config.h"
#include "dvbapi.h"
#include "tools.h"
class cStatusMonitor : public cListObject {
private:
static cList<cStatusMonitor> statusMonitors;
protected:
// These functions can be implemented by derived classes to receive status information:
virtual void ChannelSwitch(const cDvbApi *DvbApi, int ChannelNumber) {}
// Indicates a channel switch on DVB device DvbApi.
// If ChannelNumber is 0, this is before the channel is being switched,
// otherwise ChannelNumber is the number of the channel that has been switched to.
virtual void Recording(const cDvbApi *DvbApi, const char *Name) {}
// DVB device DvbApi has started recording Name. Name is the full directory
// name of the recording. If Name is NULL, the recording has ended.
virtual void Replaying(const cDvbApi *DvbApi, const char *Name) {}
// DVB device DvbApi has started replaying Name. Name is the full directory
// name of the recording. If Name is NULL, the replay has ended.
virtual void SetVolume(int Volume, bool Absolute) {}
// The volume has been set to the given value, either
// absolutely or relative to the current volume.
virtual void OsdClear(void) {}
// The OSD has been cleared.
virtual void OsdTitle(const char *Title) {}
// Title has been displayed in the title line of the menu.
virtual void OsdStatusMessage(const char *Message) {}
// Message has been displayed in the status line of the menu.
// If Message is NULL, the status line has been cleared.
virtual void OsdHelpKeys(const char *Red, const char *Green, const char *Yellow, const char *Blue) {}
// The help keys have been set to the given values (may be NULL).
virtual void OsdCurrentItem(const char *Text) {}
// The OSD displays the given single line Text as the current menu item.
virtual void OsdTextItem(const char *Text, bool Scroll) {}
// The OSD displays the given multi line text. If Text points to an
// actual string, that text shall be displayed and Scroll has no
// meaning. If Text is NULL, Scroll defines whether the previously
// received text shall be scrolled up (true) or down (false) and
// the text shall be redisplayed with the new offset.
virtual void OsdChannel(const char *Text) {}
// The OSD displays the single line Text with the current channel information.
virtual void OsdProgramme(time_t PresentTime, const char *PresentTitle, const char *PresentSubtitle, time_t FollowingTime, const char *FollowingTitle, const char *FollowingSubtitle) {}
// The OSD displays the given programme information.
public:
cStatusMonitor(void);
virtual ~cStatusMonitor();
// These functions are called whenever the related status information changes:
static void MsgChannelSwitch(const cDvbApi *DvbApi, int ChannelNumber);
static void MsgRecording(const cDvbApi *DvbApi, const char *Name);
static void MsgReplaying(const cDvbApi *DvbApi, const char *Name);
static void MsgSetVolume(int Volume, bool Absolute);
static void MsgOsdClear(void);
static void MsgOsdTitle(const char *Title);
static void MsgOsdStatusMessage(const char *Message);
static void MsgOsdHelpKeys(const char *Red, const char *Green, const char *Yellow, const char *Blue);
static void MsgOsdCurrentItem(const char *Text);
static void MsgOsdTextItem(const char *Text, bool Scroll = false);
static void MsgOsdChannel(const char *Text);
static void MsgOsdProgramme(time_t PresentTime, const char *PresentTitle, const char *PresentSubtitle, time_t FollowingTime, const char *FollowingTitle, const char *FollowingSubtitle);
};
#endif //__STATUS_H

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: tools.c 1.66 2002/05/13 17:56:17 kls Exp $
* $Id: tools.c 1.67 2002/05/18 15:10:45 kls Exp $
*/
#include "tools.h"
@ -793,14 +793,15 @@ void cListBase::Ins(cListObject *Object, cListObject *Before)
}
}
void cListBase::Del(cListObject *Object)
void cListBase::Del(cListObject *Object, bool DeleteObject)
{
if (Object == objects)
objects = Object->Next();
if (Object == lastObject)
lastObject = Object->Prev();
Object->Unlink();
delete Object;
if (DeleteObject)
delete Object;
}
void cListBase::Move(int From, int To)

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: tools.h 1.45 2002/05/13 16:21:55 kls Exp $
* $Id: tools.h 1.46 2002/05/18 15:10:10 kls Exp $
*/
#ifndef __TOOLS_H
@ -135,7 +135,7 @@ public:
virtual ~cListBase();
void Add(cListObject *Object, cListObject *After = NULL);
void Ins(cListObject *Object, cListObject *Before = NULL);
void Del(cListObject *Object);
void Del(cListObject *Object, bool DeleteObject = true);
virtual void Move(int From, int To);
void Move(cListObject *From, cListObject *To);
virtual void Clear(void);