23 #include "playertable.h"
25 #include "application.h"
27 #include "gui/dockBuddiesList.h"
28 #include "gui/mainwindow.h"
29 #include "serverapi/server.h"
31 #include "serverapi/tooltips/tooltiprenderhint.h"
34 #include <QFontMetrics>
40 static const int MAX_TEAMNAME_SIZE = 100;
48 bool isTeamGame()
const
50 return server->gameMode().isTeamGame();
53 int maxShownPlayers()
const
55 if (this->renderHint.boundingRect().isNull())
58 QFontMetrics fontMetrics(this->renderHint.font());
61 int viewportHeight = this->renderHint.boundingRect().height();
62 viewportHeight = qMax(300, viewportHeight * 80 / 100);
64 return viewportHeight / fontMetrics.height();
72 d->renderHint = renderHint;
76 PlayerTable::~PlayerTable()
80 QString PlayerTable::generateHTML()
82 static const QString css =
"<style>"
84 " background-color: #FFFFFF;"
88 " border-top: 1px solid black;"
89 " border-bottom: 1px solid black;"
92 ".section-header-row th {"
93 " padding-left: 20px;"
99 " white-space: nowrap;"
102 " border-right: 1px dashed gray;"
106 " text-align: right;"
110 const bool isTeamGame = d->isTeamGame();
113 PlayersByTeams playersByTeams;
118 players.spectators(spectators);
120 const int maxShownPlayers = d->maxShownPlayers();
121 const int numSections = qMax(1, playersByTeams.size()
122 + qMin(spectators.size(), 1));
123 int totalPlayers = bots.count() + spectators.count();
124 for (
const PlayersList &players : playersByTeams.values())
126 totalPlayers += players.size();
128 const int maxShownPlayersBySection = (maxShownPlayers > 0 && totalPlayers > maxShownPlayers)
129 ? (maxShownPlayers / numSections)
132 QString table = R
"(<table class="player-table" cellspacing="0" width="100%">)";
133 table += tableHeader();
134 bool separator =
false;
135 for (
int i : playersByTeams.keys())
137 const PlayersList &playersList = playersByTeams[i];
140 table += teamHeader(d->server->teamName(i));
142 table += createPlayerRows(playersList, maxShownPlayersBySection);
144 if (bots.count() > 0)
146 table += sectionHeader(tr(
"Bots"));
147 table += createPlayerRows(bots, maxShownPlayersBySection);
149 if (spectators.count() > 0)
151 table += sectionHeader(tr(
"Spectators"));
152 table += createPlayerRows(spectators, maxShownPlayersBySection);
158 QString PlayerTable::createPlayerRows(
const PlayersList &playerList,
int maxShown)
const
160 DockBuddiesList *buddiesList = (gApp !=
nullptr && gApp->mainWindow() !=
nullptr)
161 ? gApp->mainWindow()->buddiesList()
164 QList<Player> sorted;
165 const QList<Player> *players = &playerList.players();
166 if (maxShown > 0 && playerList.size() > maxShown)
170 sorted = playerList.players();
171 std::sort(sorted.begin(), sorted.end(),
174 if (buddiesList !=
nullptr)
176 if (buddiesList->isBuddy(p1) && !buddiesList->isBuddy(p2))
179 if (!p1.isBot() && p2.isBot())
188 for (
const Player &player : *players)
190 rows += createPlayerRow(player);
191 if (maxShown > 0 && ++totalShown >= maxShown)
196 int remaining =
static_cast<int>(playerList.size()) - maxShown;
199 rows += createMoreRow(remaining);
205 QString PlayerTable::createPlayerRow(
const Player &player)
const
212 else if (player.isSpectating())
214 status = tr(
"SPECTATOR");
218 if (player.ping() != USHRT_MAX)
220 ping = QString::number(player.ping());
226 R"(<td class="number-cell" width="60">%2</td>)"
227 R"(<td class="number-cell" width="60">%3</td>)"
228 R"(<td width="100">%4</td>)"
236 QString PlayerTable::createMoreRow(
int count)
const
238 QString text = tr(
"(and %n more ...)",
nullptr, count);
242 R
"(<td width="60"> </td>)"
243 R"(<td width="60"> </td>)"
244 R"(<td width="100"> </td>)"
249 QString PlayerTable::tableHeader()
const
251 static const bool canCssBorders = CapsQt::canCssCellBorders();
253 const QString PLAYER = tr(
"Player");
254 const QString SCORE = tr(
"Score");
255 const QString PING = tr(
"Ping");
256 const QString STATUS = tr(
"Status");
263 header += R
"(<tr><th colspan="4"><hr width="100%"></th></tr>)";
266 R"(<tr class="header-row">)"
268 R"(<th class="number-cell" width="60"> %2</th>)"
269 R"(<th class="number-cell" width="60"> %3</th>)"
270 R"(<th width="100">%4</th>)"
278 header += R
"(<tr><th colspan="4"><hr width="100%"></th></tr>)";
283 QString PlayerTable::teamHeader(
const QString &teamName)
287 return sectionHeader(tr(
"Team %1").arg(
288 teamName.toHtmlEscaped().left(MAX_TEAMNAME_SIZE)));
291 QString PlayerTable::sectionHeader(
const QString &title)
294 R
"(<tr class="section-header-row">)"