Select Git revision
admin.cpython-36.pyc
-
Marco Wirtz authoredMarco Wirtz authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
overlaycontroller.cpp 7.79 KiB
#include "overlaycontroller.h"
#include <QDesktopWidget>
#include <QStringList>
#include "plugin.h"
#include <qdebug.h>
#include "teamspeak\public_errors.h"
//#ifndef _DEBUG
//#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )
//#endif
struct channelInfo {
uint64 id;
QString name;
uint64 parent;
QTreeWidgetItem* entry;
int order;
};
enum nodeType {
channel,
client,
spacer
};
Q_DECLARE_METATYPE(nodeType);
OverlayController::OverlayController(const struct TS3Functions funcs, quint64 serverConnectionHandlerID) : QObject(), ts3(funcs)
{
QDesktopWidget desktop;
m_screenHeight = desktop.screenGeometry().height();
m_screenWidth = desktop.screenGeometry().width();
m_speakerOffset = 0;
m_debugWindow = new QLabel;
m_debugWindow->setGeometry(320, 200, 750, 500);
m_debugWindow->setAlignment(Qt::AlignTop | Qt::AlignLeft);
m_debugWindow->show();
m_SCHID = serverConnectionHandlerID;
m_tree = new ChannelListWidget;
}
OverlayController::~OverlayController()
{
for (auto &it : m_speakers)
delete it;
m_speakers.clear();
for (auto &it : m_msgLines)
delete it;
m_msgLines.clear();
delete m_debugWindow;
delete m_tree;
}
void OverlayController::deleteChatLine(QWidget * line, QTimer *timer)
{
//TODO: delete the given line instead of the last
int index = m_msgLines.indexOf(line);
if (index != -1)
{
delete m_msgLines.at(index);
m_msgLines.remove(index);
}
if (timer)
delete timer;
}
void OverlayController::treeItemClicked(QTreeWidgetItem * item, int column)
{
int type = item->data(2, Qt::UserRole).toInt();
if (type == channel)
{
anyID clientID;
ts3.getClientID(m_SCHID, &clientID);
quint64 id = item->data(1, Qt::UserRole).value<quint64>();
ts3.requestClientMove(m_SCHID, clientID, id, "", NULL);
}
else if (type == client)
{
anyID id = item->data(1, Qt::UserRole).value<anyID>();
ts3.requestClientPoke(m_SCHID, id, "", NULL);
}
}
void OverlayController::addChatLine(QString message)
{
// generate new chatline
QWidget* w = new QWidget;
QLabel* newChatLine = new QLabel(w);
w->setAttribute(Qt::WA_TranslucentBackground);
w->setAttribute(Qt::WA_ShowWithoutActivating);
w->setWindowFlags(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::WindowTransparentForInput | Qt::SplashScreen);
newChatLine->setText(message);
newChatLine->setStyleSheet("padding:2px;border-radius:5px;border-style:solid;border-width:1px;border-color:rgb(100,100,100);font:bold; font-size:15px;background-color:rgba(50,50,50,150); color:rgb(255,255,255);");
newChatLine->adjustSize();
newChatLine->setAttribute(Qt::WA_ShowWithoutActivating);
newChatLine->setWindowFlags(Qt::WindowStaysOnTopHint | Qt::WindowTransparentForInput);
newChatLine->setAlignment(Qt::AlignCenter | Qt::AlignHCenter);
w->adjustSize();
w->setGeometry(BORDEROFFSET, BORDEROFFSET, w->size().width(), w->size().height() + SPACING);
newChatLine->show();
w->show();
// move old messages down
for (auto &it : m_msgLines)
it->setGeometry(it->geometry().x(), it->geometry().y() + w->size().height(), it->geometry().width(), it->geometry().height());
// inseart new chat line
m_msgLines.push_front(w);
// limit the number of lines
if (m_msgLines.size() > MAXLINES)
deleteChatLine(m_msgLines.last());
// hide after time
QTimer* timer = new QTimer(this);
timer->setSingleShot(true);
timer->setInterval(TIMEOUT);
connect(timer, &QTimer::timeout, [=]() {deleteChatLine(w, timer);});
timer->start();
}
void OverlayController::addSpeaker(QString name)
{
int labelWidth = 0;
QWidget* w = new QWidget;
QLabel* newSpeaker = new QLabel(w);
w->setAttribute(Qt::WA_TranslucentBackground);
w->setAttribute(Qt::WA_ShowWithoutActivating);
w->setWindowFlags(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::WindowTransparentForInput | Qt::SplashScreen);
w->setObjectName(name);
newSpeaker->setText(name);
newSpeaker->setStyleSheet("padding:2px;border-radius:5px;border-style:solid;border-width:1px;border-color:rgb(100,100,100);font:bold; font-size:15px;background-color:rgba(50,50,50,150); color:rgb(255,255,255);");
newSpeaker->adjustSize();
newSpeaker->setAttribute(Qt::WA_ShowWithoutActivating);
newSpeaker->setWindowFlags(Qt::WindowStaysOnTopHint | Qt::WindowTransparentForInput);
newSpeaker->setAlignment(Qt::AlignCenter | Qt::AlignHCenter);
w->adjustSize();
w->setGeometry(BORDEROFFSET + m_speakerOffset, m_screenHeight - BORDEROFFSET - w->size().height(), w->size().width() + SPACING, w->size().height());
labelWidth = w->geometry().width();
newSpeaker->show();
w->show();
m_speakerOffset += labelWidth;
m_speakers.push_back(w);
}
void OverlayController::removeSpeaker(QString name)
{
int index = -1;
int labelWidth = 0;
// move all speaker to the left side and find the one to delete
for (int i = 0; i < m_speakers.size(); i++)
{
QWidget* it = m_speakers.at(i);
it->setGeometry(it->geometry().x() - labelWidth, it->geometry().y(), it->geometry().width(), it->geometry().height());
if (it->objectName() == name)
{
labelWidth = it->geometry().width();
m_speakerOffset -= labelWidth;
index = i;
delete it;
}
}
// remove the deleted label from the list
if (index != -1)
m_speakers.remove(index);
}
void OverlayController::debugPrint(QString text)
{
m_debugWindow->setText(text + "\n" + m_debugWindow->text());
}
void OverlayController::reset()
{
for (auto &it : m_speakers)
delete it;
m_speakers.clear();
for (auto &it : m_msgLines)
delete it;
m_msgLines.clear();
m_speakerOffset = 0;
}
void OverlayController::updateChannelList()
{
if (m_tree->isVisible())
displayChannelList();
}
void OverlayController::displayChannelList()
{
while (int nb = m_tree->getTree()->topLevelItemCount())
{
auto item = m_tree->getTree()->takeTopLevelItem(nb - 1);
disconnect(m_tree->getTree(), &QTreeWidget::itemDoubleClicked, this, &OverlayController::treeItemClicked);
delete item;
}
uint64* channelIDList;
if (ts3.getChannelList(m_SCHID, &channelIDList) != ERROR_ok)
return;
QVector<channelInfo> channelList;
// get Channels
int i(0);
while (channelIDList[i] != NULL)
{
channelInfo tmp;
tmp.id = channelIDList[i];
tmp.name = channelID2Name(m_SCHID, channelIDList[i]);
ts3.getChannelVariableAsInt(m_SCHID, tmp.id, CHANNEL_ORDER, &tmp.order);
ts3.getParentChannelOfChannel(m_SCHID, channelIDList[i], &tmp.parent);
tmp.entry = new QTreeWidgetItem;
tmp.entry->setData(0, Qt::DisplayRole, tmp.name);
tmp.entry->setData(1, Qt::UserRole, tmp.id);
if (tmp.name.startsWith('[') && tmp.name.contains("spacer"))
tmp.entry->setData(2, Qt::UserRole, spacer);
else
tmp.entry->setData(2, Qt::UserRole, channel);
channelList.push_back(tmp);
i++;
}
qSort(channelList.begin(), channelList.end(), [](const channelInfo& a, const channelInfo& b) { return a.order < b.order; });
// build tree structure
for (auto& it : channelList)
{
if (it.parent == 0)
m_tree->getTree()->addTopLevelItem(it.entry);
else
{
bool found(false);
for (auto& it2 : channelList)
{
if (it.parent == it2.id)
{
it2.entry->addChild(it.entry);
found = true;
break;
}
}
if (!found)
{
debugPrint(QString("%1: parent %2 not found").arg(it.name).arg(it.parent));
delete it.entry;
}
}
}
// insert clients
for (auto& it : channelList)
{
anyID* clientIDList;
ts3.getChannelClientList(m_SCHID, it.id, &clientIDList);
int i(0);
while (clientIDList[i] != NULL)
{
QTreeWidgetItem* tmp = new QTreeWidgetItem;
tmp->setData(0, Qt::DisplayRole, clientID2Name(m_SCHID, clientIDList[i]));
tmp->setData(1, Qt::UserRole, clientIDList[i]);
tmp->setData(2, Qt::UserRole, client);
it.entry->addChild(tmp);
i++;
}
}
m_tree->getTree()->expandAll();
connect(m_tree->getTree(), &QTreeWidget::itemDoubleClicked, this, &OverlayController::treeItemClicked);
m_tree->getTree()->adjustSize();
m_tree->adjustSize();
m_tree->show();
}