// check if EPG is present for the configured hours void cSearchTimerThread::CheckEPGHours() { if (EPGSearchConfig.checkEPGHours <= 0 || (EPGSearchConfig.checkEPGWarnByOSD == 0 && EPGSearchConfig.checkEPGWarnByMail == 0) || EPGSearchConfig.checkEPGchannelGroupNr <= 0) return; LogFile.Log(2,"check if relevant EPG exists for the next %d hours", EPGSearchConfig.checkEPGHours); cChannelGroup* channelGroup = ChannelGroups.Get(EPGSearchConfig.checkEPGchannelGroupNr-1); // not zero-based! if (!channelGroup) { LogFile.Log(1,"channel group with index %d does not exist!", EPGSearchConfig.checkEPGchannelGroupNr); return; } LogFile.Log(2,"checking channel group '%s'", channelGroup->name); time_t checkTime = time(NULL) + EPGSearchConfig.checkEPGHours * 60 * 60; cSchedulesLock schedulesLock; const cSchedules *schedules; schedules = cSchedules::Schedules(schedulesLock); cChannelGroup channelsWithSmallEPG; cChannelGroupItem* channelInGroup = channelGroup->channels.First(); while (channelInGroup) { cChannel* channel = channelInGroup->channel; // get the channels schedule const cSchedule* schedule = schedules->GetSchedule(channel); if (!schedule || !schedule->GetEventAround(checkTime)) { LogFile.Log(3,"less than %d hours of EPG for channel %s!", EPGSearchConfig.checkEPGHours, channel->Name()); cChannelGroupItem* channelitem = new cChannelGroupItem(channel); channelsWithSmallEPG.channels.Add(channelitem); } channelInGroup = channelGroup->channels.Next(channelInGroup); } // create a string list of the channels found if (channelsWithSmallEPG.channels.Count() > 0) { string sBuffer; channelInGroup = channelsWithSmallEPG.channels.First(); while (channelInGroup) { cChannel* channel = channelInGroup->channel; if (channel) sBuffer += " " + string(channel->ShortName(true)); channelInGroup = channelsWithSmallEPG.channels.Next(channelInGroup); } if (EPGSearchConfig.checkEPGWarnByOSD) { cString msgfmt = cString::sprintf(tr("small EPG content on:%s"), sBuffer.c_str()); SendMsg(msgfmt); } if (EPGSearchConfig.checkEPGWarnByMail) { cString msgfmt = cString::sprintf(tr("small EPG content on:%s"), sBuffer.c_str()); cMailNotifier M(string(tr("VDR EPG check warning")), string(msgfmt)); } } LogFile.Log(2,"check for relevant EPG finished - %d channels with small EPG content", channelsWithSmallEPG.channels.Count()); }
bool Toolbar::ShowButton(INT_PTR iCmd, bool bShow) { BOOL bArg = bShow ? FALSE : TRUE; return WND_TRUE(SendMsg(TB_HIDEBUTTON, iCmd, bArg)); }
bool Toolbar::IsButtonEnabled(INT_PTR iCmd) { return (0L != SendMsg(TB_ISBUTTONENABLED, iCmd, 0L) ? true : false); }
bool Toolbar::EnableButton(INT_PTR iID, bool bEnable) { return WND_TRUE(SendMsg(TB_ENABLEBUTTON, iID, bEnable ? TRUE : FALSE)); }
INT_PTR Toolbar::ButtonCount(void) { return SendMsg(TB_BUTTONCOUNT, 0L, 0L); }
// Add new menuentry to menubar. void ScrollView::MenuItem(const char* parent, const char* name, int cmdEvent) { if (parent == NULL) { parent = ""; } SendMsg("addMenuBarItem('%s','%s',%d)", parent, name, cmdEvent); }
// Send an update message for a single window. void ScrollView::UpdateWindow() { SendMsg("update()"); }
// Set the visibility of the window. void ScrollView::SetVisible(bool visible) { if (visible) { SendMsg("setVisible(true)"); } else { SendMsg("setVisible(false)"); } }
// Set the alwaysOnTop flag. void ScrollView::AlwaysOnTop(bool b) { if (b) { SendMsg("setAlwaysOnTop(true)"); } else { SendMsg("setAlwaysOnTop(false)"); } }
void EvtMouseTextField(struct XObj *xobj,XButtonEvent *EvtButton) { unsigned int modif; int x1,x2,y1,y2,i; Window Win1,Win2; int PosCurs=0; int SizeBuf; char *str; int NewPos; Atom type; XEvent event; int ButPress=1; int format; unsigned long longueur,octets_restant; unsigned char *donnees=(unsigned char *)""; XRectangle rect; /* On deplace le curseur a la position de la souris */ /* On recupere la position de la souris */ /* We move the cursor at mouse position and we get the mouse position */ switch (EvtButton->button) { case Button1: XQueryPointer(dpy,*xobj->ParentWin,&Win1,&Win2,&x1,&y1,&x2,&y2,&modif); x2=x2-xobj->x; PosCurs=0; while ((PosCurs<strlen(xobj->title+xobj->value3))&& (x2>XTextWidth(xobj->xfont,xobj->title+xobj->value3,PosCurs)+8)) PosCurs++; DrawPointTxt(xobj,xobj->TabColor[back]); xobj->value=PosCurs+xobj->value3; xobj->value2=PosCurs+xobj->value3; DrawPointTxt(xobj,xobj->TabColor[fore]); DrawTextField(xobj); while (ButPress) { XNextEvent(dpy, &event); switch (event.type) { case MotionNotify: XQueryPointer(dpy,*xobj->ParentWin,&Win1,&Win2,&x1,&y1,&x2,&y2,&modif); x2=x2-xobj->x; PosCurs=0; while ((PosCurs<strlen(xobj->title+xobj->value3))&& (x2>XTextWidth(xobj->xfont,xobj->title+xobj->value3,PosCurs)+8)) PosCurs++; /* Limitation de la zone de dessin */ /* limitation of the drawing zone */ if (PosCurs>xobj->value2) { rect.x=XTextWidth(xobj->xfont,xobj->title+xobj->value3,xobj->value2); rect.y=0; rect.width=XTextWidth(xobj->xfont,xobj->title+xobj->value3,PosCurs+1) -rect.x+1; rect.height=xobj->height; xobj->value2=PosCurs+xobj->value3; DrawTextField(xobj); } else if (PosCurs<xobj->value2) { rect.x=XTextWidth(xobj->xfont,xobj->title+xobj->value3,PosCurs)-1; rect.y=0; rect.width=XTextWidth(xobj->xfont,xobj->title+xobj->value3, xobj->value2+1) - rect.x+2; rect.height=xobj->height; xobj->value2=PosCurs+xobj->value3; DrawTextField(xobj); } break; case ButtonRelease: ButPress=0; break; } } /* Enregistrement de la selection dans le presse papier */ /* Le programme devient proprietaire de la selection */ /* selection stuff: get the selection */ if (xobj->value!=xobj->value2) { str=(char*)GetText(xobj,xobj->value2); for (i=0;i<=7;i++) XStoreBuffer(dpy,str,strlen(str),i); Scrapt=(char*)realloc((void*)Scrapt,(strlen(str)+2)*sizeof(char)); Scrapt=strcpy(Scrapt,str); free(str); x11base->HaveXSelection=True; XSetSelectionOwner(dpy,XA_PRIMARY,x11base->win,EvtButton->time); SelectOneTextField(xobj); } break; case Button2: /* Colle le texte */ /* Si l'application possede pas la selection, elle la demande */ /* sinon elle lit son presse papier */ /* read the selection */ if (!x11base->HaveXSelection) { /* Demande de la selection */ /* ask for the selection */ XConvertSelection(dpy,XA_PRIMARY,XA_STRING,propriete,*xobj->ParentWin, EvtButton->time); while (!(XCheckTypedEvent(dpy,SelectionNotify,&event))) ; if (event.xselection.property!=None) if (event.xselection.selection==XA_PRIMARY) { XGetWindowProperty(dpy,event.xselection.requestor, event.xselection.property,0,8192,False, event.xselection.target,&type,&format, &longueur,&octets_restant,&donnees); if (longueur>0) { Scrapt=(char*)realloc((void*)Scrapt,(longueur+1)*sizeof(char)); Scrapt=strcpy(Scrapt,(char *)donnees); XDeleteProperty(dpy,event.xselection.requestor, event.xselection.property); XFree(donnees); } } } SizeBuf=strlen(Scrapt); if (SizeBuf>0) { NewPos=InsertText(xobj,Scrapt,SizeBuf); DrawPointTxt(xobj,xobj->TabColor[back]); xobj->value=NewPos; xobj->value2=NewPos; DrawPointTxt(xobj,xobj->TabColor[fore]); DrawTextField(xobj); SendMsg(xobj,SingleClic); } break; case Button3: /* Appuie sur le troisieme bouton */ XQueryPointer(dpy,*xobj->ParentWin,&Win1,&Win2,&x1,&y1,&x2,&y2,&modif); x2=x2-xobj->x; PosCurs=0; while ((PosCurs<strlen(xobj->title))&& (x2>XTextWidth(xobj->xfont,xobj->title+xobj->value3,PosCurs)+8)) PosCurs++; if ((PosCurs<xobj->value) && (xobj->value<xobj->value2)) xobj->value=xobj->value2; if ((PosCurs>xobj->value) && (xobj->value>xobj->value2)) xobj->value=xobj->value2; xobj->value2=PosCurs+xobj->value3; DrawTextField(xobj); while (ButPress) { XNextEvent(dpy, &event); switch (event.type) { case MotionNotify: XQueryPointer(dpy,*xobj->ParentWin,&Win1,&Win2,&x1,&y1,&x2,&y2,&modif); x2=x2-xobj->x; while ((PosCurs<strlen(xobj->title))&& (x2>XTextWidth(xobj->xfont,xobj->title+xobj->value3,PosCurs)+8)) PosCurs++; if (PosCurs>xobj->value2) { rect.x=XTextWidth(xobj->xfont,xobj->title+xobj->value3,xobj->value2); rect.y=0; rect.width=XTextWidth(xobj->xfont,xobj->title+xobj->value3,PosCurs+1) -rect.x+1; rect.height=xobj->height; xobj->value2=PosCurs; DrawTextField(xobj); } else if (PosCurs<xobj->value2) { rect.x=XTextWidth(xobj->xfont,xobj->title+xobj->value3,PosCurs)-1; rect.y=0; rect.width=XTextWidth(xobj->xfont,xobj->title+xobj->value3, xobj->value2+1)-rect.x+2; rect.height=xobj->height; xobj->value2=PosCurs+xobj->value3; DrawTextField(xobj); } PosCurs=0; break; case ButtonRelease: ButPress=0; break; } } if (xobj->value!=xobj->value2) { str=(char*)GetText(xobj,xobj->value2); for (i=0;i<=7;i++) XStoreBuffer(dpy,str,strlen(str),i); Scrapt=(char*)realloc((void*)Scrapt,(strlen(str)+2)*sizeof(char)); Scrapt=strcpy(Scrapt,str); free(str); x11base->HaveXSelection=True; XSetSelectionOwner(dpy,XA_PRIMARY,x11base->win,EvtButton->time); } break; } }
void EvtKeyTextField(struct XObj *xobj,XKeyEvent *EvtKey) { int i,x2; char car[11]; char* carks2; char* carks = NULL; KeySym ks; int Size; int NewPos; /* Recherche du charactere */ i=XLookupString(EvtKey,car,10,&ks,NULL); NewPos=xobj->value; car[i]='\0'; carks2=XKeysymToString(ks); if (carks2!=NULL) { carks=(char*)calloc(sizeof(char),30); sprintf(carks,"%s",carks2); if (strcmp(carks,"Right")==0) { NewPos++; if (NewPos>strlen(xobj->title)) NewPos=strlen(xobj->title); } else if (strcmp(carks,"Left")==0) { NewPos--; if (NewPos<0) NewPos=0; } else if (strcmp(carks,"Return")==0) { ; } else if ((strcmp(carks,"Delete")==0)||(strcmp(carks,"BackSpace")==0)) { if (NewPos>0) { Size=strlen(xobj->title); memmove(&xobj->title[NewPos-1],&xobj->title[NewPos], Size-NewPos+1); xobj->title=(char*)realloc(xobj->title,(Size)*sizeof(char)); NewPos--; SendMsg(xobj,SingleClic); } } else if (i!=0) /* Cas d'un caractere normal */ { /* Insertion du caractere dans le titre */ /* a normal character: insertion in the title */ Size=strlen(xobj->title); xobj->title=(char*)realloc(xobj->title,(2+Size)*sizeof(char)); memmove(&xobj->title[NewPos+1],&xobj->title[NewPos], Size-NewPos+1); xobj->title[NewPos]=car[0]; NewPos++; SendMsg(xobj,SingleClic); } } if ((xobj->value!=NewPos)||(xobj->value2!=NewPos)) { XSetForeground(dpy,xobj->gc,xobj->TabColor[back]); x2=XTextWidth(xobj->xfont,xobj->title,strlen(xobj->title)); XFillRectangle(dpy,xobj->win,xobj->gc,x2+4,4,xobj->width-x2-8, xobj->height-8); xobj->value=NewPos; xobj->value2=NewPos; DrawPointTxt(xobj,xobj->TabColor[fore]); DrawTextField(xobj); } free(carks); }
int main(int argc, char **argv) { char *config = MHVTL_CONFIG_PATH"/device.conf"; FILE *conf; char b[1024]; int device_type = TYPE_UNKNOWN; long deviceNo, indx; int count; char buf[1024]; char *p; if ((argc < 2) || (argc > 6)) { usage(argv[0]); exit(1); } /* checking several positions of -h/-help */ for (count = 1; count < argc; count++) { if (!strcmp(argv[count], "-h")) { usage(argv[0]); exit(1); } if (!strcmp(argv[count], "/h")) { usage(argv[0]); exit(1); } if (!strcmp(argv[count], "-help")) { usage(argv[0]); exit(1); } if (!strcasecmp(argv[count], "-v")) { printf("Version: %s\n", MHVTL_VERSION); exit(1); } } Check_Params(argc, argv); deviceNo = atol(argv[1]); if ((deviceNo < 0) || (deviceNo >= VTLCMD_Q)) { fprintf(stderr, "Invalid device number for " "tape/library: %s\n", argv[1]); exit(1); } conf = fopen(config, "r"); if (!conf) { fprintf(stderr, "Can not open config file %s : %s\n", config, strerror(errno)); exit(1); } p = buf; buf[0] = '\0'; /* While read in a line */ while (fgets(b, sizeof(b), conf) != NULL) { if (sscanf(b, "Drive: %ld ", &indx) == 1 && indx == deviceNo) { device_type = TYPE_DRIVE; break; } if (sscanf(b, "Library: %ld ", &indx) == 1 && indx == deviceNo) { device_type = TYPE_LIBRARY; break; } } fclose(conf); if (device_type == TYPE_UNKNOWN) { fprintf(stderr, "No tape/library (%s) configured with " "device number: %ld\n", config, deviceNo); exit(1); } /* Concat all args into one string */ p = buf; buf[0] = '\0'; for (count = 2; count < argc; count++) { strcat(p, argv[count]); p += strlen(argv[count]); strcat(p, " "); p += strlen(" "); } /* check if command to the specific device is allowed */ if (device_type == TYPE_LIBRARY) { if (!strncmp(buf, "online", 6)) { } else if (!strncmp(buf, "add slot", 8)) { } else if (!strncmp(buf, "offline", 7)) { } else if (!strncmp(buf, "open map", 8)) { } else if (!strncmp(buf, "close map", 9)) { } else if (!strncmp(buf, "empty map", 9)) { } else if (!strncmp(buf, "list map", 8)) { } else if (!strncmp(buf, "load map", 8)) { } else if (!strncmp(buf, "verbose", 7)) { } else if (!strncmp(buf, "debug", 5)) { } else if (!strncmp(buf, "exit", 4)) { } else if (!strncmp(buf, "TapeAlert", 9)) { } else { fprintf(stderr, "Command for library not allowed\n"); exit(1); } } if (device_type == TYPE_DRIVE) { if (!strncmp(buf, "load", 4)) { } else if (!strncmp(buf, "unload", 6)) { } else if (!strncmp(buf, "verbose", 7)) { } else if (!strncmp(buf, "debug", 5)) { } else if (!strncmp(buf, "dump", 4)) { } else if (!strncmp(buf, "exit", 4)) { } else if (!strncmp(buf, "compression", 11)) { } else if (!strncmp(buf, "TapeAlert", 9)) { } else if (!strncasecmp(buf, "append", 6)) { } else if (!strncasecmp(buf, "delay load", 10)) { } else if (!strncasecmp(buf, "delay unload", 12)) { } else if (!strncasecmp(buf, "delay rewind", 12)) { } else if (!strncasecmp(buf, "delay position", 14)) { } else if (!strncasecmp(buf, "delay thread", 12)) { } else { fprintf(stderr, "Command for tape not allowed\n"); exit(1); } } /* Check for the existance of a datafile first - abort if not there */ if (device_type == TYPE_LIBRARY) { if (!strcmp(argv[2], "load") && !strcmp(argv[3], "map")) { if (check_media(deviceNo, argv[4])) { fprintf(stderr, "Hint: Use command 'mktape' to " "create media first\n"); exit(1); } } } long ReceiverQid; ReceiverQid = OpenExistingQueue(QKEY); if (ReceiverQid == -1) { fprintf(stderr, "MessageQueue not available\n"); exit(1); } if (SendMsg(ReceiverQid, deviceNo, buf) < 0) { fprintf(stderr, "Message Queue Error: send message\n"); exit(1); } if (device_type == TYPE_LIBRARY) { if (!strcmp(argv[2], "add") && !strcmp(argv[3], "slot")) DisplayResponse(ReceiverQid, ""); if (!strcmp(argv[2], "open") && !strcmp(argv[3], "map")) DisplayResponse(ReceiverQid, ""); if (!strcmp(argv[2], "close") && !strcmp(argv[3], "map")) DisplayResponse(ReceiverQid, ""); if (!strcmp(argv[2], "empty") && !strcmp(argv[3], "map")) DisplayResponse(ReceiverQid, ""); if (!strcmp(argv[2], "list") && !strcmp(argv[3], "map")) DisplayResponse(ReceiverQid, "Contents: "); if (!strcmp(argv[2], "load") && !strcmp(argv[3], "map")) DisplayResponse(ReceiverQid, ""); } exit(0); }
void Replays::HandleSocketMsg(qint8 &cmd, qint8 &content) { SendMsg(cmd, content); }
void ChatDialog::Notify(TNotifyUI& msg) { if (_tcsicmp(msg.sType, _T("windowinit")) == 0) { OnPrepare(msg); } else if (_tcsicmp(msg.sType, _T("killfocus")) == 0) { } else if (_tcsicmp(msg.sType, _T("click")) == 0) { if (_tcsicmp(msg.pSender->GetName(), kCloseButtonControlName) == 0) { OnExit(msg); } else if (_tcsicmp(msg.pSender->GetName(), kMinButtonControlName) == 0) { #if defined(UNDER_CE) ::ShowWindow(m_hWnd, SW_MINIMIZE); #else SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, 0); #endif } else if (_tcsicmp(msg.pSender->GetName(), kMaxButtonControlName) == 0) { #if defined(UNDER_CE) ::ShowWindow(m_hWnd, SW_MAXIMIZE); CControlUI* pControl = static_cast<CControlUI*>(m_PaintManager.FindControl(kMaxButtonControlName)); if( pControl ) pControl->SetVisible(false); pControl = static_cast<CControlUI*>(m_PaintManager.FindControl(kRestoreButtonControlName)); if( pControl ) pControl->SetVisible(true); #else SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, 0); #endif } else if (_tcsicmp(msg.pSender->GetName(), kRestoreButtonControlName) == 0) { #if defined(UNDER_CE) ::ShowWindow(m_hWnd, SW_RESTORE); CControlUI* pControl = static_cast<CControlUI*>(m_PaintManager.FindControl(kMaxButtonControlName)); if( pControl ) pControl->SetVisible(true); pControl = static_cast<CControlUI*>(m_PaintManager.FindControl(kRestoreButtonControlName)); if( pControl ) pControl->SetVisible(false); #else SendMessage(WM_SYSCOMMAND, SC_RESTORE, 0); #endif } else if (_tcsicmp(msg.pSender->GetName(), kFontButtonControlName) == 0) { CContainerUI* pFontbar = static_cast<CContainerUI*>(m_PaintManager.FindControl(kFontbarControlName)); if (pFontbar != NULL) pFontbar->SetVisible(!pFontbar->IsVisible()); } else if (_tcsicmp(msg.pSender->GetName(), kEmotionButtonControlName) == 0) { POINT pt = {0}; CDuiRect rcEmotionBtn = msg.pSender->GetPos(); CDuiRect rcWindow; GetWindowRect(m_hWnd, &rcWindow); pt.y = rcWindow.top + rcEmotionBtn.top; pt.x = rcWindow.left + rcEmotionBtn.left; //emotion_list_window_.SelectEmotion(pt); } else if (_tcsicmp(msg.pSender->GetName(), kSendButtonControlName) == 0) { SendMsg(); } } else if( _tcsicmp(msg.sType, _T("return")) == 0 ) { if (_tcsicmp(msg.pSender->GetName(), kInputRichEditControlName) == 0) { SendMsg(); } } else if (_tcsicmp(msg.sType, _T("timer")) == 0) { return OnTimer(msg); } else if (_tcsicmp(msg.sType, _T("selectchanged")) == 0) { if (_tcsicmp(msg.pSender->GetName(), kColorButtonControlName) == 0) { CContainerUI* pFontbar = static_cast<CContainerUI*>(m_PaintManager.FindControl(kFontbarControlName)); if (pFontbar != NULL) { POINT pt = {0}; CDuiRect rcFontbar = pFontbar->GetPos(); CDuiRect rcColorBtn = msg.pSender->GetPos(); CDuiRect rcWindow; GetWindowRect(m_hWnd, &rcWindow); pt.y = rcWindow.top + rcFontbar.top; pt.x = rcWindow.left + rcColorBtn.left + static_cast<LONG>(rcColorBtn.right - rcColorBtn.left / 2); new CColorPicker(this, pt); } } else if (_tcsicmp(msg.pSender->GetName(), kBoldButtonControlName) == 0) { COptionUI* bold_button = static_cast<COptionUI*>(msg.pSender); if (bold_button != NULL) { bold_ = bold_button->IsSelected(); FontStyleChanged(); } } else if (_tcsicmp(msg.pSender->GetName(), kItalicButtonControlName) == 0) { COptionUI* italic_button = static_cast<COptionUI*>(msg.pSender); if (italic_button != NULL) { italic_ = italic_button->IsSelected(); FontStyleChanged(); } } else if (_tcsicmp(msg.pSender->GetName(), KUnderlineButtonControlName) == 0) { COptionUI* underline_button = static_cast<COptionUI*>(msg.pSender); if (underline_button != NULL) { underline_ = underline_button->IsSelected(); FontStyleChanged(); } } } else if (_tcsicmp(msg.sType, _T("itemselect")) == 0) { if (_tcsicmp(msg.pSender->GetName(), kFontTypeControlName) == 0) { CComboUI* font_type = static_cast<CComboUI*>(msg.pSender); if (font_type != NULL) { font_face_name_ = font_type->GetText(); FontStyleChanged(); } } else if (_tcsicmp(msg.pSender->GetName(), kFontSizeControlName) == 0) { CComboUI* font_size = static_cast<CComboUI*>(msg.pSender); if (font_size != NULL) { font_size_ = _ttoi(font_size->GetText()); FontStyleChanged(); } } } }
// Draw text at the given coordinates. void ScrollView::Text(int x, int y, const char* mystring) { SendMsg("drawText(%d,%d,'%s')", x, TranslateYCoordinate(y), mystring); }
// Set a messagebox. void ScrollView::AddMessageBox() { SendMsg("addMessageBox()"); }
// Open and draw an image given a name at (x,y). void ScrollView::Image(const char* image, int x_pos, int y_pos) { SendMsg("openImage('%s')", image); SendMsg("drawImage('%s',%d,%d)", image, x_pos, TranslateYCoordinate(y_pos)); }
// Clear the canvas. void ScrollView::Clear() { SendMsg("clear()"); }
// Add new submenu to popupmenu. void ScrollView::PopupItem(const char* parent, const char* name) { if (parent == NULL) { parent = ""; } SendMsg("addPopupMenuItem('%s','%s')", parent, name); }
// Set the stroke width. void ScrollView::Stroke(float width) { SendMsg("setStrokeWidth(%f)", width); }
// Zoom the window to the rectangle given upper left corner and // lower right corner. void ScrollView::ZoomToRectangle(int x1, int y1, int x2, int y2) { y1 = TranslateYCoordinate(y1); y2 = TranslateYCoordinate(y2); SendMsg("zoomRectangle(%d,%d,%d,%d)", MIN(x1, x2), MIN(y1, y2), MAX(x1, x2), MAX(y1, y2)); }
// Draw a rectangle using the current pen color. // The rectangle is filled with the current brush color. void ScrollView::Rectangle(int x1, int y1, int x2, int y2) { if (x1 == x2 && y1 == y2) return; // Scrollviewer locks up. SendMsg("drawRectangle(%d,%d,%d,%d)", x1, TranslateYCoordinate(y1), x2, TranslateYCoordinate(y2)); }
void Toolbar::AutoSize(void) { SendMsg(TB_AUTOSIZE, 0L, 0L); }
// Draw an ellipse using the current pen color. // The ellipse is filled with the current brush color. void ScrollView::Ellipse(int x1, int y1, int width, int height) { SendMsg("drawEllipse(%d,%d,%u,%u)", x1, TranslateYCoordinate(y1), width, height); }
bool Toolbar::CheckButton(INT_PTR iCmd, bool bCheck) { BOOL bArg = bCheck ? TRUE : FALSE; return WND_TRUE(SendMsg(TB_CHECKBUTTON, iCmd, bArg)); }
// Set the pen color to the given RGB values. void ScrollView::Pen(int red, int green, int blue, int alpha) { SendMsg("pen(%d,%d,%d,%d)", red, green, blue, alpha); }
bool Toolbar::IsButtonChecked(INT_PTR iCmd) { return (0L != SendMsg(TB_ISBUTTONCHECKED, iCmd, 0L) ? true : false); }
// Set the brush color to the given RGB values. void ScrollView::Brush(int red, int green, int blue, int alpha) { SendMsg("brush(%d,%d,%d,%d)", red, green, blue, alpha); }
bool Toolbar::IsButtonVisible(INT_PTR iCmd) { return (0L == SendMsg(TB_ISBUTTONHIDDEN, iCmd, 0L) ? true : false); }
void cSearchTimerThread::Action(void) { if (EPGSearchConfig.useExternalSVDRP && !cSVDRPClient::SVDRPSendCmd) { LogFile.eSysLog("ERROR - SVDRPSend script not specified or does not exist (use -f option)"); return; } SetPriority(SEARCHTIMER_NICE); m_Active = true; // let VDR do its startup if (!cPluginEpgsearch::VDR_readyafterStartup) LogFile.Log(2, "SearchTimerThread: waiting for VDR to become ready..."); while(Running() && m_Active && !cPluginEpgsearch::VDR_readyafterStartup) Wait.Wait(1000); time_t nextUpdate = time(NULL); while (m_Active && Running()) { time_t now = time(NULL); bool needUpdate = NeedUpdate(); if (now >= nextUpdate || needUpdate) { justRunning = true; if (updateForced & UPDS_WITH_EPGSCAN) { LogFile.Log(1,"starting EPG scan before search timer update"); EITScanner.ForceScan(); do { Wait.Wait(1000); } while(EITScanner.Active() && m_Active && Running()); LogFile.Log(1,"EPG scan finished"); } if (Timers.BeingEdited()) { Wait.Wait(1000); continue; } LogFile.iSysLog("search timer update started"); UserVars.ResetCache(); // reset internal cache of user vars cTimerObjList* pOutdatedTimers = NULL; // for thread safeness we work with a copy of the current searches, // because SVDRP would not work if the main thread would be locked cSearchExts* localSearchExts = SearchExts.Clone(); localSearchExts->SortBy(CompareSearchExtPrioDescTerm); cSearchExt *searchExt = localSearchExts->First(); // reset announcelist announceList.Clear(); while (searchExt && m_Active && Running()) { if (!searchExt->IsActiveAt(now)) { searchExt = localSearchExts->Next(searchExt); continue; } pOutdatedTimers = searchExt->GetTimerList(pOutdatedTimers); cSearchResults* pSearchResults = searchExt->Run(-1, true); if (!pSearchResults) { searchExt = localSearchExts->Next(searchExt); continue; } pSearchResults->SortBy(CompareEventTime); if (searchExt->pauseOnNrRecordings > 0) searchExt->CheckExistingRecordings(pSearchResults); for (cSearchResult* pResultObj = pSearchResults->First(); pResultObj; pResultObj = pSearchResults->Next(pResultObj)) { if (!Running()) break; const cEvent* pEvent = pResultObj->event; if (!pEvent) continue; cChannel *channel = Channels.GetByChannelID(pEvent->ChannelID(), true, true); if (!channel) continue; int index = 0; cTimer *timer = new cTimer(pEvent); // create the file char* file = NULL; if ((file = searchExt->BuildFile(pEvent)) != NULL) { while(strstr(file, "!^pipe^!")) file = strreplace(file, "!^pipe^!", "|"); // revert the translation of '|' in BuildFile if (strstr(file, "!^invalid^!") || strlen(file) == 0) { LogFile.eSysLog("Skipping timer due to invalid or empty filename"); if (time(NULL) <= timer->StopTime()) pOutdatedTimers->DelTimer(timer); delete timer; free(file); continue; } timer->SetFile(file); free(file); } int Priority = searchExt->Priority; int Lifetime = searchExt->Lifetime; // search for an already existing timer bool bTimesMatchExactly = false; cTimer *t = GetTimer(searchExt, pEvent, bTimesMatchExactly); char* Summary = NULL; uint timerMod = tmNoChange; if (t) { // already exists pOutdatedTimers->DelTimer(t); if (!t->HasFlags(tfActive)) { // do not update inactive timers LogFile.Log(2,"timer for '%s~%s' (%s - %s, channel %d) not active - won't be touched", pEvent->Title()?pEvent->Title():"no title", pEvent->ShortText()?pEvent->ShortText():"no subtitle", GETDATESTRING(pEvent), GETTIMESTRING(pEvent), ChannelNrFromEvent(pEvent)); delete timer; continue; } int triggerID = TriggeredFromSearchTimerID(t); if (!pResultObj->needsTimer && !t->Recording()) // not needed { if (triggerID == searchExt->ID) { LogFile.Log(1,"delete timer for '%s~%s' (%s - %s, channel %d)", pEvent->Title()?pEvent->Title():"no title", pEvent->ShortText()?pEvent->ShortText():"no subtitle", GETDATESTRING(pEvent), GETTIMESTRING(pEvent), ChannelNrFromEvent(pEvent)); RemoveTimer(t, pEvent); } else if (triggerID == -1) //manual timer { LogFile.Log(2,"keep obsolete timer for '%s~%s' (%s - %s, channel %d) - was manually created", pEvent->Title()?pEvent->Title():"no title", pEvent->ShortText()?pEvent->ShortText():"no subtitle", GETDATESTRING(pEvent), GETTIMESTRING(pEvent), ChannelNrFromEvent(pEvent)); } delete timer; continue; } if (TimerWasModified(t)) // don't touch timer modified by user { LogFile.Log(2,"timer for '%s~%s' (%s - %s, channel %d) modified by user - won't be touched", pEvent->Title()?pEvent->Title():"no title", pEvent->ShortText()?pEvent->ShortText():"no subtitle", GETDATESTRING(pEvent), GETTIMESTRING(pEvent), ChannelNrFromEvent(pEvent)); delete timer; continue; } if (triggerID > -1 && triggerID != searchExt->ID) { LogFile.Log(2,"timer for '%s~%s' (%s - %s, channel %d) already created by search id %d - won't be touched", pEvent->Title()?pEvent->Title():"no title", pEvent->ShortText()?pEvent->ShortText():"no subtitle", GETDATESTRING(pEvent), GETTIMESTRING(pEvent), ChannelNrFromEvent(pEvent), triggerID); delete timer; continue; } char* pFile = NULL; // File is prepared for svdrp, so prepare t->File for comparision too msprintf(&pFile, "%s", t->File()); pFile = strreplace(pFile, ':', '|'); pFile = strreplace(pFile, " ~", "~"); pFile = strreplace(pFile, "~ ", "~"); Summary = SummaryExtended(searchExt, t, pEvent); if (bTimesMatchExactly && strcmp(pFile, timer->File()) == 0 && (t->Aux() != NULL && strcmp(t->Aux(), Summary) == 0) ) { // dir, title, episode name and summary have not changed if (Summary) free(Summary); delete timer; free(pFile); continue; } else { if (!bTimesMatchExactly) timerMod = (uint)timerMod | tmStartStop; if (strcmp(pFile, timer->File()) != 0) timerMod |= tmFile; if (t->Aux() != NULL && strcmp(t->Aux(), Summary) != 0) { char* oldEventID = GetAuxValue(t, "eventid"); char* newEventID = GetAuxValue(Summary, "eventid"); if (oldEventID && newEventID && strcmp(oldEventID, newEventID) != 0) timerMod |= tmAuxEventID; free(oldEventID); free(newEventID); } if (LogFile.Level() >= 3) // output reasons for a timer modification { if (timerMod & tmStartStop) LogFile.Log(3,"timer for '%s~%s' (%s - %s, channel %d) : start/stop has changed", pEvent->Title()?pEvent->Title():"no title", pEvent->ShortText()?pEvent->ShortText():"no subtitle", GETDATESTRING(pEvent), GETTIMESTRING(pEvent), ChannelNrFromEvent(pEvent)); if (timerMod & tmFile) LogFile.Log(3,"timer for '%s~%s' (%s - %s, channel %d) : title and/or episdode has changed (old: %s, new: %s", pEvent->Title()?pEvent->Title():"no title", pEvent->ShortText()?pEvent->ShortText():"no subtitle", GETDATESTRING(pEvent), GETTIMESTRING(pEvent), ChannelNrFromEvent(pEvent), timer?timer->File():"", pFile); if (timerMod & tmAuxEventID) LogFile.Log(3,"timer for '%s~%s' (%s - %s, channel %d) : aux info for event id has changed", pEvent->Title()?pEvent->Title():"no title", pEvent->ShortText()?pEvent->ShortText():"no subtitle", GETDATESTRING(pEvent), GETTIMESTRING(pEvent), ChannelNrFromEvent(pEvent)); } index = t->Index()+1; Priority = t->Priority(); Lifetime = t->Lifetime(); } free(pFile); if (t->Recording() && t->StopTime() == timer->StopTime()) { // only update recording timers if stop time has changed, since all other settings can't be modified LogFile.Log(2,"timer for '%s~%s' (%s - %s, channel %d) already recording - no changes possible", pEvent->Title()?pEvent->Title():"no title", pEvent->ShortText()?pEvent->ShortText():"no subtitle", GETDATESTRING(pEvent), GETTIMESTRING(pEvent), ChannelNrFromEvent(pEvent)); delete timer; continue; } } else { if (!pResultObj->needsTimer) { delete timer; continue; } } if (searchExt->action == searchTimerActionAnnounceViaOSD) { if (t || // timer already exists or NoAnnounces.InList(pEvent) || // announcement not wanted anymore or (EPGSearchConfig.noAnnounceWhileReplay && cDevice::PrimaryDevice()->Replaying() && !(updateForced & UPDS_WITH_OSD)) // no announce while replay within automatic updates ) { if (Summary) free(Summary); delete timer; continue; } if (!announceList.Lookup(pEvent)) announceList.Add(new cSearchResult(pEvent, searchExt->ID)); if (Summary) free(Summary); delete timer; continue; } if (searchExt->action == searchTimerActionAnnounceViaMail) { if (t || // timer already exists or NoAnnounces.InList(pEvent) || pEvent->StartTime() < time(NULL)) // already started? { if (Summary) free(Summary); delete timer; continue; } mailNotifier.AddAnnounceEventNotification(pEvent->EventID(), pEvent->ChannelID(), searchExt->ID); if (Summary) free(Summary); delete timer; continue; } if (searchExt->action == searchTimerActionSwitchOnly || searchExt->action == searchTimerActionAnnounceAndSwitch) // add to switch list { time_t now = time(NULL); if (now < pEvent->StartTime()) { if (!SwitchTimers.InSwitchList(pEvent)) { cMutexLock SwitchTimersLock(&SwitchTimers); int mode = 0; if (searchExt->action == searchTimerActionAnnounceAndSwitch) mode = 2; LogFile.Log(3,"adding switch timer event for '%s~%s' (%s - %s); search timer: '%s'", pEvent->Title(), pEvent->ShortText()?pEvent->ShortText():"", GETDATESTRING(pEvent), GETTIMESTRING(pEvent), searchExt->search); SwitchTimers.Add(new cSwitchTimer(pEvent, searchExt->switchMinsBefore, mode, searchExt->unmuteSoundOnSwitch)); SwitchTimers.Save(); cSwitchTimerThread::Init(); } } if (Summary) free(Summary); delete timer; continue; } if (AddModTimer(timer, index, searchExt, pEvent, Priority, Lifetime, Summary, timerMod)) { if (index == 0) LogFile.Log(1,"added timer for '%s~%s' (%s - %s); search timer: '%s'", pEvent->Title(), pEvent->ShortText()?pEvent->ShortText():"", GETDATESTRING(pEvent), GETTIMESTRING(pEvent), searchExt->search); else LogFile.Log(1,"modified timer %d for '%s~%s' (%s - %s); search timer: '%s'", index, pEvent->Title(), pEvent->ShortText()?pEvent->ShortText():"", GETDATESTRING(pEvent), GETTIMESTRING(pEvent), searchExt->search); } if (Summary) free(Summary); delete timer; } delete pSearchResults; searchExt = localSearchExts->Next(searchExt); } if (localSearchExts) delete localSearchExts; if (pOutdatedTimers) { if (pOutdatedTimers->Count() > 0) { LogFile.Log(1,"removing outdated timers"); for(cTimerObj *tObj = pOutdatedTimers->First(); tObj; tObj = pOutdatedTimers->Next(tObj)) { cTimer* t = tObj->timer; // timer could have been deleted meanwhile, so check if its still there bool found = false; for(cTimer* checkT = Timers.First(); checkT; checkT = Timers.Next(checkT)) if (checkT == t) { found = true; break; } if (!found) continue; if (TimerWasModified(t)) continue; if (!t->Event()) continue; // if there is no event, we keep the timer, since EPG could have been cleared if (time(NULL) > t->StopTime()) continue; // if this timer has (just) finished, let VDR do the cleanup if (t->Recording()) continue; // do not remove recording timers LogFile.Log(1,"delete timer for '%s' (%s, channel %s)", t->File(), DAYDATETIME(t->StartTime()), CHANNELNAME(t->Channel())); RemoveTimer(t, t->Event()); } LogFile.Log(1,"removing outdated timers - done"); } delete pOutdatedTimers; } TimersDone.ClearOutdated(); TimersDone.Save(); if (announceList.Count() > 0) { cString msgfmt = cString::sprintf(tr("%d new broadcast(s) found! Show them?"), announceList.Count()); if (SendMsg(msgfmt, true,7) == kOk) { m_plugin->showAnnounces = true; cRemote::CallPlugin("epgsearch"); } } CheckEPGHours(); LogFile.iSysLog("search timer update finished"); // check for conflicts if (EPGSearchConfig.checkTimerConflictsAfterUpdate && m_Active && Running()) { LogFile.iSysLog("check for timer conflicts"); cConflictCheck conflictCheck; conflictCheck.Check(); if (conflictCheck.relevantConflicts > 0) { if (EPGSearchConfig.sendMailOnConflicts) { cMailConflictNotifier mailNotifier; mailNotifier.SendConflictNotifications(conflictCheck); } conflictCheck.EvaluateConflCheckCmd(); cString msgfmt = cString::sprintf(tr("%d timer conflict(s)! First at %s. Show them?"), conflictCheck.relevantConflicts, *DateTime(conflictCheck.nextRelevantConflictDate)); bool doMessage = EPGSearchConfig.noConflMsgWhileReplay == 0 || !cDevice::PrimaryDevice()->Replaying() || conflictCheck.nextRelevantConflictDate - now < 2*60*60 || (updateForced & UPDS_WITH_OSD); if (doMessage && SendMsg(msgfmt, true,7) == kOk) { m_plugin->showConflicts = true; cRemote::CallPlugin("epgsearch"); } } LogFile.iSysLog("check for timer conflicts - done"); } // delete expired recordings CheckExpiredRecs(); // check for updates for manual timers CheckManualTimers(); if (m_Active) mailNotifier.SendUpdateNotifications(); if ((updateForced & UPDS_WITH_OSD) && m_Active) SendMsg(tr("Search timer update done!")); // reset service call flag updateForced = 0; m_lastUpdate = time(NULL); nextUpdate = long(m_lastUpdate/60)*60 + (EPGSearchConfig.UpdateIntervall * 60); justRunning = false; } if (m_Active && Running()) Wait.Wait(2000); // to avoid high system load if time%30==0 while (Running() && m_Active && !NeedUpdate() && time(NULL)%30 != 0) // sync heart beat to a multiple of 5secs Wait.Wait(1000); }; LogFile.iSysLog("Leaving search timer thread"); }