Пример #1
0
//-----------------------------------------------------------------------------
// 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();
}
Пример #2
0
//-----------------------------------------------------------------------------
// 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;
}
Пример #4
0
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;
}