//----------------------------------------------------------------------------- // Draw a string, centred in the space of a single position, with spaces on // the left and right. Draws on the upper line of the position. //----------------------------------------------------------------------------- static void CenterWithSpaces(int cx, int cy, char *str, BOOL powered, BOOL isName) { int extra = POS_WIDTH - FormattedStrlen(str); PoweredText(powered); if(isName) NameText(); DrawChars(cx + (extra/2), cy + (POS_HEIGHT/2) - 1, str); if(isName) BodyText(); }
//----------------------------------------------------------------------------- // Draw a leaf element. Special things about a leaf: no need to recurse // further, and we must put it into the display matrix. //----------------------------------------------------------------------------- static BOOL DrawLeaf(int which, ElemLeaf *leaf, int *cx, int *cy, BOOL poweredBefore) { int cx0 = *cx, cy0 = *cy; BOOL poweredAfter = leaf->poweredAfter; switch(which) { case ELEM_COMMENT: { char tbuf[MAX_COMMENT_LEN]; char tlbuf[MAX_COMMENT_LEN+8]; strcpy(tbuf, leaf->d.comment.str); char *b = strchr(tbuf, '\n'); if(b) { if(b[-1] == '\r') b[-1] = '\0'; *b = '\0'; sprintf(tlbuf, "\x03 ; %s\x02", tbuf); DrawChars(*cx, *cy + (POS_HEIGHT/2) - 1, tlbuf); sprintf(tlbuf, "\x03 ; %s\x02", b+1); DrawChars(*cx, *cy + (POS_HEIGHT/2), tlbuf); } else { sprintf(tlbuf, "\x03 ; %s\x02", tbuf); DrawChars(*cx, *cy + (POS_HEIGHT/2) - 1, tlbuf); } *cx += ColsAvailable*POS_WIDTH; break; } case ELEM_PLACEHOLDER: { NormText(); CenterWithWiresWidth(*cx, *cy, "--", FALSE, FALSE, 2); *cx += POS_WIDTH; break; } case ELEM_CONTACTS: { char buf[4]; ElemContacts *c = &leaf->d.contacts; buf[0] = ']'; buf[1] = c->negated ? '/' : ' '; buf[2] = '['; buf[3] = '\0'; CenterWithSpaces(*cx, *cy, c->name, poweredAfter, TRUE); CenterWithWires(*cx, *cy, buf, poweredBefore, poweredAfter); *cx += POS_WIDTH; break; } { char *s; case ELEM_EQU: s = "=="; goto cmp; case ELEM_NEQ: s = "/="; goto cmp; case ELEM_GRT: s = ">"; goto cmp; case ELEM_GEQ: s = ">="; goto cmp; case ELEM_LES: s = "<"; goto cmp; case ELEM_LEQ: s = "<="; goto cmp; cmp: char s1[POS_WIDTH+10], s2[POS_WIDTH+10]; int l1, l2, lmax; l1 = 2 + 1 + strlen(s) + strlen(leaf->d.cmp.op1); l2 = 2 + 1 + strlen(leaf->d.cmp.op2); lmax = max(l1, l2); memset(s1, ' ', sizeof(s1)); s1[0] = '['; int lcmp = lmax < POS_WIDTH ? lmax : POS_WIDTH; s1[lcmp - 1] = ']'; s1[lcmp] = '\0'; strcpy(s2, s1); if(l1 >= POS_WIDTH) { memcpy(s1 + 1, leaf->d.cmp.op1, 3); memset(s1 + 4, '.', 3); memcpy(s1 + 7, leaf->d.cmp.op1 + strlen(leaf->d.cmp.op1) - 3, 3); memcpy(s1 + 9 + 2, s, strlen(s)); } else { memcpy(s1 + 1, leaf->d.cmp.op1, strlen(leaf->d.cmp.op1)); memcpy(s1 + strlen(leaf->d.cmp.op1) + 2, s, strlen(s)); } if(l2 >= POS_WIDTH) { memcpy(s2 + 1, leaf->d.cmp.op2, 3); memset(s2 + 4, '.', 3); memcpy(s2 + 7, leaf->d.cmp.op2 + strlen(leaf->d.cmp.op2) - 3, 3); } else { memcpy(s2 + 2, leaf->d.cmp.op2, strlen(leaf->d.cmp.op2)); } CenterWithSpaces(*cx, *cy, s1, poweredAfter, FALSE); CenterWithWires(*cx, *cy, s2, poweredBefore, poweredAfter); *cx += POS_WIDTH; break; } case ELEM_OPEN: CenterWithWires(*cx, *cy, "+ +", poweredBefore, poweredAfter); *cx += POS_WIDTH; break; case ELEM_SHORT: CenterWithWires(*cx, *cy, "+------+", poweredBefore, poweredAfter); *cx += POS_WIDTH; break; case ELEM_ONE_SHOT_RISING: case ELEM_ONE_SHOT_FALLING: { char *s1, *s2; if(which == ELEM_ONE_SHOT_RISING) { s1 = " _ "; s2 = "[\x01OSR\x02_/ ]"; } else if(which == ELEM_ONE_SHOT_FALLING) { s1 = " _ "; s2 = "[\x01OSF\x02 \\_]"; } else oops(); CenterWithSpaces(*cx, *cy, s1, poweredAfter, FALSE); CenterWithWires(*cx, *cy, s2, poweredBefore, poweredAfter); *cx += POS_WIDTH; break; } case ELEM_CTU: case ELEM_CTD: { char *s; if(which == ELEM_CTU) s = "\x01""CTU\x02"; else if(which == ELEM_CTD) s = "\x01""CTD\x02"; else oops(); char buf[256]; ElemCounter *c = &leaf->d.counter; sprintf(buf, "[%s >=%d]", s, c->max); CenterWithSpaces(*cx, *cy, c->name, poweredAfter, TRUE); CenterWithWires(*cx, *cy, buf, poweredBefore, poweredAfter); *cx += POS_WIDTH; break; } case ELEM_RTO: case ELEM_TON: case ELEM_TOF: { char *s; if(which == ELEM_TON) s = "\x01TON\x02"; else if(which == ELEM_TOF) s = "\x01TOF\x02"; else if(which == ELEM_RTO) s = "\x01RTO\x02"; else oops(); char buf[256]; ElemTimer *t = &leaf->d.timer; if(t->delay >= 1000*1000) { sprintf(buf, "[%s %.3f s]", s, t->delay/1000000.0); } else if(t->delay >= 100*1000) { sprintf(buf, "[%s %.1f ms]", s, t->delay/1000.0); } else { sprintf(buf, "[%s %.2f ms]", s, t->delay/1000.0); } CenterWithSpaces(*cx, *cy, t->name, poweredAfter, TRUE); CenterWithWires(*cx, *cy, buf, poweredBefore, poweredAfter); *cx += POS_WIDTH; break; } case ELEM_FORMATTED_STRING: { // Careful, string could be longer than fits in our space. char str[POS_WIDTH*2]; memset(str, 0, sizeof(str)); char *srcStr = leaf->d.fmtdStr.string; memcpy(str, srcStr, min(strlen(srcStr), POS_WIDTH*2 - 7)); char bot[100]; sprintf(bot, "{\"%s\"}", str); int extra = 2*POS_WIDTH - strlen(leaf->d.fmtdStr.var); PoweredText(poweredAfter); NameText(); DrawChars(*cx + (extra/2), *cy + (POS_HEIGHT/2) - 1, leaf->d.fmtdStr.var); BodyText(); CenterWithWiresWidth(*cx, *cy, bot, poweredBefore, poweredAfter, 2*POS_WIDTH); *cx += 2*POS_WIDTH; break; } case ELEM_UART_RECV: case ELEM_UART_SEND: CenterWithWires(*cx, *cy, (char *)((which == ELEM_UART_RECV) ? "{UART RECV}" : "{UART SEND}"), poweredBefore, poweredAfter); CenterWithSpaces(*cx, *cy, leaf->d.uart.name, poweredAfter, TRUE); *cx += POS_WIDTH; break; default: poweredAfter = DrawEndOfLine(which, leaf, cx, cy, poweredBefore); break; } // And now we can enter the element into the display matrix so that the // UI routines know what element is at position (gx, gy) when the user // clicks there, and so that we know where to put the cursor if this // element is selected. // Don't use original cx0, as an end of line element might be further // along than that. cx0 = *cx - POS_WIDTH; int gx = cx0/POS_WIDTH; int gy = cy0/POS_HEIGHT; if(CheckBoundsUndoIfFails(gx, gy)) return FALSE; DM_BOUNDS(gx, gy); DisplayMatrix[gx][gy] = leaf; DisplayMatrixWhich[gx][gy] = which; int xadj = 0; switch(which) { case ELEM_ADD: case ELEM_SUB: case ELEM_MUL: case ELEM_DIV: case ELEM_FORMATTED_STRING: DM_BOUNDS(gx-1, gy); DisplayMatrix[gx-1][gy] = leaf; DisplayMatrixWhich[gx-1][gy] = which; xadj = POS_WIDTH*FONT_WIDTH; break; } if(which == ELEM_COMMENT) { int i; for(i = 0; i < ColsAvailable; i++) { DisplayMatrix[i][gy] = leaf; DisplayMatrixWhich[i][gy] = ELEM_COMMENT; } xadj = (ColsAvailable-1)*POS_WIDTH*FONT_WIDTH; } int x0 = X_PADDING + cx0*FONT_WIDTH; int y0 = Y_PADDING + cy0*FONT_HEIGHT; if(leaf->selectedState != SELECTED_NONE && leaf == Selected) { SelectionActive = TRUE; } switch(leaf->selectedState) { case SELECTED_LEFT: Cursor.left = x0 + FONT_WIDTH - 4 - xadj; Cursor.top = y0 - FONT_HEIGHT/2; Cursor.width = 2; Cursor.height = POS_HEIGHT*FONT_HEIGHT; break; case SELECTED_RIGHT: Cursor.left = x0 + (POS_WIDTH-1)*FONT_WIDTH - 5; Cursor.top = y0 - FONT_HEIGHT/2; Cursor.width = 2; Cursor.height = POS_HEIGHT*FONT_HEIGHT; break; case SELECTED_ABOVE: Cursor.left = x0 + FONT_WIDTH/2 - xadj; Cursor.top = y0 - 2; Cursor.width = (POS_WIDTH-2)*FONT_WIDTH + xadj; Cursor.height = 2; break; case SELECTED_BELOW: Cursor.left = x0 + FONT_WIDTH/2 - xadj; Cursor.top = y0 + (POS_HEIGHT-1)*FONT_HEIGHT + FONT_HEIGHT/2 - 2; Cursor.width = (POS_WIDTH-2)*(FONT_WIDTH) + xadj; Cursor.height = 2; break; default: break; } return poweredAfter; }
int XmppMessageReciveTask::ProcessStart(void) { static buzz::StaticQName QN_DELAY = { "urn:xmpp:delay", "delay" }; // 获取下一个stanza const auto stanza = NextStanza(); if (stanza == nullptr) { return STATE_BLOCKED; } // 获取消息体 const auto body = stanza->FirstNamed(buzz::QN_BODY); if (body == nullptr) { return STATE_BLOCKED; } XmppMessageInfo message; // 消息id message.SetUid(Utf8ToWStr(stanza->Attr(buzz::QN_ID))); // 消息类型 message.SetType(Utf8ToWStr(stanza->Attr(buzz::QN_TYPE))); // 获取发送人 std::wstring from(Utf8ToWStr(stanza->Attr(buzz::QN_FROM))); message.SetFrom(from); message.SetFromResource(from); // 获取接收人 message.SetTo(Utf8ToWStr(stanza->Attr(buzz::QN_TO))); message.SetToResource(Utf8ToWStr(stanza->Attr(buzz::QN_TO))); // 获取消息 message.SetContent(conv.from_bytes(body->BodyText())); // 获取时间 const auto delay = stanza->FirstNamed(QN_DELAY); if (delay != nullptr) { message.SetTime(Utf8ToWStr(delay->Attr(buzz::kQnStamp))); } // 是否离线消息 message.SetIsOfflineMsg(delay != nullptr); // 获取主题 const auto subject = stanza->FirstNamed(buzz::QN_SUBJECT); if (subject != nullptr) { message.SetSubject(Utf8ToWStr(subject->BodyText())); // 主题数据 if (subject->HasAttr(buzz::QN_VALUE)) { message.SetSubjectValue(Utf8ToWStr(subject->Attr(buzz::QN_VALUE))); } } // 获取扩展数据 auto extention = stanza->FirstNamed(QN_EXTENTION); if (extention != nullptr) { std::map<std::wstring, std::wstring> mapValue; auto elChild = extention->FirstElement(); while (elChild != nullptr) { auto name = elChild->Name().LocalPart(); mapValue.emplace(Utf8ToWStr(name), Utf8ToWStr(elChild->BodyText().c_str())); elChild = elChild->NextElement(); } message.SetExtention(mapValue); } MessageReceived(message); return STATE_START; }
BEmailMessage * BEmailMessage::ReplyMessage(mail_reply_to_mode replyTo, bool accountFromMail, const char *quoteStyle) { BEmailMessage *reply = new BEmailMessage; // Set ReplyTo: if (replyTo == B_MAIL_REPLY_TO_ALL) { reply->SetTo(From()); BList list; get_address_list(list, CC(), extract_address); get_address_list(list, To(), extract_address); // Filter out the sender BMailAccounts accounts; BMailAccountSettings* account = accounts.AccountByID(Account()); BString sender; if (account) sender = account->ReturnAddress(); extract_address(sender); BString cc; for (int32 i = list.CountItems(); i-- > 0;) { char *address = (char *)list.RemoveItem((int32)0); // add everything which is not the sender and not already in the list if (sender.ICompare(address) && cc.FindFirst(address) < 0) { if (cc.Length() > 0) cc << ", "; cc << address; } free(address); } if (cc.Length() > 0) reply->SetCC(cc.String()); } else if (replyTo == B_MAIL_REPLY_TO_SENDER || ReplyTo() == NULL) reply->SetTo(From()); else reply->SetTo(ReplyTo()); // Set special "In-Reply-To:" header (used for threading) const char *messageID = _body ? _body->HeaderField("Message-Id") : NULL; if (messageID != NULL) reply->SetHeaderField("In-Reply-To", messageID); // quote body text reply->SetBodyTextTo(BodyText()); if (quoteStyle) reply->Body()->Quote(quoteStyle); // Set the subject (and add a "Re:" if needed) BString string = Subject(); if (string.ICompare("re:", 3) != 0) string.Prepend("Re: "); reply->SetSubject(string.String()); // set the matching outbound chain if (accountFromMail) reply->SendViaAccountFrom(this); return reply; }