serverfilterbuildermenu.cpp
1 //------------------------------------------------------------------------------
2 // serverfilterbuildermenu.cpp
3 //------------------------------------------------------------------------------
4 //
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License, or (at your option) any later version.
9 //
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 // 02110-1301 USA
19 //
20 //------------------------------------------------------------------------------
21 // Copyright (C) 2013 "Zalewa" <zalewapl@gmail.com>
22 //------------------------------------------------------------------------------
23 #include "serverfilterbuildermenu.h"
24 
25 #include "gui/entity/serverlistfilterinfo.h"
26 #include "serverapi/server.h"
28 
29 DClass<ServerFilterBuilderMenu>
30 {
31 public:
32  QHostAddress address;
33  ServerListFilterInfo filter;
34  QString gameMode;
35  unsigned maxPing;
36 
37  static void addIfNotContains(QStringList &target, const QString &candidate)
38  {
39  if (!target.contains(candidate, Qt::CaseInsensitive))
40  target << candidate;
41  }
42 };
43 
44 DPointered(ServerFilterBuilderMenu)
45 
47  const ServerListFilterInfo &filter, QWidget *parent)
48  : QMenu(tr("Build server filter ..."), parent)
49 {
50  d->filter = filter;
51  d->address = server.address();
52  d->gameMode = server.gameMode().name();
53  d->maxPing = server.ping();
54 
55  addAction(this, tr("Show only servers with ping lower than %1").arg(d->maxPing),
56  SLOT(applyPingFilter()));
57  if (!d->filter.gameModes.contains(d->gameMode, Qt::CaseInsensitive))
58  {
59  addAction(this, tr("Filter by game mode \"%1\"").arg(d->gameMode),
60  SLOT(applyGameModeFilter()));
61  }
62  if (!d->filter.gameModesExcluded.contains(d->gameMode, Qt::CaseInsensitive))
63  {
64  addAction(this, tr("Hide game mode \"%1\"").arg(d->gameMode),
65  SLOT(applyGameModeExcludedFilter()));
66  }
67 
68  QMenu *includeWads = new QMenu(tr("Include WAD ..."), this);
69  QMenu *excludeWads = new QMenu(tr("Exclude WAD ..."), this);
70 
71  QStringList wads = server.allWadNames();
72  for (const QString &wad : wads)
73  {
74  if (!d->filter.wadsExcluded.contains(wad, Qt::CaseInsensitive))
75  mkExcludeWadAction(excludeWads, wad);
76  if (!d->filter.wads.contains(wad, Qt::CaseInsensitive))
77  mkIncludeWadAction(includeWads, wad);
78  }
79 
80  if (!excludeWads->isEmpty())
81  addMenu(excludeWads);
82  if (!includeWads->isEmpty())
83  addMenu(includeWads);
84 
85  addAction(this, tr("Filter by address"), SLOT(applyAddressFilter()));
86 }
87 
88 ServerFilterBuilderMenu::~ServerFilterBuilderMenu()
89 {
90 }
91 
92 QAction *ServerFilterBuilderMenu::addAction(QMenu *menu, const QString &text, const char *slot)
93 {
94  auto action = new QAction(menu);
95  action->setText(text);
96  this->connect(action, SIGNAL(triggered()), slot);
97  menu->addAction(action);
98  return action;
99 }
100 
101 void ServerFilterBuilderMenu::applyAddressFilter()
102 {
103  const int mask = d->address.toIPv4Address() ? 32 : 128;
104  auto subnet = qMakePair(d->address, mask);
105  if (!d->filter.addresses.contains(subnet))
106  d->filter.addresses << subnet;
107 }
108 
109 void ServerFilterBuilderMenu::applyGameModeExcludedFilter()
110 {
111  if (!d->filter.gameModesExcluded.contains(d->gameMode, Qt::CaseInsensitive))
112  d->filter.gameModesExcluded << d->gameMode;
113 }
114 
115 void ServerFilterBuilderMenu::applyGameModeFilter()
116 {
117  if (!d->filter.gameModes.contains(d->gameMode, Qt::CaseInsensitive))
118  d->filter.gameModes << d->gameMode;
119 }
120 
121 void ServerFilterBuilderMenu::applyPingFilter()
122 {
123  d->filter.maxPing = d->maxPing;
124 }
125 
126 void ServerFilterBuilderMenu::excludeWadFromAction()
127 {
128  auto action = static_cast<QAction *>(sender());
129  PrivData<ServerFilterBuilderMenu>::addIfNotContains(d->filter.wadsExcluded, action->text());
130 }
131 
132 const ServerListFilterInfo &ServerFilterBuilderMenu::filter() const
133 {
134  return d->filter;
135 }
136 
137 void ServerFilterBuilderMenu::includeWadFromAction()
138 {
139  auto action = static_cast<QAction *>(sender());
140  PrivData<ServerFilterBuilderMenu>::addIfNotContains(d->filter.wads, action->text());
141 }
142 
143 QAction *ServerFilterBuilderMenu::mkExcludeWadAction(QMenu *menu, const QString &wadName)
144 {
145  return addAction(menu, wadName, SLOT(excludeWadFromAction()));
146 }
147 
148 QAction *ServerFilterBuilderMenu::mkIncludeWadAction(QMenu *menu, const QString &wadName)
149 {
150  return addAction(menu, wadName, SLOT(includeWadFromAction()));
151 }