serverlistcontextmenu.cpp
1 //------------------------------------------------------------------------------
2 // serverlistcontextmenu.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) 2010 "Zalewa" <zalewapl@gmail.com>
22 //------------------------------------------------------------------------------
23 #include "serverlistcontextmenu.h"
24 
25 #include "clipboard.h"
26 #include "customservers.h"
27 #include "gui/entity/serverlistfilterinfo.h"
28 #include "gui/serverlist.h"
29 #include "gui/widgets/serverfilterbuildermenu.h"
30 #include "serverapi/server.h"
31 #include "strings.hpp"
32 #include <cassert>
33 #include <QApplication>
34 #include <QModelIndex>
35 
36 DClass<ServerListContextMenu>
37 {
38 public:
39  QAction *copyAddress;
40  QAction *copyEmail;
41  QAction *copyName;
42  QAction *copyUrl;
43  QAction *clearAdditionalSorting;
44  QAction *findMissingWads;
45  QAction *join;
46  QAction *openUrlInDefaultBrowser;
47  QAction *rcon;
48  QAction *refresh;
49  QAction *removeAdditionalSortingForColumn;
50  QAction *showJoinCommandLine;
51  QAction *sortAdditionallyAscending;
52  QAction *sortAdditionallyDescending;
53  QAction *toggleServerPinned;
54  QMenu *menu;
55  ServerFilterBuilderMenu *filterBuilder;
56  ServerPtr serverAtIndex;
57  QModelIndex modelIndex;
58  ServerListFilterInfo serverFilter;
59  QList<ServerPtr> servers;
60  ServerList *parent;
61 
62  bool isServerPinned() const
63  {
64  return CustomServers::isServerPinned(
65  CustomServerInfo::fromServer(serverAtIndex.data()));
66  }
67 
68  void togglePinAllServers()
69  {
70  bool toggleTo = !isServerPinned();
71  for (const ServerPtr &server : servers)
72  {
73  CustomServers::setServerPinned(
74  CustomServerInfo::fromServer(server.data()),
75  toggleTo);
76  server->setCustom(toggleTo);
77  }
78  }
79 };
80 
81 DPointered(ServerListContextMenu)
82 
83 ServerListContextMenu::ServerListContextMenu(ServerPtr serverAtIndex,
84  const ServerListFilterInfo &filter,
85  const QModelIndex &modelIndex,
86  const QList<ServerPtr> &servers,
87  ServerList *parent)
88  : QObject(parent)
89 {
90  d->serverAtIndex = serverAtIndex;
91  d->parent = parent;
92  d->servers = servers;
93  d->serverFilter = filter;
94  d->modelIndex = modelIndex;
95  initializeMembers();
96  createMembers();
97 }
98 
99 ServerListContextMenu::~ServerListContextMenu()
100 {
101  delete d->menu;
102 }
103 
104 QMenu *ServerListContextMenu::createCopyMenu(QWidget *parent)
105 {
106  QMenu *copyMenu = new QMenu(tr("Copy"), parent);
107  d->copyAddress = copyMenu->addAction(tr("Copy Address"));
108 
109  if (!d->serverAtIndex->email().isEmpty())
110  d->copyEmail = copyMenu->addAction(tr("Copy E-Mail"));
111 
112  if (!d->serverAtIndex->webSite().isEmpty())
113  d->copyUrl = copyMenu->addAction(tr("Copy URL"));
114 
115  d->copyName = copyMenu->addAction(tr("Copy Name"));
116 
117  return copyMenu;
118 }
119 
120 void ServerListContextMenu::createMembers()
121 {
122  d->menu = new QMenu();
123  this->connect(d->menu, SIGNAL(aboutToHide()), SIGNAL(aboutToHide()));
124  this->connect(d->menu, SIGNAL(triggered(QAction*)), SIGNAL(triggered(QAction*)));
125 
126  d->refresh = d->menu->addAction(tr("Refresh"));
127  d->join = d->menu->addAction(tr("Join"));
128  d->showJoinCommandLine = d->menu->addAction(tr("Show join command line"));
129  d->findMissingWads = d->menu->addAction(tr("Find missing WADs"));
130 
131  // Website.
132  const QString &webSite = d->serverAtIndex->webSite();
133  bool bShouldAllowOpenUrl = !webSite.isEmpty() && Strings::isUrlSafe(webSite);
134 
135  if (bShouldAllowOpenUrl)
136  d->openUrlInDefaultBrowser = d->menu->addAction(tr("Open URL in browser"));
137 
138  // Pinning ("marking as favourite").
139  QString pinnedLabel = !d->isServerPinned() ? tr("Pin") : tr ("Unpin");
140  d->toggleServerPinned = d->menu->addAction(pinnedLabel);
141 
142  // Copy menu.
143  QMenu *copyMenu = createCopyMenu(d->menu);
144  d->menu->addMenu(copyMenu);
145 
146  // Filter builder.
147  d->filterBuilder = new ServerFilterBuilderMenu(*d->serverAtIndex, d->serverFilter, d->menu);
148  if (d->serverAtIndex->isKnown() && !d->filterBuilder->isEmpty())
149  d->menu->addMenu(d->filterBuilder);
150 
151  d->rcon = nullptr;
152  if (d->serverAtIndex->hasRcon())
153  {
154  d->menu->addSeparator();
155  d->rcon = d->menu->addAction(tr("Remote Console"));
156  }
157 
158  // Sorts.
159  d->menu->addSeparator();
160  if (!d->parent->isSortingByColumn(d->modelIndex.column()))
161  {
162  d->sortAdditionallyAscending = d->menu->addAction(tr("Sort additionally ascending"));
163  d->sortAdditionallyDescending = d->menu->addAction(tr("Sort additionally descending"));
164  }
165  if (d->parent->isSortingAdditionallyByColumn(d->modelIndex.column()))
166  {
167  d->removeAdditionalSortingForColumn = d->menu->addAction(
168  tr("Remove additional sorting for column"));
169  }
170  if (d->parent->isAnyColumnSortedAdditionally())
171  d->clearAdditionalSorting = d->menu->addAction(tr("Clear additional sorting"));
172 }
173 
174 void ServerListContextMenu::initializeMembers()
175 {
176  d->clearAdditionalSorting = nullptr;
177  d->removeAdditionalSortingForColumn = nullptr;
178  d->sortAdditionallyAscending = nullptr;
179  d->sortAdditionallyDescending = nullptr;
180  d->copyAddress = nullptr;
181  d->copyEmail = nullptr;
182  d->copyName = nullptr;
183  d->copyUrl = nullptr;
184  d->filterBuilder = nullptr;
185  d->findMissingWads = nullptr;
186  d->join = nullptr;
187  d->menu = nullptr;
188  d->openUrlInDefaultBrowser = nullptr;
189  d->rcon = nullptr;
190  d->refresh = nullptr;
191  d->showJoinCommandLine = nullptr;
192  d->toggleServerPinned = nullptr;
193 }
194 
195 const QModelIndex &ServerListContextMenu::modelIndex() const
196 {
197  return d->modelIndex;
198 }
199 
200 void ServerListContextMenu::popup(const QPoint &point)
201 {
202  d->menu->popup(point);
203 }
204 
205 ServerPtr ServerListContextMenu::server() const
206 {
207  return d->serverAtIndex;
208 }
209 
210 const QList<ServerPtr> &ServerListContextMenu::servers() const
211 {
212  return d->servers;
213 }
214 
215 const ServerListFilterInfo &ServerListContextMenu::serverFilter() const
216 {
217  assert(d->filterBuilder);
218  return d->filterBuilder->filter();
219 }
220 
221 ServerListContextMenu::Result ServerListContextMenu::translateQMenuResult(QAction *resultAction)
222 {
223  if (resultAction == nullptr)
224  return NothingHappened;
225 
226  // Now perform checks against menu items.
227  if (resultAction == d->refresh)
228  return Refresh;
229  else if (resultAction == d->join)
230  return Join;
231  else if (resultAction == d->showJoinCommandLine)
232  return ShowJoinCommandLine;
233  else if (resultAction == d->openUrlInDefaultBrowser)
234  return OpenURL;
235  else if (resultAction == d->copyAddress)
236  {
237  QString addr = QString("%1:%2").arg(d->serverAtIndex->address().toString()).arg(d->serverAtIndex->port());
238  Clipboard::setText(addr);
239  return DataCopied;
240  }
241  else if (resultAction == d->copyEmail)
242  {
243  Clipboard::setText(d->serverAtIndex->email());
244  return DataCopied;
245  }
246  else if (resultAction == d->copyName)
247  {
248  Clipboard::setText(d->serverAtIndex->name());
249  return DataCopied;
250  }
251  else if (resultAction == d->copyUrl)
252  {
253  Clipboard::setText(d->serverAtIndex->webSite());
254  return DataCopied;
255  }
256  else if (resultAction == d->findMissingWads)
257  return FindMissingWADs;
258  else if (resultAction == d->rcon)
259  return OpenRemoteConsole;
260  else if (resultAction == d->sortAdditionallyAscending)
261  return SortAdditionallyAscending;
262  else if (resultAction == d->sortAdditionallyDescending)
263  return SortAdditionallyDescending;
264  else if (resultAction == d->clearAdditionalSorting)
265  return ClearAdditionalSorting;
266  else if (resultAction == d->removeAdditionalSortingForColumn)
267  return RemoveAdditionalSortingForColumn;
268  else if (resultAction == d->toggleServerPinned)
269  {
270  d->togglePinAllServers();
271  return TogglePinServers;
272  }
273 
274  return NothingHappened;
275 }