1 /**********************************************************************************************
2 Copyright (C) 2014 Oliver Eichler <oliver.eichler@gmx.de>
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17 **********************************************************************************************/
18
19 #include "CMainWindow.h"
20 #include "map/CMapDraw.h"
21 #include "map/CMapItem.h"
22 #include "map/CMapList.h"
23 #include "misc.h"
24
25 #include <QtWidgets>
26
dragEnterEvent(QDragEnterEvent * e)27 void CMapTreeWidget::dragEnterEvent(QDragEnterEvent* e)
28 {
29 collapseAll();
30 QTreeWidget::dragEnterEvent(e);
31 }
32
dragMoveEvent(QDragMoveEvent * e)33 void CMapTreeWidget::dragMoveEvent(QDragMoveEvent* e)
34 {
35 CMapItem* item = dynamic_cast<CMapItem*>(itemAt(e->pos()));
36
37 if(item && item->isActivated())
38 {
39 e->setDropAction(Qt::MoveAction);
40 QTreeWidget::dragMoveEvent(e);
41 }
42 else
43 {
44 e->setDropAction(Qt::IgnoreAction);
45 }
46 }
47
dropEvent(QDropEvent * e)48 void CMapTreeWidget::dropEvent(QDropEvent* e)
49 {
50 CMapItem* item = dynamic_cast<CMapItem*>(currentItem());
51 if(item)
52 {
53 item->showChildren(false);
54 }
55
56 QTreeWidget::dropEvent(e);
57
58 if(item)
59 {
60 item->showChildren(true);
61 }
62
63 emit sigChanged();
64 }
65
CMapList(QWidget * parent)66 CMapList::CMapList(QWidget* parent)
67 : QWidget(parent)
68 {
69 setupUi(this);
70 lineFilter->addAction(actionClearFilter, QLineEdit::TrailingPosition);
71
72 connect(treeWidget, &CMapTreeWidget::customContextMenuRequested, this, &CMapList::slotContextMenu);
73 connect(treeWidget, &CMapTreeWidget::sigChanged, this, &CMapList::sigChanged);
74 connect(actionActivate, &QAction::triggered, this, &CMapList::slotActivate);
75 connect(actionMoveUp, &QAction::triggered, this, &CMapList::slotMoveUp);
76 connect(actionMoveDown, &QAction::triggered, this, &CMapList::slotMoveDown);
77 connect(actionReloadMaps, &QAction::triggered, this, &CMapList::slotReloadMaps);
78 connect(labelHelpFillMapList, &QLabel::linkActivated, &CMainWindow::self(), static_cast<void (CMainWindow::*)(const QString&)>(&CMainWindow::slotLinkActivated));
79 connect(lineFilter, &QLineEdit::textChanged, this, &CMapList::slotFilter);
80
81 menu = new QMenu(this);
82 menu->addAction(actionActivate);
83 menu->addAction(actionMoveUp);
84 menu->addAction(actionMoveDown);
85 menu->addSeparator();
86 menu->addAction(actionReloadMaps);
87 menu->addAction(CMainWindow::self().getMapSetupAction());
88 }
89
~CMapList()90 CMapList::~CMapList()
91 {
92 }
93
clear()94 void CMapList::clear()
95 {
96 treeWidget->clear();
97 }
98
99
sort()100 void CMapList::sort()
101 {
102 QList<CMapItem*> items1;
103 while(treeWidget->topLevelItemCount())
104 {
105 CMapItem* item = dynamic_cast<CMapItem*>(treeWidget->takeTopLevelItem(0));
106 if(item != nullptr)
107 {
108 items1 << item;
109 }
110 }
111
112 qSort(items1.begin(), items1.end(), &sortByName<CMapItem>);
113
114 QList<QTreeWidgetItem*> items2;
115 for(CMapItem* item : qAsConst(items1))
116 {
117 items2 << item;
118 }
119 treeWidget->addTopLevelItems(items2);
120 }
121
count()122 int CMapList::count()
123 {
124 return treeWidget->topLevelItemCount();
125 }
126
item(int i)127 CMapItem* CMapList::item(int i)
128 {
129 return dynamic_cast<CMapItem*>(treeWidget->topLevelItem(i));
130 }
131
updateHelpText()132 void CMapList::updateHelpText()
133 {
134 bool haveMaps = (treeWidget->topLevelItemCount() > 0);
135
136 labelHelpFillMapList->setVisible(!haveMaps);
137
138 if(!haveMaps)
139 {
140 labelIcon->show();
141 labelHelpActivateMap->hide();
142 }
143 else
144 {
145 CMapItem* item = dynamic_cast<CMapItem*>(treeWidget->topLevelItem(0));
146
147 bool showHelp = !(item && item->isActivated());
148 labelIcon->setVisible(showHelp);
149 labelHelpActivateMap->setVisible(showHelp);
150 }
151 }
152
slotActivate()153 void CMapList::slotActivate()
154 {
155 CMapItem* item = dynamic_cast<CMapItem*>(treeWidget->currentItem());
156 if(nullptr == item)
157 {
158 return;
159 }
160
161 bool activated = item->toggleActivate();
162 if(!activated)
163 {
164 treeWidget->setCurrentItem(0);
165 }
166
167 updateHelpText();
168 }
169
slotMoveUp()170 void CMapList::slotMoveUp()
171 {
172 CMapItem* item = dynamic_cast<CMapItem*>(treeWidget->currentItem());
173 if(item == nullptr)
174 {
175 return;
176 }
177
178 int index = treeWidget->indexOfTopLevelItem(item);
179 if(index == NOIDX)
180 {
181 return;
182 }
183
184 item->showChildren(false);
185 treeWidget->takeTopLevelItem(index);
186 treeWidget->insertTopLevelItem(index - 1, item);
187 item->showChildren(true);
188 treeWidget->setCurrentItem(0);
189 emit treeWidget->sigChanged();
190 }
191
slotMoveDown()192 void CMapList::slotMoveDown()
193 {
194 CMapItem* item = dynamic_cast<CMapItem*>(treeWidget->currentItem());
195 if(item == nullptr)
196 {
197 return;
198 }
199
200 int index = treeWidget->indexOfTopLevelItem(item);
201 if(index == NOIDX)
202 {
203 return;
204 }
205
206 item->showChildren(false);
207 treeWidget->takeTopLevelItem(index);
208 treeWidget->insertTopLevelItem(index + 1, item);
209 item->showChildren(true);
210 treeWidget->setCurrentItem(0);
211 emit treeWidget->sigChanged();
212 }
213
slotContextMenu(const QPoint & point)214 void CMapList::slotContextMenu(const QPoint& point)
215 {
216 CMapItem* item = dynamic_cast<CMapItem*>(treeWidget->currentItem());
217
218 bool itemIsSelected = nullptr != item;
219 bool itemIsActivated = item ? item->isActivated() : false;
220
221 actionActivate->setEnabled(itemIsSelected);
222 actionMoveUp->setEnabled(itemIsSelected);
223 actionMoveDown->setEnabled(itemIsSelected);
224
225 actionActivate->setChecked(itemIsActivated);
226 actionActivate->setText(itemIsActivated ? tr("Deactivate") : tr("Activate"));
227
228 if(itemIsSelected)
229 {
230 CMapItem* item1 = dynamic_cast<CMapItem*>(treeWidget->itemBelow(item));
231 actionMoveUp->setEnabled(itemIsActivated && (treeWidget->itemAbove(item) != 0));
232 actionMoveDown->setEnabled(itemIsActivated && item1 && item1->isActivated());
233 }
234 QPoint p = treeWidget->mapToGlobal(point);
235 menu->exec(p);
236 }
237
saveResource(const QString & name,QDir & dir)238 static void saveResource(const QString& name, QDir& dir)
239 {
240 QFile resource1(QString("://map/%1").arg(name));
241 resource1.open(QIODevice::ReadOnly);
242
243 QFile file(dir.absoluteFilePath(name));
244 file.open(QIODevice::WriteOnly);
245 file.write(resource1.readAll());
246 file.close();
247 }
248
slotMapHonk()249 void CMapList::slotMapHonk()
250 {
251 QString mapPath = CMainWindow::self().getMapsPath();
252 if(mapPath.isEmpty())
253 {
254 mapPath = QDir::homePath();
255 }
256
257 mapPath = QFileDialog::getExistingDirectory(CMainWindow::getBestWidgetForParent(), tr("Where do you want to store maps?"), mapPath);
258 if(mapPath.isEmpty())
259 {
260 return;
261 }
262
263 QDir dir(mapPath);
264
265 saveResource("WorldSat.wmts", dir);
266 saveResource("WorldTopo.wmts", dir);
267 saveResource("OpenStreetMap.tms", dir);
268 saveResource("OSM_Topo.tms", dir);
269 saveResource("OpenCycleMap.tms", dir);
270
271 CMapDraw::setupMapPath(mapPath);
272
273 CCanvas* canvas = CMainWindow::self().getVisibleCanvas();
274 if(canvas)
275 {
276 canvas->setScales(CCanvas::eScalesSquare);
277 }
278 }
279
slotReloadMaps()280 void CMapList::slotReloadMaps()
281 {
282 CMapDraw::setupMapPath(CMapDraw::getMapPaths());
283 }
284
285
slotFilter(const QString & str)286 void CMapList::slotFilter(const QString& str)
287 {
288 actionClearFilter->setIcon(str.isEmpty() ? QIcon("://icons/32x32/Filter.png") : QIcon("://icons/32x32/Cancel.png"));
289
290 const int N = treeWidget->topLevelItemCount();
291
292 if(str.isEmpty())
293 {
294 for(int n = 0; n < N; n++)
295 {
296 CMapItem* map = dynamic_cast<CMapItem*>(treeWidget->topLevelItem(n));
297 if(map == nullptr)
298 {
299 continue;
300 }
301 map->setHidden(false);
302 }
303 }
304 else
305 {
306 const QString& tmp = str.toUpper();
307 for(int n = 0; n < N; n++)
308 {
309 CMapItem* map = dynamic_cast<CMapItem*>(treeWidget->topLevelItem(n));
310 if(map == nullptr)
311 {
312 continue;
313 }
314
315 map->setHidden(!map->getName().toUpper().contains(tmp));
316 }
317 }
318 }
319