The complete source code of IdealIRC http://www.idealirc.org/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
idealirc/IWin/IWinStatus.cpp

236 lines
6.5 KiB

/*
* IdealIRC - Internet Relay Chat client
* Copyright (C) 2019 Tom-Andre Barstad
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "IWinStatus.h"
#include "IWinChannel.h"
#include "MdiManager.h"
#include "Script/Manager.h"
#include "IRC.h"
#include <QMessageBox>
int IWinStatus::StatusWindowCount = 0;
IWinStatus::IWinStatus(const QString& buttonText)
: IWin(Type::Status)
, connection(*this)
{
setButtonText(buttonText);
++StatusWindowCount;
layout = new QVBoxLayout();
view = new IIRCView();
input = new ILineEdit([this](int a, QString& b){ return tabComplete(a,b); });
static int connectionIdCount{ 0 };
connect(view, &IIRCView::customContextMenuRequested, [this](const QPoint& point){
menuSymbols.set("cid", ++connectionIdCount);
ScriptManager::instance()->contextMenuPopup(ScriptMenuType::Status, mapToGlobal(point), menuSymbols);
});
layout->setMargin(0);
layout->setSpacing(2);
layout->addWidget(view);
layout->addWidget(input);
setLayout(layout);
setTabOrder(input, view);
view->setFocusPolicy(Qt::FocusPolicy::NoFocus);
connect(input, &ILineEdit::returnPressed,
this, &IWinStatus::inputEnter);
connect(&connection, &IRC::connected, [this] {
MdiManager::instance().connectionStateChange();
refreshWindowTitle();
});
connect(&connection, &IRC::registered, [this] {
refreshWindowTitle();
});
connect(&connection, &IRC::disconnected, [this] {
disconnectedFromServer();
MdiManager::instance().connectionStateChange();
refreshWindowTitle();
});
Qt_Eventloop_Hook();
}
bool IWinStatus::print(const PrintType ptype, const QString& text)
{
view->print(ptype, text);
MdiManager::instance().highlight(this, HL_Activity);
return true;
}
void IWinStatus::refreshWindowTitle()
{
const auto& isupport = connection.isupport();
const auto it = isupport.find("NETWORK");
QString title;
if (!connection.isOnline() && !connection.isConnected())
title = tr("Status (Offline)");
else if (!connection.isOnline() && connection.isConnected())
title = tr("Status (Registering)");
else if (it == isupport.end())
title = QStringLiteral("%1 (%2)")
.arg(QString::fromStdString( connection.getNickname() ))
.arg(QString::fromStdString( connection.getHostname() ));
else
title = QStringLiteral("%1 (%2)")
.arg(QString::fromStdString( connection.getNickname() ))
.arg(QString::fromStdString( it->second ));
setWindowTitle(title);
MdiManager::instance().renameWindowButton(this, title);
}
void IWinStatus::printTo(const QString& target, const PrintType ptype, const QString& text)
{
MdiManager::instance().print(this, target, ptype, text);
}
void IWinStatus::printToTypes(const IWin::Type toType, const PrintType ptype, const QString& text)
{
MdiManager::instance().printToTypes(this, toType, ptype, text);
}
void IWinStatus::printToActive(const PrintType ptype, const QString& text)
{
MdiManager::instance().printToActive(this, ptype, text);
}
void IWinStatus::printToAll(const PrintType ptype, const QString& text)
{
MdiManager::instance().printToAll(this, ptype, text);
}
IWinChannel* IWinStatus::createChannelWindow(const QString& name)
{
auto& mdiManager = MdiManager::instance();
IWin* subwinBase = mdiManager.findWindow(this, name);
if (!subwinBase)
subwinBase = mdiManager.createSubwindow(this, name, IWin::Type::Channel);
return dynamic_cast<IWinChannel*>(subwinBase);
}
IWin* IWinStatus::createPrivateWindow(const QString& target, bool setFocus)
{
auto& mdiManager = MdiManager::instance();
IWin* subwinBase = mdiManager.findWindow(this, target);
if (!subwinBase)
subwinBase = mdiManager.createSubwindow(this, target, IWin::Type::Private, setFocus);
return subwinBase;
}
IWin* IWinStatus::getActiveWindow()
{
auto& mdiManager = MdiManager::instance();
if (mdiManager.currentWindow()->getStatusParent() != this)
return this;
return mdiManager.currentWindow();
}
QList<IWin*> IWinStatus::subWindows() const
{
return MdiManager::instance().childrenOf(this);
}
void IWinStatus::closeEvent(QCloseEvent* evt)
{
auto& mdiManager = MdiManager::instance();
if (StatusWindowCount == 1 ||
(connection.isConnected() && QMessageBox::question(this, tr("Close status window"), tr("This status window has a connection. Close?"))
== QMessageBox::No)) {
evt->ignore();
return;
}
if (connection.isConnected()) {
connect(&connection, &IRC::disconnected, [&] { closeAllChildren(); mdiManager.toMdiwin(this)->close(); });
connection.disconnectFromServer();
evt->ignore();
return;
}
--StatusWindowCount;
IWin::closeEvent(evt);
}
void IWinStatus::inputEnter()
{
QString text = input->text();
input->clear();
InputHandler inHndl(connection);
inHndl.parse(*this, text);
}
void IWinStatus::closeAllChildren()
{
auto& mdiManager = MdiManager::instance();
QList<QMdiSubWindow*> subwinList = mdiManager.mdiChildrenOf(this);
for (QMdiSubWindow* subwin : subwinList)
subwin->close();
}
void IWinStatus::Qt_Eventloop_Hook()
{
const int nextInterval = connection.poll() ? 0 : 10;
QTimer::singleShot(nextInterval, this, std::bind(&IWinStatus::Qt_Eventloop_Hook, this));
}
void IWinStatus::disconnectedFromServer()
{
const auto printDisconnected = [this](IWin* sw){
sw->print(PrintType::ProgramInfo, tr("Disconnected"));
};
printDisconnected(this);
auto subwins = subWindows();
for (auto* sw : subwins) {
if (sw->getType() == IWin::Type::Channel) {
auto* chan = dynamic_cast<IWinChannel*>(sw);
chan->resetNicklist();
printDisconnected(chan);
}
else if (sw->getType() == IWin::Type::Private) {
printDisconnected(sw);
}
}
}
int IWinStatus::tabComplete(int index, QString& pattern)
{
if (pattern.isEmpty() || !connection.isOnline())
return 0;
if (connection.isChannelSymbol( pattern[0].toLatin1() ))
return connection.channelAutoComplete(index, pattern);
return 0;
}