File indexing completed on 2025-01-05 03:58:34
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2010-05-12 0007 * Description : A widget to apply Reverse Geocoding 0008 * 0009 * SPDX-FileCopyrightText: 2010 by Michael G. Hansen <mike at mghansen dot de> 0010 * SPDX-FileCopyrightText: 2010 by Gabriel Voicu <ping dot gabi at gmail dot com> 0011 * 0012 * SPDX-License-Identifier: GPL-2.0-or-later 0013 * 0014 * ============================================================ */ 0015 0016 #include "rgwidget.h" 0017 0018 // Qt includes 0019 0020 #include <QCheckBox> 0021 #include <QContextMenuEvent> 0022 #include <QHBoxLayout> 0023 #include <QLabel> 0024 #include <QLineEdit> 0025 #include <QList> 0026 #include <QMap> 0027 #include <QPointer> 0028 #include <QPushButton> 0029 #include <QTreeView> 0030 #include <QVBoxLayout> 0031 #include <QMenu> 0032 #include <QInputDialog> 0033 #include <QAction> 0034 #include <QComboBox> 0035 #include <QApplication> 0036 #include <QMessageBox> 0037 0038 // KDE includes 0039 0040 #include <kconfiggroup.h> 0041 #include <klocalizedstring.h> 0042 0043 // local includes 0044 0045 #include "dlayoutbox.h" 0046 #include "gpsundocommand.h" 0047 #include "gpsitemmodel.h" 0048 #include "backend-geonames-rg.h" 0049 #include "backend-osm-rg.h" 0050 #include "backend-geonamesUS-rg.h" 0051 #include "parsetagstring.h" 0052 #include "rgtagmodel.h" 0053 #include "simpletreemodel.h" 0054 #include "dmessagebox.h" 0055 #include "dexpanderbox.h" 0056 #include "dmetadata.h" 0057 #include "digikam_debug.h" 0058 0059 #ifdef GPSSYNC_MODELTEST 0060 # include <modeltest.h> 0061 #endif // GPSSYNC_MODELTEST 0062 0063 namespace Digikam 0064 { 0065 0066 /** 0067 * @class RGWidget 0068 * 0069 * @brief The RGWidget class represents the main widget for reverse geocoding. 0070 */ 0071 0072 class Q_DECL_HIDDEN RGWidget::Private 0073 { 0074 public: 0075 0076 explicit Private() 0077 : currentlyAskingCancelQuestion (false), 0078 hideOptions (true), 0079 UIEnabled (true), 0080 label (nullptr), 0081 imageModel (nullptr), 0082 selectionModel (nullptr), 0083 buttonRGSelected (nullptr), 0084 undoCommand (nullptr), 0085 serviceComboBox (nullptr), 0086 languageEdit (nullptr), 0087 currentBackend (nullptr), 0088 requestedRGCount (0), 0089 receivedRGCount (0), 0090 buttonHideOptions (nullptr), 0091 tagsLoc (nullptr), 0092 metaLoc (nullptr), 0093 UGridContainer (nullptr), 0094 LGridContainer (nullptr), 0095 serviceLabel (nullptr), 0096 languageLabel (nullptr), 0097 separator (nullptr), 0098 tagModel (nullptr), 0099 tagTreeView (nullptr), 0100 tagSelectionModel (nullptr), 0101 actionAddCountry (nullptr), 0102 actionAddState (nullptr), 0103 actionAddStateDistrict (nullptr), 0104 actionAddCounty (nullptr), 0105 actionAddCity (nullptr), 0106 actionAddCityDistrict (nullptr), 0107 actionAddSuburb (nullptr), 0108 actionAddTown (nullptr), 0109 actionAddVillage (nullptr), 0110 actionAddHamlet (nullptr), 0111 actionAddStreet (nullptr), 0112 actionAddHouseNumber (nullptr), 0113 actionAddPlace (nullptr), 0114 actionAddLAU2 (nullptr), 0115 actionAddLAU1 (nullptr), 0116 actionAddCustomizedSpacer (nullptr), 0117 actionRemoveTag (nullptr), 0118 actionRemoveAllSpacers (nullptr), 0119 actionAddAllAddressElementsToTag (nullptr) 0120 { 0121 } 0122 0123 bool currentlyAskingCancelQuestion; 0124 bool hideOptions; 0125 bool UIEnabled; 0126 QLabel* label; 0127 GPSItemModel* imageModel; 0128 QItemSelectionModel* selectionModel; 0129 QPushButton* buttonRGSelected; 0130 0131 GPSUndoCommand* undoCommand; 0132 QModelIndex currentTagTreeIndex; 0133 0134 QComboBox* serviceComboBox; 0135 QComboBox* languageEdit; 0136 QList<RGInfo> photoList; 0137 QList<RGBackend*> backendRGList; 0138 RGBackend* currentBackend; 0139 int requestedRGCount; 0140 int receivedRGCount; 0141 QPushButton* buttonHideOptions; 0142 QCheckBox* tagsLoc; 0143 QCheckBox* metaLoc; 0144 QWidget* UGridContainer; 0145 QWidget* LGridContainer; 0146 QLabel* serviceLabel; 0147 QLabel* languageLabel; 0148 DLineWidget* separator; 0149 0150 RGTagModel* tagModel; 0151 QTreeView* tagTreeView; 0152 0153 QItemSelectionModel* tagSelectionModel; 0154 QAction* actionAddCountry; 0155 QAction* actionAddState; 0156 QAction* actionAddStateDistrict; 0157 QAction* actionAddCounty; 0158 QAction* actionAddCity; 0159 QAction* actionAddCityDistrict; 0160 QAction* actionAddSuburb; 0161 QAction* actionAddTown; 0162 QAction* actionAddVillage; 0163 QAction* actionAddHamlet; 0164 QAction* actionAddStreet; 0165 QAction* actionAddHouseNumber; 0166 QAction* actionAddPlace; 0167 QAction* actionAddLAU2; 0168 QAction* actionAddLAU1; 0169 QAction* actionAddCustomizedSpacer; 0170 QAction* actionRemoveTag; 0171 QAction* actionRemoveAllSpacers; 0172 QAction* actionAddAllAddressElementsToTag; 0173 0174 QMap<QString, QString> countryCode; 0175 }; 0176 0177 /** 0178 * Constructor 0179 * @param imageModel image model 0180 * @param selectionModel image selection model 0181 * @param parent The parent object 0182 */ 0183 RGWidget::RGWidget(GPSItemModel* const imageModel, QItemSelectionModel* const selectionModel, 0184 QAbstractItemModel* externTagModel, QWidget* const parent) 0185 : QWidget(parent), 0186 d (new Private()) 0187 { 0188 d->imageModel = imageModel; 0189 d->selectionModel = selectionModel; 0190 0191 // we need to have a main layout and add QVBoxLayout 0192 0193 QVBoxLayout* const vBoxLayout = new QVBoxLayout(this); 0194 d->UGridContainer = new QWidget(this); 0195 0196 vBoxLayout->addWidget(d->UGridContainer); 0197 d->tagTreeView = new QTreeView(this); 0198 d->tagTreeView->setHeaderHidden(true); 0199 vBoxLayout->addWidget(d->tagTreeView); 0200 0201 Q_ASSERT(d->tagTreeView != nullptr); 0202 0203 if (!externTagModel) 0204 { 0205 externTagModel = new SimpleTreeModel(1, this); 0206 } 0207 0208 d->tagModel = new RGTagModel(externTagModel, this); 0209 d->tagTreeView->setModel(d->tagModel); 0210 0211 #ifdef GPSSYNC_MODELTEST 0212 0213 new ModelTest(externTagModel, d->tagTreeView); 0214 new ModelTest(d->tagModel, d->tagTreeView); 0215 0216 #endif // GPSSYNC_MODELTEST 0217 0218 d->tagSelectionModel = new QItemSelectionModel(d->tagModel); 0219 d->tagTreeView->setSelectionModel(d->tagSelectionModel); 0220 0221 d->actionAddCountry = new QAction(i18n("Add country tag"), this); 0222 d->actionAddCountry->setData(QLatin1String("{Country}")); 0223 d->actionAddState = new QAction(i18n("Add state tag"), this); 0224 d->actionAddState->setData(QLatin1String("{State}")); 0225 d->actionAddStateDistrict = new QAction(i18n("Add state district tag"), this); 0226 d->actionAddStateDistrict->setData(QLatin1String("{State district}")); 0227 d->actionAddCounty = new QAction(i18n("Add county tag"), this); 0228 d->actionAddCounty->setData(QLatin1String("{County}")); 0229 d->actionAddCity = new QAction(i18n("Add city tag"), this); 0230 d->actionAddCity->setData(QLatin1String("{City}")); 0231 d->actionAddCityDistrict = new QAction(i18n("Add city district tag"), this); 0232 d->actionAddCityDistrict->setData(QLatin1String("{City district}")); 0233 d->actionAddSuburb = new QAction(i18n("Add suburb tag"), this); 0234 d->actionAddSuburb->setData(QLatin1String("{Suburb}")); 0235 d->actionAddTown = new QAction(i18n("Add town tag"), this); 0236 d->actionAddTown->setData(QLatin1String("{Town}")); 0237 d->actionAddVillage = new QAction(i18n("Add village tag"), this); 0238 d->actionAddVillage->setData(QLatin1String("{Village}")); 0239 d->actionAddHamlet = new QAction(i18n("Add hamlet tag"), this); 0240 d->actionAddHamlet->setData(QLatin1String("{Hamlet}")); 0241 d->actionAddStreet = new QAction(i18n("Add street"), this); 0242 d->actionAddStreet->setData(QLatin1String("{Street}")); 0243 d->actionAddHouseNumber = new QAction(i18n("Add house number tag"), this); 0244 d->actionAddHouseNumber->setData(QLatin1String("{House number}")); 0245 d->actionAddPlace = new QAction(i18n("Add place"), this); 0246 d->actionAddPlace->setData(QLatin1String("{Place}")); 0247 d->actionAddLAU2 = new QAction(i18n("Add Local Administrative Area 2"), this); 0248 d->actionAddLAU2->setData(QLatin1String("{LAU2}")); 0249 d->actionAddLAU1 = new QAction(i18n("Add Local Administrative Area 1"), this); 0250 d->actionAddLAU1->setData(QLatin1String("{LAU1}")); 0251 d->actionAddCustomizedSpacer = new QAction(i18n("Add new tag"), this); 0252 d->actionRemoveTag = new QAction(i18n("Remove selected tag"), this); 0253 d->actionRemoveAllSpacers = new QAction(i18n("Remove all control tags below this tag"), this); 0254 d->actionRemoveAllSpacers->setData(QLatin1String("Remove all spacers")); 0255 0256 d->actionAddAllAddressElementsToTag = new QAction(i18n("Add all address elements"), this); 0257 QGridLayout* const gridLayout = new QGridLayout(d->UGridContainer); 0258 0259 d->languageLabel = new QLabel(i18n("Select language:"), d->UGridContainer); 0260 d->languageEdit = new QComboBox(d->UGridContainer); 0261 0262 DMetadata::CountryCodeMap map = DMetadata::countryCodeMap(); 0263 0264 for (DMetadata::CountryCodeMap::Iterator it = map.begin() ; it != map.end() ; ++it) 0265 { 0266 d->languageEdit->addItem(QString::fromUtf8("%1 - %2").arg(it.key()).arg(it.value()), it.key().toLower()); 0267 } 0268 0269 d->serviceLabel = new QLabel(i18n("Select service:"), d->UGridContainer); 0270 d->serviceComboBox = new QComboBox(d->UGridContainer); 0271 0272 d->serviceComboBox->addItem(i18n("Open Street Map")); 0273 d->serviceComboBox->addItem(i18n("Geonames.org place name (non-US)")); 0274 d->serviceComboBox->addItem(i18n("Geonames.org full address (US only)")); 0275 0276 gridLayout->addWidget(d->serviceLabel, 0, 0, 1, 2); 0277 gridLayout->addWidget(d->serviceComboBox, 1, 0, 1, 2); 0278 gridLayout->addWidget(d->languageLabel, 2, 0, 1, 1); 0279 gridLayout->addWidget(d->languageEdit, 2, 1, 1, 1); 0280 0281 d->UGridContainer->setLayout(gridLayout); 0282 0283 d->separator = new DLineWidget(Qt::Horizontal, this); 0284 vBoxLayout->addWidget(d->separator); 0285 0286 d->buttonHideOptions = new QPushButton(i18n("Less options"), this); 0287 vBoxLayout->addWidget(d->buttonHideOptions); 0288 0289 d->LGridContainer = new QWidget(this); 0290 vBoxLayout->addWidget(d->LGridContainer); 0291 QGridLayout* const LGridLayout = new QGridLayout(d->LGridContainer); 0292 0293 d->tagsLoc = new QCheckBox(i18n("Write locations as tags"), d->LGridContainer); 0294 d->metaLoc = new QCheckBox(i18n("Write locations metadata"), d->LGridContainer); 0295 0296 LGridLayout->addWidget(d->tagsLoc, 0, 0, 1, 3); 0297 LGridLayout->addWidget(d->metaLoc, 1, 0, 1, 3); 0298 0299 d->LGridContainer->setLayout(LGridLayout); 0300 0301 d->buttonRGSelected = new QPushButton(i18n("Process reverse geocoding"), this); 0302 vBoxLayout->addWidget(d->buttonRGSelected); 0303 0304 d->backendRGList.append(new BackendOsmRG(this)); 0305 d->backendRGList.append(new BackendGeonamesRG(this)); 0306 d->backendRGList.append(new BackendGeonamesUSRG(this)); 0307 0308 d->tagTreeView->installEventFilter(this); 0309 0310 createCountryCodeMap(); 0311 0312 updateUIState(); 0313 0314 connect(d->buttonRGSelected, SIGNAL(clicked()), 0315 this, SLOT(slotButtonRGSelected())); 0316 0317 connect(d->buttonHideOptions, SIGNAL(clicked()), 0318 this, SLOT(slotHideOptions())); 0319 0320 connect(d->selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)), 0321 this, SLOT(updateUIState())); 0322 0323 connect(d->actionAddCountry, SIGNAL(triggered(bool)), 0324 this, SLOT(slotAddSingleSpacer())); 0325 0326 connect(d->actionAddState, SIGNAL(triggered(bool)), 0327 this, SLOT(slotAddSingleSpacer())); 0328 0329 connect(d->actionAddStateDistrict, SIGNAL(triggered(bool)), 0330 this, SLOT(slotAddSingleSpacer())); 0331 0332 connect(d->actionAddCounty, SIGNAL(triggered(bool)), 0333 this, SLOT(slotAddSingleSpacer())); 0334 0335 connect(d->actionAddCity, SIGNAL(triggered(bool)), 0336 this, SLOT(slotAddSingleSpacer())); 0337 0338 connect(d->actionAddCityDistrict, SIGNAL(triggered(bool)), 0339 this, SLOT(slotAddSingleSpacer())); 0340 0341 connect(d->actionAddSuburb, SIGNAL(triggered(bool)), 0342 this, SLOT(slotAddSingleSpacer())); 0343 0344 connect(d->actionAddTown, SIGNAL(triggered(bool)), 0345 this, SLOT(slotAddSingleSpacer())); 0346 0347 connect(d->actionAddVillage, SIGNAL(triggered(bool)), 0348 this, SLOT(slotAddSingleSpacer())); 0349 0350 connect(d->actionAddHamlet, SIGNAL(triggered(bool)), 0351 this, SLOT(slotAddSingleSpacer())); 0352 0353 connect(d->actionAddHouseNumber, SIGNAL(triggered(bool)), 0354 this, SLOT(slotAddSingleSpacer())); 0355 0356 connect(d->actionAddStreet, SIGNAL(triggered(bool)), 0357 this, SLOT(slotAddSingleSpacer())); 0358 0359 connect(d->actionAddPlace, SIGNAL(triggered(bool)), 0360 this, SLOT(slotAddSingleSpacer())); 0361 0362 connect(d->actionAddLAU2, SIGNAL(triggered(bool)), 0363 this, SLOT(slotAddSingleSpacer())); 0364 0365 connect(d->actionAddLAU1, SIGNAL(triggered(bool)), 0366 this, SLOT(slotAddSingleSpacer())); 0367 0368 connect(d->actionAddCustomizedSpacer, SIGNAL(triggered(bool)), 0369 this, SLOT(slotAddCustomizedSpacer())); 0370 0371 connect(d->actionAddAllAddressElementsToTag, SIGNAL(triggered(bool)), 0372 this, SLOT(slotAddAllAddressElementsToTag())); 0373 0374 connect(d->imageModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), 0375 this, SLOT(slotRegenerateNewTags())); 0376 0377 connect(d->actionRemoveTag, SIGNAL(triggered(bool)), 0378 this, SLOT(slotRemoveTag())); 0379 0380 connect(d->actionRemoveAllSpacers, SIGNAL(triggered(bool)), 0381 this, SLOT(slotRemoveAllSpacers())); 0382 0383 for (int i = 0 ; i < d->backendRGList.count() ; ++i) 0384 { 0385 connect(d->backendRGList[i], SIGNAL(signalRGReady(QList<RGInfo>&)), 0386 this, SLOT(slotRGReady(QList<RGInfo>&))); 0387 } 0388 0389 int currentServiceIndex = d->serviceComboBox->currentIndex(); 0390 d->currentBackend = d->backendRGList[currentServiceIndex]; 0391 } 0392 0393 /** 0394 * Destructor 0395 */ 0396 RGWidget::~RGWidget() 0397 { 0398 delete d; 0399 } 0400 0401 /** 0402 * Enables or disables the containing widgets. 0403 */ 0404 void RGWidget::updateUIState() 0405 { 0406 const bool haveSelection = d->selectionModel->hasSelection(); 0407 0408 d->buttonRGSelected->setEnabled(d->UIEnabled && haveSelection); 0409 d->serviceLabel->setEnabled(d->UIEnabled); 0410 d->serviceComboBox->setEnabled(d->UIEnabled); 0411 d->languageLabel->setEnabled(d->UIEnabled); 0412 d->languageEdit->setEnabled(d->UIEnabled); 0413 d->buttonHideOptions->setEnabled(d->UIEnabled); 0414 d->tagsLoc->setEnabled(d->UIEnabled); 0415 d->metaLoc->setEnabled(d->UIEnabled); 0416 } 0417 0418 /** 0419 * This slot triggers when the button that start the reverse geocoding process is pressed. 0420 */ 0421 void RGWidget::slotButtonRGSelected() 0422 { 0423 // get the selected images 0424 0425 const QModelIndexList selectedItems = d->selectionModel->selectedRows(); 0426 int currentServiceIndex = d->serviceComboBox->currentIndex(); 0427 d->currentBackend = d->backendRGList[currentServiceIndex]; 0428 d->undoCommand = new GPSUndoCommand(); 0429 d->undoCommand->setText(i18n("Image tags are changed.")); 0430 0431 QList<RGInfo> photoList; 0432 QString wantedLanguage = d->languageEdit->itemData(d->languageEdit->currentIndex()).toString(); 0433 QList<QList<TagData> > returnedSpacers = d->tagModel->getSpacers(); 0434 0435 for (int i = 0 ; i < selectedItems.count() ; ++i) 0436 { 0437 const QPersistentModelIndex itemIndex = selectedItems.at(i); 0438 GPSItemContainer* const selectedItem = d->imageModel->itemFromIndex(itemIndex); 0439 const GPSDataContainer gpsData = selectedItem->gpsData(); 0440 0441 if (!gpsData.hasCoordinates()) 0442 { 0443 continue; 0444 } 0445 0446 const qreal latitude = gpsData.getCoordinates().lat(); 0447 const qreal longitude = gpsData.getCoordinates().lon(); 0448 0449 RGInfo photoObj; 0450 photoObj.id = itemIndex; 0451 photoObj.coordinates = GeoCoordinates(latitude, longitude); 0452 0453 photoList << photoObj; 0454 0455 selectedItem->writeTagsToXmp(d->tagsLoc->isChecked()); 0456 selectedItem->writeLocations(d->metaLoc->isChecked()); 0457 } 0458 0459 if (!photoList.isEmpty()) 0460 { 0461 d->receivedRGCount = 0; 0462 d->requestedRGCount = photoList.count(); 0463 0464 Q_EMIT signalSetUIEnabled(false, this, QString::fromUtf8(SLOT(slotRGCanceled()))); 0465 Q_EMIT signalProgressSetup(d->requestedRGCount, i18n("Retrieving RG info -")); 0466 0467 d->currentBackend->callRGBackend(photoList, wantedLanguage); 0468 } 0469 } 0470 0471 /** 0472 * Hide or shows the extra options. 0473 */ 0474 void RGWidget::slotHideOptions() 0475 { 0476 if (d->hideOptions) 0477 { 0478 d->LGridContainer->hide(); 0479 d->hideOptions = false; 0480 d->buttonHideOptions->setText(i18n("More options")); 0481 } 0482 else 0483 { 0484 d->LGridContainer->show(); 0485 d->hideOptions = true; 0486 d->buttonHideOptions->setText(i18n("Less options")); 0487 } 0488 } 0489 0490 /** 0491 * The data has returned from backend and now it's processed here. 0492 * @param returnedRGList Contains the data returned by backend. 0493 */ 0494 void RGWidget::slotRGReady(QList<RGInfo>& returnedRGList) 0495 { 0496 const QString errorString = d->currentBackend->getErrorMessage(); 0497 0498 if (!errorString.isEmpty()) 0499 { 0500 /// @todo This collides with the message box displayed if the user aborts the RG process 0501 0502 QMessageBox::critical(QApplication::activeWindow(), i18nc("@title:window", "Reverse Geo-coding Error"), errorString); 0503 0504 d->receivedRGCount += returnedRGList.count(); 0505 0506 Q_EMIT signalSetUIEnabled(true); 0507 0508 return; 0509 } 0510 0511 QString address; 0512 0513 for (int i = 0 ; i < returnedRGList.count() ; ++i) 0514 { 0515 QPersistentModelIndex currentImageIndex = returnedRGList[i].id; 0516 0517 if (!returnedRGList[i].rgData.isEmpty()) 0518 { 0519 QString addressElementsWantedFormat; 0520 0521 if (d->currentBackend->backendName() == QLatin1String("Geonames")) 0522 { 0523 addressElementsWantedFormat.append(QLatin1String("/{Country}/{Country code}/{Place}")); 0524 } 0525 else if (d->currentBackend->backendName() == QLatin1String("GeonamesUS")) 0526 { 0527 addressElementsWantedFormat.append(QLatin1String("/{LAU2}/{LAU1}/{City}")); 0528 } 0529 else 0530 { 0531 addressElementsWantedFormat.append(QLatin1String("/{Country}/{Country code}/{State}/{State district}" 0532 "/{County}/{City}/{City district}/{Suburb}/{Town}" 0533 "/{Village}/{Hamlet}/{Street}/{House number}")); 0534 } 0535 0536 QStringList combinedResult = makeTagString(returnedRGList[i], 0537 addressElementsWantedFormat, 0538 d->currentBackend->backendName()); 0539 0540 QString addressFormat = combinedResult[0]; 0541 QString addressElements = combinedResult[1]; 0542 0543 // removes first "/" from tag addresses 0544 0545 addressFormat.remove(0, 1); 0546 addressElements.remove(0, 1); 0547 addressElementsWantedFormat.remove(0, 1); 0548 0549 const QStringList listAddressElementsWantedFormat = addressElementsWantedFormat.split(QLatin1Char('/')); 0550 const QStringList listAddressElements = addressElements.split(QLatin1Char('/')); 0551 const QStringList listAddressFormat = addressFormat.split(QLatin1Char('/')); 0552 QStringList elements, resultedData; 0553 0554 for (int j = 0 ; j < listAddressElementsWantedFormat.count() ; ++j) 0555 { 0556 QString currentAddressFormat = listAddressElementsWantedFormat.at(j); 0557 int currentIndexFormat = listAddressFormat.indexOf(currentAddressFormat); 0558 0559 if (currentIndexFormat != -1) 0560 { 0561 elements << currentAddressFormat; 0562 resultedData << listAddressElements.at(currentIndexFormat); 0563 } 0564 } 0565 0566 QList<QList<TagData> > returnedTags = d->tagModel->addNewData(elements, resultedData); 0567 0568 int countryCodeIndex = listAddressFormat.indexOf(QLatin1String("{Country code}")); 0569 0570 if (countryCodeIndex != -1) 0571 { 0572 TagData countryCode; 0573 countryCode.tagName = d->countryCode.value(listAddressElements.at(countryCodeIndex).toUpper()); 0574 countryCode.tipName = QLatin1String("{Country code}"); 0575 returnedTags << (QList<TagData>() << countryCode); 0576 } 0577 0578 GPSItemContainer* const currentItem = d->imageModel->itemFromIndex(currentImageIndex); 0579 0580 GPSUndoCommand::UndoInfo undoInfo(currentImageIndex); 0581 undoInfo.readOldDataFromItem(currentItem); 0582 0583 currentItem->setTagList(returnedTags); 0584 0585 undoInfo.readNewDataFromItem(currentItem); 0586 d->undoCommand->addUndoInfo(undoInfo); 0587 } 0588 } 0589 0590 d->receivedRGCount += returnedRGList.count(); 0591 0592 if (d->receivedRGCount >= d->requestedRGCount) 0593 { 0594 if (d->currentlyAskingCancelQuestion) 0595 { 0596 // if the user is currently answering the cancel question, do nothing, only report progress 0597 0598 Q_EMIT signalProgressChanged(d->receivedRGCount); 0599 } 0600 else 0601 { 0602 Q_EMIT signalUndoCommand(d->undoCommand); 0603 0604 d->undoCommand = nullptr; 0605 0606 Q_EMIT signalSetUIEnabled(true); 0607 } 0608 } 0609 else 0610 { 0611 Q_EMIT signalProgressChanged(d->receivedRGCount); 0612 } 0613 } 0614 0615 /** 0616 * Sets whether the containing widgets are enabled or disabled. 0617 * @param state If true, the controls are enabled. 0618 */ 0619 void RGWidget::setUIEnabled(const bool state) 0620 { 0621 d->UIEnabled = state; 0622 updateUIState(); 0623 } 0624 0625 /** 0626 * Here are filtered the events. 0627 */ 0628 bool RGWidget::eventFilter(QObject* watched, QEvent* event) 0629 { 0630 if (watched == d->tagTreeView) 0631 { 0632 if ((event->type() == QEvent::ContextMenu) && d->UIEnabled) 0633 { 0634 QMenu* const menu = new QMenu(d->tagTreeView); 0635 const int currentServiceIndex = d->serviceComboBox->currentIndex(); 0636 d->currentBackend = d->backendRGList[currentServiceIndex]; 0637 QString backendName = d->currentBackend->backendName(); 0638 QContextMenuEvent* const e = static_cast<QContextMenuEvent*>(event); 0639 d->currentTagTreeIndex = d->tagTreeView->indexAt(e->pos()); 0640 const Type tagType = d->tagModel->getTagType(d->currentTagTreeIndex); 0641 0642 if (backendName == QLatin1String("OSM")) 0643 { 0644 menu->addAction(d->actionAddAllAddressElementsToTag); 0645 menu->addSeparator(); 0646 menu->addAction(d->actionAddCountry); 0647 menu->addAction(d->actionAddState); 0648 menu->addAction(d->actionAddStateDistrict); 0649 menu->addAction(d->actionAddCounty); 0650 menu->addAction(d->actionAddCity); 0651 menu->addAction(d->actionAddCityDistrict); 0652 menu->addAction(d->actionAddSuburb); 0653 menu->addAction(d->actionAddTown); 0654 menu->addAction(d->actionAddVillage); 0655 menu->addAction(d->actionAddHamlet); 0656 menu->addAction(d->actionAddStreet); 0657 menu->addAction(d->actionAddHouseNumber); 0658 } 0659 else if (backendName == QLatin1String("Geonames")) 0660 { 0661 menu->addAction(d->actionAddAllAddressElementsToTag); 0662 menu->addAction(d->actionAddCountry); 0663 menu->addAction(d->actionAddPlace); 0664 } 0665 else if (backendName == QLatin1String("GeonamesUS")) 0666 { 0667 menu->addAction(d->actionAddAllAddressElementsToTag); 0668 menu->addAction(d->actionAddLAU2); 0669 menu->addAction(d->actionAddLAU1); 0670 menu->addAction(d->actionAddCity); 0671 } 0672 0673 menu->addSeparator(); 0674 menu->addAction(d->actionAddCustomizedSpacer); 0675 menu->addSeparator(); 0676 0677 if (tagType == TypeSpacer) 0678 { 0679 menu->addAction(d->actionRemoveTag); 0680 } 0681 0682 menu->addAction(d->actionRemoveAllSpacers); 0683 menu->exec(e->globalPos()); 0684 delete menu; 0685 } 0686 } 0687 0688 return QObject::eventFilter(watched, event); 0689 } 0690 0691 /** 0692 * Saves the settings of widgets contained in reverse geocoding widget. 0693 * @param group Here are stored the settings. 0694 */ 0695 void RGWidget::saveSettingsToGroup(KConfigGroup* const group) 0696 { 0697 group->writeEntry("RG Backend", d->serviceComboBox->currentIndex()); 0698 group->writeEntry("Language", d->languageEdit->currentIndex()); 0699 group->writeEntry("Hide options", d->hideOptions); 0700 group->writeEntry("Tags location", d->tagsLoc->isChecked()); 0701 group->writeEntry("Metadata location", d->metaLoc->isChecked()); 0702 0703 QList<QList<TagData> > currentSpacerList = d->tagModel->getSpacers(); 0704 const int spacerCount = currentSpacerList.count(); 0705 group->writeEntry("Spacers count", spacerCount); 0706 0707 for (int i = 0 ; i < currentSpacerList.count() ; ++i) 0708 { 0709 QString spacerName; 0710 spacerName.append(QString::fromLatin1("Spacerlistname %1").arg(i)); 0711 QString spacerType; 0712 spacerType.append(QString::fromLatin1("Spacerlisttype %1").arg(i)); 0713 0714 QStringList spacerTagNames; 0715 QStringList spacerTypes; 0716 0717 for (int j = 0 ; j < currentSpacerList[i].count() ; ++j) 0718 { 0719 spacerTagNames.append(currentSpacerList[i].at(j).tagName); 0720 0721 if (currentSpacerList[i].at(j).tagType == TypeSpacer) 0722 { 0723 spacerTypes.append(QLatin1String("Spacer")); 0724 } 0725 else if (currentSpacerList[i].at(j).tagType == TypeNewChild) 0726 { 0727 spacerTypes.append(QLatin1String("NewChild")); 0728 } 0729 else 0730 { 0731 spacerTypes.append(QLatin1String("OldChild")); 0732 } 0733 } 0734 0735 group->writeEntry(spacerName, spacerTagNames); 0736 group->writeEntry(spacerType, spacerTypes); 0737 } 0738 } 0739 0740 /** 0741 * Restores the settings of widgets contained in reverse geocoding widget. 0742 * @param group Here are stored the settings. 0743 */ 0744 void RGWidget::readSettingsFromGroup(const KConfigGroup* const group) 0745 { 0746 const int spacerCount = group->readEntry("Spacers count", 0); 0747 QList<QList<TagData> > spacersList; 0748 0749 for (int i = 0 ; i < spacerCount ; ++i) 0750 { 0751 QStringList spacerTagNames = group->readEntry(QString::fromLatin1("Spacerlistname %1").arg(i), QStringList()); 0752 QStringList spacerTypes = group->readEntry(QString::fromLatin1("Spacerlisttype %1").arg(i), QStringList()); 0753 QList<TagData> currentSpacerAddress; 0754 0755 for (int j = 0 ; j < spacerTagNames.count() ; ++j) 0756 { 0757 TagData currentTagData; 0758 currentTagData.tagName = spacerTagNames.at(j); 0759 QString currentTagType = spacerTypes.at(j); 0760 0761 if (currentTagType == QLatin1String("Spacer")) 0762 { 0763 currentTagData.tagType = TypeSpacer; 0764 } 0765 else if (currentTagType == QLatin1String("NewChild")) 0766 { 0767 currentTagData.tagType = TypeNewChild; 0768 } 0769 else if (currentTagType == QLatin1String("OldChild")) 0770 { 0771 currentTagData.tagType = TypeChild; 0772 } 0773 else 0774 { 0775 qCWarning(DIGIKAM_GENERAL_LOG) << "Unknown tag type" << currentTagType; 0776 continue; 0777 } 0778 0779 currentSpacerAddress.append(currentTagData); 0780 } 0781 0782 spacersList.append(currentSpacerAddress); 0783 } 0784 0785 // this make sure that all external tags are added to tag tree view before spacers are re-added 0786 0787 d->tagModel->addAllExternalTagsToTreeView(); 0788 d->tagModel->readdNewTags(spacersList); 0789 0790 d->serviceComboBox->setCurrentIndex(group->readEntry("RG Backend", 0)); 0791 d->languageEdit->setCurrentIndex(group->readEntry("Language", 0)); 0792 0793 d->hideOptions = !(group->readEntry("Hide options", false)); 0794 slotHideOptions(); 0795 0796 d->tagsLoc->setChecked(group->readEntry("Tags location", true)); 0797 d->metaLoc->setChecked(group->readEntry("Metadata location", false)); 0798 } 0799 0800 /** 0801 * Adds a tag to tag tree. 0802 */ 0803 void RGWidget::slotAddSingleSpacer() 0804 { 0805 /* 0806 const QModelIndex baseIndex = d->tagSelectionModel->currentIndex(); 0807 */ 0808 QModelIndex baseIndex; 0809 0810 if (!d->currentTagTreeIndex.isValid()) 0811 { 0812 baseIndex = d->currentTagTreeIndex; 0813 } 0814 else 0815 { 0816 baseIndex = d->tagSelectionModel->currentIndex(); 0817 } 0818 0819 QAction* const senderAction = qobject_cast<QAction*>(sender()); 0820 QString currentSpacerName = senderAction->data().toString(); 0821 0822 d->tagModel->addSpacerTag(baseIndex, currentSpacerName); 0823 } 0824 0825 /** 0826 * Adds a new tag to the tag tree. 0827 */ 0828 void RGWidget::slotAddCustomizedSpacer() 0829 { 0830 QModelIndex baseIndex; 0831 0832 if (!d->currentTagTreeIndex.isValid()) 0833 { 0834 baseIndex = d->currentTagTreeIndex; 0835 } 0836 else 0837 { 0838 baseIndex = d->tagSelectionModel->currentIndex(); 0839 } 0840 0841 bool ok = false; 0842 QString textString = QInputDialog::getText(this, i18nc("@title:window", "Add New Tag"), 0843 i18n("Select a name for the new tag:"), 0844 QLineEdit::Normal, QString(), &ok); 0845 0846 if (ok && !textString.isEmpty()) 0847 { 0848 d->tagModel->addSpacerTag(baseIndex, textString); 0849 } 0850 } 0851 0852 /** 0853 * Removes a tag from tag tree. 0854 * Note: If the tag is an external, it is no more deleted. 0855 */ 0856 void RGWidget::slotRemoveTag() 0857 { 0858 const QModelIndex baseIndex = d->tagSelectionModel->currentIndex(); 0859 d->tagModel->deleteTag(baseIndex); 0860 } 0861 0862 /** 0863 * Removes all spacers. 0864 */ 0865 void RGWidget::slotRemoveAllSpacers() 0866 { 0867 QString whatShouldRemove = QLatin1String("Spacers"); 0868 QModelIndex baseIndex; 0869 0870 if (!d->currentTagTreeIndex.isValid()) 0871 { 0872 baseIndex = d->currentTagTreeIndex; 0873 } 0874 else 0875 { 0876 baseIndex = d->tagSelectionModel->currentIndex(); 0877 } 0878 0879 d->tagModel->deleteAllSpacersOrNewTags(baseIndex, TypeSpacer); 0880 } 0881 0882 /** 0883 * Re-adds all deleted tags based on Undo/Redo widget. 0884 */ 0885 void RGWidget::slotReaddNewTags() 0886 { 0887 for (int row = 0 ; row < d->imageModel->rowCount() ; ++row) 0888 { 0889 GPSItemContainer* const currentItem = d->imageModel->itemFromIndex(d->imageModel->index(row, 0)); 0890 QList<QList<TagData> > tagAddresses = currentItem->getTagList(); 0891 0892 if (!tagAddresses.isEmpty()) 0893 { 0894 d->tagModel->readdNewTags(tagAddresses); 0895 } 0896 } 0897 } 0898 0899 /** 0900 * Deletes and re-adds all new added tags. 0901 */ 0902 void RGWidget::slotRegenerateNewTags() 0903 { 0904 QModelIndex baseIndex = QModelIndex(); 0905 d->tagModel->deleteAllSpacersOrNewTags(baseIndex, TypeNewChild); 0906 0907 slotReaddNewTags(); 0908 } 0909 0910 /** 0911 * Adds all address elements below the selected tag. The address ellements are order by area size. 0912 * For example: country > state > state district > city ... 0913 */ 0914 void RGWidget::slotAddAllAddressElementsToTag() 0915 { 0916 QModelIndex baseIndex; 0917 0918 if (!d->currentTagTreeIndex.isValid()) 0919 { 0920 baseIndex = d->currentTagTreeIndex; 0921 } 0922 else 0923 { 0924 baseIndex = d->tagSelectionModel->currentIndex(); 0925 } 0926 0927 QStringList spacerList; 0928 0929 if (d->currentBackend->backendName() == QLatin1String("OSM")) 0930 { 0931 /// @todo Why are these wrapped in QString? 0932 0933 spacerList.append(QLatin1String("{Country}")); 0934 spacerList.append(QLatin1String("{State}")); 0935 spacerList.append(QLatin1String("{State district}")); 0936 spacerList.append(QLatin1String("{County}")); 0937 spacerList.append(QLatin1String("{City}")); 0938 spacerList.append(QLatin1String("{City district}")); 0939 spacerList.append(QLatin1String("{Suburb}")); 0940 spacerList.append(QLatin1String("{Town}")); 0941 spacerList.append(QLatin1String("{Village}")); 0942 spacerList.append(QLatin1String("{Hamlet}")); 0943 spacerList.append(QLatin1String("{Street}")); 0944 spacerList.append(QLatin1String("{House number}")); 0945 } 0946 else if (d->currentBackend->backendName() == QLatin1String("Geonames")) 0947 { 0948 spacerList.append(QLatin1String("{Country}")); 0949 spacerList.append(QLatin1String("{Place}")); 0950 } 0951 else 0952 { 0953 spacerList.append(QLatin1String("{LAU1}")); 0954 spacerList.append(QLatin1String("{LAU2}")); 0955 spacerList.append(QLatin1String("{City}")); 0956 } 0957 0958 d->tagModel->addAllSpacersToTag(baseIndex, spacerList,0); 0959 } 0960 0961 void RGWidget::slotRGCanceled() 0962 { 0963 if (!d->undoCommand) 0964 { 0965 // the undo command object is not available, therefore 0966 // RG has probably been finished already 0967 0968 return; 0969 } 0970 0971 if (d->receivedRGCount > 0) 0972 { 0973 // Before we abort, ask the user whether he wants to discard 0974 // the information obtained so far. 0975 0976 // ATTENTION: While we ask the question, the RG backend continues running 0977 // and sends information about new images to this widget. 0978 // This means that RG might finish while we ask the question!!! 0979 0980 d->currentlyAskingCancelQuestion = true; 0981 0982 QString question; 0983 0984 if (d->receivedRGCount > 1) 0985 { 0986 question = i18n("%1 out of %2 images have been reverse geocoded. " 0987 "Would you like to keep the tags which were " 0988 "already obtained?", 0989 d->receivedRGCount, d->requestedRGCount); 0990 } 0991 else 0992 { 0993 question = i18n("1 image have been reverse geocoded. " 0994 "Would you like to keep the tags which were " 0995 "already obtained?"); 0996 } 0997 0998 const int result = DMessageBox::showYesNo(QMessageBox::Warning, this, 0999 i18nc("@title:window", "Abort reverse geocoding?"), 1000 question); 1001 1002 d->currentlyAskingCancelQuestion = false; 1003 1004 if (result == QMessageBox::Cancel) 1005 { 1006 // continue 1007 1008 // did RG finish while we asked the question? 1009 1010 if (d->receivedRGCount==d->requestedRGCount) 1011 { 1012 // the undo data was delayed, now send it 1013 1014 if (d->undoCommand) 1015 { 1016 Q_EMIT signalUndoCommand(d->undoCommand); 1017 d->undoCommand = nullptr; 1018 } 1019 1020 // unlock the UI 1021 1022 Q_EMIT signalSetUIEnabled(true); 1023 } 1024 1025 return; 1026 } 1027 1028 if (result == QMessageBox::No) 1029 { 1030 // discard the tags 1031 1032 d->undoCommand->undo(); 1033 } 1034 1035 if (result == QMessageBox::Yes) 1036 { 1037 if (d->undoCommand) 1038 { 1039 Q_EMIT signalUndoCommand(d->undoCommand); 1040 d->undoCommand = nullptr; 1041 } 1042 } 1043 } 1044 1045 // clean up the RG request: 1046 1047 d->currentBackend->cancelRequests(); 1048 1049 if (d->undoCommand) 1050 { 1051 delete d->undoCommand; 1052 d->undoCommand = nullptr; 1053 } 1054 1055 Q_EMIT signalSetUIEnabled(true); 1056 } 1057 1058 void RGWidget::createCountryCodeMap() 1059 { 1060 // All ISO 3166-1 country codes to convert alpha2 to alpha3 1061 // https://en.wikipedia.org/wiki/ISO_3166-1 1062 // https://www.iban.com/country-codes 1063 1064 d->countryCode.insert(QLatin1String("AF"), QLatin1String("AFG")); 1065 d->countryCode.insert(QLatin1String("AL"), QLatin1String("ALB")); 1066 d->countryCode.insert(QLatin1String("DZ"), QLatin1String("DZA")); 1067 d->countryCode.insert(QLatin1String("AS"), QLatin1String("ASM")); 1068 d->countryCode.insert(QLatin1String("AD"), QLatin1String("AND")); 1069 d->countryCode.insert(QLatin1String("AO"), QLatin1String("AGO")); 1070 d->countryCode.insert(QLatin1String("AI"), QLatin1String("AIA")); 1071 d->countryCode.insert(QLatin1String("AQ"), QLatin1String("ATA")); 1072 d->countryCode.insert(QLatin1String("AG"), QLatin1String("ATG")); 1073 d->countryCode.insert(QLatin1String("AR"), QLatin1String("ARG")); 1074 d->countryCode.insert(QLatin1String("AM"), QLatin1String("ARM")); 1075 d->countryCode.insert(QLatin1String("AW"), QLatin1String("ABW")); 1076 d->countryCode.insert(QLatin1String("AU"), QLatin1String("AUS")); 1077 d->countryCode.insert(QLatin1String("AT"), QLatin1String("AUT")); 1078 d->countryCode.insert(QLatin1String("AZ"), QLatin1String("AZE")); 1079 d->countryCode.insert(QLatin1String("BS"), QLatin1String("BHS")); 1080 d->countryCode.insert(QLatin1String("BH"), QLatin1String("BHR")); 1081 d->countryCode.insert(QLatin1String("BD"), QLatin1String("BGD")); 1082 d->countryCode.insert(QLatin1String("BB"), QLatin1String("BRB")); 1083 d->countryCode.insert(QLatin1String("BY"), QLatin1String("BLR")); 1084 d->countryCode.insert(QLatin1String("BE"), QLatin1String("BEL")); 1085 d->countryCode.insert(QLatin1String("BZ"), QLatin1String("BLZ")); 1086 d->countryCode.insert(QLatin1String("BJ"), QLatin1String("BEN")); 1087 d->countryCode.insert(QLatin1String("BM"), QLatin1String("BMU")); 1088 d->countryCode.insert(QLatin1String("BT"), QLatin1String("BTN")); 1089 d->countryCode.insert(QLatin1String("BO"), QLatin1String("BOL")); 1090 d->countryCode.insert(QLatin1String("BQ"), QLatin1String("BES")); 1091 d->countryCode.insert(QLatin1String("BA"), QLatin1String("BIH")); 1092 d->countryCode.insert(QLatin1String("BW"), QLatin1String("BWA")); 1093 d->countryCode.insert(QLatin1String("BV"), QLatin1String("BVT")); 1094 d->countryCode.insert(QLatin1String("BR"), QLatin1String("BRA")); 1095 d->countryCode.insert(QLatin1String("IO"), QLatin1String("IOT")); 1096 d->countryCode.insert(QLatin1String("BN"), QLatin1String("BRN")); 1097 d->countryCode.insert(QLatin1String("BG"), QLatin1String("BGR")); 1098 d->countryCode.insert(QLatin1String("BF"), QLatin1String("BFA")); 1099 d->countryCode.insert(QLatin1String("BI"), QLatin1String("BDI")); 1100 d->countryCode.insert(QLatin1String("CV"), QLatin1String("CPV")); 1101 d->countryCode.insert(QLatin1String("KH"), QLatin1String("KHM")); 1102 d->countryCode.insert(QLatin1String("CM"), QLatin1String("CMR")); 1103 d->countryCode.insert(QLatin1String("CA"), QLatin1String("CAN")); 1104 d->countryCode.insert(QLatin1String("KY"), QLatin1String("CYM")); 1105 d->countryCode.insert(QLatin1String("CF"), QLatin1String("CAF")); 1106 d->countryCode.insert(QLatin1String("TD"), QLatin1String("TCD")); 1107 d->countryCode.insert(QLatin1String("CL"), QLatin1String("CHL")); 1108 d->countryCode.insert(QLatin1String("CN"), QLatin1String("CHN")); 1109 d->countryCode.insert(QLatin1String("CX"), QLatin1String("CXR")); 1110 d->countryCode.insert(QLatin1String("CC"), QLatin1String("CCK")); 1111 d->countryCode.insert(QLatin1String("CO"), QLatin1String("COL")); 1112 d->countryCode.insert(QLatin1String("KM"), QLatin1String("COM")); 1113 d->countryCode.insert(QLatin1String("CD"), QLatin1String("COD")); 1114 d->countryCode.insert(QLatin1String("CG"), QLatin1String("COG")); 1115 d->countryCode.insert(QLatin1String("CK"), QLatin1String("COK")); 1116 d->countryCode.insert(QLatin1String("CR"), QLatin1String("CRI")); 1117 d->countryCode.insert(QLatin1String("HR"), QLatin1String("HRV")); 1118 d->countryCode.insert(QLatin1String("CU"), QLatin1String("CUB")); 1119 d->countryCode.insert(QLatin1String("CW"), QLatin1String("CUW")); 1120 d->countryCode.insert(QLatin1String("CY"), QLatin1String("CYP")); 1121 d->countryCode.insert(QLatin1String("CZ"), QLatin1String("CZE")); 1122 d->countryCode.insert(QLatin1String("CI"), QLatin1String("CIV")); 1123 d->countryCode.insert(QLatin1String("DK"), QLatin1String("DNK")); 1124 d->countryCode.insert(QLatin1String("DJ"), QLatin1String("DJI")); 1125 d->countryCode.insert(QLatin1String("DM"), QLatin1String("DMA")); 1126 d->countryCode.insert(QLatin1String("DO"), QLatin1String("DOM")); 1127 d->countryCode.insert(QLatin1String("EC"), QLatin1String("ECU")); 1128 d->countryCode.insert(QLatin1String("EG"), QLatin1String("EGY")); 1129 d->countryCode.insert(QLatin1String("SV"), QLatin1String("SLV")); 1130 d->countryCode.insert(QLatin1String("GQ"), QLatin1String("GNQ")); 1131 d->countryCode.insert(QLatin1String("ER"), QLatin1String("ERI")); 1132 d->countryCode.insert(QLatin1String("EE"), QLatin1String("EST")); 1133 d->countryCode.insert(QLatin1String("SZ"), QLatin1String("SWZ")); 1134 d->countryCode.insert(QLatin1String("ET"), QLatin1String("ETH")); 1135 d->countryCode.insert(QLatin1String("FK"), QLatin1String("FLK")); 1136 d->countryCode.insert(QLatin1String("FO"), QLatin1String("FRO")); 1137 d->countryCode.insert(QLatin1String("FJ"), QLatin1String("FJI")); 1138 d->countryCode.insert(QLatin1String("FI"), QLatin1String("FIN")); 1139 d->countryCode.insert(QLatin1String("FR"), QLatin1String("FRA")); 1140 d->countryCode.insert(QLatin1String("GF"), QLatin1String("GUF")); 1141 d->countryCode.insert(QLatin1String("PF"), QLatin1String("PYF")); 1142 d->countryCode.insert(QLatin1String("TF"), QLatin1String("ATF")); 1143 d->countryCode.insert(QLatin1String("GA"), QLatin1String("GAB")); 1144 d->countryCode.insert(QLatin1String("GM"), QLatin1String("GMB")); 1145 d->countryCode.insert(QLatin1String("GE"), QLatin1String("GEO")); 1146 d->countryCode.insert(QLatin1String("DE"), QLatin1String("DEU")); 1147 d->countryCode.insert(QLatin1String("GH"), QLatin1String("GHA")); 1148 d->countryCode.insert(QLatin1String("GI"), QLatin1String("GIB")); 1149 d->countryCode.insert(QLatin1String("GR"), QLatin1String("GRC")); 1150 d->countryCode.insert(QLatin1String("GL"), QLatin1String("GRL")); 1151 d->countryCode.insert(QLatin1String("GD"), QLatin1String("GRD")); 1152 d->countryCode.insert(QLatin1String("GP"), QLatin1String("GLP")); 1153 d->countryCode.insert(QLatin1String("GU"), QLatin1String("GUM")); 1154 d->countryCode.insert(QLatin1String("GT"), QLatin1String("GTM")); 1155 d->countryCode.insert(QLatin1String("GG"), QLatin1String("GGY")); 1156 d->countryCode.insert(QLatin1String("GN"), QLatin1String("GIN")); 1157 d->countryCode.insert(QLatin1String("GW"), QLatin1String("GNB")); 1158 d->countryCode.insert(QLatin1String("GY"), QLatin1String("GUY")); 1159 d->countryCode.insert(QLatin1String("HT"), QLatin1String("HTI")); 1160 d->countryCode.insert(QLatin1String("HM"), QLatin1String("HMD")); 1161 d->countryCode.insert(QLatin1String("VA"), QLatin1String("VAT")); 1162 d->countryCode.insert(QLatin1String("HN"), QLatin1String("HND")); 1163 d->countryCode.insert(QLatin1String("HK"), QLatin1String("HKG")); 1164 d->countryCode.insert(QLatin1String("HU"), QLatin1String("HUN")); 1165 d->countryCode.insert(QLatin1String("IS"), QLatin1String("ISL")); 1166 d->countryCode.insert(QLatin1String("IN"), QLatin1String("IND")); 1167 d->countryCode.insert(QLatin1String("ID"), QLatin1String("IDN")); 1168 d->countryCode.insert(QLatin1String("IR"), QLatin1String("IRN")); 1169 d->countryCode.insert(QLatin1String("IQ"), QLatin1String("IRQ")); 1170 d->countryCode.insert(QLatin1String("IE"), QLatin1String("IRL")); 1171 d->countryCode.insert(QLatin1String("IM"), QLatin1String("IMN")); 1172 d->countryCode.insert(QLatin1String("IL"), QLatin1String("ISR")); 1173 d->countryCode.insert(QLatin1String("IT"), QLatin1String("ITA")); 1174 d->countryCode.insert(QLatin1String("JM"), QLatin1String("JAM")); 1175 d->countryCode.insert(QLatin1String("JP"), QLatin1String("JPN")); 1176 d->countryCode.insert(QLatin1String("JE"), QLatin1String("JEY")); 1177 d->countryCode.insert(QLatin1String("JO"), QLatin1String("JOR")); 1178 d->countryCode.insert(QLatin1String("KZ"), QLatin1String("KAZ")); 1179 d->countryCode.insert(QLatin1String("KE"), QLatin1String("KEN")); 1180 d->countryCode.insert(QLatin1String("KI"), QLatin1String("KIR")); 1181 d->countryCode.insert(QLatin1String("KP"), QLatin1String("PRK")); 1182 d->countryCode.insert(QLatin1String("KR"), QLatin1String("KOR")); 1183 d->countryCode.insert(QLatin1String("KW"), QLatin1String("KWT")); 1184 d->countryCode.insert(QLatin1String("KG"), QLatin1String("KGZ")); 1185 d->countryCode.insert(QLatin1String("LA"), QLatin1String("LAO")); 1186 d->countryCode.insert(QLatin1String("LV"), QLatin1String("LVA")); 1187 d->countryCode.insert(QLatin1String("LB"), QLatin1String("LBN")); 1188 d->countryCode.insert(QLatin1String("LS"), QLatin1String("LSO")); 1189 d->countryCode.insert(QLatin1String("LR"), QLatin1String("LBR")); 1190 d->countryCode.insert(QLatin1String("LY"), QLatin1String("LBY")); 1191 d->countryCode.insert(QLatin1String("LI"), QLatin1String("LIE")); 1192 d->countryCode.insert(QLatin1String("LT"), QLatin1String("LTU")); 1193 d->countryCode.insert(QLatin1String("LU"), QLatin1String("LUX")); 1194 d->countryCode.insert(QLatin1String("MO"), QLatin1String("MAC")); 1195 d->countryCode.insert(QLatin1String("MG"), QLatin1String("MDG")); 1196 d->countryCode.insert(QLatin1String("MW"), QLatin1String("MWI")); 1197 d->countryCode.insert(QLatin1String("MY"), QLatin1String("MYS")); 1198 d->countryCode.insert(QLatin1String("MV"), QLatin1String("MDV")); 1199 d->countryCode.insert(QLatin1String("ML"), QLatin1String("MLI")); 1200 d->countryCode.insert(QLatin1String("MT"), QLatin1String("MLT")); 1201 d->countryCode.insert(QLatin1String("MH"), QLatin1String("MHL")); 1202 d->countryCode.insert(QLatin1String("MQ"), QLatin1String("MTQ")); 1203 d->countryCode.insert(QLatin1String("MR"), QLatin1String("MRT")); 1204 d->countryCode.insert(QLatin1String("MU"), QLatin1String("MUS")); 1205 d->countryCode.insert(QLatin1String("YT"), QLatin1String("MYT")); 1206 d->countryCode.insert(QLatin1String("MX"), QLatin1String("MEX")); 1207 d->countryCode.insert(QLatin1String("FM"), QLatin1String("FSM")); 1208 d->countryCode.insert(QLatin1String("MD"), QLatin1String("MDA")); 1209 d->countryCode.insert(QLatin1String("MC"), QLatin1String("MCO")); 1210 d->countryCode.insert(QLatin1String("MN"), QLatin1String("MNG")); 1211 d->countryCode.insert(QLatin1String("ME"), QLatin1String("MNE")); 1212 d->countryCode.insert(QLatin1String("MS"), QLatin1String("MSR")); 1213 d->countryCode.insert(QLatin1String("MA"), QLatin1String("MAR")); 1214 d->countryCode.insert(QLatin1String("MZ"), QLatin1String("MOZ")); 1215 d->countryCode.insert(QLatin1String("MM"), QLatin1String("MMR")); 1216 d->countryCode.insert(QLatin1String("NA"), QLatin1String("NAM")); 1217 d->countryCode.insert(QLatin1String("NR"), QLatin1String("NRU")); 1218 d->countryCode.insert(QLatin1String("NP"), QLatin1String("NPL")); 1219 d->countryCode.insert(QLatin1String("NL"), QLatin1String("NLD")); 1220 d->countryCode.insert(QLatin1String("NC"), QLatin1String("NCL")); 1221 d->countryCode.insert(QLatin1String("NZ"), QLatin1String("NZL")); 1222 d->countryCode.insert(QLatin1String("NI"), QLatin1String("NIC")); 1223 d->countryCode.insert(QLatin1String("NE"), QLatin1String("NER")); 1224 d->countryCode.insert(QLatin1String("NG"), QLatin1String("NGA")); 1225 d->countryCode.insert(QLatin1String("NU"), QLatin1String("NIU")); 1226 d->countryCode.insert(QLatin1String("NF"), QLatin1String("NFK")); 1227 d->countryCode.insert(QLatin1String("MP"), QLatin1String("MNP")); 1228 d->countryCode.insert(QLatin1String("NO"), QLatin1String("NOR")); 1229 d->countryCode.insert(QLatin1String("OM"), QLatin1String("OMN")); 1230 d->countryCode.insert(QLatin1String("PK"), QLatin1String("PAK")); 1231 d->countryCode.insert(QLatin1String("PW"), QLatin1String("PLW")); 1232 d->countryCode.insert(QLatin1String("PS"), QLatin1String("PSE")); 1233 d->countryCode.insert(QLatin1String("PA"), QLatin1String("PAN")); 1234 d->countryCode.insert(QLatin1String("PG"), QLatin1String("PNG")); 1235 d->countryCode.insert(QLatin1String("PY"), QLatin1String("PRY")); 1236 d->countryCode.insert(QLatin1String("PE"), QLatin1String("PER")); 1237 d->countryCode.insert(QLatin1String("PH"), QLatin1String("PHL")); 1238 d->countryCode.insert(QLatin1String("PN"), QLatin1String("PCN")); 1239 d->countryCode.insert(QLatin1String("PL"), QLatin1String("POL")); 1240 d->countryCode.insert(QLatin1String("PT"), QLatin1String("PRT")); 1241 d->countryCode.insert(QLatin1String("PR"), QLatin1String("PRI")); 1242 d->countryCode.insert(QLatin1String("QA"), QLatin1String("QAT")); 1243 d->countryCode.insert(QLatin1String("MK"), QLatin1String("MKD")); 1244 d->countryCode.insert(QLatin1String("RO"), QLatin1String("ROU")); 1245 d->countryCode.insert(QLatin1String("RU"), QLatin1String("RUS")); 1246 d->countryCode.insert(QLatin1String("RW"), QLatin1String("RWA")); 1247 d->countryCode.insert(QLatin1String("RE"), QLatin1String("REU")); 1248 d->countryCode.insert(QLatin1String("BL"), QLatin1String("BLM")); 1249 d->countryCode.insert(QLatin1String("SH"), QLatin1String("SHN")); 1250 d->countryCode.insert(QLatin1String("KN"), QLatin1String("KNA")); 1251 d->countryCode.insert(QLatin1String("LC"), QLatin1String("LCA")); 1252 d->countryCode.insert(QLatin1String("MF"), QLatin1String("MAF")); 1253 d->countryCode.insert(QLatin1String("PM"), QLatin1String("SPM")); 1254 d->countryCode.insert(QLatin1String("VC"), QLatin1String("VCT")); 1255 d->countryCode.insert(QLatin1String("WS"), QLatin1String("WSM")); 1256 d->countryCode.insert(QLatin1String("SM"), QLatin1String("SMR")); 1257 d->countryCode.insert(QLatin1String("ST"), QLatin1String("STP")); 1258 d->countryCode.insert(QLatin1String("SA"), QLatin1String("SAU")); 1259 d->countryCode.insert(QLatin1String("SN"), QLatin1String("SEN")); 1260 d->countryCode.insert(QLatin1String("RS"), QLatin1String("SRB")); 1261 d->countryCode.insert(QLatin1String("SC"), QLatin1String("SYC")); 1262 d->countryCode.insert(QLatin1String("SL"), QLatin1String("SLE")); 1263 d->countryCode.insert(QLatin1String("SG"), QLatin1String("SGP")); 1264 d->countryCode.insert(QLatin1String("SX"), QLatin1String("SXM")); 1265 d->countryCode.insert(QLatin1String("SK"), QLatin1String("SVK")); 1266 d->countryCode.insert(QLatin1String("SI"), QLatin1String("SVN")); 1267 d->countryCode.insert(QLatin1String("SB"), QLatin1String("SLB")); 1268 d->countryCode.insert(QLatin1String("SO"), QLatin1String("SOM")); 1269 d->countryCode.insert(QLatin1String("ZA"), QLatin1String("ZAF")); 1270 d->countryCode.insert(QLatin1String("GS"), QLatin1String("SGS")); 1271 d->countryCode.insert(QLatin1String("SS"), QLatin1String("SSD")); 1272 d->countryCode.insert(QLatin1String("ES"), QLatin1String("ESP")); 1273 d->countryCode.insert(QLatin1String("LK"), QLatin1String("LKA")); 1274 d->countryCode.insert(QLatin1String("SD"), QLatin1String("SDN")); 1275 d->countryCode.insert(QLatin1String("SR"), QLatin1String("SUR")); 1276 d->countryCode.insert(QLatin1String("SJ"), QLatin1String("SJM")); 1277 d->countryCode.insert(QLatin1String("SE"), QLatin1String("SWE")); 1278 d->countryCode.insert(QLatin1String("CH"), QLatin1String("CHE")); 1279 d->countryCode.insert(QLatin1String("SY"), QLatin1String("SYR")); 1280 d->countryCode.insert(QLatin1String("TW"), QLatin1String("TWN")); 1281 d->countryCode.insert(QLatin1String("TJ"), QLatin1String("TJK")); 1282 d->countryCode.insert(QLatin1String("TZ"), QLatin1String("TZA")); 1283 d->countryCode.insert(QLatin1String("TH"), QLatin1String("THA")); 1284 d->countryCode.insert(QLatin1String("TL"), QLatin1String("TLS")); 1285 d->countryCode.insert(QLatin1String("TG"), QLatin1String("TGO")); 1286 d->countryCode.insert(QLatin1String("TK"), QLatin1String("TKL")); 1287 d->countryCode.insert(QLatin1String("TO"), QLatin1String("TON")); 1288 d->countryCode.insert(QLatin1String("TT"), QLatin1String("TTO")); 1289 d->countryCode.insert(QLatin1String("TN"), QLatin1String("TUN")); 1290 d->countryCode.insert(QLatin1String("TR"), QLatin1String("TUR")); 1291 d->countryCode.insert(QLatin1String("TM"), QLatin1String("TKM")); 1292 d->countryCode.insert(QLatin1String("TC"), QLatin1String("TCA")); 1293 d->countryCode.insert(QLatin1String("TV"), QLatin1String("TUV")); 1294 d->countryCode.insert(QLatin1String("UG"), QLatin1String("UGA")); 1295 d->countryCode.insert(QLatin1String("UA"), QLatin1String("UKR")); 1296 d->countryCode.insert(QLatin1String("AE"), QLatin1String("ARE")); 1297 d->countryCode.insert(QLatin1String("GB"), QLatin1String("GBR")); 1298 d->countryCode.insert(QLatin1String("UM"), QLatin1String("UMI")); 1299 d->countryCode.insert(QLatin1String("US"), QLatin1String("USA")); 1300 d->countryCode.insert(QLatin1String("UY"), QLatin1String("URY")); 1301 d->countryCode.insert(QLatin1String("UZ"), QLatin1String("UZB")); 1302 d->countryCode.insert(QLatin1String("VU"), QLatin1String("VUT")); 1303 d->countryCode.insert(QLatin1String("VE"), QLatin1String("VEN")); 1304 d->countryCode.insert(QLatin1String("VN"), QLatin1String("VNM")); 1305 d->countryCode.insert(QLatin1String("VG"), QLatin1String("VGB")); 1306 d->countryCode.insert(QLatin1String("VI"), QLatin1String("VIR")); 1307 d->countryCode.insert(QLatin1String("WF"), QLatin1String("WLF")); 1308 d->countryCode.insert(QLatin1String("EH"), QLatin1String("ESH")); 1309 d->countryCode.insert(QLatin1String("YE"), QLatin1String("YEM")); 1310 d->countryCode.insert(QLatin1String("ZM"), QLatin1String("ZMB")); 1311 d->countryCode.insert(QLatin1String("ZW"), QLatin1String("ZWE")); 1312 d->countryCode.insert(QLatin1String("AX"), QLatin1String("ALA")); 1313 } 1314 1315 } // namespace Digikam 1316 1317 #include "moc_rgwidget.cpp"