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