1 /***************************************************************************
2  *   Copyright (C) 2004-2006 by Albert Astals Cid                          *
3  *   aacid@kde.org                                                         *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  ***************************************************************************/
10 
11 #include "mapchooser.h"
12 
13 #include <KLocalizedString>
14 #include <KMessageBox>
15 #include <KListWidgetSearchLine>
16 
17 #include <QDir>
18 #include <QImage>
19 #include <QLabel>
20 #include <QLayout>
21 #include <QListWidget>
22 #include <QDialogButtonBox>
23 #include <QPushButton>
24 #include <QSet>
25 
26 #include <algorithm>
27 
28 #include "settings.h"
29 
myLessThan(const QString & s1,const QString & s2)30 bool myLessThan(const QString &s1, const QString &s2)
31 {
32 	return s1.localeAwareCompare(s2) < 0;
33 }
34 
mapChooser(QWidget * parent)35 mapChooser::mapChooser(QWidget *parent) : QDialog(parent)
36 {
37 	setWindowTitle(i18n("Choose Map to Use"));
38 
39 	QVBoxLayout *mainLayout = new QVBoxLayout();
40 
41 	QHBoxLayout *horizontalLayout = new QHBoxLayout();
42 
43 	QVBoxLayout *listFilterLayout = new QVBoxLayout();
44 	p_listBox = new QListWidget();
45 	KListWidgetSearchLine *searchLine = new KListWidgetSearchLine(this, p_listBox);
46 	searchLine->setPlaceholderText(i18n("Filter Maps"));
47 	listFilterLayout -> addWidget(searchLine);
48 	listFilterLayout -> addWidget(p_listBox);
49 
50 	horizontalLayout->addLayout(listFilterLayout);
51 
52 	p_imageContainer = new QLabel();
53 	p_imageContainer -> setFixedSize(300, 225);
54 	p_imageContainer -> setAlignment(Qt::AlignCenter);
55 	horizontalLayout -> addWidget(p_imageContainer);
56 
57 	mainLayout->addLayout(horizontalLayout);
58 
59 	QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok
60 									 | QDialogButtonBox::Cancel);
61 	connect(buttonBox, &QDialogButtonBox::accepted, this, &mapChooser::accept);
62 	connect(buttonBox, &QDialogButtonBox::rejected, this, &mapChooser::reject);
63 	mainLayout->addWidget(buttonBox);
64 
65 	QStringList errorTexts;
66 	QString lastMapFile = kgeographySettings::self() -> lastMap();
67 	QString stringToSelect;
68 	QStringList texts;
69 	QSet<QString> loadedMaps;
70 	const QStringList dirs = QStandardPaths::locateAll(QStandardPaths::DataLocation, QLatin1String(""), QStandardPaths::LocateDirectory);
71 	foreach (const QString &dir, dirs)
72 	{
73 		const QStringList fileNames = QDir(dir).entryList(QStringList() << QStringLiteral("*.kgm"));
74 		foreach (const QString &file, fileNames)
75 		{
76 			// avoid multiple and should guarantee that first in XDG_DATA_DIRS is chosen)
77 			if (loadedMaps.contains(file))
78 				continue;
79 
80 			QString mapFilename = dir + '/' + file;
81 
82 			KGmap *m = p_reader.parseMap(mapFilename);
83 			if (!m)
84 				errorTexts << i18n("Error parsing %1: %2", mapFilename, p_reader.getError());
85 			else
86 			{
87 				QString text = m -> getName();
88 				KGmap* existingMap = p_maps.value(text);
89 				if (existingMap)
90 				{
91 					errorTexts << i18n("The map %1 has the same name of map %2", mapFilename, existingMap -> getFile());
92 					delete m;
93 				}
94 				else
95 				{
96 					texts << text;
97 					p_maps.insert(text, m);
98 					if ( mapFilename == lastMapFile )
99 						stringToSelect = text;
100 					loadedMaps << file;
101 				}
102 			}
103 		}
104 	}
105 
106 	if (errorTexts.size() > 0)
107 		KMessageBox::errorList(this, i18n("Error parsing"), errorTexts);
108 
109 	connect(p_listBox, &QListWidget::currentTextChanged, this, &mapChooser::putImage);
110 	connect(p_listBox, &QListWidget::itemActivated, this, &mapChooser::accept);
111 
112 	std::sort(texts.begin(), texts.end(), myLessThan);
113 	foreach(const QString &text, texts)
114 		p_listBox -> addItem(text);
115 
116 	if (p_listBox -> count() == 0)
117 		buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
118 	else {
119 		QList<QListWidgetItem *> itemsWhere = p_listBox->findItems(stringToSelect, Qt::MatchExactly);
120 		if ( itemsWhere.size() > 0 )
121 			p_listBox->setCurrentItem(itemsWhere[0]);
122 		else
123 			p_listBox -> setCurrentRow(0);
124 	}
125 
126 	setLayout(mainLayout);
127 
128 	p_listBox -> setFocus();
129 }
130 
~mapChooser()131 mapChooser::~mapChooser()
132 {
133 	qDeleteAll(p_maps);
134 }
135 
getMap()136 KGmap *mapChooser::getMap()
137 {
138 	KGmap *m;
139 	m = p_maps[p_listBox -> currentItem() -> text()];
140 	p_maps.remove(p_listBox -> currentItem() -> text());
141 	return m;
142 }
143 
putImage(const QString & mapName)144 void mapChooser::putImage(const QString &mapName)
145 {
146 	KGmap *m;
147 	m = p_maps[mapName];
148 	QImage image(m -> getMapFile());
149 	image = image.scaled(300, 225, Qt::KeepAspectRatio, Qt::SmoothTransformation);
150 	p_imageContainer -> setPixmap( QPixmap::fromImage(image) );
151 }
152 
153 
154