32 C4Rect rcDefault(0,0,10,10);
45 ParentClass::UpdateOwnPos();
47 if (pStatusIcon && pNameLabel)
51 pNameLabel->SetBounds(caMain.
GetAll());
58 const char *szPrefix = pByUser->
getPrefix();
59 if (!szPrefix) szPrefix =
"";
70 pStatusIcon->SetIcon(eStatusIcon);
72 pNameLabel->SetText(pByUser->
getName());
79 const auto *pNickItem1 =
static_cast<const NickItem *
>(pEl1);
80 const auto *pNickItem2 =
static_cast<const NickItem *
>(pEl2);
81 int32_t s1 = pNickItem1->
GetStatus(), s2 = pNickItem2->GetStatus();
82 if (s1 != s2)
return s1 - s2;
83 return stricmp(pNickItem2->GetNick(), pNickItem1->GetNick());
89 C4ChatControl::ChatSheet::ChatSheet(
C4ChatControl *pChatControl,
const char *szTitle,
const char *szIdent, SheetType eType)
90 :
C4GUI::Tabular::
Sheet(szTitle,
C4Rect(0,0,10,10),
C4GUI::
Ico_None, true, false), pChatControl(pChatControl), pNickList(nullptr), pInputLbl(nullptr), iBackBufferIndex(-1), eType(eType), fHasUnread(false)
92 if (szIdent) sIdent.Copy(szIdent);
94 C4Rect rcDefault(0,0,10,10);
95 pChatBox =
new C4GUI::TextWindow(rcDefault,0,0,0,100,4096,
" ",
false,
nullptr,0,
true);
96 pChatBox->SetDecoration(
false,
false,
nullptr,
false);
98 if (eType == CS_Channel)
101 pNickList->SetDecoration(
false,
nullptr,
true,
false);
105 if (eType != CS_Server)
108 pInputEdit->SetToolTip(
LoadResStr(
"IDS_DLGTIP_CHAT"));
111 pInputLbl->SetToolTip(
LoadResStr(
"IDS_DLGTIP_CHAT"));
112 pInputLbl->SetClickFocusControl(pInputEdit);
121 C4ChatControl::ChatSheet::~ChatSheet()
123 delete pKeyHistoryUp;
124 delete pKeyHistoryDown;
127 void C4ChatControl::ChatSheet::UpdateSize()
131 ParentClass::UpdateSize();
135 if (pNickList) pNickList->SetBounds(caMain.GetFromRight(std::max<int32_t>(caMain.GetInnerWidth()/5, 100)));
136 pChatBox->SetBounds(caMain.GetAll());
137 if (pInputLbl) pInputLbl->SetBounds(caChat.GetFromLeft(40));
138 pInputEdit->SetBounds(caChat.GetAll());
141 void C4ChatControl::ChatSheet::OnShown(
bool fByUser)
155 const char *szInputText = pInputEdit->GetText();
157 if (!szInputText || !*szInputText)
170 pInputEdit->SelectAll(); pInputEdit->DeleteSelection();
172 iBackBufferIndex = -1;
177 bool C4ChatControl::ChatSheet::KeyHistoryUpDown(
bool fUp)
180 if (!
IsFocused(pInputEdit))
return false;
181 pInputEdit->SelectAll(); pInputEdit->DeleteSelection();
183 if (!szPrevInput || !*szPrevInput)
184 iBackBufferIndex = -1;
187 pInputEdit->InsertText(szPrevInput,
true);
188 pInputEdit->SelectAll();
193 void C4ChatControl::ChatSheet::OnNickDblClick(
class C4GUI::Element *pEl)
196 NickItem *pNickItem =
static_cast<NickItem *
>(pEl);
197 pChatControl->
OpenQuery(pNickItem->GetNick(),
true,
nullptr);
200 void C4ChatControl::ChatSheet::AddTextLine(
const char *szText, uint32_t dwClr)
204 for (
char c=
'\x01'; c<
' '; ++c)
210 pChatBox->AddTextLine(sText.
getData(), pUseFont, dwClr,
true,
false);
211 pChatBox->ScrollToBottom();
220 void C4ChatControl::ChatSheet::ResetUnread()
230 void C4ChatControl::ChatSheet::DoError(
const char *szError)
239 void C4ChatControl::ChatSheet::Update(
bool fLock)
249 if (eType == CS_Channel)
257 const char *szTopic = pIRCChan->
getTopic();
258 sChatTitle.Format(
"%s%s%s", sIdent.getData(), szTopic ?
": " :
"", szTopic ? szTopic :
"");
259 sChatTitle.EnsureUnicode();
266 NickItem *pNickItem, *pNextNickItem;
268 for (; pUsers; pUsers = pUsers->
getNext())
270 if ((pNickItem = GetNickItem(pUsers->
getName())))
272 pNickItem->Update(pUsers);
277 pNickItem =
new NickItem(pUsers);
278 pNickList->AddElement(pNickItem);
280 pNickItem->SetFlaggedExisting(
true);
283 pNextNickItem = GetFirstNickItem();
284 while ((pNickItem = pNextNickItem))
286 pNextNickItem = GetNextNickItem(pNickItem);
287 if (!pNickItem->IsFlaggedExisting())
295 pNickItem->SetFlaggedExisting(
false);
302 void C4ChatControl::ChatSheet::UserClose()
319 ParentClass::UserClose();
327 for (NickItem *pNickItem = GetFirstNickItem(); pNickItem; pNickItem = GetNextNickItem(pNickItem))
340 C4Rect rcDefault(0,0,10,10);
368 pEdtLoginNick->
SetText(szNick,
false);
369 pEdtLoginRealName->
SetText(szRealName,
false);
380 delete pTitleChangeBC;
385 delete pTitleChangeBC;
386 pTitleChangeBC = pNewCB;
388 if (pTitleChangeBC) pTitleChangeBC->
OnOK(sTitle);
395 ParentClass::UpdateSize();
404 int32_t iLoginWdt = iLoginHgt*2/3;
408 caLogin.
ExpandTop(2*(iIndent1-iIndent2));
411 caLogin.
ExpandTop(2*(iIndent1-iIndent2));
414 caLogin.
ExpandTop(2*(iIndent1-iIndent2));
417 caLogin.
ExpandTop(2*(iIndent1-iIndent2));
429 if (
GetDlg()->GetFocus())
return nullptr;
430 ChatSheet *pActiveSheet = GetActiveChatSheet();
431 if (pActiveSheet)
return pActiveSheet->GetInputEdit();
432 if (pBtnLogin->
IsVisible())
return pBtnLogin;
436 C4ChatControl::ChatSheet *C4ChatControl::GetActiveChatSheet()
441 if (pSheet)
return static_cast<ChatSheet *
>(pSheet);
446 C4ChatControl::ChatSheet *C4ChatControl::GetSheetByIdent(
const char *szIdent, C4ChatControl::ChatSheet::SheetType eType)
449 while ((pSheet = pTabChats->
GetSheet(i++)))
451 ChatSheet *pChatSheet =
static_cast<ChatSheet *
>(pSheet);
452 if ((szCheckIdent = pChatSheet->GetIdent()))
454 if (eType == pChatSheet->GetSheetType())
460 C4ChatControl::ChatSheet *C4ChatControl::GetSheetByTitle(
const char *szTitle, C4ChatControl::ChatSheet::SheetType eType)
463 while ((pSheet = pTabChats->
GetSheet(i++)))
464 if ((szCheckTitle = pSheet->
GetTitle()))
467 ChatSheet *pChatSheet =
static_cast<ChatSheet *
>(pSheet);
468 if (eType == pChatSheet->GetSheetType())
474 C4ChatControl::ChatSheet *C4ChatControl::GetServerSheet()
477 return static_cast<ChatSheet *
>(pTabChats->
GetSheet(0));
539 ChatSheet *pServerSheet = GetServerSheet();
542 pServerSheet->SetChatTitle(sServer.
getData());
565 bool C4ChatControl::IsServiceName(
const char *szName)
568 if (!szName)
return false;
569 const char *szServiceNames [] = {
"NickServ",
"ChanServ",
"MemoServ",
"HelpServ",
"Global",
nullptr }, *szServiceName;
571 while ((szServiceName = szServiceNames[i++]))
583 ChatSheet *pChanSheet = GetSheetByIdent(pChan->getName(), ChatSheet::CS_Channel);
587 pTabChats->
AddCustomSheet(pChanSheet =
new ChatSheet(
this, pChan->getName(), pChan->getName(), ChatSheet::CS_Channel));
594 while ((pSheet = pTabChats->
GetSheet(i++)))
597 ChatSheet *pChatSheet =
static_cast<ChatSheet *
>(pSheet);
598 if (pChatSheet->GetSheetType() == ChatSheet::CS_Channel)
599 if (!(pIRCChan = pIRCClient->
getChannel(pChatSheet->GetTitle())))
607 if (fInitialMessagesReceived)
614 fInitialMessagesReceived =
true;
617 for (; pMsg; pMsg = pMsg->
getNext())
620 ChatSheet *pChatSheet;
StdStrBuf sUser, sIdent;
621 bool fMsgToService =
false;
625 pChatSheet = GetServerSheet();
635 pChatSheet = GetSheetByIdent(pMsg->
getTarget(), ChatSheet::CS_Channel);
637 else if (IsServiceName(sUser.
getData()))
640 pChatSheet = GetServerSheet();
645 pChatSheet = GetActiveChatSheet();
646 if (!pChatSheet) pChatSheet = GetServerSheet();
651 pChatSheet = GetServerSheet();
659 pChatSheet = GetServerSheet();
660 fMsgToService =
true;
665 if (pChatSheet) pChatSheet->SetChatTitle(pMsg->
getTarget());
672 if (pChatSheet) pChatSheet->SetChatTitle(pMsg->
getSource());
722 pChatSheet->AddTextLine(sMsg.
getData(), dwClr);
728 ChatSheet *pActiveSheet = GetActiveChatSheet();
729 if (pActiveSheet) pActiveSheet->Update(
false);
737 ChatSheet *pChatSheet = GetSheetByTitle(szForNick, ChatSheet::CS_Query);
739 if (!pChatSheet && szIdentFallback) pChatSheet = GetSheetByIdent(szIdentFallback, ChatSheet::CS_Query);
743 pTabChats->
AddCustomSheet(pChatSheet =
new ChatSheet(
this, szForNick, szIdentFallback, ChatSheet::CS_Query));
745 pChatSheet->SetChatTitle(szForNick);
750 pChatSheet->SetTitle(szForNick);
751 if (szIdentFallback) pChatSheet->SetIdent(szIdentFallback);
753 if (fSelect) pTabChats->
SelectSheet(pChatSheet,
true);
763 sNewTitle =
LoadResStr(
"IDS_CHAT_NOTCONNECTED");
768 ChatSheet *pActiveSheet = GetActiveChatSheet();
771 sNewTitle = pActiveSheet->GetChatTitle();
777 if (sTitle != sNewTitle)
779 sTitle.
Take(std::move(sNewTitle));
780 if (pTitleChangeBC) pTitleChangeBC->
OnOK(sTitle);
793 void C4ChatControl::ClearChatSheets()
805 bool fIRCSuccess =
true;
809 pChatSheet->DoError(
LoadResStr(
"IDS_ERR_NOTCONNECTEDTOSERVER"));
813 if (!szInput || !*szInput || !pChatSheet)
return fResult;
821 pChatSheet->DoError(
LoadResStr(
"IDS_ERR_HELPCMD"));
833 if (!sParam.
getLength() && pChatSheet->GetSheetType() == ChatSheet::CS_Channel)
835 sParam.
Copy(pChatSheet->GetIdent());
874 const char *szMsgTarget;
877 else szMsgTarget =
"MemoServ";
908 const char *szMsgTarget;
909 ChatSheet::SheetType eSheetType = pChatSheet->GetSheetType();
910 if (eSheetType == ChatSheet::CS_Server)
912 pChatSheet->DoError(
LoadResStr(
"IDS_ERR_NOTONACHANNEL"));
916 szMsgTarget = pChatSheet->GetTitle();
918 fIRCSuccess = pIRCClient->
Action(szMsgTarget, szInput+4);
920 fIRCSuccess = pIRCClient->
Message(szMsgTarget, szInput);
926 pChatSheet->DoError(pIRCClient->
GetError());
948 C4ChatDlg *C4ChatDlg::pInstance =
nullptr;
982 if (!pInstance)
return;
983 pInstance->
Close(
false);
989 if (pInstance && pInstance->
IsShown())
990 pInstance->
Close(
false);
1018 rcPos.
x += rcPos.
Wdt/10; rcPos.
Wdt -= rcPos.
Wdt/5;
1019 rcPos.
y += rcPos.
Hgt/10; rcPos.
Hgt -= rcPos.
Hgt/5;
1027 pInstance =
nullptr;
1029 ParentClass::OnClosed(
fOK);
1036 ParentClass::OnShown();
1044 ParentClass::UpdateSize();
C4Application Application
C4GraphicsResource GraphicsResource
#define C4GUI_InactMessageFontClr
#define C4GUI_DefDlgIndent
#define C4GUI_CaptionFontClr
#define C4GUI_ErrorFontClr
#define C4GUI_NotifyFontClr
#define C4GUI_DefDlgSmallIndent
#define C4GUI_MessageFontClr
#define C4GUI_DefButtonWdt
#define C4GUI_Caption2FontClr
const char * LoadResStr(const char *id)
void SCopy(const char *szSource, char *sTarget, size_t iMaxL)
bool SEqualNoCase(const char *szStr1, const char *szStr2, int iLen)
bool SEqual2NoCase(const char *szStr1, const char *szStr2, int iLen)
StdStrBuf FormatString(const char *szFmt,...)
C4InteractiveThread InteractiveThread
C4Network2IRCClient & IRCClient
void Update(class C4Network2IRCUser *pByUser)
int32_t GetStatus() const
NickItem(class C4Network2IRCUser *pByUser)
void UpdateOwnPos() override
static int32_t SortFunc(const C4GUI::Element *pEl1, const C4GUI::Element *pEl2, void *)
C4GUI::Edit::InputResult OnLoginDataEnter(C4GUI::Edit *edt, bool fPasting, bool fPastingMore)
void SetTitleChangeCB(C4GUI::BaseInputCallback *pNewCB)
virtual class C4GUI::Control * GetDefaultControl()
C4ChatControl(C4Network2IRCClient *pIRC)
void OnConnectBtn(C4GUI::Control *btn)
C4Network2IRCClient * getIRCClient()
bool ProcessInput(const char *szInput, ChatSheet *pChatSheet)
~C4ChatControl() override
void UpdateSize() override
ChatSheet * OpenQuery(const char *szForNick, bool fSelect, const char *szIdentFallback)
static bool IsChatEnabled()
static C4ChatDlg * ShowChat()
void UpdateSize() override
void OnClosed(bool fOK) override
class C4GUI::Control * GetDefaultControl() override
void OnChatTitleChange(const StdStrBuf &sNewTitle)
bool DoPlacement(C4GUI::Screen *pOnScreen, const C4Rect &rPreferredDlgRect) override
static bool IsChatActive()
void OnExitBtn(C4GUI::Control *btn)
char Channel[CFG_MaxString+1]
char Nick[CFG_MaxString+1]
char RealName[CFG_MaxString+1]
char Server[CFG_MaxString+1]
ValidatedStdCopyStrBuf< C4InVal::VAL_NameAllowEmpty > Nick
int32_t HideMsgIRCDangerous
int32_t GetInnerHeight() const
bool GetFromLeft(int32_t iWdt, int32_t iHgt, C4Rect &rcOut)
bool GetCentered(int32_t iWdt, int32_t iHgt, C4Rect &rcOut)
int32_t GetInnerWidth() const
void ExpandTop(int32_t iByHgt)
bool GetFromTop(int32_t iHgt, int32_t iWdt, C4Rect &rcOut)
void GetAll(C4Rect &rcOut)
void AddElement(Element *pChild)
virtual bool IsFocused(Control *pCtrl)
void SetFocus(Control *pCtrl, bool fByMouse)
void SetDelOnClose(bool fToVal=true)
virtual void UserClose(bool fOK)
void AdvanceFocus(bool fBackwards)
void SetTitle(const char *szToTitle, bool fShowCloseButton=true)
bool Show(Screen *pOnScreen, bool fCB)
static int32_t GetDefaultEditHeight()
bool SetText(const char *szText, bool fUser)
void SetPasswordMask(char cNewPasswordMask)
virtual Screen * GetScreen()
C4Rect GetContainedClientRect()
void SetBounds(const C4Rect &rcNewBound)
virtual class Dialog * GetDlg()
void SetToolTip(const char *szNewTooltip, bool is_immediate=false)
bool ShowErrorMessage(const char *szMessage)
void ActivateDialog(Dialog *pDlg)
Sheet(const char *szTitle, const C4Rect &rcBounds, int32_t icoTitle=Ico_None, bool fHasCloseButton=false, bool fTitleMarkup=true)
void SetCaptionColor(uint32_t dwNewClr=0)
Sheet * AddSheet(const char *szTitle, int32_t icoTitle=Ico_None)
void SelectSheet(int32_t iIndex, bool fByUser)
int32_t GetActiveSheetIndex()
Sheet * GetSheet(int32_t iIndex)
void SetDrawDecoration(bool fToVal)
void AddCustomSheet(Sheet *pAddSheet)
void SetSheetMargin(int32_t iMargin)
void ClearCallback(C4InteractiveEventType eEvent, Callback *pnNetworkCallback)
bool AddProc(StdSchedulerProc *pProc)
void SetCallback(C4InteractiveEventType eEvent, Callback *pnNetworkCallback)
virtual const char * GetError() const
bool isUsersLocked() const
C4Network2IRCUser * getUsers() const
const char * getTopic() const
void SetNotify(class C4InteractiveThread *pnNotify)
bool Action(const char *szTarget, const char *szText)
C4Network2IRCMessage * getMessageLog() const
bool Connect(const char *szServer, const char *szNick, const char *szRealName, const char *szPassword=nullptr, const char *szChannel=nullptr)
bool ChangeNick(const char *szNewNick)
void MarkMessageLogRead()
bool Notice(const char *szTarget, const char *szText)
bool Join(const char *szChannel)
C4Network2IRCMessage * getUnreadMessageLog() const
C4Network2IRCChannel * getFirstChannel() const
const char * getUserName() const
C4Network2IRCChannel * getChannel(const char *szName) const
C4Network2IRCChannel * getNextChannel(C4Network2IRCChannel *pPrevChan) const
bool Message(const char *szTarget, const char *szText)
bool Quit(const char *szReason)
bool Part(const char *szChannel)
bool Send(const char *szCommand, const char *szParameters=nullptr)
C4Network2IRCMessageType getType() const
C4Network2IRCMessage * getNext() const
const char * getSource() const
const char * getData() const
const char * getTarget() const
const char * getPrefix() const
C4Network2IRCUser * getNext() const
const char * getName() const
void Set(int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt)
int GetLineHeight() const
void Ref(const char *pnData)
const char * getData() const
bool SplitAtChar(char cSplit, StdStrBuf *psSplit)
int ReplaceChar(char cOld, char cNew)
void Format(const char *szFmt,...) GNUC_FORMAT_ATTRIBUTE_O
void GUISound(const char *szSound)
bool ValidateString(char *szString, ValidationOption eOption, size_t iMaxSize)