#include #include "tab_supervisor.h" #include "abstractclient.h" #include "tab_server.h" #include "tab_room.h" #include "tab_game.h" #include "tab_deck_storage.h" #include "tab_admin.h" #include "tab_message.h" #include "tab_userlists.h" #include "protocol_items.h" #include "pixmapgenerator.h" #include #include CloseButton::CloseButton(QWidget *parent) : QAbstractButton(parent) { setFocusPolicy(Qt::NoFocus); setCursor(Qt::ArrowCursor); resize(sizeHint()); } QSize CloseButton::sizeHint() const { ensurePolished(); int width = style()->pixelMetric(QStyle::PM_TabCloseIndicatorWidth, 0, this); int height = style()->pixelMetric(QStyle::PM_TabCloseIndicatorHeight, 0, this); return QSize(width, height); } void CloseButton::enterEvent(QEvent *event) { update(); QAbstractButton::enterEvent(event); } void CloseButton::leaveEvent(QEvent *event) { update(); QAbstractButton::leaveEvent(event); } void CloseButton::paintEvent(QPaintEvent * /*event*/) { QPainter p(this); QStyleOption opt; opt.init(this); opt.state |= QStyle::State_AutoRaise; if (isEnabled() && underMouse() && !isChecked() && !isDown()) opt.state |= QStyle::State_Raised; if (isChecked()) opt.state |= QStyle::State_On; if (isDown()) opt.state |= QStyle::State_Sunken; if (const QTabBar *tb = qobject_cast(parent())) { int index = tb->currentIndex(); QTabBar::ButtonPosition position = (QTabBar::ButtonPosition) style()->styleHint(QStyle::SH_TabBar_CloseButtonPosition, 0, tb); if (tb->tabButton(index, position) == this) opt.state |= QStyle::State_Selected; } style()->drawPrimitive(QStyle::PE_IndicatorTabClose, &opt, &p, this); } TabSupervisor::TabSupervisor(QWidget *parent) : QTabWidget(parent), client(0), tabServer(0), tabDeckStorage(0), tabAdmin(0) { tabChangedIcon = new QIcon(":/resources/icon_tab_changed.svg"); setElideMode(Qt::ElideRight); setIconSize(QSize(15, 15)); connect(this, SIGNAL(currentChanged(int)), this, SLOT(updateCurrent(int))); } TabSupervisor::~TabSupervisor() { stop(); delete tabChangedIcon; } void TabSupervisor::retranslateUi() { QList tabs; if (tabServer) tabs.append(tabServer); if (tabDeckStorage) tabs.append(tabDeckStorage); QMapIterator roomIterator(roomTabs); while (roomIterator.hasNext()) tabs.append(roomIterator.next().value()); QMapIterator gameIterator(gameTabs); while (gameIterator.hasNext()) tabs.append(gameIterator.next().value()); for (int i = 0; i < tabs.size(); ++i) { setTabText(indexOf(tabs[i]), tabs[i]->getTabText()); tabs[i]->retranslateUi(); } } int TabSupervisor::myAddTab(Tab *tab) { connect(tab, SIGNAL(userEvent(bool)), this, SLOT(tabUserEvent(bool))); return addTab(tab, tab->getTabText()); } void TabSupervisor::start(AbstractClient *_client, ServerInfo_User *userInfo) { client = _client; userName = userInfo->getName(); userLevel = userInfo->getUserLevel(); connect(client, SIGNAL(roomEventReceived(RoomEvent *)), this, SLOT(processRoomEvent(RoomEvent *))); connect(client, SIGNAL(gameEventContainerReceived(GameEventContainer *)), this, SLOT(processGameEventContainer(GameEventContainer *))); connect(client, SIGNAL(gameJoinedEventReceived(Event_GameJoined *)), this, SLOT(gameJoined(Event_GameJoined *))); connect(client, SIGNAL(messageEventReceived(Event_Message *)), this, SLOT(processMessageEvent(Event_Message *))); connect(client, SIGNAL(maxPingTime(int, int)), this, SLOT(updatePingTime(int, int))); tabServer = new TabServer(this, client); connect(tabServer, SIGNAL(roomJoined(ServerInfo_Room *, bool)), this, SLOT(addRoomTab(ServerInfo_Room *, bool))); myAddTab(tabServer); tabUserLists = new TabUserLists(this, client, userInfo); connect(tabUserLists, SIGNAL(openMessageDialog(const QString &, bool)), this, SLOT(addMessageTab(const QString &, bool))); connect(tabUserLists, SIGNAL(userJoined(const QString &)), this, SLOT(processUserJoined(const QString &))); connect(tabUserLists, SIGNAL(userLeft(const QString &)), this, SLOT(processUserLeft(const QString &))); myAddTab(tabUserLists); updatePingTime(0, -1); if (userInfo->getUserLevel() & ServerInfo_User::IsRegistered) { tabDeckStorage = new TabDeckStorage(this, client); myAddTab(tabDeckStorage); } else tabDeckStorage = 0; if (userInfo->getUserLevel() & ServerInfo_User::IsModerator) { tabAdmin = new TabAdmin(this, client, (userInfo->getUserLevel() & ServerInfo_User::IsAdmin)); myAddTab(tabAdmin); } else tabAdmin = 0; retranslateUi(); } void TabSupervisor::startLocal(const QList &_clients) { localClients = _clients; for (int i = 0; i < localClients.size(); ++i) connect(localClients[i], SIGNAL(gameEventContainerReceived(GameEventContainer *)), this, SLOT(processGameEventContainer(GameEventContainer *))); connect(localClients.first(), SIGNAL(gameJoinedEventReceived(Event_GameJoined *)), this, SLOT(localGameJoined(Event_GameJoined *))); } void TabSupervisor::stop() { if ((!client) && localClients.isEmpty()) return; if (client) { disconnect(client, 0, this, 0); client = 0; } if (!localClients.isEmpty()) { for (int i = 0; i < localClients.size(); ++i) localClients[i]->deleteLater(); localClients.clear(); emit localGameEnded(); } clear(); tabServer->deleteLater(); tabServer = 0; tabDeckStorage->deleteLater(); tabDeckStorage = 0; QMapIterator roomIterator(roomTabs); while (roomIterator.hasNext()) roomIterator.next().value()->deleteLater(); roomTabs.clear(); QMapIterator gameIterator(gameTabs); while (gameIterator.hasNext()) gameIterator.next().value()->deleteLater(); gameTabs.clear(); QMapIterator messageIterator(messageTabs); while (messageIterator.hasNext()) messageIterator.next().value()->deleteLater(); messageTabs.clear(); } void TabSupervisor::updatePingTime(int value, int max) { if (!tabServer) return; if (tabServer->getContentsChanged()) return; setTabIcon(0, QIcon(PingPixmapGenerator::generatePixmap(15, value, max))); } void TabSupervisor::closeButtonPressed() { Tab *tab = static_cast(static_cast(sender())->property("tab").value()); tab->closeRequest(); } void TabSupervisor::addCloseButtonToTab(Tab *tab, int tabIndex) { QTabBar::ButtonPosition closeSide = (QTabBar::ButtonPosition) tabBar()->style()->styleHint(QStyle::SH_TabBar_CloseButtonPosition, 0, tabBar()); CloseButton *closeButton = new CloseButton; connect(closeButton, SIGNAL(clicked()), this, SLOT(closeButtonPressed())); closeButton->setProperty("tab", qVariantFromValue((QObject *) tab)); tabBar()->setTabButton(tabIndex, closeSide, closeButton); } void TabSupervisor::gameJoined(Event_GameJoined *event) { TabGame *tab = new TabGame(this, QList() << client, event->getGameId(), event->getGameDescription(), event->getPlayerId(), event->getSpectator(), event->getSpectatorsCanTalk(), event->getSpectatorsSeeEverything(), event->getResuming()); connect(tab, SIGNAL(gameClosing(TabGame *)), this, SLOT(gameLeft(TabGame *))); connect(tab, SIGNAL(openMessageDialog(const QString &, bool)), this, SLOT(addMessageTab(const QString &, bool))); int tabIndex = myAddTab(tab); addCloseButtonToTab(tab, tabIndex); gameTabs.insert(event->getGameId(), tab); setCurrentWidget(tab); } void TabSupervisor::localGameJoined(Event_GameJoined *event) { TabGame *tab = new TabGame(this, localClients, event->getGameId(), event->getGameDescription(), event->getPlayerId(), event->getSpectator(), event->getSpectatorsCanTalk(), event->getSpectatorsSeeEverything(), event->getResuming()); connect(tab, SIGNAL(gameClosing(TabGame *)), this, SLOT(gameLeft(TabGame *))); int tabIndex = myAddTab(tab); addCloseButtonToTab(tab, tabIndex); gameTabs.insert(event->getGameId(), tab); setCurrentWidget(tab); for (int i = 1; i < localClients.size(); ++i) { Command_JoinGame *cmd = new Command_JoinGame(0, event->getGameId()); localClients[i]->sendCommand(cmd); } } void TabSupervisor::gameLeft(TabGame *tab) { emit setMenu(0); gameTabs.remove(tab->getGameId()); removeTab(indexOf(tab)); if (!localClients.isEmpty()) stop(); } void TabSupervisor::addRoomTab(ServerInfo_Room *info, bool setCurrent) { TabRoom *tab = new TabRoom(this, client, userName, info); connect(tab, SIGNAL(roomClosing(TabRoom *)), this, SLOT(roomLeft(TabRoom *))); connect(tab, SIGNAL(openMessageDialog(const QString &, bool)), this, SLOT(addMessageTab(const QString &, bool))); int tabIndex = myAddTab(tab); addCloseButtonToTab(tab, tabIndex); roomTabs.insert(info->getRoomId(), tab); if (setCurrent) setCurrentWidget(tab); } void TabSupervisor::roomLeft(TabRoom *tab) { emit setMenu(0); roomTabs.remove(tab->getRoomId()); removeTab(indexOf(tab)); } TabMessage *TabSupervisor::addMessageTab(const QString &receiverName, bool focus) { if (receiverName == userName) return 0; TabMessage *tab = new TabMessage(this, client, userName, receiverName); connect(tab, SIGNAL(talkClosing(TabMessage *)), this, SLOT(talkLeft(TabMessage *))); int tabIndex = myAddTab(tab); addCloseButtonToTab(tab, tabIndex); messageTabs.insert(receiverName, tab); if (focus) setCurrentWidget(tab); return tab; } void TabSupervisor::talkLeft(TabMessage *tab) { emit setMenu(0); messageTabs.remove(tab->getUserName()); removeTab(indexOf(tab)); } void TabSupervisor::tabUserEvent(bool globalEvent) { Tab *tab = static_cast(sender()); if (tab != currentWidget()) { tab->setContentsChanged(true); setTabIcon(indexOf(tab), *tabChangedIcon); } if (globalEvent) QApplication::alert(this); } void TabSupervisor::processRoomEvent(RoomEvent *event) { TabRoom *tab = roomTabs.value(event->getRoomId(), 0); if (tab) tab->processRoomEvent(event); } void TabSupervisor::processGameEventContainer(GameEventContainer *cont) { TabGame *tab = gameTabs.value(cont->getGameId()); if (tab) { qDebug() << "gameEvent gameId =" << cont->getGameId(); tab->processGameEventContainer(cont, qobject_cast(sender())); } else qDebug() << "gameEvent: invalid gameId"; } void TabSupervisor::processMessageEvent(Event_Message *event) { TabMessage *tab = messageTabs.value(event->getSenderName()); if (!tab) tab = messageTabs.value(event->getReceiverName()); if (!tab) tab = addMessageTab(event->getSenderName(), false); if (!tab) return; tab->processMessageEvent(event); } void TabSupervisor::processUserLeft(const QString &userName) { TabMessage *tab = messageTabs.value(userName); if (tab) tab->processUserLeft(); } void TabSupervisor::processUserJoined(const QString &userName) { TabMessage *tab = messageTabs.value(userName); if (tab) tab->processUserJoined(); } void TabSupervisor::updateCurrent(int index) { if (index != -1) { Tab *tab = static_cast(widget(index)); if (tab->getContentsChanged()) { setTabIcon(index, QIcon()); tab->setContentsChanged(false); } emit setMenu(static_cast(widget(index))->getTabMenu()); } else emit setMenu(0); } bool TabSupervisor::getAdminLocked() const { if (!tabAdmin) return true; return tabAdmin->getLocked(); }