File indexing completed on 2025-01-19 03:53:38
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2007-11-01 0007 * Description : Access item position stored in database. 0008 * 0009 * SPDX-FileCopyrightText: 2007-2008 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de> 0010 * 0011 * SPDX-License-Identifier: GPL-2.0-or-later 0012 * 0013 * ============================================================ */ 0014 0015 #include "itemposition.h" 0016 0017 // Local includes 0018 0019 #include "coredbaccess.h" 0020 #include "coredb.h" 0021 #include "dmetadata.h" 0022 #include "metadatainfo.h" 0023 0024 namespace Digikam 0025 { 0026 0027 class Q_DECL_HIDDEN ItemPositionPriv : public QSharedData 0028 { 0029 0030 public: 0031 0032 ItemPositionPriv() 0033 : empty (true), 0034 // NOTE: Do not initialize the QVariants here, they are expected to be null 0035 imageId (-1), 0036 dirtyFields (DatabaseFields::ItemPositionsNone) 0037 { 0038 } 0039 0040 void resetData() 0041 { 0042 description.clear(); 0043 latitude.clear(); 0044 longitude.clear(); 0045 latitudeNumber = QVariant(); 0046 longitudeNumber = QVariant(); 0047 altitude = QVariant(); 0048 orientation = QVariant(); 0049 tilt = QVariant(); 0050 roll = QVariant(); 0051 empty = true; 0052 dirtyFields = DatabaseFields::ItemPositionsNone; 0053 } 0054 0055 void init(const CoreDbAccess& access, qlonglong imageId); 0056 0057 public: 0058 0059 bool empty; 0060 0061 QVariant latitudeNumber; 0062 QVariant longitudeNumber; 0063 QVariant altitude; 0064 QVariant orientation; 0065 QVariant tilt; 0066 QVariant roll; 0067 QVariant accuracy; 0068 0069 qlonglong imageId; 0070 0071 QString description; 0072 QString latitude; 0073 QString longitude; 0074 0075 DatabaseFields::ItemPositions dirtyFields; 0076 }; 0077 0078 void ItemPositionPriv::init(const CoreDbAccess& access, qlonglong id) 0079 { 0080 imageId = id; 0081 QVariantList values = access.db()->getItemPosition(imageId); 0082 0083 if (values.size() == 10) 0084 { 0085 empty = false; 0086 latitude = values.at(0).toString(); 0087 latitudeNumber = values.at(1); 0088 longitude = values.at(2).toString(); 0089 longitudeNumber = values.at(3); 0090 altitude = values.at(4); 0091 orientation = values.at(5); 0092 tilt = values.at(6); 0093 roll = values.at(7); 0094 accuracy = values.at(8); 0095 description = values.at(9).toString(); 0096 } 0097 } 0098 0099 // ------------------------------------------------------ 0100 0101 ItemPosition::ItemPosition() 0102 { 0103 } 0104 0105 ItemPosition::ItemPosition(qlonglong imageId) 0106 : d(new ItemPositionPriv) 0107 { 0108 CoreDbAccess access; 0109 d->init(access, imageId); 0110 } 0111 0112 ItemPosition::ItemPosition(const CoreDbAccess& access, qlonglong imageId) 0113 : d(new ItemPositionPriv) 0114 { 0115 d->init(access, imageId); 0116 } 0117 0118 ItemPosition::ItemPosition(const ItemPosition& other) 0119 : d(other.d) 0120 { 0121 } 0122 0123 ItemPosition::~ItemPosition() 0124 { 0125 apply(); 0126 } 0127 0128 ItemPosition& ItemPosition::operator=(const ItemPosition& other) 0129 { 0130 d = other.d; 0131 0132 return *this; 0133 } 0134 0135 bool ItemPosition::isNull() const 0136 { 0137 return !d; 0138 } 0139 0140 bool ItemPosition::isEmpty() const 0141 { 0142 return (!d || d->empty); 0143 } 0144 0145 QString ItemPosition::latitude() const 0146 { 0147 if (!d) 0148 { 0149 return QString(); 0150 } 0151 0152 return d->latitude; 0153 } 0154 0155 QString ItemPosition::longitude() const 0156 { 0157 if (!d) 0158 { 0159 return QString(); 0160 } 0161 0162 return d->longitude; 0163 } 0164 0165 double ItemPosition::latitudeNumber() const 0166 { 0167 if (!d) 0168 { 0169 return 0; 0170 } 0171 0172 return d->latitudeNumber.toDouble(); 0173 } 0174 0175 double ItemPosition::longitudeNumber() const 0176 { 0177 if (!d) 0178 { 0179 return 0; 0180 } 0181 0182 return d->longitudeNumber.toDouble(); 0183 } 0184 0185 QString ItemPosition::latitudeFormatted() const 0186 { 0187 if (!d) 0188 { 0189 return QString(); 0190 } 0191 0192 return DMetadata::valueToString(d->latitude, MetadataInfo::Latitude); 0193 } 0194 0195 QString ItemPosition::longitudeFormatted() const 0196 { 0197 if (!d) 0198 { 0199 return QString(); 0200 } 0201 0202 return DMetadata::valueToString(d->longitude, MetadataInfo::Longitude); 0203 } 0204 0205 bool ItemPosition::latitudeUserPresentableNumbers(int* degrees, int* minutes, double* seconds, char* directionReference) 0206 { 0207 if (!d) 0208 { 0209 return false; 0210 } 0211 0212 return DMetadata::convertToUserPresentableNumbers(d->latitude, degrees, minutes, seconds, directionReference); 0213 } 0214 0215 bool ItemPosition::longitudeUserPresentableNumbers(int* degrees, int* minutes, double* seconds, char* directionReference) 0216 { 0217 if (!d) 0218 { 0219 return false; 0220 } 0221 0222 return DMetadata::convertToUserPresentableNumbers(d->longitude, degrees, minutes, seconds, directionReference); 0223 } 0224 0225 double ItemPosition::altitude() const 0226 { 0227 if (!d) 0228 { 0229 return 0; 0230 } 0231 0232 return d->altitude.toDouble(); 0233 } 0234 0235 QString ItemPosition::altitudeFormatted() const 0236 { 0237 if (!d) 0238 { 0239 return QString(); 0240 } 0241 0242 return DMetadata::valueToString(d->altitude, MetadataInfo::Altitude); 0243 } 0244 0245 double ItemPosition::orientation() const 0246 { 0247 if (!d) 0248 { 0249 return 0; 0250 } 0251 0252 return d->orientation.toDouble(); 0253 } 0254 0255 double ItemPosition::tilt() const 0256 { 0257 if (!d) 0258 { 0259 return 0; 0260 } 0261 0262 return d->tilt.toDouble(); 0263 } 0264 0265 double ItemPosition::roll() const 0266 { 0267 if (!d) 0268 { 0269 return 0; 0270 } 0271 0272 return d->roll.toDouble(); 0273 } 0274 0275 double ItemPosition::accuracy() const 0276 { 0277 if (!d) 0278 { 0279 return 0; 0280 } 0281 0282 return d->accuracy.toDouble(); 0283 } 0284 0285 QString ItemPosition::description() const 0286 { 0287 if (!d) 0288 { 0289 return QString(); 0290 } 0291 0292 return d->description; 0293 } 0294 0295 bool ItemPosition::hasCoordinates() const 0296 { 0297 return (d && !d->latitudeNumber.isNull() && !d->longitudeNumber.isNull()); 0298 } 0299 0300 bool ItemPosition::hasAltitude() const 0301 { 0302 return (d && !d->altitude.isNull()); 0303 } 0304 0305 bool ItemPosition::hasOrientation() const 0306 { 0307 return (d && !d->orientation.isNull()); 0308 } 0309 0310 bool ItemPosition::hasTilt() const 0311 { 0312 return (d && !d->tilt.isNull()); 0313 } 0314 0315 bool ItemPosition::hasRoll() const 0316 { 0317 return (d && !d->roll.isNull()); 0318 } 0319 0320 bool ItemPosition::hasAccuracy() const 0321 { 0322 return (d && !d->accuracy.isNull()); 0323 } 0324 0325 bool ItemPosition::setLatitude(const QString& latitude) 0326 { 0327 if (!d) 0328 { 0329 return false; 0330 } 0331 0332 double number; 0333 0334 if (!DMetadata::convertFromGPSCoordinateString(latitude, &number)) 0335 { 0336 return false; 0337 } 0338 0339 d->latitude = latitude; 0340 d->latitudeNumber = number; 0341 d->dirtyFields |= DatabaseFields::Latitude | DatabaseFields::LatitudeNumber; 0342 0343 return true; 0344 } 0345 0346 bool ItemPosition::setLongitude(const QString& longitude) 0347 { 0348 if (!d) 0349 { 0350 return false; 0351 } 0352 0353 double number; 0354 0355 if (!DMetadata::convertFromGPSCoordinateString(longitude, &number)) 0356 { 0357 return false; 0358 } 0359 0360 d->longitude = longitude; 0361 d->longitudeNumber = number; 0362 d->dirtyFields |= DatabaseFields::Longitude | DatabaseFields::LongitudeNumber; 0363 0364 return true; 0365 } 0366 0367 bool ItemPosition::setLatitude(double latitudeNumber) 0368 { 0369 if (!d) 0370 { 0371 return false; 0372 } 0373 0374 QString string = DMetadata::convertToGPSCoordinateString(true, latitudeNumber); 0375 0376 if (string.isNull()) 0377 { 0378 return false; 0379 } 0380 0381 d->latitude = string; 0382 d->latitudeNumber = latitudeNumber; 0383 d->dirtyFields |= DatabaseFields::Latitude | DatabaseFields::LatitudeNumber; 0384 0385 return true; 0386 } 0387 0388 bool ItemPosition::setLongitude(double longitudeNumber) 0389 { 0390 if (!d) 0391 { 0392 return false; 0393 } 0394 0395 QString string = DMetadata::convertToGPSCoordinateString(false, longitudeNumber); 0396 0397 if (string.isNull()) 0398 { 0399 return false; 0400 } 0401 0402 d->longitude = string; 0403 d->longitudeNumber = longitudeNumber; 0404 d->dirtyFields |= DatabaseFields::Longitude | DatabaseFields::LongitudeNumber; 0405 0406 return true; 0407 } 0408 0409 void ItemPosition::setAltitude(double altitude) 0410 { 0411 if (!d) 0412 { 0413 return; 0414 } 0415 0416 d->altitude = altitude; 0417 d->dirtyFields |= DatabaseFields::Altitude; 0418 } 0419 0420 void ItemPosition::setOrientation(double orientation) 0421 { 0422 if (!d) 0423 { 0424 return; 0425 } 0426 0427 d->orientation = orientation; 0428 d->dirtyFields |= DatabaseFields::PositionOrientation; 0429 } 0430 0431 void ItemPosition::setTilt(double tilt) 0432 { 0433 if (!d) 0434 { 0435 return; 0436 } 0437 0438 d->tilt = tilt; 0439 d->dirtyFields |= DatabaseFields::PositionTilt; 0440 } 0441 0442 void ItemPosition::setRoll(double roll) 0443 { 0444 if (!d) 0445 { 0446 return; 0447 } 0448 0449 d->roll = roll; 0450 d->dirtyFields |= DatabaseFields::PositionRoll; 0451 } 0452 0453 void ItemPosition::setAccuracy(double accuracy) 0454 { 0455 if (!d) 0456 { 0457 return; 0458 } 0459 0460 d->accuracy = accuracy; 0461 d->dirtyFields |= DatabaseFields::PositionAccuracy; 0462 } 0463 0464 void ItemPosition::setDescription(const QString& description) 0465 { 0466 if (!d) 0467 { 0468 return; 0469 } 0470 0471 d->description = description; 0472 d->dirtyFields |= DatabaseFields::PositionDescription; 0473 } 0474 0475 void ItemPosition::apply() 0476 { 0477 if (!d) 0478 { 0479 return; 0480 } 0481 0482 if (d->dirtyFields == DatabaseFields::ItemPositionsNone) 0483 { 0484 return; 0485 } 0486 0487 QVariantList values; 0488 0489 if (d->dirtyFields & DatabaseFields::Latitude) 0490 { 0491 values << d->latitude; 0492 } 0493 0494 if (d->dirtyFields & DatabaseFields::LatitudeNumber) 0495 { 0496 values << d->latitudeNumber; 0497 } 0498 0499 if (d->dirtyFields & DatabaseFields::Longitude) 0500 { 0501 values << d->longitude; 0502 } 0503 0504 if (d->dirtyFields & DatabaseFields::LongitudeNumber) 0505 { 0506 values << d->longitudeNumber; 0507 } 0508 0509 if (d->dirtyFields & DatabaseFields::Altitude) 0510 { 0511 values << d->altitude; 0512 } 0513 0514 if (d->dirtyFields & DatabaseFields::PositionOrientation) 0515 { 0516 values << d->orientation; 0517 } 0518 0519 if (d->dirtyFields & DatabaseFields::PositionTilt) 0520 { 0521 values << d->tilt; 0522 } 0523 0524 if (d->dirtyFields & DatabaseFields::PositionRoll) 0525 { 0526 values << d->roll; 0527 } 0528 0529 if (d->dirtyFields & DatabaseFields::PositionAccuracy) 0530 { 0531 values << d->accuracy; 0532 } 0533 0534 if (d->dirtyFields & DatabaseFields::PositionDescription) 0535 { 0536 values << d->description; 0537 } 0538 0539 if (d->empty) 0540 { 0541 CoreDbAccess().db()->addItemPosition(d->imageId, values, d->dirtyFields); 0542 d->empty = false; 0543 } 0544 else 0545 { 0546 CoreDbAccess().db()->changeItemPosition(d->imageId, values, d->dirtyFields); 0547 } 0548 0549 d->dirtyFields = DatabaseFields::ItemPositionsNone; 0550 } 0551 0552 void ItemPosition::remove() 0553 { 0554 CoreDbAccess().db()->removeItemPosition(d->imageId); 0555 d->resetData(); 0556 } 0557 0558 void ItemPosition::removeAltitude() 0559 { 0560 CoreDbAccess().db()->removeItemPositionAltitude(d->imageId); 0561 d->dirtyFields &= ~DatabaseFields::Altitude; 0562 d->altitude = QVariant(); 0563 } 0564 0565 } // namespace Digikam