diff --git a/static/reports/cppcheck/master/0.html b/static/reports/cppcheck/master/0.html index b72d4b80f..39e5aee92 100644 --- a/static/reports/cppcheck/master/0.html +++ b/static/reports/cppcheck/master/0.html @@ -1,2327 +1,1037 @@ - Cppcheck - HTML report - digiKam-master-rev-907aafb5fa + Cppcheck - HTML report - digiKam-master-rev-e85fcd090f
-
   1
-   2
-   3
-   4
-   5
-   6
-   7
-   8
-   9
-  10
-  11
-  12
-  13
-  14
-  15
-  16
-  17
-  18
-  19
-  20
-  21
-  22
-  23
-  24
-  25
-  26
-  27
-  28
-  29
-  30
-  31
-  32
-  33
-  34
-  35
-  36
-  37
-  38
-  39
-  40
-  41
-  42
-  43
-  44
-  45
-  46
-  47
-  48
-  49
-  50
-  51
-  52
-  53
-  54
-  55
-  56
-  57
-  58
-  59
-  60
-  61
-  62
-  63
-  64
-  65
-  66
-  67
-  68
-  69
-  70
-  71
-  72
-  73
-  74
-  75
-  76
-  77
-  78
-  79
-  80
-  81
-  82
-  83
-  84
-  85
-  86
-  87
-  88
-  89
-  90
-  91
-  92
-  93
-  94
-  95
-  96
-  97
-  98
-  99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
- 575
- 576
- 577
- 578
- 579
- 580
- 581
- 582
- 583
- 584
- 585
- 586
- 587
- 588
- 589
- 590
- 591
- 592
- 593
- 594
- 595
- 596
- 597
- 598
- 599
- 600
- 601
- 602
- 603
- 604
- 605
- 606
- 607
- 608
- 609
- 610
- 611
- 612
- 613
- 614
- 615
- 616
- 617
- 618
- 619
- 620
- 621
- 622
- 623
- 624
- 625
- 626
- 627
- 628
- 629
- 630
- 631
- 632
- 633
- 634
- 635
- 636
- 637
- 638
- 639
- 640
- 641
- 642
- 643
- 644
- 645
- 646
- 647
- 648
- 649
- 650
- 651
- 652
- 653
- 654
- 655
- 656
- 657
- 658
- 659
- 660
- 661
- 662
- 663
- 664
- 665
- 666
- 667
- 668
- 669
- 670
- 671
- 672
- 673
- 674
- 675
- 676
- 677
- 678
- 679
- 680
- 681
- 682
- 683
- 684
- 685
- 686
- 687
- 688
- 689
- 690
- 691
- 692
- 693
- 694
- 695
- 696
- 697
- 698
- 699
- 700
- 701
- 702
- 703
- 704
- 705
- 706
- 707
- 708
- 709
- 710
- 711
- 712
- 713
- 714
- 715
- 716
- 717
- 718
- 719
- 720
- 721
- 722
- 723
- 724
- 725
- 726
- 727
- 728
- 729
- 730
- 731
- 732
- 733
- 734
- 735
- 736
- 737
- 738
- 739
- 740
- 741
- 742
- 743
- 744
- 745
- 746
- 747
- 748
- 749
- 750
- 751
- 752
- 753
- 754
- 755
- 756
- 757
- 758
- 759
- 760
- 761
- 762
- 763
- 764
- 765
- 766
- 767
- 768
- 769
- 770
- 771
- 772
- 773
- 774
- 775
- 776
- 777
- 778
- 779
- 780
- 781
- 782
- 783
- 784
- 785
- 786
- 787
- 788
- 789
- 790
- 791
- 792
- 793
- 794
- 795
- 796
- 797
- 798
- 799
- 800
- 801
- 802
- 803
- 804
- 805
- 806
- 807
- 808
- 809
- 810
- 811
- 812
- 813
- 814
- 815
- 816
- 817
- 818
- 819
- 820
- 821
- 822
- 823
- 824
- 825
- 826
- 827
- 828
- 829
- 830
- 831
- 832
- 833
- 834
- 835
- 836
- 837
- 838
- 839
- 840
- 841
- 842
- 843
- 844
- 845
- 846
- 847
- 848
- 849
- 850
- 851
- 852
- 853
- 854
- 855
- 856
- 857
- 858
- 859
- 860
- 861
- 862
- 863
- 864
- 865
- 866
- 867
- 868
- 869
- 870
- 871
- 872
- 873
- 874
- 875
- 876
- 877
- 878
- 879
- 880
- 881
- 882
- 883
- 884
- 885
- 886
- 887
- 888
- 889
- 890
- 891
- 892
- 893
- 894
- 895
- 896
- 897
- 898
- 899
- 900
- 901
- 902
- 903
- 904
- 905
- 906
- 907
- 908
- 909
- 910
- 911
- 912
- 913
- 914
- 915
- 916
- 917
- 918
- 919
- 920
- 921
- 922
- 923
- 924
- 925
- 926
- 927
- 928
- 929
- 930
- 931
- 932
- 933
- 934
- 935
- 936
- 937
- 938
- 939
- 940
- 941
- 942
- 943
- 944
- 945
- 946
- 947
- 948
- 949
- 950
- 951
- 952
- 953
- 954
- 955
- 956
- 957
- 958
- 959
- 960
- 961
- 962
- 963
- 964
- 965
- 966
- 967
- 968
- 969
- 970
- 971
- 972
- 973
- 974
- 975
- 976
- 977
- 978
- 979
- 980
- 981
- 982
- 983
- 984
- 985
- 986
- 987
- 988
- 989
- 990
- 991
- 992
- 993
- 994
- 995
- 996
- 997
- 998
- 999
-1000
-1001
-1002
-1003
-1004
-1005
-1006
-1007
-1008
-1009
-1010
-1011
-1012
-1013
-1014
-1015
-1016
-1017
-1018
-1019
-1020
-1021
-1022
-1023
-1024
-1025
-1026
-1027
-1028
-1029
-1030
-1031
-1032
-1033
-1034
-1035
-1036
-1037
-1038
-1039
-1040
-1041
-1042
-1043
-1044
-1045
-1046
-1047
-1048
-1049
-1050
-1051
-1052
-1053
-1054
-1055
-1056
-1057
-1058
-1059
-1060
-1061
-1062
-1063
-1064
-1065
-1066
-1067
-1068
-1069
-1070
-1071
-1072
-1073
-1074
-1075
-1076
-1077
-1078
-1079
-1080
-1081
-1082
-1083
-1084
-1085
-1086
-1087
-1088
-1089
-1090
-1091
/* ============================================================
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
/* ============================================================
  *
  * This file is a part of digiKam project
  * https://www.digikam.org
  *
- * Date        : 2006-05-16
- * Description : A tool to edit geolocation
+ * Date        : 2011-03-22
+ * Description : a Iface C++ interface
  *
- * Copyright (C) 2006-2020 by Gilles Caulier <caulier dot gilles at gmail dot com>
- * Copyright (C) 2010-2014 by Michael G. Hansen <mike at mghansen dot de>
- * Copyright (C) 2010      by Gabriel Voicu <ping dot gabi at gmail dot com>
- * Copyright (C) 2014      by Justus Schwartz <justus at gmx dot li>
+ * Copyright (C) 2011-2020 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ * Copyright (C) 2011      by Alexandre Mendes <alex dot mendes1988 at gmail dot com>
+ * Copyright (C) 2011      by Hormiere Guillaume <hormiere dot guillaume at gmail dot com>
+ * Copyright (C) 2011      by Manuel Campomanes <campomanes dot manuel at gmail dot com>
  *
  * This program is free software; you can redistribute it
  * and/or modify it under the terms of the GNU General
  * Public License as published by the Free Software Foundation;
- * either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * ============================================================ */
-
-#include "geolocationedit.h"
-
-// Qt includes
-
-#include <QtConcurrentMap>
-#include <QButtonGroup>
-#include <QCheckBox>
-#include <QCloseEvent>
-#include <QFuture>
-#include <QFutureWatcher>
-#include <QGroupBox>
-#include <QHBoxLayout>
-#include <QHeaderView>
-#include <QLabel>
-#include <QPushButton>
-#include <QGridLayout>
-#include <QPointer>
-#include <QRadioButton>
-#include <QSplitter>
-#include <QStackedLayout>
-#include <QStackedWidget>
-#include <QTimer>
-#include <QToolButton>
-#include <QTreeView>
-#include <QMenu>
-#include <QUndoView>
-#include <QAction>
-#include <QApplication>
-#include <QComboBox>
-#include <QDialogButtonBox>
-
-// KDE includes
+ * either version 2, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * ============================================================ */
+
+#include "mediawiki_edit.h"
+
+// Qt includes
+
+#include <QTimer>
+#include <QUrl>
+#include <QUrlQuery>
+#include <QXmlStreamReader>
+#include <QCryptographicHash>
+#include <QStringList>
+
+#include <QNetworkCookie>
+#include <QNetworkCookieJar>
+#include <QNetworkReply>
+#include <QNetworkRequest>
+
+// Local includes
+
+#include "mediawiki_iface.h"
+#include "mediawiki_queryinfo.h"
+#include "mediawiki_job_p.h"
+
+namespace MediaWiki
+{
+
+class Q_DECL_HIDDEN Result
+{
+public:
+
+    explicit Result()
+    {
+        m_captchaId = -1;
+    }
 
-#include <kconfiggroup.h>
-#include <ksharedconfig.h>
-#include <klocalizedstring.h>
-
-// Local includes
-
-#include "dlayoutbox.h"
-#include "digikam_config.h"
-#include "itemmarkertiler.h"
-#include "trackmanager.h"
-#include "gpscommon.h"
-#include "gpsitemmodel.h"
-#include "mapdragdrophandler.h"
-#include "gpsitemlist.h"
-#include "gpsitemlistdragdrophandler.h"
-#include "gpsitemlistcontextmenu.h"
-#include "gpscorrelatorwidget.h"
-#include "digikam_debug.h"
-#include "dmessagebox.h"
-#include "rgwidget.h"
-#include "kmlwidget.h"
-#include "statusprogressbar.h"
-#include "searchwidget.h"
-#include "backend-rg.h"
-#include "gpsitemdetails.h"
-#include "gpsgeoifacemodelhelper.h"
-#include "dxmlguiwindow.h"
-#include "gpsbookmarkowner.h"
-#include "gpsbookmarkmodelhelper.h"
-
-#ifdef GPSSYNC_MODELTEST
-#   include <modeltest.h>
-#endif
-
-using namespace Digikam;
-
-namespace DigikamGenericGeolocationEditPlugin
-{
+    unsigned int m_captchaId;
+    QVariant     m_captchaQuestion;
+    QString      m_captchaAnswer;
+};
+
+class Q_DECL_HIDDEN EditPrivate : public JobPrivate
+{
+public:
+
+    explicit EditPrivate(Iface& MediaWiki)
+        : JobPrivate(MediaWiki)
+    {
+    }
+
+    static int error(const QString& error)
+    {
+        QString temp = error;
+        int ret      = 0;
+        QStringList list;
+        list    << QStringLiteral("notext")
+                << QStringLiteral("invalidsection")
+                << QStringLiteral("protectedtitle")
+                << QStringLiteral("cantcreate")
+                << QStringLiteral("cantcreateanon")
+                << QStringLiteral("articleexists")
+                << QStringLiteral("noimageredirectanon")
+                << QStringLiteral("noimageredirect")
+                << QStringLiteral("spamdetected")
+                << QStringLiteral("filtered")
+                << QStringLiteral("contenttoobig")
+                << QStringLiteral("noeditanon")
+                << QStringLiteral("noedit")
+                << QStringLiteral("pagedeleted")
+                << QStringLiteral("emptypage")
+                << QStringLiteral("emptynewsection")
+                << QStringLiteral("editconflict")
+                << QStringLiteral("revwrongpage")
+                << QStringLiteral("undofailure");
 
-struct SaveChangedImagesHelper
-{
-public:
-
-    explicit SaveChangedImagesHelper(GPSItemModel* const model)
-        : imageModel(model)
-    {
-    }
-
-    QPair<QUrl, QString> operator()(const QPersistentModelIndex& itemIndex)
-    {
-        GPSItemContainer* const item = imageModel->itemFromIndex(itemIndex);
-
-        if (!item)
-            return QPair<QUrl, QString>(QUrl(), QString());
-
-        return QPair<QUrl, QString>(item->url(), item->saveChanges());
-    }
-
-public:
-
-    typedef QPair<QUrl, QString> result_type;
-    GPSItemModel* const          imageModel;
-};
-
-// ---------------------------------------------------------------------------------
-
-struct LoadFileMetadataHelper
-{
-public:
-
-    explicit LoadFileMetadataHelper(GPSItemModel* const model)
-        : imageModel(model)
-    {
-    }
-
-    QPair<QUrl, QString> operator()(const QPersistentModelIndex& itemIndex)
-    {
-        GPSItemContainer* const item = imageModel->itemFromIndex(itemIndex);
-
-        if (!item)
-            return QPair<QUrl, QString>(QUrl(), QString());
-
-        item->loadImageData();
-
-        return QPair<QUrl, QString>(item->url(), QString());
-    }
-
-public:
-
-    typedef QPair<QUrl, QString> result_type;
-    GPSItemModel* const         imageModel;
-};
-
-// ---------------------------------------------------------------------------------
-
-class Q_DECL_HIDDEN GeolocationEdit::Private
-{
-public:
-
-    explicit Private()
-    {
-        imageModel               = nullptr;
-        selectionModel           = nullptr;
-        uiEnabled                = true;
-        listViewContextMenu      = nullptr;
-        trackManager             = nullptr;
-        fileIOFutureWatcher      = nullptr;
-        fileIOCountDone          = 0;
-        fileIOCountTotal         = 0;
-        fileIOCloseAfterSaving   = false;
-        buttonBox                = nullptr;
-        VSplitter                = nullptr;
-        HSplitter                = nullptr;
-        treeView                 = nullptr;
-        stackedWidget            = nullptr;
-        tabBar                   = nullptr;
-        splitterSize             = 0;
-        undoStack                = nullptr;
-        undoView                 = nullptr;
-        progressBar              = nullptr;
-        progressCancelButton     = nullptr;
-        progressCancelObject     = nullptr;
-        detailsWidget            = nullptr;
-        correlatorWidget         = nullptr;
-        rgWidget                 = nullptr;
-        searchWidget             = nullptr;
-        kmlWidget                = nullptr;
-        mapSplitter              = nullptr;
-        mapWidget                = nullptr;
-        mapWidget2               = nullptr;
-        mapDragDropHandler       = nullptr;
-        mapModelHelper           = nullptr;
-        geoifaceMarkerModel      = nullptr;
-        sortActionOldestFirst    = nullptr;
-        sortActionYoungestFirst  = nullptr;
-        sortMenu                 = nullptr;
-        mapLayout                = MapLayoutOne;
-        cbMapLayout              = nullptr;
-        bookmarkOwner            = nullptr;
-        actionBookmarkVisibility = nullptr;
-        iface                    = nullptr;
-    }
-
-    // General things
-    GPSItemModel*                            imageModel;
-    QItemSelectionModel*                     selectionModel;
-    bool                                     uiEnabled;
-    GPSItemListContextMenu*                  listViewContextMenu;
-    TrackManager*                            trackManager;
-
-    // Loading and saving
-    QFuture<QPair<QUrl,QString> >            fileIOFuture;
-    QFutureWatcher<QPair<QUrl,QString> >*    fileIOFutureWatcher;
-    int                                      fileIOCountDone;
-    int                                      fileIOCountTotal;
-    bool                                     fileIOCloseAfterSaving;
-
-    // UI
-    QDialogButtonBox*                        buttonBox;
-    QSplitter*                               VSplitter;
-    QSplitter*                               HSplitter;
-    GPSItemList*                             treeView;
-    QStackedWidget*                          stackedWidget;
-    QTabBar*                                 tabBar;
-    int                                      splitterSize;
-    QUndoStack*                              undoStack;
-    QUndoView*                               undoView;
-
-    // UI: progress
-    StatusProgressBar*                       progressBar;
-    QPushButton*                             progressCancelButton;
-    QObject*                                 progressCancelObject;
-    QString                                  progressCancelSlot;
-
-    // UI: tab widgets
-    GPSItemDetails*                          detailsWidget;
-    GPSCorrelatorWidget*                     correlatorWidget;
-    RGWidget*                                rgWidget;
-    SearchWidget*                            searchWidget;
-    KmlWidget*                               kmlWidget;
-
-    // map: UI
-    MapLayout                                mapLayout;
-    QSplitter*                               mapSplitter;
-    MapWidget*                               mapWidget;
-    MapWidget*                               mapWidget2;
-
-    // map: helpers
-    MapDragDropHandler*                      mapDragDropHandler;
-    GPSGeoIfaceModelHelper*                  mapModelHelper;
-    ItemMarkerTiler*                         geoifaceMarkerModel;
+        ret = list.indexOf(temp.remove(QChar::fromLatin1('-')));
+
+        if (ret == -1)
+        {
+            ret = 0;
+        }
+
+        return  ret + (int)Edit::TextMissing ;
+    }
+
+    QUrl                   baseUrl;
+    QMap<QString, QString> requestParameter;
+    Result                 result;
+};
+
+Edit::Edit(Iface& media, QObject* const parent)
+    : Job(*new EditPrivate(media), parent)
+{
+}
+
+void Edit::setUndoAfter(int undoafter)
+{
+    Q_D(Edit);
+    d->requestParameter[QStringLiteral("undoafter")] = QString::number(undoafter);
+}
+
+void Edit::setUndo(int undo)
+{
+    Q_D(Edit);
+    d->requestParameter[QStringLiteral("undo")] = QString::number(undo);
+}
+
+void Edit::setPrependText(const QString& prependText)
+{
+    Q_D(Edit);
+    d->requestParameter[QStringLiteral("prependtext")] = prependText;
+    d->requestParameter[QStringLiteral("md5")]         = QString();
+}
+
+void Edit::setAppendText(const QString& appendText)
+{
+    Q_D(Edit);
+    d->requestParameter[QStringLiteral("appendtext")] = appendText;
+    d->requestParameter[QStringLiteral("md5")]        = QString();
+}
+
+void Edit::setPageName(const QString& pageName)
+{
+    Q_D(Edit);
+    d->requestParameter[QStringLiteral("title")] = pageName;
+}
+
+void Edit::setToken(const QString& token)
+{
+    Q_D(Edit);
+    d->requestParameter[QStringLiteral("token")] = token;
+}
+
+void Edit::setBaseTimestamp(const QDateTime& baseTimestamp)
+{
+    Q_D(Edit);
+    d->requestParameter[QStringLiteral("basetimestamp")] = baseTimestamp.toString(QStringLiteral("yyyy-MM-ddThh:mm:ssZ"));
+}
+
+void Edit::setStartTimestamp(const QDateTime& startTimestamp)
+{
+    Q_D(Edit);
+    d->requestParameter[QStringLiteral("starttimestamp")] = startTimestamp.toString(QStringLiteral("yyyy-MM-ddThh:mm:ssZ"));
+}
+
+void Edit::setText(const QString& text)
+{
+    Q_D(Edit);
+    d->requestParameter[QStringLiteral("text")] = text;
+    d->requestParameter[QStringLiteral("md5")]  = QString();
+}
+
+void Edit::setRecreate(bool recreate)
+{
+    Q_D(Edit);
+
+    if (recreate)
+    {
+        d->requestParameter[QStringLiteral("recreate")] = QStringLiteral("on");
+        d->requestParameter[QStringLiteral("md5")]      = QString();
+    }
+}
+
+void Edit::setCreateonly(bool createonly)
+{
+    Q_D(Edit);
+
+    if (createonly)
+    {
+        d->requestParameter[QStringLiteral("createonly")] = QStringLiteral("on");
+        d->requestParameter[QStringLiteral("md5")]        = QString();
+    }
+}
+
+void Edit::setNocreate(bool norecreate)
+{
+    Q_D(Edit);
+
+    if (norecreate)
+    {
+        d->requestParameter[QStringLiteral("nocreate")] = QStringLiteral("on");
+        d->requestParameter[QStringLiteral("md5")]      = QString();
+    }
+}
+
+void Edit::setMinor(bool minor)
+{
+    Q_D(Edit);
+
+    if (minor)
+        d->requestParameter[QStringLiteral("minor")]    = QStringLiteral("on");
+    else
+        d->requestParameter[QStringLiteral("notminor")] = QStringLiteral("on");
+}
+
+void Edit::setSection(const QString& section)
+{
+    Q_D(Edit);
+    d->requestParameter[QStringLiteral("section")] = section;
+}
+
+void Edit::setSummary(const QString& summary)
+{
+    Q_D(Edit);
+    d->requestParameter[QStringLiteral("summary")] = summary;
+}
+
+void Edit::setWatchList(Edit::Watchlist watchlist)
+{
+    Q_D(Edit);
+
+    switch (watchlist)
+    {
+        case Edit::watch:
+            d->requestParameter[QStringLiteral("watchlist")] = QString(QStringLiteral("watch"));
+            break;
+        case Edit::unwatch:
+            d->requestParameter[QStringLiteral("watchlist")] = QString(QStringLiteral("unwatch"));
+            break;
+        case Edit::nochange:
+            d->requestParameter[QStringLiteral("watchlist")] = QString(QStringLiteral("nochange"));
+            break;
+        case Edit::preferences:
+            d->requestParameter[QStringLiteral("watchlist")] = QString(QStringLiteral("preferences"));
+            break;
+    }
+}
 
-    // map: actions
-    QAction*                                 sortActionOldestFirst;
-    QAction*                                 sortActionYoungestFirst;
-    QMenu*                                   sortMenu;
-    QComboBox*                               cbMapLayout;
-
-    GPSBookmarkOwner*                        bookmarkOwner;
-    QAction*                                 actionBookmarkVisibility;
-
-    DInfoInterface*                          iface;
-};
-
-GeolocationEdit::GeolocationEdit(QWidget* const parent, DInfoInterface* const iface)
-    : DPluginDialog(parent, QLatin1String("Geolocation Edit Settings")),
-      d(new Private)
-{
-    setAttribute(Qt::WA_DeleteOnClose, true);
-    setWindowTitle(i18n("Geolocation Editor"));
-    setMinimumSize(300, 400);
-    setModal(true);
-
-    d->iface          = iface;
-    d->imageModel     = new GPSItemModel(this);
-    d->selectionModel = new QItemSelectionModel(d->imageModel);
-    d->trackManager   = new TrackManager(this);
-
-#ifdef GPSSYNC_MODELTEST
-    new ModelTest(d->imageModel, this);
-#endif
-
-    d->bookmarkOwner = new GPSBookmarkOwner(d->imageModel, this);
-    d->undoStack     = new QUndoStack(this);
-    d->stackedWidget = new QStackedWidget();
-    d->searchWidget  = new SearchWidget(d->bookmarkOwner,
-                                        d->imageModel,
-                                        d->selectionModel,
-                                        d->stackedWidget);
+Edit::~Edit()
+{
+}
+
+void Edit::start()
+{
+    Q_D(Edit);
+    QueryInfo* const info = new QueryInfo(d->MediaWiki,this);
+    info->setPageName(d->requestParameter[QStringLiteral("title")]);
+    info->setToken(QStringLiteral("edit"));
+
+    connect(info, SIGNAL(page(Page)),
+            this, SLOT(doWorkSendRequest(Page)));
+
+    info->start();
+}
+
+void Edit::doWorkSendRequest(Page page)
+{
+    Q_D(Edit);
+    d->requestParameter[QStringLiteral("token")] = page.pageEditToken();
+    // Set the url
+    QUrl    url                                  = d->MediaWiki.url();
+    QUrlQuery query;
+    query.addQueryItem(QStringLiteral("format"), QStringLiteral("xml"));
+    query.addQueryItem(QStringLiteral("action"), QStringLiteral("edit"));
+
+    // Add params
+    if (d->requestParameter.contains(QStringLiteral("md5")))
+    {
+        QString text;
+
+        if (d->requestParameter.contains(QStringLiteral("prependtext")))
+            text += d->requestParameter[QStringLiteral("prependtext")];
+
+        if (d->requestParameter.contains(QStringLiteral("appendtext")))
+            text += d->requestParameter[QStringLiteral("appendtext")];
 
-    GPSItemContainer::setHeaderData(d->imageModel);
-    d->mapModelHelper      = new GPSGeoIfaceModelHelper(d->imageModel, d->selectionModel, this);
-    d->mapModelHelper->addUngroupedModelHelper(d->bookmarkOwner->bookmarkModelHelper());
-
-    d->mapModelHelper->addUngroupedModelHelper(d->searchWidget->getModelHelper());
-    d->mapDragDropHandler  = new MapDragDropHandler(d->imageModel, d->mapModelHelper);
-    d->geoifaceMarkerModel = new ItemMarkerTiler(d->mapModelHelper, this);
-
-    d->actionBookmarkVisibility = new QAction(this);
-    d->actionBookmarkVisibility->setIcon(QIcon::fromTheme(QLatin1String("bookmark-new")));
-    d->actionBookmarkVisibility->setToolTip(i18n("Display bookmarked positions on the map."));
-    d->actionBookmarkVisibility->setCheckable(true);
+        if (d->requestParameter.contains(QStringLiteral("text")))
+            text = d->requestParameter[QStringLiteral("text")];
+
+        QByteArray hash                            = QCryptographicHash::hash(text.toUtf8(),QCryptographicHash::Md5);
+        d->requestParameter[QStringLiteral("md5")] = QString::fromLatin1(hash.toHex());
+    }
+
+    QMapIterator<QString, QString> i(d->requestParameter);<--- Shadowed declaration
+
+    while (i.hasNext())
+    {
+        i.next();
 
-    connect(d->actionBookmarkVisibility, SIGNAL(changed()),
-            this, SLOT(slotBookmarkVisibilityToggled()));
-
-    QVBoxLayout* const mainLayout = new QVBoxLayout(this);
-    setLayout(mainLayout);
-
-    DHBox* const hboxMain = new DHBox(this);
-    mainLayout->addWidget(hboxMain, 10);
-
-    d->HSplitter          = new QSplitter(Qt::Horizontal, hboxMain);
-    d->HSplitter->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
-
-    // ------------------------------------------------------------------------------------------------
-
-    DHBox* const hbox            = new DHBox(this);
-    QLabel* const labelMapLayout = new QLabel(i18n("Layout:"), hbox);
-    d->cbMapLayout               = new QComboBox(hbox);
-    d->cbMapLayout->addItem(i18n("One map"),               QVariant::fromValue(MapLayoutOne));
-    d->cbMapLayout->addItem(i18n("Two maps - horizontal"), QVariant::fromValue(MapLayoutHorizontal));
-    d->cbMapLayout->addItem(i18n("Two maps - vertical"),   QVariant::fromValue(MapLayoutVertical));
-    labelMapLayout->setBuddy(d->cbMapLayout);
-
-    d->progressBar          = new StatusProgressBar(hbox);
-    d->progressBar->setVisible(false);
-    d->progressBar->setProgressBarMode(StatusProgressBar::ProgressBarMode);
-    d->progressBar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
-
-    d->progressCancelButton = new QPushButton(hbox);
-    d->progressCancelButton->setVisible(false);
-    d->progressCancelButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
-    d->progressCancelButton->setIcon(QIcon::fromTheme(QLatin1String("dialog-cancel")));
-
-    connect(d->progressCancelButton, SIGNAL(clicked()),
-            this, SLOT(slotProgressCancelButtonClicked()));
-
-    m_buttons->addButton(QDialogButtonBox::Apply);
-    m_buttons->addButton(QDialogButtonBox::Close);
-    m_buttons->setParent(hbox);
-
-    connect(m_buttons->button(QDialogButtonBox::Apply), &QPushButton::clicked,
-            this, &GeolocationEdit::slotApplyClicked);
-
-    connect(m_buttons->button(QDialogButtonBox::Close), &QPushButton::clicked,
-            this, &GeolocationEdit::close);
+        if (i.key() != QStringLiteral("token"))
+            query.addQueryItem(i.key(),i.value());
+    }
+
+    QByteArray cookie;
+    QList<QNetworkCookie> MediaWikiCookies = d->manager->cookieJar()->cookiesForUrl(d->MediaWiki.url());
+
+    for (int i = 0 ; i < MediaWikiCookies.size() ; ++i)<--- Shadow variable
+    {
+        cookie += MediaWikiCookies.at(i).toRawForm(QNetworkCookie::NameAndValueOnly);
+        cookie += ';';
+    }
+
+    // Add the token
+    query.addQueryItem(QStringLiteral("token"), d->requestParameter[QStringLiteral("token")]);
+    url.setQuery(query);
+    d->baseUrl = url;
+
+    // Set the request
+    QNetworkRequest request( url );
+    request.setRawHeader("User-Agent", d->MediaWiki.userAgent().toUtf8());
+    request.setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("application/x-www-form-urlencoded"));
+    request.setRawHeader("Cookie", cookie);
+
+    setPercent(25); // Request ready.
+
+    // Send the request
+    d->reply = d->manager->post( request, url.toString().toUtf8() );
+    connectReply();
+
+    connect( d->reply, SIGNAL(finished()),
+             this, SLOT(finishedEdit()) );
+
+    setPercent(50); // Request sent.
+}
+
+void Edit::finishedEdit()
+{
+    Q_D(Edit);
+
+    disconnect(d->reply, SIGNAL(finished()),
+               this, SLOT(finishedEdit()));
+
+    setPercent(75); // Response received.
 
-    mainLayout->addWidget(hbox, 0);
-
-    // ------------------------------------------------------------------------------------------------
-
-    d->VSplitter = new QSplitter(Qt::Vertical, d->HSplitter);
-    d->HSplitter->addWidget(d->VSplitter);
-    d->HSplitter->setStretchFactor(0, 10);
-
-    d->sortMenu = new QMenu(this);
-    d->sortMenu->setTitle(i18n("Sorting"));
-    QActionGroup* const sortOrderExclusive = new QActionGroup(d->sortMenu);
-    sortOrderExclusive->setExclusive(true);
-
-    connect(sortOrderExclusive, SIGNAL(triggered(QAction*)),
-            this, SLOT(slotSortOptionTriggered(QAction*)));
-
-    d->sortActionOldestFirst = new QAction(i18n("Show oldest first"), sortOrderExclusive);
-    d->sortActionOldestFirst->setCheckable(true);
-    d->sortMenu->addAction(d->sortActionOldestFirst);
-
-    d->sortActionYoungestFirst = new QAction(i18n("Show youngest first"), sortOrderExclusive);
-    d->sortMenu->addAction(d->sortActionYoungestFirst);
-    d->sortActionYoungestFirst->setCheckable(true);
-
-    QWidget* mapVBox = nullptr;
-    d->mapWidget     = makeMapWidget(&mapVBox);
-    d->searchWidget->setPrimaryMapWidget(d->mapWidget);
-    d->mapSplitter   = new QSplitter(this);
-    d->mapSplitter->addWidget(mapVBox);
-    d->VSplitter->addWidget(d->mapSplitter);
-
-    d->treeView      = new GPSItemList(this);
-    d->treeView->setModelAndSelectionModel(d->imageModel, d->selectionModel);
-    d->treeView->setDragDropHandler(new GPSItemListDragDropHandler(this));
-    d->treeView->setDragEnabled(true);
-    // TODO: save and restore the state of the header
-    // TODO: add a context menu to the header to select which columns should be visible
-    // TODO: add sorting by column
-    d->treeView->setSelectionMode(QAbstractItemView::ExtendedSelection);
-    d->treeView->setSortingEnabled(true);
-    d->VSplitter->addWidget(d->treeView);
-
-    d->listViewContextMenu  = new GPSItemListContextMenu(d->treeView, d->bookmarkOwner);
-    d->HSplitter->addWidget(d->stackedWidget);
-    d->HSplitter->setCollapsible(1, true);
-    d->splitterSize         = 0;
-
-    DVBox* const vboxTabBar = new DVBox(hboxMain);
-    vboxTabBar->layout()->setContentsMargins(QMargins());
-    vboxTabBar->layout()->setSpacing(0);
-
-    d->tabBar = new QTabBar(vboxTabBar);
-    d->tabBar->setShape(QTabBar::RoundedEast);
-
-    dynamic_cast<QVBoxLayout*>(vboxTabBar->layout())->addStretch(200);
-
-    d->tabBar->addTab(i18n("Details"));
-    d->tabBar->addTab(i18n("GPS Correlator"));
-    d->tabBar->addTab(i18n("Undo/Redo"));
-    d->tabBar->addTab(i18n("Reverse Geocoding"));
-    d->tabBar->addTab(i18n("Search"));
-    d->tabBar->addTab(i18n("KML Export"));
-
-    d->tabBar->installEventFilter(this);
-
-    d->detailsWidget    = new GPSItemDetails(d->stackedWidget, d->imageModel);
-    d->stackedWidget->addWidget(d->detailsWidget);
-
-    d->correlatorWidget = new GPSCorrelatorWidget(d->stackedWidget, d->imageModel, d->trackManager);
-    d->stackedWidget->addWidget(d->correlatorWidget);
-
-    d->undoView         = new QUndoView(d->undoStack, d->stackedWidget);
-    d->stackedWidget->addWidget(d->undoView);
-
-    d->rgWidget         = new RGWidget(d->imageModel, d->selectionModel, d->iface->tagFilterModel(), d->stackedWidget);
-    d->stackedWidget->addWidget(d->rgWidget);
-
-    d->stackedWidget->addWidget(d->searchWidget);
-
-    d->kmlWidget        = new KmlWidget(this, d->imageModel, d->iface);
-    d->stackedWidget->addWidget(d->kmlWidget);
-
-    // ---------------------------------------------------------------
-
-    connect(d->treeView, SIGNAL(signalImageActivated(QModelIndex)),
-            this, SLOT(slotImageActivated(QModelIndex)));
-
-    connect(d->correlatorWidget, SIGNAL(signalSetUIEnabled(bool)),
-            this, SLOT(slotSetUIEnabled(bool)));
-
-    connect(d->correlatorWidget, SIGNAL(signalSetUIEnabled(bool,QObject*const,QString)),
-            this, SLOT(slotSetUIEnabled(bool,QObject*const,QString)));
-
-    connect(d->correlatorWidget, SIGNAL(signalProgressSetup(int,QString)),
-            this, SLOT(slotProgressSetup(int,QString)));
-
-    connect(d->correlatorWidget, SIGNAL(signalProgressChanged(int)),
-            this, SLOT(slotProgressChanged(int)));
-
-    connect(d->correlatorWidget, SIGNAL(signalUndoCommand(GPSUndoCommand*)),
-            this, SLOT(slotGPSUndoCommand(GPSUndoCommand*)));
-
-    connect(d->mapModelHelper, SIGNAL(signalUndoCommand(GPSUndoCommand*)),
-            this, SLOT(slotGPSUndoCommand(GPSUndoCommand*)));
-
-    connect(d->rgWidget, SIGNAL(signalSetUIEnabled(bool)),
-            this, SLOT(slotSetUIEnabled(bool)));
-
-    connect(d->rgWidget, SIGNAL(signalSetUIEnabled(bool,QObject*const,QString)),
-            this, SLOT(slotSetUIEnabled(bool,QObject*const,QString)));
-
-    connect(d->rgWidget, SIGNAL(signalProgressSetup(int,QString)),
-            this, SLOT(slotProgressSetup(int,QString)));
-
-    connect(d->rgWidget, SIGNAL(signalProgressChanged(int)),
-            this, SLOT(slotProgressChanged(int)));
-
-    connect(d->rgWidget, SIGNAL(signalUndoCommand(GPSUndoCommand*)),
-            this, SLOT(slotGPSUndoCommand(GPSUndoCommand*)));
-
-    connect(d->searchWidget, SIGNAL(signalUndoCommand(GPSUndoCommand*)),
-            this, SLOT(slotGPSUndoCommand(GPSUndoCommand*)));
-
-    connect(d->listViewContextMenu, SIGNAL(signalSetUIEnabled(bool)),
-            this, SLOT(slotSetUIEnabled(bool)));
-
-    connect(d->listViewContextMenu, SIGNAL(signalSetUIEnabled(bool,QObject*const,QString)),
-            this, SLOT(slotSetUIEnabled(bool,QObject*const,QString)));
-
-    connect(d->listViewContextMenu, SIGNAL(signalProgressSetup(int,QString)),
-            this, SLOT(slotProgressSetup(int,QString)));
-
-    connect(d->listViewContextMenu, SIGNAL(signalProgressChanged(int)),
-            this, SLOT(slotProgressChanged(int)));
-
-    connect(d->listViewContextMenu, SIGNAL(signalUndoCommand(GPSUndoCommand*)),
-            this, SLOT(slotGPSUndoCommand(GPSUndoCommand*)));
-
-    connect(d->tabBar, SIGNAL(currentChanged(int)),
-            this, SLOT(slotCurrentTabChanged(int)));
-
-    connect(d->bookmarkOwner->bookmarkModelHelper(),
-            SIGNAL(signalUndoCommand(GPSUndoCommand*)),
-            this, SLOT(slotGPSUndoCommand(GPSUndoCommand*)));
-
-    connect(d->detailsWidget, SIGNAL(signalUndoCommand(GPSUndoCommand*)),
-            this, SLOT(slotGPSUndoCommand(GPSUndoCommand*)));
-
-    connect(d->cbMapLayout, SIGNAL(activated(int)),
-            this, SLOT(slotLayoutChanged(int)));
-
-    connect(this, SIGNAL(signalMetadataChangedForUrl(QUrl)),
-            d->iface, SLOT(slotMetadataChangedForUrl(QUrl)));
-
-    readSettings();
-
-    d->mapWidget->setActive(true);
-
-    setItems(d->iface->currentGPSItems());
-}
-
-GeolocationEdit::~GeolocationEdit()
-{
-    delete d;
-}
-
-bool GeolocationEdit::eventFilter(QObject* const o, QEvent* const e)
-{
-    if ((o == d->tabBar) && (e->type() == QEvent::MouseButtonPress))
-    {
-        QMouseEvent const* m = static_cast<QMouseEvent*>(e);
-
-        QPoint p (m->x(), m->y());
-        const int var = d->tabBar->tabAt(p);
-
-        if (var < 0)
-        {
-            return false;
-        }
-
-        QList<int> sizes = d->HSplitter->sizes();
-
-        if (d->splitterSize == 0)
-        {
-            if (sizes.at(1) == 0)
-            {
-                sizes[1] = d->stackedWidget->widget(var)->minimumSizeHint().width();
-            }
-            else if (d->tabBar->currentIndex() == var)
-            {
-                d->splitterSize = sizes.at(1);
-                sizes[1]        = 0;
-            }
-        }
-        else
-        {
-            sizes[1]        = d->splitterSize;
-            d->splitterSize = 0;
-        }
-
-        d->tabBar->setCurrentIndex(var);
-        d->stackedWidget->setCurrentIndex(var);
-        d->HSplitter->setSizes(sizes);
-        d->detailsWidget->slotSetActive((d->stackedWidget->currentWidget() == d->detailsWidget) &&
-                                        (d->splitterSize == 0));
-
-        return true;
-    }
-
-    return QWidget::eventFilter(o, e);
-}
-
-void GeolocationEdit::slotCurrentTabChanged(int index)
-{
-    d->tabBar->setCurrentIndex(index);
-    d->stackedWidget->setCurrentIndex(index);
-    d->detailsWidget->slotSetActive(d->stackedWidget->currentWidget() == d->detailsWidget);
-}
-
-void GeolocationEdit::setCurrentTab(int index)
-{
-    d->tabBar->setCurrentIndex(index);
-    d->stackedWidget->setCurrentIndex(index);
-    QList<int> sizes = d->HSplitter->sizes();
-
-    if (d->splitterSize >= 0)
-    {
-        sizes[1] = d->splitterSize;
-        d->splitterSize = 0;
-    }
-
-    d->HSplitter->setSizes(sizes);
-    d->detailsWidget->slotSetActive((d->stackedWidget->currentWidget() == d->detailsWidget) &&
-                                    (d->splitterSize == 0));
-}
-
-void GeolocationEdit::setImages(const QList<QUrl>& images)
-{
-    QList<GPSItemContainer*> items;
-
-    foreach (const QUrl& u, images)
-    {
-        items << new GPSItemContainer(u);
-    }
-
-    setItems(items);
-}
-
-void GeolocationEdit::setItems(const QList<GPSItemContainer*>& items)
-{
-    foreach (GPSItemContainer* const newItem, items)
-    {
-        newItem->loadImageData();
-        d->imageModel->addItem(newItem);
-    }
-
-    QList<QPersistentModelIndex> imagesToLoad;
-
-    for (int i = 0 ; i < d->imageModel->rowCount() ; ++i)
-    {
-        imagesToLoad << d->imageModel->index(i, 0);
-    }
-
-    slotSetUIEnabled(false);
-    slotProgressSetup(imagesToLoad.count(), i18n("Loading metadata -"));
-
-    // initiate the saving
-    d->fileIOCountDone     = 0;
-    d->fileIOCountTotal    = imagesToLoad.count();
-    d->fileIOFutureWatcher = new QFutureWatcher<QPair<QUrl, QString> >(this);
-
-    connect(d->fileIOFutureWatcher, SIGNAL(resultsReadyAt(int,int)),
-            this, SLOT(slotFileMetadataLoaded(int,int)));
-
-    d->fileIOFuture = QtConcurrent::mapped(imagesToLoad, LoadFileMetadataHelper(d->imageModel));
-    d->fileIOFutureWatcher->setFuture(d->fileIOFuture);
-}
-
-void GeolocationEdit::slotFileMetadataLoaded(int beginIndex, int endIndex)
-{
-    qCDebug(DIGIKAM_DPLUGIN_GENERIC_LOG) << beginIndex << endIndex;
-    d->fileIOCountDone += (endIndex-beginIndex);
-    slotProgressChanged(d->fileIOCountDone);
-
-    if (d->fileIOCountDone == d->fileIOCountTotal)
-    {
-        slotSetUIEnabled(true);
-    }
-}
-
-void GeolocationEdit::readSettings()
-{
-    KSharedConfig::Ptr config = KSharedConfig::openConfig();
-    KConfigGroup group = config->group("Geolocation Edit Settings");
-
-    // --------------------------
-
-    // TODO: sanely determine a default backend
-    const KConfigGroup groupMapWidget = KConfigGroup(&group, "Map Widget");<--- Shadowed declaration
-    d->mapWidget->readSettingsFromGroup(&groupMapWidget);
-
-    const KConfigGroup groupCorrelatorWidget = KConfigGroup(&group, "Correlator Widget");
-    d->correlatorWidget->readSettingsFromGroup(&groupCorrelatorWidget);
-
-    const KConfigGroup groupTreeView = KConfigGroup(&group, "Tree View");
-    d->treeView->readSettingsFromGroup(&groupTreeView);
-
-    const KConfigGroup groupSearchWidget = KConfigGroup(&group, "Search Widget");
-    d->searchWidget->readSettingsFromGroup(&groupSearchWidget);
-
-    const KConfigGroup groupRGWidget = KConfigGroup(&group, "Reverse Geocoding Widget");
-    d->rgWidget->readSettingsFromGroup(&groupRGWidget);
-
-    const KConfigGroup groupDialog = KConfigGroup(&group, "Dialog");
-
-    // --------------------------
-
-    setCurrentTab(group.readEntry("Current Tab", 0));
-    const bool showOldestFirst = group.readEntry("Show oldest images first", false);
-
-    if (showOldestFirst)
-    {
-        d->sortActionOldestFirst->setChecked(true);
-        d->mapWidget->setSortKey(1);
-    }
-    else
-    {
-        d->sortActionYoungestFirst->setChecked(true);
-        d->mapWidget->setSortKey(0);
-    }
-
-    d->actionBookmarkVisibility->setChecked(group.readEntry("Bookmarks visible", false));
-    slotBookmarkVisibilityToggled();
-
-    if (group.hasKey("SplitterState V1"))
-    {
-        const QByteArray splitterState = QByteArray::fromBase64(group.readEntry("SplitterState V1", QByteArray()));
-
-        if (!splitterState.isEmpty())
-        {
-            d->VSplitter->restoreState(splitterState);
-        }
-    }
-
-    if (group.hasKey("SplitterState H1"))
-    {
-        const QByteArray splitterState = QByteArray::fromBase64(group.readEntry("SplitterState H1", QByteArray()));
-
-        if (!splitterState.isEmpty())
-        {
-            d->HSplitter->restoreState(splitterState);
-        }
-    }
-
-    d->splitterSize = group.readEntry("Splitter H1 CollapsedSize", 0);
-
-    // ----------------------------------
-
-    d->mapLayout = MapLayout(group.readEntry("Map Layout", QVariant::fromValue(int(MapLayoutOne))).value<int>());
-    d->cbMapLayout->setCurrentIndex(d->mapLayout);
-    adjustMapLayout(false);
-
-    if (d->mapWidget2)
-    {
-        const KConfigGroup groupMapWidget = KConfigGroup(&group, "Map Widget 2");<--- Shadow variable
-        d->mapWidget2->readSettingsFromGroup(&groupMapWidget);
-
-        d->mapWidget2->setActive(true);
-    }
-}
-
-void GeolocationEdit::saveSettings()
-{
-    KSharedConfig::Ptr config = KSharedConfig::openConfig();
-    KConfigGroup group = config->group("Geolocation Edit Settings");
-
-    // --------------------------
-
-    KConfigGroup groupMapWidget = KConfigGroup(&group, "Map Widget");<--- Shadowed declaration
-    d->mapWidget->saveSettingsToGroup(&groupMapWidget);
-
-    if (d->mapWidget2)
-    {
-        KConfigGroup groupMapWidget = KConfigGroup(&group, "Map Widget 2");<--- Shadow variable
-        d->mapWidget2->saveSettingsToGroup(&groupMapWidget);
-    }
-
-    KConfigGroup groupCorrelatorWidget = KConfigGroup(&group, "Correlator Widget");
-    d->correlatorWidget->saveSettingsToGroup(&groupCorrelatorWidget);
-
-    KConfigGroup groupTreeView = KConfigGroup(&group, "Tree View");
-    d->treeView->saveSettingsToGroup(&groupTreeView);
-
-    KConfigGroup groupSearchWidget = KConfigGroup(&group, "Search Widget");
-    d->searchWidget->saveSettingsToGroup(&groupSearchWidget);
-
-    KConfigGroup groupRGWidget = KConfigGroup(&group, "Reverse Geocoding Widget");
-    d->rgWidget->saveSettingsToGroup(&groupRGWidget);
-
-    // --------------------------
-
-    group.writeEntry("Current Tab",               d->tabBar->currentIndex());
-    group.writeEntry("Show oldest images first",  d->sortActionOldestFirst->isChecked());
-    group.writeEntry("SplitterState V1",          d->VSplitter->saveState().toBase64());
-    group.writeEntry("SplitterState H1",          d->HSplitter->saveState().toBase64());
-    group.writeEntry("Splitter H1 CollapsedSize", d->splitterSize);
-    group.writeEntry("Map Layout",                QVariant::fromValue(int(d->mapLayout)));
-    group.writeEntry("Bookmarks visible",         d->actionBookmarkVisibility->isChecked());
-
-    config->sync();
-}
-
-void GeolocationEdit::closeEvent(QCloseEvent *e)
-{
-    if (!e) return;
-
-    // is the UI locked?
-    if (!d->uiEnabled)
-    {
-        // please wait until we are done ...
-        return;
-    }
-
-    // are there any modified images?
-    int dirtyImagesCount = 0;
-
-    for (int i = 0 ; i < d->imageModel->rowCount() ; ++i)
-    {
-        const QModelIndex itemIndex  = d->imageModel->index(i, 0);
-        GPSItemContainer* const item = d->imageModel->itemFromIndex(itemIndex);
-
-        if (item->isDirty() || item->isTagListDirty())
-        {
-            ++dirtyImagesCount;
-        }
-    }
-
-    if (dirtyImagesCount > 0)
-    {
-        const QString message = i18np(
-                    "You have 1 modified image.",
-                    "You have %1 modified images.",
-                    dirtyImagesCount
-                );
-
-        const int chosenAction = DMessageBox::showYesNo(QMessageBox::Warning,
-                                                        this,
-                                                        i18n("Unsaved changes"),
-                                                        i18n("%1 Would you like to save the changes you made to them?", message)
-                                                       );
-
-        if (chosenAction == QMessageBox::No)
-        {
-            saveSettings();
-            e->accept();
-            return;
-        }
-
-        if (chosenAction == QMessageBox::Yes)
-        {
-            // the user wants to save his changes.
-            // this will initiate the saving process and then close the dialog.
-            saveChanges(true);
-        }
-
-        // do not close the dialog for now
-        e->ignore();
-        return;
-    }
-
-    saveSettings();
-    e->accept();
-}
-
-void GeolocationEdit::slotImageActivated(const QModelIndex& index)
-{
-    d->detailsWidget->slotSetCurrentImage(index);
-
-    if (!index.isValid())
-        return;
-
-    GPSItemContainer* const item = d->imageModel->itemFromIndex(index);
-
-    if (!item)
-        return;
-
-    const GeoCoordinates imageCoordinates = item->coordinates();
-
-    if (imageCoordinates.hasCoordinates())
-    {
-        d->mapWidget->setCenter(imageCoordinates);
-    }
-}
-
-void GeolocationEdit::slotSetUIEnabled(const bool enabledState,
-                                       QObject* const cancelObject,
-                                       const QString& cancelSlot)
-{
-    if (enabledState)
-    {
-        // hide the progress bar
-        d->progressBar->setVisible(false);
-        d->progressCancelButton->setVisible(false);
-        d->progressBar->setProgressValue(d->progressBar->progressTotalSteps());
-    }
-
-    // TODO: disable the worldmapwidget and the images list (at least disable editing operations)
-    d->progressCancelObject = cancelObject;
-    d->progressCancelSlot   = cancelSlot;
-    d->uiEnabled            = enabledState;
-    m_buttons->setEnabled(enabledState);
-    d->correlatorWidget->setUIEnabledExternal(enabledState);
-    d->detailsWidget->setUIEnabledExternal(enabledState);
-    d->rgWidget->setUIEnabled(enabledState);
-    d->treeView->setEditEnabled(enabledState);
-    d->listViewContextMenu->setEnabled(enabledState);
-    d->mapWidget->setAllowModifications(enabledState);
-}
-
-void GeolocationEdit::slotSetUIEnabled(const bool enabledState)
-{
-    slotSetUIEnabled(enabledState, nullptr, QString());
-}
-
-void GeolocationEdit::saveChanges(const bool closeAfterwards)
-{
-    // TODO: actually save the changes
-    // are there any modified images?
-    QList<QPersistentModelIndex> dirtyImages;
-
-    for (int i = 0 ; i < d->imageModel->rowCount() ; ++i)
-    {
-        const QModelIndex itemIndex  = d->imageModel->index(i, 0);
-        GPSItemContainer* const item = d->imageModel->itemFromIndex(itemIndex);
-
-        if (item->isDirty() || item->isTagListDirty())
-        {
-            dirtyImages << itemIndex;
-        }
-    }
-
-    if (dirtyImages.isEmpty())
-    {
-        if (closeAfterwards)
-        {
-            close();
-        }
-
-        return;
-    }
-
-    // TODO: disable the UI and provide progress and cancel information
-    slotSetUIEnabled(false);
-    slotProgressSetup(dirtyImages.count(), i18n("Saving changes -"));
-
-    // initiate the saving
-    d->fileIOCountDone        = 0;
-    d->fileIOCountTotal       = dirtyImages.count();
-    d->fileIOCloseAfterSaving = closeAfterwards;
-    d->fileIOFutureWatcher    = new QFutureWatcher<QPair<QUrl, QString> >(this);
-
-    connect(d->fileIOFutureWatcher, SIGNAL(resultsReadyAt(int,int)),
-            this, SLOT(slotFileChangesSaved(int,int)));
-
-    d->fileIOFuture = QtConcurrent::mapped(dirtyImages, SaveChangedImagesHelper(d->imageModel));
-    d->fileIOFutureWatcher->setFuture(d->fileIOFuture);
-}
-
-void GeolocationEdit::slotFileChangesSaved(int beginIndex, int endIndex)
-{
-    qCDebug(DIGIKAM_DPLUGIN_GENERIC_LOG) << beginIndex << endIndex;
-
-    d->fileIOCountDone += (endIndex-beginIndex);
-    slotProgressChanged(d->fileIOCountDone);
-
-    if (d->fileIOCountDone == d->fileIOCountTotal)
-    {
-        slotSetUIEnabled(true);
-
-        // any errors?
-        QList<QPair<QUrl, QString> > errorList;
-
-        for (int i = 0 ; i < d->fileIOFuture.resultCount() ; ++i)
-        {
-            if (!d->fileIOFuture.resultAt(i).second.isEmpty())
-                errorList << d->fileIOFuture.resultAt(i);
-
-            // To rescan item metadata from host.
-            emit signalMetadataChangedForUrl(d->fileIOFuture.resultAt(i).first);
-        }
-
-        if (!errorList.isEmpty())
-        {
-            QStringList errorStrings;
-
-            for (int i = 0 ; i < errorList.count() ; ++i)
-            {
-                errorStrings << QString::fromLatin1("%1: %2")
-                    .arg(errorList.at(i).first.toLocalFile())
-                    .arg(errorList.at(i).second);
-            }
-
-            DMessageBox::showInformationList(QMessageBox::Critical,
-                                             this,
-                                             i18n("Error"),
-                                             i18n("Failed to save some information:"),
-                                             errorStrings);
-        }
-
-        // done saving files
-        if (d->fileIOCloseAfterSaving)
-        {
-            close();
-        }
-    }
-}
-
-void GeolocationEdit::slotApplyClicked()
-{
-    // save the changes, but do not close afterwards
-    saveChanges(false);
-}
-
-void GeolocationEdit::slotProgressChanged(const int currentProgress)
-{
-    d->progressBar->setProgressValue(currentProgress);
-}
-
-void GeolocationEdit::slotProgressSetup(const int maxProgress, const QString& progressText)
-{
-    d->progressBar->setProgressText(progressText);
-    d->progressBar->setProgressTotalSteps(maxProgress);
-    d->progressBar->setProgressValue(0);
-    d->progressBar->setNotify(true);
-    d->progressBar->setNotificationTitle(i18n("Edit Geolocation"), QIcon::fromTheme(QLatin1String("globe")));
-    d->progressBar->setVisible(true);
-    d->progressCancelButton->setVisible(d->progressCancelObject != nullptr);
-}
-
-void GeolocationEdit::slotGPSUndoCommand(GPSUndoCommand* undoCommand)
-{
-    d->undoStack->push(undoCommand);
-}
-
-void GeolocationEdit::slotSortOptionTriggered(QAction* /*sortAction*/)
-{
-    int newSortKey = 0;
-
-    if (d->sortActionOldestFirst->isChecked())
-    {
-        newSortKey |= 1;
-    }
-
-    d->mapWidget->setSortKey(newSortKey);
-}
-
-void GeolocationEdit::slotProgressCancelButtonClicked()
-{
-    if (d->progressCancelObject)
-    {
-        QTimer::singleShot(0, d->progressCancelObject, d->progressCancelSlot.toUtf8().constData());
-
-        d->progressBar->setProgressValue(d->progressBar->progressTotalSteps());
-    }
-}
-
-void GeolocationEdit::slotBookmarkVisibilityToggled()
-{
-    d->bookmarkOwner->bookmarkModelHelper()->setVisible(d->actionBookmarkVisibility->isChecked());
-}
-
-void GeolocationEdit::slotLayoutChanged(int lay)
-{
-    d->mapLayout = (MapLayout)lay;
-    adjustMapLayout(true);
-}
-
-MapWidget* GeolocationEdit::makeMapWidget(QWidget** const pvbox)
-{
-    QWidget* const dummyWidget = new QWidget(this);
-    QVBoxLayout* const vbox    = new QVBoxLayout(dummyWidget);
-    MapWidget* const mapWidget = new MapWidget(dummyWidget);
-    mapWidget->setAvailableMouseModes(MouseModePan | MouseModeZoomIntoGroup | MouseModeSelectThumbnail);
-    mapWidget->setVisibleMouseModes(MouseModePan | MouseModeZoomIntoGroup | MouseModeSelectThumbnail);
-    mapWidget->setMouseMode(MouseModeSelectThumbnail);
-    mapWidget->setGroupedModel(d->geoifaceMarkerModel);
-    mapWidget->setDragDropHandler(d->mapDragDropHandler);
-    mapWidget->addUngroupedModel(d->bookmarkOwner->bookmarkModelHelper());
-    mapWidget->addUngroupedModel(d->searchWidget->getModelHelper());
-    mapWidget->setTrackManager(d->trackManager);
-    mapWidget->setSortOptionsMenu(d->sortMenu);
-
-    vbox->addWidget(mapWidget);
-    vbox->addWidget(mapWidget->getControlWidget());
-
-    QToolButton* const bookmarkVisibilityButton = new QToolButton(mapWidget);
-    bookmarkVisibilityButton->setDefaultAction(d->actionBookmarkVisibility);
-    mapWidget->addWidgetToControlWidget(bookmarkVisibilityButton);
-
-    *pvbox = dummyWidget;
-
-    return mapWidget;
-}
-
-void GeolocationEdit::adjustMapLayout(const bool syncSettings)
-{
-    if (d->mapLayout == MapLayoutOne)
-    {
-        if (d->mapSplitter->count() > 1)
-        {
-            delete d->mapSplitter->widget(1);
-            d->mapWidget2 = nullptr;
-        }
-    }
-    else
-    {
-        if (d->mapSplitter->count() == 1)
-        {
-            QWidget* mapHolder = nullptr;
-            d->mapWidget2      = makeMapWidget(&mapHolder);
-            d->mapSplitter->addWidget(mapHolder);
-
-            if (syncSettings)
-            {
-                KSharedConfig::Ptr config         = KSharedConfig::openConfig();
-                KConfigGroup group                = config->group("Geolocation Edit Settings");
-                const KConfigGroup groupMapWidget = KConfigGroup(&group, "Map Widget");
-                d->mapWidget2->readSettingsFromGroup(&groupMapWidget);
-                d->mapWidget2->setActive(true);
-            }
-        }
-
-        if (d->mapLayout == MapLayoutHorizontal)
-        {
-            d->mapSplitter->setOrientation(Qt::Horizontal);
-        }
-        else
-        {
-            d->mapSplitter->setOrientation(Qt::Vertical);
-        }
-    }
-}
-
-} // namespace DigikamGenericGeolocationEditPlugin
+    if (d->reply->error() != QNetworkReply::NoError)
+    {
+        this->setError(this->NetworkError);
+        d->reply->close();
+        d->reply->deleteLater();
+        emitResult();
+        return;
+    }
+
+    QXmlStreamReader reader( d->reply );
+
+    while (!reader.atEnd() && !reader.hasError())
+    {
+        QXmlStreamReader::TokenType token = reader.readNext();
+
+        if (token == QXmlStreamReader::StartElement)
+        {
+            QXmlStreamAttributes attrs = reader.attributes();
+
+            if (reader.name() == QStringLiteral("edit"))
+            {
+                if (attrs.value( QStringLiteral("result") ).toString() == QLatin1String("Success"))
+                {
+                    setPercent(100); // Response parsed successfully.
+                    this->setError(KJob::NoError);
+                    d->reply->close();
+                    d->reply->deleteLater();
+                    emitResult();
+                    return;
+                }
+                else if (attrs.value( QStringLiteral("result") ).toString() == QLatin1String("Failure"))
+                {
+                    this->setError(KJob::NoError);
+                    reader.readNext();
+                    attrs = reader.attributes();
+                    d->result.m_captchaId = attrs.value( QStringLiteral("id") ).toString().toUInt();
+
+                    if (!attrs.value( QStringLiteral("question") ).isEmpty())
+                        d->result.m_captchaQuestion = QVariant(attrs.value( QStringLiteral("question") ).toString()) ;
+                    else if (!attrs.value( QStringLiteral("url") ).isEmpty())
+                        d->result.m_captchaQuestion = QVariant(attrs.value( QStringLiteral("url") ).toString()) ;
+                }
+            }
+            else if (reader.name() == QStringLiteral("error"))
+            {
+                this->setError(EditPrivate::error(attrs.value( QStringLiteral("code") ).toString()));
+                d->reply->close();
+                d->reply->deleteLater();
+                emitResult();
+                return;
+            }
+        }
+        else if (token == QXmlStreamReader::Invalid && reader.error() != QXmlStreamReader::PrematureEndOfDocumentError)
+        {
+            this->setError(this->XmlError);
+            d->reply->close();
+            d->reply->deleteLater();
+            emitResult();
+            return;
+        }
+    }
+
+    d->reply->close();
+    d->reply->deleteLater();
+    emit resultCaptcha(d->result.m_captchaQuestion);
+}
+
+void Edit::finishedCaptcha(const QString& captcha)
+{
+    Q_D(Edit);
+    d->result.m_captchaAnswer = captcha;
+    QUrl url                  = d->baseUrl;
+    QUrlQuery query;
+    query.addQueryItem(QStringLiteral("CaptchaId"),     QString::number(d->result.m_captchaId));
+    query.addQueryItem(QStringLiteral("CaptchaAnswer"), d->result.m_captchaAnswer);
+    url.setQuery(query);
+    QString data              = url.toString();
+    QByteArray cookie;
+    QList<QNetworkCookie> MediaWikiCookies = d->manager->cookieJar()->cookiesForUrl(d->MediaWiki.url());
+
+    for (int i = 0 ; i < MediaWikiCookies.size() ; ++i)
+    {
+        cookie += MediaWikiCookies.at(i).toRawForm(QNetworkCookie::NameAndValueOnly);
+        cookie += ';';
+    }
+
+    // Set the request
+    QNetworkRequest request(url);
+    request.setRawHeader("User-Agent", d->MediaWiki.userAgent().toUtf8());
+    request.setRawHeader("Cookie", cookie);
+    request.setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("application/x-www-form-urlencoded"));
+    // Send the request
+    d->reply = d->manager->post(request, data.toUtf8());
+
+    connect( d->reply, SIGNAL(finished()),
+             this, SLOT(finishedEdit()) );
+}
+
+} // namespace MediaWiki
 
diff --git a/static/reports/cppcheck/master/1.html b/static/reports/cppcheck/master/1.html index 7a66236c3..3058e4b0a 100644 --- a/static/reports/cppcheck/master/1.html +++ b/static/reports/cppcheck/master/1.html @@ -1,1575 +1,617 @@ - Cppcheck - HTML report - digiKam-master-rev-907aafb5fa + Cppcheck - HTML report - digiKam-master-rev-e85fcd090f
  1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
-236
-237
-238
-239
-240
-241
-242
-243
-244
-245
-246
-247
-248
-249
-250
-251
-252
-253
-254
-255
-256
-257
-258
-259
-260
-261
-262
-263
-264
-265
-266
-267
-268
-269
-270
-271
-272
-273
-274
-275
-276
-277
-278
-279
-280
-281
-282
-283
-284
-285
-286
-287
-288
-289
-290
-291
-292
-293
-294
-295
-296
-297
-298
-299
-300
-301
-302
-303
-304
-305
-306
-307
-308
-309
-310
-311
-312
-313
-314
-315
-316
-317
-318
-319
-320
-321
-322
-323
-324
-325
-326
-327
-328
-329
-330
-331
-332
-333
-334
-335
-336
-337
-338
-339
-340
-341
-342
-343
-344
-345
-346
-347
-348
-349
-350
-351
-352
-353
-354
-355
-356
-357
-358
-359
-360
-361
-362
-363
-364
-365
-366
-367
-368
-369
-370
-371
-372
-373
-374
-375
-376
-377
-378
-379
-380
-381
-382
-383
-384
-385
-386
-387
-388
-389
-390
-391
-392
-393
-394
-395
-396
-397
-398
-399
-400
-401
-402
-403
-404
-405
-406
-407
-408
-409
-410
-411
-412
-413
-414
-415
-416
-417
-418
-419
-420
-421
-422
-423
-424
-425
-426
-427
-428
-429
-430
-431
-432
-433
-434
-435
-436
-437
-438
-439
-440
-441
-442
-443
-444
-445
-446
-447
-448
-449
-450
-451
-452
-453
-454
-455
-456
-457
-458
-459
-460
-461
-462
-463
-464
-465
-466
-467
-468
-469
-470
-471
-472
-473
-474
-475
-476
-477
-478
-479
-480
-481
-482
-483
-484
-485
-486
-487
-488
-489
-490
-491
-492
-493
-494
-495
-496
-497
-498
-499
-500
-501
-502
-503
-504
-505
-506
-507
-508
-509
-510
-511
-512
-513
-514
-515
-516
-517
-518
-519
-520
-521
-522
-523
-524
-525
-526
-527
-528
-529
-530
-531
-532
-533
-534
-535
-536
-537
-538
-539
-540
-541
-542
-543
-544
-545
-546
-547
-548
-549
-550
-551
-552
-553
-554
-555
-556
-557
-558
-559
-560
-561
-562
-563
-564
-565
-566
-567
-568
-569
-570
-571
-572
-573
-574
-575
-576
-577
-578
-579
-580
-581
-582
-583
-584
-585
-586
-587
-588
-589
-590
-591
-592
-593
-594
-595
-596
-597
-598
-599
-600
-601
-602
-603
-604
-605
-606
-607
-608
-609
-610
-611
-612
-613
-614
-615
-616
-617
-618
-619
-620
-621
-622
-623
-624
-625
-626
-627
-628
-629
-630
-631
-632
-633
-634
-635
-636
-637
-638
-639
-640
-641
-642
-643
-644
-645
-646
-647
-648
-649
-650
-651
-652
-653
-654
-655
-656
-657
-658
-659
-660
-661
-662
-663
-664
-665
-666
-667
-668
-669
-670
-671
-672
-673
-674
-675
-676
-677
-678
-679
-680
-681
-682
-683
-684
-685
-686
-687
-688
-689
-690
-691
-692
-693
-694
-695
-696
-697
-698
-699
-700
-701
-702
-703
-704
-705
-706
-707
-708
-709
-710
-711
-712
-713
-714
-715
/* ============================================================
+236
/* ============================================================
  *
  * This file is a part of digiKam project
  * https://www.digikam.org
  *
- * Date        : 2006-10-13
- * Description : IPTC origin settings page.
+ * Date        : 2011-03-22
+ * Description : a Iface C++ interface
  *
- * Copyright (C) 2006-2020 by Gilles Caulier <caulier dot gilles at gmail dot com>
- *
- * This program is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General
- * Public License as published by the Free Software Foundation;
- * either version 2, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * ============================================================ */
-
-#include "iptcorigin.h"
-
-// Qt includes
-
-#include <QCheckBox>
-#include <QLabel>
-#include <QMap>
-#include <QPushButton>
-#include <QTimeEdit>
-#include <QValidator>
-#include <QGridLayout>
-#include <QApplication>
-#include <QStyle>
-#include <QComboBox>
-#include <QDateEdit>
-#include <QLineEdit>
-
-// KDE includes
-
-#include <klocalizedstring.h>
+ * Copyright (C) 2011-2020 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ * Copyright (C) 2011      by Alexandre Mendes <alex dot mendes1988 at gmail dot com>
+ *
+ * This program is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * ============================================================ */
+
+#include "mediawiki_queryinfo.h"
+
+// Qt includes
+
+#include <QDateTime>
+#include <QTimer>
+#include <QUrl>
+#include <QUrlQuery>
+#include <QXmlStreamReader>
+#include <QRegExp>
+#include <QNetworkAccessManager>
+#include <QNetworkCookie>
+#include <QNetworkReply>
+#include <QNetworkRequest>
+
+// Local includes
+
+#include "mediawiki_iface.h"
+#include "mediawiki_job_p.h"
 
-// Local includes
-
-#include "dlayoutbox.h"
-#include "squeezedcombobox.h"
-#include "metadatacheckbox.h"
-#include "timezonecombobox.h"
-#include "multivaluesedit.h"
-#include "dmetadata.h"
-#include "countryselector.h"
-#include "dexpanderbox.h"
-
-using namespace Digikam;
-
-namespace DigikamGenericMetadataEditPlugin
-{
-
-class Q_DECL_HIDDEN IPTCOrigin::Private
-{
-public:
-
-    explicit Private()
-    {
-        cityEdit               = nullptr;
-        sublocationEdit        = nullptr;
-        provinceEdit           = nullptr;
-        locationEdit           = nullptr;
-        cityCheck              = nullptr;
-        sublocationCheck       = nullptr;
-        provinceCheck          = nullptr;
-        countryCheck           = nullptr;
-        dateCreatedSel         = nullptr;
-        dateDigitalizedSel     = nullptr;
-        timeCreatedSel         = nullptr;
-        timeDigitalizedSel     = nullptr;
-        zoneCreatedSel         = nullptr;
-        zoneDigitalizedSel     = nullptr;
-        dateCreatedCheck       = nullptr;
-        dateDigitalizedCheck   = nullptr;
-        timeCreatedCheck       = nullptr;
-        timeDigitalizedCheck   = nullptr;
-        syncEXIFDateCheck      = nullptr;
-        setTodayCreatedBtn     = nullptr;
-        setTodayDigitalizedBtn = nullptr;
-        countryCB              = nullptr;
-    }
-
-    QCheckBox*                     dateCreatedCheck;
-    QCheckBox*                     dateDigitalizedCheck;
-    QCheckBox*                     timeCreatedCheck;
-    QCheckBox*                     timeDigitalizedCheck;
-    QCheckBox*                     syncEXIFDateCheck;
-    QCheckBox*                     cityCheck;
-    QCheckBox*                     sublocationCheck;
-    QCheckBox*                     provinceCheck;
+namespace MediaWiki
+{
+
+class Q_DECL_HIDDEN QueryInfoPrivate : public JobPrivate
+{
+public:
+
+    explicit QueryInfoPrivate(Iface& MediaWiki)
+        : JobPrivate(MediaWiki)
+    {
+    }
+
+    QVector<Protection>    protections;
+    QMap<QString, QString> requestParameter;
+    Page                   page;
+};
+
+QueryInfo::QueryInfo(Iface& MediaWiki, QObject* const parent)
+    : Job(*new QueryInfoPrivate(MediaWiki), parent)
+{
+}
+
+QueryInfo::~QueryInfo()
+{
+}
+
+void QueryInfo::setPageName(const QString& title)
+{
+    Q_D(QueryInfo);
+    d->requestParameter[QStringLiteral("titles")] = title;
+}
+
+void QueryInfo::setToken(const QString& token)
+{
+    Q_D(QueryInfo);
+    d->requestParameter[QStringLiteral("intoken")] = token;
+}
+
+void QueryInfo::setPageId(unsigned int id)
+{
+    Q_D(QueryInfo);
+    d->requestParameter[QStringLiteral("pageids")] = QString::number(id);
+}
+
+void QueryInfo::setRevisionId(unsigned int id)
+{
+    Q_D(QueryInfo);
+    d->requestParameter[QStringLiteral("revids")] = QString::number(id);
+}
+
+void QueryInfo::start()
+{
+    QTimer::singleShot(0, this, SLOT(doWorkSendRequest()));
+}
 
-    QTimeEdit*                     timeCreatedSel;
-    QTimeEdit*                     timeDigitalizedSel;
-
-    TimeZoneComboBox*              zoneCreatedSel;
-    TimeZoneComboBox*              zoneDigitalizedSel;
-
-    QPushButton*                   setTodayCreatedBtn;
-    QPushButton*                   setTodayDigitalizedBtn;
-
-    QDateEdit*                     dateCreatedSel;
-    QDateEdit*                     dateDigitalizedSel;
+void QueryInfo::doWorkSendRequest()
+{
+    Q_D(QueryInfo);
+
+    // Set the url
+    QUrl url = d->MediaWiki.url();
+    QUrlQuery query;
+    query.addQueryItem(QStringLiteral("format"), QStringLiteral("xml"));
+    query.addQueryItem(QStringLiteral("action"), QStringLiteral("query"));
+    query.addQueryItem(QStringLiteral("prop"),   QStringLiteral("info"));
+    query.addQueryItem(QStringLiteral("inprop"), QStringLiteral("protection|talkid|watched|subjectid|url|readable|preload"));
 
-    QLineEdit*                     cityEdit;
-    QLineEdit*                     sublocationEdit;
-    QLineEdit*                     provinceEdit;
-
-    MultiValuesEdit*               locationEdit;
-
-    MetadataCheckBox*              countryCheck;
-
-    CountrySelector*               countryCB;
-};
-
-IPTCOrigin::IPTCOrigin(QWidget* const parent)
-    : QWidget(parent),
-      d(new Private)
-{
-    QGridLayout* const grid = new QGridLayout(this);
-
-    // IPTC only accept printable Ascii char.
-    QRegExp asciiRx(QLatin1String("[\x20-\x7F]+$"));
-    QValidator* const asciiValidator = new QRegExpValidator(asciiRx, this);
-
-    QString dateFormat  = QLocale().dateFormat(QLocale::ShortFormat);
-
-    if (!dateFormat.contains(QLatin1String("yyyy")))
-    {
-        dateFormat.replace(QLatin1String("yy"),
-                           QLatin1String("yyyy"));
-    }
-
-    QString timeFormat = QLatin1String("hh:mm:ss");
-
-    // --------------------------------------------------------
-
-    d->dateDigitalizedCheck   = new QCheckBox(i18n("Digitization date"), this);
-    d->timeDigitalizedCheck   = new QCheckBox(i18n("Digitization time"), this);
-    d->zoneDigitalizedSel     = new TimeZoneComboBox(this);
+    QMapIterator<QString, QString> i(d->requestParameter);<--- Shadowed declaration
+
+    while (i.hasNext())
+    {
+        i.next();
+        query.addQueryItem(i.key(), i.value());
+    }
+    url.setQuery(query);
+
+    // Set the request
+    QNetworkRequest request(url);
+    request.setRawHeader("User-Agent", d->MediaWiki.userAgent().toUtf8());
+    QByteArray cookie = "";
+    QList<QNetworkCookie> MediaWikiCookies = d->manager->cookieJar()->cookiesForUrl(d->MediaWiki.url());
+
+    for (int i = 0 ; i < MediaWikiCookies.size() ; ++i)<--- Shadow variable
+    {
+        cookie += MediaWikiCookies.at(i).toRawForm(QNetworkCookie::NameAndValueOnly);
+        cookie += ';';
+    }
+    request.setRawHeader( "Cookie", cookie );
+
+    // Send the request
+    d->reply = d->manager->get(request);
+    connectReply();
+
+    connect(d->reply, SIGNAL(finished()),
+            this, SLOT(doWorkProcessReply()));
+}
+
+void QueryInfo::doWorkProcessReply()
+{
+    Q_D(QueryInfo);
+
+    disconnect(d->reply, SIGNAL(finished()), 
+               this, SLOT(doWorkProcessReply()));
 
-    d->dateDigitalizedSel     = new QDateEdit(this);
-    d->dateDigitalizedSel->setDisplayFormat(dateFormat);
-
-    d->timeDigitalizedSel     = new QTimeEdit(this);
-    d->timeDigitalizedSel->setDisplayFormat(timeFormat);
-
-    d->setTodayDigitalizedBtn = new QPushButton();
-    d->setTodayDigitalizedBtn->setIcon(QIcon::fromTheme(QLatin1String("go-jump-today")));
-    d->setTodayDigitalizedBtn->setWhatsThis(i18n("Set digitization date to today"));
-
-    d->dateDigitalizedSel->setWhatsThis(i18n("Set here the creation date of "
-                                             "digital representation."));
-    d->timeDigitalizedSel->setWhatsThis(i18n("Set here the creation time of "
-                                             "digital representation."));
-    d->zoneDigitalizedSel->setWhatsThis(i18n("Set here the time zone of "
-                                             "digital representation."));
-
-    slotSetTodayDigitalized();
-
-    // --------------------------------------------------------
-
-    d->dateCreatedCheck   = new QCheckBox(i18n("Creation date"), this);
-    d->timeCreatedCheck   = new QCheckBox(i18n("Creation time"), this);
-    d->zoneCreatedSel     = new TimeZoneComboBox(this);
-
-    d->dateCreatedSel     = new QDateEdit(this);
-    d->dateCreatedSel->setDisplayFormat(dateFormat);
-
-    d->timeCreatedSel     = new QTimeEdit(this);
-    d->timeCreatedSel->setDisplayFormat(timeFormat);
-
-    d->syncEXIFDateCheck  = new QCheckBox(i18n("Sync EXIF creation date"), this);
-
-    d->setTodayCreatedBtn = new QPushButton();
-    d->setTodayCreatedBtn->setIcon(QIcon::fromTheme(QLatin1String("go-jump-today")));
-    d->setTodayCreatedBtn->setWhatsThis(i18n("Set creation date to today"));
-
-    d->dateCreatedSel->setWhatsThis(i18n("Set here the creation date of "
-                                         "intellectual content."));
-    d->timeCreatedSel->setWhatsThis(i18n("Set here the creation time of "
-                                         "intellectual content."));
-    d->zoneCreatedSel->setWhatsThis(i18n("Set here the time zone of "
-                                         "intellectual content."));
+    if (d->reply->error() == QNetworkReply::NoError)
+    {
+        // Replace & in &amp;
+        QString content = QString::fromUtf8(d->reply->readAll());
+        QRegExp regex(QStringLiteral("&(?!\\w+;)"));
+        content.replace(regex, QStringLiteral("&amp;"));
+        QXmlStreamReader reader(content);
+        QVector<Protection> protect;
+
+        while (!reader.atEnd() && !reader.hasError())
+        {
+            QXmlStreamReader::TokenType token = reader.readNext();
+            QXmlStreamAttributes attrs = reader.attributes();
+
+            if (token == QXmlStreamReader::StartElement)
+            {
+                if (reader.name() == QLatin1String("page"))
+                {
+                    d->page.setPageId(attrs.value(QStringLiteral("pageid")).toString().toUInt());
+                    d->page.setTitle(attrs.value(QStringLiteral("title")).toString());
+                    d->page.setNs(attrs.value(QStringLiteral("ns")).toString().toUInt());
+                    d->page.setTouched(QDateTime::fromString(attrs.value(QStringLiteral("touched")).toString(), QStringLiteral("yyyy'-'MM'-'dd'T'hh':'mm':'ss'Z'")));
+                    d->page.setLastRevId(attrs.value(QStringLiteral("lastrevid")).toString().toUInt());
+                    d->page.setCounter(attrs.value(QStringLiteral("counter")).toString().toUInt());
+                    d->page.setLength(attrs.value(QStringLiteral("length")).toString().toUInt());
+                    d->page.setStarttimestamp(QDateTime::fromString(attrs.value(QStringLiteral("starttimestamp")).toString(), QStringLiteral("yyyy'-'MM'-'dd'T'hh':'mm':'ss'Z'")));
+                    d->page.setEditToken(attrs.value(QStringLiteral("edittoken")).toString());
+                    d->page.setTalkid(attrs.value(QStringLiteral("talkid")).toString().toUInt());
+                    d->page.setFullurl(QUrl(attrs.value(QStringLiteral("fullurl")).toString()));
+                    d->page.setEditurl(QUrl(attrs.value(QStringLiteral("editurl")).toString()));
+                    d->page.setReadable(attrs.value(QStringLiteral("readable")).toString());
+                    d->page.setPreload(attrs.value(QStringLiteral("preload")).toString());
+                }
+                else if (reader.name() == QLatin1String("protection"))
+                {
+                    protect.clear();
+                }
+                else if (reader.name() == QLatin1String("pr"))
+                {
+                    QString expiry(attrs.value(QStringLiteral("expiry")).toString());
+                    QString level(attrs.value(QStringLiteral("level")).toString());
+                    QString type(attrs.value(QStringLiteral("type")).toString());
+                    QString source;
 
-    slotSetTodayCreated();
-
-    // --------------------------------------------------------
-
-    d->locationEdit = new MultiValuesEdit(this, i18n("Location:"),
-                          i18n("Set here the full country name referenced by the content."));
-
-    // --------------------------------------------------------
+                    if (!attrs.value(QStringLiteral("source")).toString().isEmpty())
+                    {
+                        source = attrs.value(QStringLiteral("source")).toString();
+                    }
+                    else if (!attrs.value(QStringLiteral("cascade")).toString().isEmpty())
+                    {
+                        source = attrs.value(QStringLiteral("cascade")).toString();
+                    }
 
-    d->cityCheck = new QCheckBox(i18n("City:"), this);
-    d->cityEdit  = new QLineEdit(this);
-    d->cityEdit->setClearButtonEnabled(true);
-    d->cityEdit->setValidator(asciiValidator);
-    d->cityEdit->setMaxLength(32);
-    d->cityEdit->setWhatsThis(i18n("Set here the city of content origin. "
-                                   "This field is limited to 32 ASCII characters."));
-
-    // --------------------------------------------------------
-
-    d->sublocationCheck = new QCheckBox(i18n("Sublocation:"), this);
-    d->sublocationEdit  = new QLineEdit(this);
-    d->sublocationEdit->setClearButtonEnabled(true);
-    d->sublocationEdit->setValidator(asciiValidator);
-    d->sublocationEdit->setMaxLength(32);
-    d->sublocationEdit->setWhatsThis(i18n("Set here the content location within city. "
-                                          "This field is limited to 32 ASCII characters."));
-
-    // --------------------------------------------------------
-
-    d->provinceCheck = new QCheckBox(i18n("State/Province:"), this);
-    d->provinceEdit  = new QLineEdit(this);
-    d->provinceEdit->setClearButtonEnabled(true);
-    d->provinceEdit->setValidator(asciiValidator);
-    d->provinceEdit->setMaxLength(32);
-    d->provinceEdit->setWhatsThis(i18n("Set here the Province or State of content origin. "
-                                       "This field is limited to 32 ASCII characters."));
-
-    // --------------------------------------------------------
-
-    d->countryCheck = new MetadataCheckBox(i18n("Country:"), this);
-    d->countryCB    = new CountrySelector(this);
-    d->countryCB->setWhatsThis(i18n("Select here country name of content origin."));
-    // Remove 2 last items for the list (separator + Unknown item)
-    d->countryCB->removeItem(d->countryCB->count()-1);
-    d->countryCB->removeItem(d->countryCB->count()-1);
-
-    QStringList list;
-
-    for (int i = 0 ; i < d->countryCB->count() ; ++i)
-        list.append(d->countryCB->itemText(i));
-
-    d->locationEdit->setData(list);
-
-    // --------------------------------------------------------
-
-    QLabel* const note = new QLabel(i18n("<b>Note: "
-                 "<b><a href='https://en.wikipedia.org/wiki/IPTC_Information_Interchange_Model'>IPTC</a></b> "
-                 "text tags only support the printable "
-                 "<b><a href='https://en.wikipedia.org/wiki/Ascii'>ASCII</a></b> "
-                 "characters and limit string sizes. "
-                 "Use contextual help for details.</b>"), this);
-    note->setOpenExternalLinks(true);
-    note->setWordWrap(true);
-    note->setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
-
-    // --------------------------------------------------------
-
-    grid->addWidget(d->dateDigitalizedCheck,                0, 0, 1, 2);
-    grid->addWidget(d->timeDigitalizedCheck,                0, 2, 1, 2);
-    grid->addWidget(d->dateDigitalizedSel,                  1, 0, 1, 2);
-    grid->addWidget(d->timeDigitalizedSel,                  1, 2, 1, 1);
-    grid->addWidget(d->zoneDigitalizedSel,                  1, 3, 1, 1);
-    grid->addWidget(d->setTodayDigitalizedBtn,              1, 5, 1, 1);
-    grid->addWidget(d->dateCreatedCheck,                    2, 0, 1, 2);
-    grid->addWidget(d->timeCreatedCheck,                    2, 2, 1, 2);
-    grid->addWidget(d->dateCreatedSel,                      3, 0, 1, 2);
-    grid->addWidget(d->timeCreatedSel,                      3, 2, 1, 1);
-    grid->addWidget(d->zoneCreatedSel,                      3, 3, 1, 1);
-    grid->addWidget(d->setTodayCreatedBtn,                  3, 5, 1, 1);
-    grid->addWidget(d->syncEXIFDateCheck,                   5, 0, 1, 6);
-    grid->addWidget(d->locationEdit,                        6, 0, 1, 6);
-    grid->addWidget(new DLineWidget(Qt::Horizontal, this),   7, 0, 1, 6);
-    grid->addWidget(d->cityCheck,                           8, 0, 1, 1);
-    grid->addWidget(d->cityEdit,                            8, 1, 1, 5);
-    grid->addWidget(d->sublocationCheck,                    9, 0, 1, 1);
-    grid->addWidget(d->sublocationEdit,                     9, 1, 1, 5);
-    grid->addWidget(d->provinceCheck,                      10, 0, 1, 1);
-    grid->addWidget(d->provinceEdit,                       10, 1, 1, 5);
-    grid->addWidget(d->countryCheck,                       11, 0, 1, 1);
-    grid->addWidget(d->countryCB,                          11, 1, 1, 5);
-    grid->addWidget(note,                                  12, 0, 1, 6);
-    grid->setColumnStretch(4, 10);
-    grid->setRowStretch(13, 10);
-    grid->setContentsMargins(QMargins());
-    grid->setSpacing(QApplication::style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing));
-
-    // --------------------------------------------------------
-
-    connect(d->dateCreatedCheck, SIGNAL(toggled(bool)),
-            d->dateCreatedSel, SLOT(setEnabled(bool)));
-
-    connect(d->dateDigitalizedCheck, SIGNAL(toggled(bool)),
-            d->dateDigitalizedSel, SLOT(setEnabled(bool)));
-
-    connect(d->timeCreatedCheck, SIGNAL(toggled(bool)),
-            d->timeCreatedSel, SLOT(setEnabled(bool)));
-
-    connect(d->timeDigitalizedCheck, SIGNAL(toggled(bool)),
-            d->timeDigitalizedSel, SLOT(setEnabled(bool)));
-
-    connect(d->timeCreatedCheck, SIGNAL(toggled(bool)),
-            d->zoneCreatedSel, SLOT(setEnabled(bool)));
-
-    connect(d->timeDigitalizedCheck, SIGNAL(toggled(bool)),
-            d->zoneDigitalizedSel, SLOT(setEnabled(bool)));
-
-    connect(d->dateCreatedCheck, SIGNAL(toggled(bool)),
-            d->syncEXIFDateCheck, SLOT(setEnabled(bool)));
-
-    connect(d->cityCheck, SIGNAL(toggled(bool)),
-            d->cityEdit, SLOT(setEnabled(bool)));
-
-    connect(d->sublocationCheck, SIGNAL(toggled(bool)),
-            d->sublocationEdit, SLOT(setEnabled(bool)));
-
-    connect(d->provinceCheck, SIGNAL(toggled(bool)),
-            d->provinceEdit, SLOT(setEnabled(bool)));
-
-    connect(d->countryCheck, SIGNAL(toggled(bool)),
-            d->countryCB, SLOT(setEnabled(bool)));
-
-    // --------------------------------------------------------
-
-    connect(d->dateCreatedCheck, SIGNAL(toggled(bool)),
-            this, SIGNAL(signalModified()));
-
-    connect(d->dateDigitalizedCheck, SIGNAL(toggled(bool)),
-            this, SIGNAL(signalModified()));
-
-    connect(d->timeCreatedCheck, SIGNAL(toggled(bool)),
-            this, SIGNAL(signalModified()));
-
-    connect(d->timeDigitalizedCheck, SIGNAL(toggled(bool)),
-            this, SIGNAL(signalModified()));
-
-    connect(d->cityCheck, SIGNAL(toggled(bool)),
-            this, SIGNAL(signalModified()));
-
-    connect(d->sublocationCheck, SIGNAL(toggled(bool)),
-            this, SIGNAL(signalModified()));
-
-    connect(d->provinceCheck, SIGNAL(toggled(bool)),
-            this, SIGNAL(signalModified()));
-
-    connect(d->countryCheck, SIGNAL(toggled(bool)),
-            this, SIGNAL(signalModified()));
-
-    connect(d->locationEdit, SIGNAL(signalModified()),
-            this, SIGNAL(signalModified()));
-
-    // --------------------------------------------------------
-
-    connect(d->dateCreatedSel, SIGNAL(dateChanged(QDate)),
-            this, SIGNAL(signalModified()));
-
-    connect(d->dateDigitalizedSel, SIGNAL(dateChanged(QDate)),
-            this, SIGNAL(signalModified()));
-
-    connect(d->timeCreatedSel, SIGNAL(timeChanged(QTime)),
-            this, SIGNAL(signalModified()));
-
-    connect(d->timeDigitalizedSel, SIGNAL(timeChanged(QTime)),
-            this, SIGNAL(signalModified()));
-
-    connect(d->zoneCreatedSel, SIGNAL(currentIndexChanged(QString)),
-            this, SIGNAL(signalModified()));
-
-    connect(d->zoneDigitalizedSel, SIGNAL(currentIndexChanged(QString)),
-            this, SIGNAL(signalModified()));
-
-    // --------------------------------------------------------
-
-    connect(d->setTodayCreatedBtn, SIGNAL(clicked()),
-            this, SLOT(slotSetTodayCreated()));
-
-    connect(d->setTodayDigitalizedBtn, SIGNAL(clicked()),
-            this, SLOT(slotSetTodayDigitalized()));
-
-    // --------------------------------------------------------
-
-    connect(d->countryCB, SIGNAL(activated(int)),
-            this, SIGNAL(signalModified()));
-
-    connect(d->cityEdit, SIGNAL(textChanged(QString)),
-            this, SIGNAL(signalModified()));
-
-    connect(d->sublocationEdit, SIGNAL(textChanged(QString)),
-            this, SIGNAL(signalModified()));
-
-    connect(d->provinceEdit, SIGNAL(textChanged(QString)),
-            this, SIGNAL(signalModified()));
-}
-
-IPTCOrigin::~IPTCOrigin()
-{
-    delete d;
-}
-
-void IPTCOrigin::slotSetTodayCreated()
-{
-    d->dateCreatedSel->setDate(QDate::currentDate());
-    d->timeCreatedSel->setTime(QTime::currentTime());
-    d->zoneCreatedSel->setToUTC();
-}
-
-void IPTCOrigin::slotSetTodayDigitalized()
-{
-    d->dateDigitalizedSel->setDate(QDate::currentDate());
-    d->timeDigitalizedSel->setTime(QTime::currentTime());
-    d->zoneDigitalizedSel->setToUTC();
-}
-
-bool IPTCOrigin::syncEXIFDateIsChecked() const
-{
-    return d->syncEXIFDateCheck->isChecked();
-}
-
-void IPTCOrigin::setCheckedSyncEXIFDate(bool c)
-{
-    d->syncEXIFDateCheck->setChecked(c);
-}
-
-QDateTime IPTCOrigin::getIPTCCreationDate() const
-{
-    return QDateTime(d->dateCreatedSel->date(), d->timeCreatedSel->time());
-}
-
-void IPTCOrigin::readMetadata(QByteArray& iptcData)
-{
-    blockSignals(true);
-    DMetadata meta;
-    meta.setIptc(iptcData);
-
-    QString     data;<--- Shadowed declaration
-    QStringList code, list;
-    QDate       date;
-    QTime       time;
-    QString     dateStr, timeStr;
-
-    dateStr = meta.getIptcTagString("Iptc.Application2.DateCreated", false);
-    timeStr = meta.getIptcTagString("Iptc.Application2.TimeCreated", false);
-
-    d->dateCreatedSel->setDate(QDate::currentDate());
-    d->dateCreatedCheck->setChecked(false);
-
-    if (!dateStr.isEmpty())
-    {
-        date = QDate::fromString(dateStr, Qt::ISODate);
-
-        if (date.isValid())
-        {
-            d->dateCreatedSel->setDate(date);
-            d->dateCreatedCheck->setChecked(true);
-        }
-    }
-
-    d->dateCreatedSel->setEnabled(d->dateCreatedCheck->isChecked());
-    d->syncEXIFDateCheck->setEnabled(d->dateCreatedCheck->isChecked());
-
-    d->timeCreatedSel->setTime(QTime::currentTime());
-    d->timeCreatedCheck->setChecked(false);
-    d->zoneCreatedSel->setToUTC();
-
-    if (!timeStr.isEmpty())
-    {
-        time = QTime::fromString(timeStr, Qt::ISODate);
-
-        if (time.isValid())
-        {
-            d->timeCreatedSel->setTime(time);
-            d->timeCreatedCheck->setChecked(true);
-            d->zoneCreatedSel->setTimeZone(timeStr);
-        }
-    }
-
-    d->timeCreatedSel->setEnabled(d->timeCreatedCheck->isChecked());
-    d->zoneCreatedSel->setEnabled(d->timeCreatedCheck->isChecked());
-
-    dateStr = meta.getIptcTagString("Iptc.Application2.DigitizationDate", false);
-    timeStr = meta.getIptcTagString("Iptc.Application2.DigitizationTime", false);
-
-    d->dateDigitalizedSel->setDate(QDate::currentDate());
-    d->dateDigitalizedCheck->setChecked(false);
-
-    if (!dateStr.isEmpty())
-    {
-        date = QDate::fromString(dateStr, Qt::ISODate);
-
-        if (date.isValid())
-        {
-            d->dateDigitalizedSel->setDate(date);
-            d->dateDigitalizedCheck->setChecked(true);
-        }
-    }
-
-    d->dateDigitalizedSel->setEnabled(d->dateDigitalizedCheck->isChecked());
-
-    d->timeDigitalizedSel->setTime(QTime::currentTime());
-    d->timeDigitalizedCheck->setChecked(false);
-    d->zoneDigitalizedSel->setToUTC();
-
-    if (!timeStr.isEmpty())
-    {
-        time = QTime::fromString(timeStr, Qt::ISODate);
-
-        if (time.isValid())
-        {
-            d->timeDigitalizedSel->setTime(time);
-            d->timeDigitalizedCheck->setChecked(true);
-            d->zoneDigitalizedSel->setTimeZone(timeStr);
-        }
-    }
-
-    d->timeDigitalizedSel->setEnabled(d->timeDigitalizedCheck->isChecked());
-    d->zoneDigitalizedSel->setEnabled(d->timeDigitalizedCheck->isChecked());
-
-    code = meta.getIptcTagsStringList("Iptc.Application2.LocationCode", false);
-
-    for (QStringList::Iterator it = code.begin(); it != code.end(); ++it)
-    {
-        QStringList data = d->locationEdit->getData();<--- Shadow variable
-        QStringList::Iterator it2;
-
-        for (it2 = data.begin(); it2 != data.end(); ++it2)
-        {
-            if ((*it2).left(3) == (*it))
-            {
-                list.append(*it2);
-                break;
-            }
-        }
-
-        if (it2 == data.end())
-            d->locationEdit->setValid(false);
-    }
-
-    d->locationEdit->setValues(list);
-
-    d->cityEdit->clear();
-    d->cityCheck->setChecked(false);
-    data = meta.getIptcTagString("Iptc.Application2.City", false);
-
-    if (!data.isNull())
-    {
-        d->cityEdit->setText(data);
-        d->cityCheck->setChecked(true);
-    }
-
-    d->cityEdit->setEnabled(d->cityCheck->isChecked());
-
-    d->sublocationEdit->clear();
-    d->sublocationCheck->setChecked(false);
-    data = meta.getIptcTagString("Iptc.Application2.SubLocation", false);
-
-    if (!data.isNull())
-    {
-        d->sublocationEdit->setText(data);
-        d->sublocationCheck->setChecked(true);
-    }
-
-    d->sublocationEdit->setEnabled(d->sublocationCheck->isChecked());
-
-    d->provinceEdit->clear();
-    d->provinceCheck->setChecked(false);
-    data = meta.getIptcTagString("Iptc.Application2.ProvinceState", false);
-
-    if (!data.isNull())
-    {
-        d->provinceEdit->setText(data);
-        d->provinceCheck->setChecked(true);
-    }
-
-    d->provinceEdit->setEnabled(d->provinceCheck->isChecked());
-
-    d->countryCB->setCurrentIndex(0);
-    d->countryCheck->setChecked(false);
-    data = meta.getIptcTagString("Iptc.Application2.CountryCode", false);
-
-    if (!data.isNull())
-    {
-        int item = -1;
-
-        for (int i = 0 ; i < d->countryCB->count() ; ++i)
-        {
-            if (d->countryCB->itemText(i).left(3) == data)
-                item = i;
-        }
-
-        if (item != -1)
-        {
-            d->countryCB->setCurrentIndex(item);
-            d->countryCheck->setChecked(true);
-        }
-        else
-        {
-            d->countryCheck->setValid(false);
-        }
-    }
-
-    d->countryCB->setEnabled(d->countryCheck->isChecked());
-
-    blockSignals(false);
-}
-
-void IPTCOrigin::applyMetadata(QByteArray& exifData, QByteArray& iptcData)
-{
-    DMetadata meta;
-    meta.setExif(exifData);
-    meta.setIptc(iptcData);
-
-    if (d->dateCreatedCheck->isChecked())
-    {
-        meta.setIptcTagString("Iptc.Application2.DateCreated", getIPTCCreationDate().toString(Qt::ISODate));
-
-        if (syncEXIFDateIsChecked())
-        {
-            meta.setExifTagString("Exif.Image.DateTime",
-                                  getIPTCCreationDate().toString(QLatin1String("yyyy:MM:dd hh:mm:ss")));
-        }
-    }
-    else
-    {
-        meta.removeIptcTag("Iptc.Application2.DateCreated");
-    }
-
-    if (d->dateDigitalizedCheck->isChecked())
-    {
-        meta.setIptcTagString("Iptc.Application2.DigitizationDate", d->dateDigitalizedSel->date().toString(Qt::ISODate));
-    }
-    else
-    {
-        meta.removeIptcTag("Iptc.Application2.DigitizationDate");
-    }
-
-    if (d->timeCreatedCheck->isChecked())
-    {
-        meta.setIptcTagString("Iptc.Application2.TimeCreated", d->timeCreatedSel->time().toString(Qt::ISODate) +
-                                                               d->zoneCreatedSel->getTimeZone());
-    }
-    else
-    {
-        meta.removeIptcTag("Iptc.Application2.TimeCreated");
-    }
-
-    if (d->timeDigitalizedCheck->isChecked())
-    {
-        meta.setIptcTagString("Iptc.Application2.DigitizationTime", d->timeDigitalizedSel->time().toString(Qt::ISODate) +
-                                                                    d->zoneDigitalizedSel->getTimeZone());
-    }
-    else
-    {
-        meta.removeIptcTag("Iptc.Application2.DigitizationTime");
-    }
-
-    QStringList oldList, newList;
-
-    if (d->locationEdit->getValues(oldList, newList))
-    {
-        QStringList oldCode, newCode, oldName, newName;
-
-        for (QStringList::Iterator it = oldList.begin(); it != oldList.end(); ++it)
-        {
-            oldCode.append((*it).left(3));
-            oldName.append((*it).mid(6));
-        }
-
-        for (QStringList::Iterator it2 = newList.begin(); it2 != newList.end(); ++it2)
-        {
-            newCode.append((*it2).left(3));
-            newName.append((*it2).mid(6));
-        }
-
-        meta.setIptcTagsStringList("Iptc.Application2.LocationCode", 3, oldCode, newCode);
-        meta.setIptcTagsStringList("Iptc.Application2.LocationName", 64, oldName, newName);
-    }
-    else
-    {
-        meta.removeIptcTag("Iptc.Application2.LocationCode");
-        meta.removeIptcTag("Iptc.Application2.LocationName");
-    }
-
-    if (d->cityCheck->isChecked())
-        meta.setIptcTagString("Iptc.Application2.City", d->cityEdit->text());
-    else
-        meta.removeIptcTag("Iptc.Application2.City");
-
-    if (d->sublocationCheck->isChecked())
-        meta.setIptcTagString("Iptc.Application2.SubLocation", d->sublocationEdit->text());
-    else
-        meta.removeIptcTag("Iptc.Application2.SubLocation");
-
-    if (d->provinceCheck->isChecked())
-        meta.setIptcTagString("Iptc.Application2.ProvinceState", d->provinceEdit->text());
-    else
-        meta.removeIptcTag("Iptc.Application2.ProvinceState");
-
-    if (d->countryCheck->isChecked())
-    {
-        QString countryName = d->countryCB->currentText().mid(6);
-        QString countryCode = d->countryCB->currentText().left(3);
-        meta.setIptcTagString("Iptc.Application2.CountryCode", countryCode);
-        meta.setIptcTagString("Iptc.Application2.CountryName", countryName);
-    }
-    else if (d->countryCheck->isValid())
-    {
-        meta.removeIptcTag("Iptc.Application2.CountryCode");
-        meta.removeIptcTag("Iptc.Application2.CountryName");
-    }
-
-    exifData = meta.getExifEncoded();
-    iptcData = meta.getIptc();
-}
-
-} // namespace DigikamGenericMetadataEditPlugin
+                    Protection p;
+                    p.setExpiry(expiry);
+                    p.setLevel(level);
+                    p.setType(type);
+                    p.setSource(source);
+                    protect.push_back(p);
+                }
+            }
+            else if (token == QXmlStreamReader::EndElement)
+            {
+                if (reader.name() == QLatin1String("page"))
+                {
+                    d->protections = protect;
+                }
+            }
+        }
+        if (!reader.hasError())
+        {
+            setError(KJob::NoError);
+            emit protection(protect);
+            emit page(d->page);
+        }
+        else
+        {
+            setError(Job::XmlError);
+        }
+    }
+    else
+    {
+        setError(Job::NetworkError);
+    }
+
+    emitResult();
+}
+
+} // namespace MediaWiki
 
diff --git a/static/reports/cppcheck/master/10.html b/static/reports/cppcheck/master/10.html deleted file mode 100644 index bccbb44ef..000000000 --- a/static/reports/cppcheck/master/10.html +++ /dev/null @@ -1,387 +0,0 @@ - - - - - - Cppcheck - HTML report - digiKam-master-rev-907aafb5fa - - - - - - - -
-
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
/* ============================================================
- *
- * This file is a part of digiKam project
- * https://www.digikam.org
- *
- * Date        : 2010-06-21
- * Description : Test for SimpleTreeModel.
- *
- * Copyright (C) 2010 by Michael G. Hansen <mike at mghansen dot de>
- *
- * This program is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General
- * Public License as published by the Free Software Foundation;
- * either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * ============================================================ */
-
-#include "test_simpletreemodel.h"
-
-// Qt includes
-
-#include <QUrl>
-#include <QDebug>
-
-// local includes
-
-#include "simpletreemodel.h"
-#include "modeltest.h"
-
-using namespace Digikam;
-
-/**
- * Description : Dummy test that does nothing
- */
-void TestSimpleTreeModel::testNoOp()
-{
-}
-
-void TestSimpleTreeModel::testModel1()
-{
-    SimpleTreeModel* const treeModel = new SimpleTreeModel(1, this);
-    new ModelTest(treeModel, this);
-    Q_ASSERT(!treeModel->index(0, 0).isValid());
-    Q_ASSERT(treeModel->indexToItem(QModelIndex())==treeModel->rootItem());
-    Q_ASSERT(!treeModel->itemToIndex(treeModel->rootItem()).isValid());
-    Q_ASSERT(!treeModel->itemToIndex(nullptr).isValid());
-    Q_ASSERT(!treeModel->parent(QModelIndex()).isValid());
-
-    SimpleTreeModel::Item* const item1 = treeModel->addItem();
-    Q_ASSERT(item1!=nullptr);
-    const QPersistentModelIndex item1Index = treeModel->itemToIndex(item1);
-    Q_ASSERT(item1Index.isValid());
-    Q_ASSERT(treeModel->indexToItem(item1Index)==item1);
-    Q_ASSERT(!treeModel->parent(item1Index).isValid());
-
-    SimpleTreeModel::Item* const item2 = treeModel->addItem();
-    Q_ASSERT(item2!=nullptr);
-    const QModelIndex item2Index = treeModel->itemToIndex(item2);
-    Q_ASSERT(item2Index.isValid());
-    Q_ASSERT(treeModel->indexToItem(item2Index)==item2);
-    Q_ASSERT(!treeModel->parent(item2Index).isValid());
-
-    SimpleTreeModel::Item* const item21 = treeModel->addItem(item2);<--- Shadowed declaration<--- Shadowed declaration
-    Q_ASSERT(item21!=nullptr);
-    const QModelIndex item21Index = treeModel->itemToIndex(item21);<--- Shadowed declaration<--- Shadowed declaration
-    Q_ASSERT(item21Index.isValid());
-    Q_ASSERT(treeModel->indexToItem(item21Index)==item21);
-    Q_ASSERT(treeModel->parent(item21Index)==item2Index);
-    Q_ASSERT(treeModel->index(0, 0, item2Index)==item21Index);
-
-    // just make sure another modeltest will test things for consistency in case a signal went missing
-    new ModelTest(treeModel, this);
-
-    Q_ASSERT(treeModel->rootItem() == treeModel->indexToItem(QModelIndex()));
-    Q_ASSERT(treeModel->indexToItem(treeModel->itemToIndex(item1))==item1);
-    Q_ASSERT(treeModel->hasIndex(0, 0) == true);
-
-    QModelIndex topIndex = treeModel->index(0, 0, QModelIndex());
-
-    if (treeModel->rowCount(topIndex) > 0)
-    {
-        QModelIndex childIndex = treeModel->index(0, 0, topIndex);
-        qDebug() << childIndex;
-        qDebug() << treeModel->parent(childIndex);
-        Q_ASSERT(treeModel->parent(childIndex) == topIndex);
-    }
-
-    // add another few items:
-    {
-        SimpleTreeModel::Item* const item21 = treeModel->addItem(item2, 0);<--- Shadow variable
-        Q_ASSERT(item21!=nullptr);
-        const QModelIndex item21Index = treeModel->itemToIndex(item21);<--- Shadow variable
-        Q_ASSERT(item21Index.isValid());
-        Q_ASSERT(treeModel->indexToItem(item21Index)==item21);
-        Q_ASSERT(treeModel->parent(item21Index)==item2Index);
-        Q_ASSERT(treeModel->index(0, 0, item2Index)==item21Index);
-        Q_ASSERT(item21Index.row()==0);
-    }
-
-    // add another few items:
-    {
-        SimpleTreeModel::Item* const item21 = treeModel->addItem(item2, 1);<--- Shadow variable
-        Q_ASSERT(item21!=nullptr);
-        const QModelIndex item21Index = treeModel->itemToIndex(item21);<--- Shadow variable
-        Q_ASSERT(item21Index.isValid());
-        Q_ASSERT(treeModel->indexToItem(item21Index)==item21);
-        Q_ASSERT(treeModel->parent(item21Index)==item2Index);
-        Q_ASSERT(treeModel->index(1, 0, item2Index)==item21Index);
-        Q_ASSERT(item21Index.row()==1);
-    }
-
-    new ModelTest(treeModel, this);
-}
-
-QTEST_GUILESS_MAIN(TestSimpleTreeModel)
-
-
-
- - - diff --git a/static/reports/cppcheck/master/11.html b/static/reports/cppcheck/master/11.html deleted file mode 100644 index 8efa7f9cc..000000000 --- a/static/reports/cppcheck/master/11.html +++ /dev/null @@ -1,379 +0,0 @@ - - - - - - Cppcheck - HTML report - digiKam-master-rev-907aafb5fa - - - - - - - -
-
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
/* ============================================================
- *
- * This file is a part of digiKam project
- * https://www.digikam.org
- *
- * Date        : 2011-03-22
- * Description : a MediaWiki C++ interface
- *
- * Copyright (C) 2011-2020 by Gilles Caulier <caulier dot gilles at gmail dot com>
- * Copyright (C) 2011      by Alexandre Mendes <alex dot mendes1988 at gmail dot com>
- * Copyright (C) 2011      by Hormiere Guillaume <hormiere dot guillaume at gmail dot com>
- * Copyright (C) 2011      by Manuel Campomanes <campomanes dot manuel at gmail dot com>
- *
- * This program is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General
- * Public License as published by the Free Software Foundation;
- * either version 2, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * ============================================================ */
-
-// Qt includes
-
-#include <QObject>
-#include <QtTest>
-
-// KDE includes
-
-#include <kjob.h>
-
-// Local includes
-
-#include "mediawiki_iface.h"
-#include "mediawiki_logout.h"
-#include "fakeserver/fakeserver.h"
-
-using MediaWiki::Iface;
-using MediaWiki::Logout;
-
-class Q_DECL_HIDDEN LogoutTest : public QObject
-{
-    Q_OBJECT
-
-public:
-
-    LogoutTest()
-    {
-        logoutCount = 0;
-        m_mediaWiki = nullptr;
-        m_server    = nullptr;
-    }
-
-public Q_SLOTS:
-
-    void logoutHandle(KJob* job)
-    {
-        Q_UNUSED(job)
-        logoutCount++;
-    }
-
-private Q_SLOTS:
-
-    void initTestCase()
-    {
-        logoutCount       = 0;
-        this->m_mediaWiki = new Iface(QUrl(QStringLiteral("http://127.0.0.1:12566")));
-        this->m_server    = new FakeServer;
-        this->request     = QStringLiteral("/?format=xml&action=logout");
-    }
-
-    void logoutTestConnectTrue()
-    {
-        QString senario(QStringLiteral("<api />") );
-        QString cookie( QStringLiteral("cookieprefix=\"enwiki\" sessionid=\"17ab96bd8ffbe8ca58a78657a918558e\" expires=\"Sat, 12-Feb-2011 21:39:30 GMT\""));
-        m_server->setScenario(senario, cookie);
-        m_server->startAndWait();
-
-        logoutCount = 0;
-        Logout logout(*m_mediaWiki);
-
-        connect(&logout, SIGNAL(result(KJob*)),
-                this, SLOT(logoutHandle(KJob*)));
-
-        logout.exec();   // krazy:exclude=crashy
-        QCOMPARE(this->logoutCount, 1);
-        QCOMPARE(logout.error(), (int)Logout::NoError);
-
-        QList<FakeServer::Request> requests = m_server->getRequest();
-        QCOMPARE(requests.size(), 1);
-
-        FakeServer::Request request = requests[0];<--- Shadow variable
-        QCOMPARE(request.agent, m_mediaWiki->userAgent());
-        QCOMPARE(request.type, QStringLiteral("GET"));
-        QCOMPARE(request.value, QStringLiteral("/?format=xml&action=logout"));
-    }
-
-    void cleanupTestCase()
-    {
-        delete this->m_mediaWiki;
-        delete this->m_server;
-    }
-
-private:
-
-    int         logoutCount;
-    QString     request;<--- Shadowed declaration
-    Iface*      m_mediaWiki;
-    FakeServer* m_server;
-};
-
-QTEST_MAIN(LogoutTest)
-
-#include "logouttest.moc"
-
-
-
- - - diff --git a/static/reports/cppcheck/master/12.html b/static/reports/cppcheck/master/12.html deleted file mode 100644 index 0c3492788..000000000 --- a/static/reports/cppcheck/master/12.html +++ /dev/null @@ -1,1987 +0,0 @@ - - - - - - Cppcheck - HTML report - digiKam-master-rev-907aafb5fa - - - - - - - -
-
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-172
-173
-174
-175
-176
-177
-178
-179
-180
-181
-182
-183
-184
-185
-186
-187
-188
-189
-190
-191
-192
-193
-194
-195
-196
-197
-198
-199
-200
-201
-202
-203
-204
-205
-206
-207
-208
-209
-210
-211
-212
-213
-214
-215
-216
-217
-218
-219
-220
-221
-222
-223
-224
-225
-226
-227
-228
-229
-230
-231
-232
-233
-234
-235
-236
-237
-238
-239
-240
-241
-242
-243
-244
-245
-246
-247
-248
-249
-250
-251
-252
-253
-254
-255
-256
-257
-258
-259
-260
-261
-262
-263
-264
-265
-266
-267
-268
-269
-270
-271
-272
-273
-274
-275
-276
-277
-278
-279
-280
-281
-282
-283
-284
-285
-286
-287
-288
-289
-290
-291
-292
-293
-294
-295
-296
-297
-298
-299
-300
-301
-302
-303
-304
-305
-306
-307
-308
-309
-310
-311
-312
-313
-314
-315
-316
-317
-318
-319
-320
-321
-322
-323
-324
-325
-326
-327
-328
-329
-330
-331
-332
-333
-334
-335
-336
-337
-338
-339
-340
-341
-342
-343
-344
-345
-346
-347
-348
-349
-350
-351
-352
-353
-354
-355
-356
-357
-358
-359
-360
-361
-362
-363
-364
-365
-366
-367
-368
-369
-370
-371
-372
-373
-374
-375
-376
-377
-378
-379
-380
-381
-382
-383
-384
-385
-386
-387
-388
-389
-390
-391
-392
-393
-394
-395
-396
-397
-398
-399
-400
-401
-402
-403
-404
-405
-406
-407
-408
-409
-410
-411
-412
-413
-414
-415
-416
-417
-418
-419
-420
-421
-422
-423
-424
-425
-426
-427
-428
-429
-430
-431
-432
-433
-434
-435
-436
-437
-438
-439
-440
-441
-442
-443
-444
-445
-446
-447
-448
-449
-450
-451
-452
-453
-454
-455
-456
-457
-458
-459
-460
-461
-462
-463
-464
-465
-466
-467
-468
-469
-470
-471
-472
-473
-474
-475
-476
-477
-478
-479
-480
-481
-482
-483
-484
-485
-486
-487
-488
-489
-490
-491
-492
-493
-494
-495
-496
-497
-498
-499
-500
-501
-502
-503
-504
-505
-506
-507
-508
-509
-510
-511
-512
-513
-514
-515
-516
-517
-518
-519
-520
-521
-522
-523
-524
-525
-526
-527
-528
-529
-530
-531
-532
-533
-534
-535
-536
-537
-538
-539
-540
-541
-542
-543
-544
-545
-546
-547
-548
-549
-550
-551
-552
-553
-554
-555
-556
-557
-558
-559
-560
-561
-562
-563
-564
-565
-566
-567
-568
-569
-570
-571
-572
-573
-574
-575
-576
-577
-578
-579
-580
-581
-582
-583
-584
-585
-586
-587
-588
-589
-590
-591
-592
-593
-594
-595
-596
-597
-598
-599
-600
-601
-602
-603
-604
-605
-606
-607
-608
-609
-610
-611
-612
-613
-614
-615
-616
-617
-618
-619
-620
-621
-622
-623
-624
-625
-626
-627
-628
-629
-630
-631
-632
-633
-634
-635
-636
-637
-638
-639
-640
-641
-642
-643
-644
-645
-646
-647
-648
-649
-650
-651
-652
-653
-654
-655
-656
-657
-658
-659
-660
-661
-662
-663
-664
-665
-666
-667
-668
-669
-670
-671
-672
-673
-674
-675
-676
-677
-678
-679
-680
-681
-682
-683
-684
-685
-686
-687
-688
-689
-690
-691
-692
-693
-694
-695
-696
-697
-698
-699
-700
-701
-702
-703
-704
-705
-706
-707
-708
-709
-710
-711
-712
-713
-714
-715
-716
-717
-718
-719
-720
-721
-722
-723
-724
-725
-726
-727
-728
-729
-730
-731
-732
-733
-734
-735
-736
-737
-738
-739
-740
-741
-742
-743
-744
-745
-746
-747
-748
-749
-750
-751
-752
-753
-754
-755
-756
-757
-758
-759
-760
-761
-762
-763
-764
-765
-766
-767
-768
-769
-770
-771
-772
-773
-774
-775
-776
-777
-778
-779
-780
-781
-782
-783
-784
-785
-786
-787
-788
-789
-790
-791
-792
-793
-794
-795
-796
-797
-798
-799
-800
-801
-802
-803
-804
-805
-806
-807
-808
-809
-810
-811
-812
-813
-814
-815
-816
-817
-818
-819
-820
-821
-822
-823
-824
-825
-826
-827
-828
-829
-830
-831
-832
-833
-834
-835
-836
-837
-838
-839
-840
-841
-842
-843
-844
-845
-846
-847
-848
-849
-850
-851
-852
-853
-854
-855
-856
-857
-858
-859
-860
-861
-862
-863
-864
-865
-866
-867
-868
-869
-870
-871
-872
-873
-874
-875
-876
-877
-878
-879
-880
-881
-882
-883
-884
-885
-886
-887
-888
-889
-890
-891
-892
-893
-894
-895
-896
-897
-898
-899
-900
-901
-902
-903
-904
-905
-906
-907
-908
-909
-910
-911
-912
-913
-914
-915
-916
-917
-918
-919
-920
-921
/* ============================================================
- *
- * This file is a part of digiKam project
- * https://www.digikam.org
- *
- * Date        : 2003-08-03
- * Description : setup Metadata tab.
- *
- * Copyright (C) 2003-2004 by Ralf Holzer <ralf at well dot com>
- * Copyright (C) 2003-2020 by Gilles Caulier <caulier dot gilles at gmail dot com>
- * Copyright (C) 2009-2012 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
- * Copyright (C) 2017      by Simon Frei <freisim93 at gmail dot com>
- *
- * This program is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General
- * Public License as published by the Free Software Foundation;
- * either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * ============================================================ */
-
-#include "setupmetadata.h"
-
-// Qt includes
-
-#include <QApplication>
-#include <QButtonGroup>
-#include <QCheckBox>
-#include <QComboBox>
-#include <QFrame>
-#include <QGridLayout>
-#include <QGroupBox>
-#include <QIcon>
-#include <QLabel>
-#include <QLineEdit>
-#include <QMessageBox>
-#include <QPointer>
-#include <QRadioButton>
-#include <QStandardPaths>
-#include <QStyle>
-#include <QToolButton>
-#include <QVBoxLayout>
-
-// KDE includes
-
-#include <klocalizedstring.h>
-
-// Local includes
-
-#include "advancedmetadatatab.h"
-#include "applicationsettings.h"
-#include "dactivelabel.h"
-#include "digikam_config.h"
-#include "digikam_debug.h"
-#include "metaengine.h"
-#include "metadatapanel.h"
-#include "metaenginesettings.h"
-#include "setuputils.h"
-
-namespace Digikam
-{
-
-class Q_DECL_HIDDEN SetupMetadata::Private
-{
-public:
-
-    explicit Private()
-      : exifAutoRotateOriginal(false),
-        exifAutoRotateShowedInfo(false),
-        clearMetadataShowedInfo(false),
-        fieldsGroup(nullptr),
-        readWriteGroup(nullptr),
-        rotationGroup(nullptr),
-        rotationAdvGroup(nullptr),
-        saveTagsBox(nullptr),
-        saveCommentsBox(nullptr),
-        saveRatingBox(nullptr),
-        savePickLabelBox(nullptr),
-        saveColorLabelBox(nullptr),
-        saveDateTimeBox(nullptr),
-        saveTemplateBox(nullptr),
-        saveFaceTags(nullptr),
-        useLazySync(nullptr),
-        writeRawFilesBox(nullptr),
-        writeXMPSidecarBox(nullptr),
-        readXMPSidecarBox(nullptr),
-        sidecarFileNameBox(nullptr),
-        updateFileTimeStampBox(nullptr),
-        rescanImageIfModifiedBox(nullptr),
-        clearMetadataIfRescanBox(nullptr),
-        writingModeCombo(nullptr),
-        rotateByFlag(nullptr),
-        rotateByContents(nullptr),
-        allowRotateByMetadata(nullptr),
-        allowLossyRotate(nullptr),
-        exifRotateBox(nullptr),
-        exifSetOrientationBox(nullptr),
-        saveToBalooBox(nullptr),
-        readFromBalooBox(nullptr),
-        tab(nullptr),
-        displaySubTab(nullptr),
-        tagsCfgPanel(nullptr),
-        advTab(nullptr),
-        extensionsEdit(nullptr)
-    {
-    }
-
-    bool                 exifAutoRotateOriginal;
-    bool                 exifAutoRotateShowedInfo;
-    bool                 clearMetadataShowedInfo;
-
-    QGroupBox*           fieldsGroup;
-    QGroupBox*           readWriteGroup;
-    QGroupBox*           rotationGroup;
-    QGroupBox*           rotationAdvGroup;
-
-    QCheckBox*           saveTagsBox;
-    QCheckBox*           saveCommentsBox;
-    QCheckBox*           saveRatingBox;
-    QCheckBox*           savePickLabelBox;
-    QCheckBox*           saveColorLabelBox;
-    QCheckBox*           saveDateTimeBox;
-    QCheckBox*           saveTemplateBox;
-    QCheckBox*           saveFaceTags;
-
-    QCheckBox*           useLazySync;
-    QCheckBox*           writeRawFilesBox;
-    QCheckBox*           writeXMPSidecarBox;
-    QCheckBox*           readXMPSidecarBox;
-    QCheckBox*           sidecarFileNameBox;
-    QCheckBox*           updateFileTimeStampBox;
-    QCheckBox*           rescanImageIfModifiedBox;
-    QCheckBox*           clearMetadataIfRescanBox;
-    QComboBox*           writingModeCombo;
-
-    QRadioButton*        rotateByFlag;
-    QRadioButton*        rotateByContents;
-    QCheckBox*           allowRotateByMetadata;
-    QCheckBox*           allowLossyRotate;
-    QCheckBox*           exifRotateBox;
-    QCheckBox*           exifSetOrientationBox;
-
-    QCheckBox*           saveToBalooBox;
-    QCheckBox*           readFromBalooBox;
-
-    QTabWidget*          tab;
-    QTabWidget*          displaySubTab;
-
-    MetadataPanel*       tagsCfgPanel;
-    AdvancedMetadataTab* advTab;
-
-    QLineEdit*           extensionsEdit;
-};
-
-SetupMetadata::SetupMetadata(QWidget* const parent)
-    : QScrollArea(parent),
-      d(new Private)
-{
-    d->tab                          = new QTabWidget(viewport());
-    setWidget(d->tab);
-    setWidgetResizable(true);
-
-    QWidget* const panel            = new QWidget;
-    QVBoxLayout* const mainLayout   = new QVBoxLayout;
-
-    // --------------------------------------------------------
-
-    d->fieldsGroup                  = new QGroupBox;
-    QGridLayout* const fieldsLayout = new QGridLayout;
-
-    d->fieldsGroup->setWhatsThis(xi18nc("@info:whatsthis",
-                                        "<para>In addition to the pixel content, image files usually "
-                                        "contain a variety of metadata. A lot of the parameters you can use "
-                                        "in digiKam to manage files, such as rating or comment, can be written "
-                                        "to the files' metadata.</para> "
-                                        "<para>Storing in metadata allows one to preserve this information "
-                                        "when moving or sending the files to different systems.</para>"));
-
-    QLabel* const fieldsIconLabel = new QLabel;
-    fieldsIconLabel->setPixmap(QIcon::fromTheme(QLatin1String("format-list-unordered")).pixmap(32));
-
-    QLabel* const fieldsLabel     = new QLabel(i18nc("@label", "Write This Information to the Metadata"));
-
-    d->saveTagsBox       = new QCheckBox;
-    d->saveTagsBox->setText(i18nc("@option:check", "Image tags"));
-    d->saveTagsBox->setWhatsThis(i18nc("@info:whatsthis", "Turn on this option to store the item tags "
-                                       "in the XMP and IPTC tags."));
-
-    d->saveCommentsBox   = new QCheckBox;
-    d->saveCommentsBox->setText(i18nc("@option:check", "Captions and title"));
-    d->saveCommentsBox->setWhatsThis(i18nc("@info:whatsthis", "Turn on this option to store item caption and title "
-                                           "in the JFIF Comment section, the EXIF tag, the XMP tag, "
-                                           "and the IPTC tag."));
-
-    d->saveRatingBox     = new QCheckBox;
-    d->saveRatingBox->setText(i18nc("@option:check", "Rating"));
-    d->saveRatingBox->setWhatsThis(i18nc("@info:whatsthis", "Turn on this option to store the item rating "
-                                         "in the EXIF tag and the XMP tags."));
-
-    d->savePickLabelBox  = new QCheckBox;
-    d->savePickLabelBox->setText(i18nc("@option:check", "Pick label"));
-    d->savePickLabelBox->setWhatsThis(i18nc("@info:whatsthis", "Turn on this option to store the item pick label "
-                                            "in the XMP tags."));
-
-    d->saveColorLabelBox = new QCheckBox;
-    d->saveColorLabelBox->setText(i18nc("@option:check", "Color label"));
-    d->saveColorLabelBox->setWhatsThis(i18nc("@info:whatsthis", "Turn on this option to store the item color label "
-                                             "in the XMP tags."));
-
-    d->saveDateTimeBox   = new QCheckBox;
-    d->saveDateTimeBox->setText(i18nc("@option:check", "Timestamps"));
-    d->saveDateTimeBox->setWhatsThis(i18nc("@info:whatsthis", "Turn on this option to store the item date and time "
-                                           "in the EXIF, XMP, and IPTC tags."));
-
-    d->saveTemplateBox   = new QCheckBox;
-    d->saveTemplateBox->setText(i18nc("@option:check", "Metadata templates (Copyright etc.)"));
-    d->saveTemplateBox->setWhatsThis(i18nc("@info:whatsthis", "Turn on this option to store the metadata "
-                                           "template in the XMP and the IPTC tags. "
-                                           "You can set template values to Template setup page."));
-    d->saveFaceTags      = new QCheckBox;
-    d->saveFaceTags->setText(i18nc("@option:check", "Face Tags (including face areas)"));
-    d->saveFaceTags->setWhatsThis(i18nc("@info:whatsthis", "Turn on this option to store face tags "
-                                        "with face rectangles in the XMP tags."));
-
-    fieldsLayout->addWidget(fieldsIconLabel,       0, 0, 2, 3);
-    fieldsLayout->addWidget(fieldsLabel,           0, 1, 2, 3);
-    fieldsLayout->addWidget(d->saveTagsBox,        2, 0, 1, 3);
-    fieldsLayout->addWidget(d->saveCommentsBox,    3, 0, 1, 3);
-    fieldsLayout->addWidget(d->saveRatingBox,      4, 0, 1, 3);
-    fieldsLayout->addWidget(d->savePickLabelBox,   5, 0, 1, 3);
-    fieldsLayout->addWidget(d->saveColorLabelBox,  6, 0, 1, 3);
-    fieldsLayout->addWidget(d->saveDateTimeBox,    7, 0, 1, 3);
-    fieldsLayout->addWidget(d->saveTemplateBox,    8, 0, 1, 3);
-    fieldsLayout->addWidget(d->saveFaceTags,       9 ,0, 1, 3);
-    fieldsLayout->setColumnStretch(3, 10);
-    d->fieldsGroup->setLayout(fieldsLayout);
-
-    // --------------------------------------------------------
-
-    d->readWriteGroup                  = new QGroupBox;
-    QGridLayout* const readWriteLayout = new QGridLayout;
-
-    QLabel* const readWriteIconLabel   = new QLabel;
-    readWriteIconLabel->setPixmap(QIcon::fromTheme(QLatin1String("document-open")).pixmap(32));
-
-    QLabel* const readWriteLabel       = new QLabel(i18nc("@label", "Reading and Writing Metadata"));
-
-    d->useLazySync        = new QCheckBox;
-    d->useLazySync->setText(i18nc("@option:check", "Use lazy synchronization"));
-    d->useLazySync->setWhatsThis(i18nc("@info:whatsthis",
-                                       "Instead of synchronizing metadata, just schedule it for synchronization."
-                                       "Synchronization can be done later by triggering the apply pending, or at digikam exit"));
-    d->writeRawFilesBox   = new QCheckBox;
-    d->writeRawFilesBox->setText(i18nc("@option:check", "If possible write Metadata to RAW files (experimental)"));
-    d->writeRawFilesBox->setWhatsThis(i18nc("@info:whatsthis", "Turn on this option to write metadata into RAW TIFF/EP files. "
-                                            "This feature requires the Exiv2 shared library, version >= 0.18.0. It is still "
-                                            "experimental, and is disabled by default."));
-    d->writeRawFilesBox->setEnabled(MetaEngine::supportMetadataWritting(QLatin1String("image/x-raw")));
-
-    d->updateFileTimeStampBox = new QCheckBox;
-    d->updateFileTimeStampBox->setText(i18nc("@option:check", "&Update file modification timestamp when files are modified"));
-    d->updateFileTimeStampBox->setWhatsThis(i18nc("@info:whatsthis",
-                                                  "Turn off this option to not update file timestamps when files are changed as "
-                                                  "when you update metadata or image data. Note: disabling this option can "
-                                                  "introduce some dysfunctions with applications which use file timestamps "
-                                                  "properties to detect file modifications automatically."));
-
-    d->rescanImageIfModifiedBox = new QCheckBox;
-    d->rescanImageIfModifiedBox->setText(i18nc("@option:check", "&Rescan file when files are modified"));
-    d->rescanImageIfModifiedBox->setWhatsThis(i18nc("@info:whatsthis",
-                                                    "Turning this option on, will force digiKam to rescan files that has been "
-                                                    "modified outside digiKam. If a file has changed it is file size or if "
-                                                    "the last modified timestamp has changed, a rescan of that "
-                                                    "file will be performed when digiKam starts."));
-
-    d->clearMetadataIfRescanBox    = new QCheckBox;
-    d->clearMetadataIfRescanBox->setText(i18nc("@option:check", "&Clean up the metadata from the database when rescan files"));
-    d->clearMetadataIfRescanBox->setWhatsThis(i18nc("@info:whatsthis",
-                                                    "Turning this option on, will force digiKam to delete the file metadata "
-                                                    "contained in the database before the file is rescanned. WARNING: "
-                                                    "if your metadata has been written to the database only and not "
-                                                    "to the file or sidecar, you will be able to lose inserted "
-                                                    "metadata such as tags, keywords, or geographic coordinates."));
-
-    readWriteLayout->addWidget(readWriteIconLabel,          0, 0, 2, 3);
-    readWriteLayout->addWidget(readWriteLabel,              0, 1, 2, 3);
-    readWriteLayout->addWidget(d->useLazySync,              2, 0, 1, 3);
-    readWriteLayout->addWidget(d->writeRawFilesBox,         3, 0, 1, 3);
-    readWriteLayout->addWidget(d->updateFileTimeStampBox,   4, 0, 1, 3);
-    readWriteLayout->addWidget(d->rescanImageIfModifiedBox, 5, 0, 1, 3);
-    readWriteLayout->addWidget(d->clearMetadataIfRescanBox, 6, 0, 1, 3);
-    readWriteLayout->setColumnStretch(3, 10);
-    d->readWriteGroup->setLayout(readWriteLayout);
-
-    // --------------------------------------------------------
-
-    QFrame* const infoBox           = new QFrame;
-    QGridLayout* const infoBoxGrid  = new QGridLayout;
-    infoBox->setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
-
-    DActiveLabel* const exiv2LogoLabel = new DActiveLabel(QUrl(QLatin1String("https://www.exiv2.org")),
-                                                          QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1String("digikam/data/logo-exiv2.png")),
-                                                          infoBox);
-    exiv2LogoLabel->setWhatsThis(i18n("Visit Exiv2 project website"));
-
-    QLabel* const explanation = new QLabel(infoBox);
-    explanation->setOpenExternalLinks(true);
-    explanation->setWordWrap(true);
-    QString txt;
-
-    txt.append(i18n("<p><a href='https://en.wikipedia.org/wiki/Exif'>EXIF</a> - "
-                    "a standard used by most digital cameras today to store technical "
-                    "information (like aperture and shutter speed) about an image.</p>"));
-
-    txt.append(i18n("<p><a href='https://en.wikipedia.org/wiki/IPTC_Information_Interchange_Model'>IPTC</a> - "
-                    "an older standard used in digital photography to store "
-                    "photographer information in images.</p>"));
-
-    if (MetaEngine::supportXmp())
-    {
-        txt.append(i18n("<p><a href='https://en.wikipedia.org/wiki/Extensible_Metadata_Platform'>XMP</a> - "
-                        "a new standard used in digital photography, designed to replace IPTC.</p>"));
-    }
-
-    explanation->setText(txt);
-
-    infoBoxGrid->addWidget(exiv2LogoLabel, 0, 0, 1, 1);
-    infoBoxGrid->addWidget(explanation,    0, 1, 1, 2);
-    infoBoxGrid->setColumnStretch(1, 10);
-    infoBoxGrid->setRowStretch(1, 10);
-    infoBoxGrid->setSpacing(0);
-    infoBox->setLayout(infoBoxGrid);
-
-    // --------------------------------------------------------
-
-    mainLayout->addWidget(d->fieldsGroup);
-    mainLayout->addWidget(d->readWriteGroup);
-    mainLayout->addWidget(infoBox);
-    panel->setLayout(mainLayout);
-
-    d->tab->insertTab(Behavior, panel, i18nc("@title:tab", "Behavior"));
-
-    // --------------------------------------------------------
-
-    QWidget* const rotationPanel      = new QWidget(d->tab);
-    QVBoxLayout* const rotationLayout = new QVBoxLayout;
-
-    d->rotationGroup                       = new QGroupBox;
-    QGridLayout* const rotationGroupLayout = new QGridLayout;
-
-    QLabel* const rotationExplanation = new QLabel(i18nc("@label", "When rotating a file"));
-    QLabel* const rotationIcon        = new QLabel;
-    rotationIcon->setPixmap(QIcon::fromTheme(QLatin1String("transform-rotate")).pixmap(32));
-
-    d->rotateByFlag          = new QRadioButton(i18nc("@option:radio", "Rotate by only setting a flag"));
-    d->rotateByContents      = new QRadioButton(i18nc("@option:radio", "Rotate by changing the content if possible"));
-    d->allowLossyRotate      = new QCheckBox(i18nc("@option:check", "Even allow lossy rotation if necessary"));
-    d->allowRotateByMetadata = new QCheckBox(i18nc("@option:check", "Write flag to metadata if possible"));
-
-    connect(d->rotateByContents, SIGNAL(toggled(bool)),
-            d->allowLossyRotate, SLOT(setEnabled(bool)));
-
-    d->rotateByFlag->setChecked(false);
-    d->rotateByContents->setChecked(false);
-    d->allowLossyRotate->setEnabled(false);
-    d->allowLossyRotate->setChecked(false);
-    d->allowRotateByMetadata->setChecked(true);
-
-    d->rotateByFlag->setToolTip(i18nc("@info:tooltip",
-                                      "Rotate files only by changing a flag, not touching the pixel data"));
-    d->rotateByFlag->setWhatsThis(xi18nc("@info:whatsthis",
-                                         "<para>A file can be rotated in two ways:<nl/> "
-                                         "You can change the contents, rearranging the individual pixels of the image data.<nl/> "
-                                         "Or you can set a flag that the file is to be rotated before it is shown.</para> "
-                                         "<para>Select this option if you always want to set only a flag. "
-                                         "This is less obtrusive, but requires support if the file is accessed with another software. "
-                                         "Ensure to allow setting the flag in the metadata if you want to share your files "
-                                         "outside digiKam.</para>"));
-
-    d->rotateByContents->setToolTip(i18nc("@info:tooltip",
-                                          "If possible rotate files by changing the pixel data"));
-    d->rotateByContents->setWhatsThis(xi18nc("@info:whatsthis",
-                                             "<para>A file can be rotated in two ways:<nl/> "
-                                             "You can change the contents, rearranging the individual pixels of the image data.<nl/> "
-                                             "Or you can set a flag that the file is to be rotated before it is shown.</para> "
-                                             "<para>Select this option if you want the file to be rotated by changing the content. "
-                                             "This is a lossless operation for JPEG files. For other formats it is a lossy operation, "
-                                             "which you need to enable explicitly. "
-                                             "It is not support for RAW and other read-only formats, "
-                                             "which will be rotated by flag only.</para>"));
-
-    d->allowLossyRotate->setToolTip(i18nc("@info:tooltip",
-                                          "Rotate files by changing the pixel data even if the operation will incur quality loss"));
-    d->allowLossyRotate->setWhatsThis(i18nc("@info:whatsthis",
-                                            "For some file formats which apply lossy compression, "
-                                            "data will be lost each time the content is rotated. "
-                                            "Check this option to allow lossy rotation. "
-                                            "If not enabled, these files will be rotated by flag."));
-
-    d->allowRotateByMetadata->setToolTip(i18nc("@info:tooltip",
-                                               "When rotating a file by setting a flag, also change this flag in the file's metadata"));
-    d->allowRotateByMetadata->setWhatsThis(i18nc("@info:whatsthis",
-                                                 "File metadata typically contains a flag describing "
-                                                 "that a file shall be shown rotated. "
-                                                 "Enable this option to allow editing this field. "));
-
-    rotationGroupLayout->addWidget(rotationIcon,             0, 0, 1, 1);
-    rotationGroupLayout->addWidget(rotationExplanation,      0, 1, 1, 2);
-    rotationGroupLayout->addWidget(d->rotateByFlag,          1, 0, 1, 3);
-    rotationGroupLayout->addWidget(d->rotateByContents,      2, 0, 1, 3);
-    rotationGroupLayout->addWidget(d->allowLossyRotate,      3, 2, 1, 1);
-    rotationGroupLayout->addWidget(d->allowRotateByMetadata, 4, 0, 1, 3);
-    rotationGroupLayout->setColumnStretch(3, 10);
-
-    d->rotationGroup->setLayout(rotationGroupLayout);
-
-    // --------------------------------------------------------
-
-    d->rotationAdvGroup                  = new QGroupBox;
-    QGridLayout* const rotationAdvLayout = new QGridLayout;
-
-    QLabel* const rotationAdvExpl        = new QLabel(i18nc("@label", "Rotate actions"));
-    QLabel* const rotationAdvIcon        = new QLabel;
-    rotationAdvIcon->setPixmap(QIcon::fromTheme(QLatin1String("configure")).pixmap(32));
-
-    d->exifRotateBox                     = new QCheckBox;
-    d->exifRotateBox->setText(i18n("Show images/thumbnails &rotated according to orientation tag."));
-    d->exifSetOrientationBox             = new QCheckBox;
-    d->exifSetOrientationBox->setText(i18n("Set orientation tag to normal after rotate/flip."));
-
-    rotationAdvLayout->addWidget(rotationAdvIcon,          0, 0, 1, 1);
-    rotationAdvLayout->addWidget(rotationAdvExpl,          0, 1, 1, 1);
-    rotationAdvLayout->addWidget(d->exifRotateBox,         1, 0, 1, 3);
-    rotationAdvLayout->addWidget(d->exifSetOrientationBox, 2, 0, 1, 3);
-    rotationAdvLayout->setColumnStretch(2, 10);
-    d->rotationAdvGroup->setLayout(rotationAdvLayout);
-
-    // --------------------------------------------------------
-
-    QLabel* const rotationNote = new QLabel(i18n("<b>Note: These settings affect the album view "
-                                                 "and not the image editor. The image editor always "
-                                                 "changes the image data during the rotation.</b>"));
-    rotationNote->setWordWrap(true);
-    rotationNote->setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
-
-    // --------------------------------------------------------
-
-    rotationLayout->addWidget(d->rotationGroup);
-    rotationLayout->addWidget(d->rotationAdvGroup);
-    rotationLayout->addWidget(rotationNote);
-    rotationLayout->addStretch();
-    rotationPanel->setLayout(rotationLayout);
-
-    d->tab->insertTab(Rotation, rotationPanel, i18nc("@title:tab", "Rotation"));
-
-    // --------------------------------------------------------
-
-    QWidget* const displayPanel      = new QWidget;
-    QGridLayout* const displayLayout = new QGridLayout;
-
-    QLabel* const displayLabel       = new QLabel(i18nc("@info:label", "Select Metadata Fields to Be Displayed"));
-
-    QLabel* const displayIcon        = new QLabel;
-    displayIcon->setPixmap(QIcon::fromTheme(QLatin1String("view-list-tree")).pixmap(32));
-
-    d->displaySubTab                 = new QTabWidget;
-    d->tagsCfgPanel                  = new MetadataPanel(d->displaySubTab);
-
-    displayLayout->addWidget(displayIcon,      0, 0);
-    displayLayout->addWidget(displayLabel,     0, 1);
-    displayLayout->addWidget(d->displaySubTab, 1, 0, 1, 3);
-    displayLayout->setColumnStretch(2, 1);
-
-    displayPanel->setLayout(displayLayout);
-    d->tab->insertTab(Display, displayPanel, i18nc("@title:tab", "Views"));
-
-    // --------------------------------------------------------
-
-#ifdef HAVE_KFILEMETADATA
-
-    QWidget* const balooPanel      = new QWidget(d->tab);
-    QVBoxLayout* const balooLayout = new QVBoxLayout(balooPanel);
-
-    QGroupBox* const balooGroup    = new QGroupBox(i18n("Baloo Desktop Search"), balooPanel);
-    QVBoxLayout* const gLayout3    = new QVBoxLayout(balooGroup);
-
-    d->saveToBalooBox              = new QCheckBox;
-    d->saveToBalooBox->setText(i18n("Store metadata from digiKam in Baloo"));
-    d->saveToBalooBox->setWhatsThis(i18n("Turn on this option to push rating, comments and tags "
-                                         "from digiKam into the Baloo storage"));
-
-    d->readFromBalooBox            = new QCheckBox;
-    d->readFromBalooBox->setText(i18n("Read metadata from Baloo"));
-    d->readFromBalooBox->setWhatsThis(i18n("Turn on this option if you want to apply changes to "
-                                           "rating, comments and tags made in Baloo to digiKam's metadata storage. "
-                                           "Please note that image metadata will not be edited automatically."));
-
-    gLayout3->addWidget(d->saveToBalooBox);
-    gLayout3->addWidget(d->readFromBalooBox);
-
-    d->tab->insertTab(Baloo, balooPanel, i18nc("@title:tab", "Baloo"));
-
-    // --------------------------------------------------------
-
-    QFrame* const balooBox         = new QFrame(balooPanel);
-    QGridLayout* const balooGrid   = new QGridLayout(balooBox);
-    balooBox->setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
-
-    QLabel* const balooLogoLabel   = new QLabel;
-    balooLogoLabel->setPixmap(QIcon::fromTheme(QLatin1String("baloo")).pixmap(48));
-
-    QLabel* const balooExplanation = new QLabel(balooBox);
-    balooExplanation->setOpenExternalLinks(true);
-    balooExplanation->setWordWrap(true);
-    QString balootxt;
-
-    balootxt.append(i18n("<p><a href='http://community.kde.org/Baloo'>Baloo</a> "
-                         "provides the basis to handle all kinds of metadata on the KDE desktop in a generic fashion. "
-                         "It allows you to tag, rate and comment your files in KDE applications like Dolphin.</p> "
-                         "<p>Please set here if you want to synchronize the metadata stored by digiKam desktop-wide with the "
-                         "Baloo Desktop Search.</p> "));
-
-    balooExplanation->setText(balootxt);
-
-    balooGrid->addWidget(balooLogoLabel,   0, 0, 1, 1);
-    balooGrid->addWidget(balooExplanation, 0, 1, 1, 2);
-    balooGrid->setColumnStretch(1, 10);
-    balooGrid->setSpacing(0);
-
-    // --------------------------------------------------------
-
-    balooLayout->addWidget(balooGroup);
-    balooLayout->addWidget(balooBox);
-/*
-    balooLayout->addWidget(d->resyncButton, 0, Qt::AlignRight);
-*/
-    balooLayout->addStretch();
-
-#endif // HAVE_KFILEMETADATA
-
-    //--------------Advanced Metadata Configuration --------------
-
-    d->advTab = new AdvancedMetadataTab(this);
-    d->tab->insertTab(AdvancedConfig, d->advTab, i18nc("@title:tab", "Advanced"));
-
-    //------------------------Sidecars-------------------------
-
-    QWidget* const sidecarsPanel      = new QWidget(d->tab);
-    QVBoxLayout* const sidecarsLayout = new QVBoxLayout(sidecarsPanel);
-
-    // --------------------------------------------------------
-
-    QGroupBox* rwSidecarsGroup          = new QGroupBox;
-    QGridLayout* const rwSidecarsLayout = new QGridLayout;
-
-    QLabel* const rwSidecarsLabel       = new QLabel(i18nc("@label", "Reading and Writing to Sidecars"));
-
-    d->readXMPSidecarBox  = new QCheckBox;
-    d->readXMPSidecarBox->setText(i18nc("@option:check", "Read from sidecar files"));
-    d->readXMPSidecarBox->setWhatsThis(i18nc("@info:whatsthis",
-                                             "Turn on this option to read metadata from XMP sidecar files when reading metadata."));
-    d->readXMPSidecarBox->setEnabled(MetaEngine::supportXmp());
-
-    d->writeXMPSidecarBox = new QCheckBox;
-    d->writeXMPSidecarBox->setText(i18nc("@option:check", "Write to sidecar files"));
-    d->writeXMPSidecarBox->setWhatsThis(i18nc("@info:whatsthis",
-                                              "Turn on this option to save, as specified, metadata to XMP sidecar files."));
-    d->writeXMPSidecarBox->setEnabled(MetaEngine::supportXmp());
-
-    d->writingModeCombo   = new QComboBox;
-    d->writingModeCombo->addItem(i18n("Write to XMP sidecar for read-only item only"), MetaEngine::WRITE_TO_SIDECAR_ONLY_FOR_READ_ONLY_FILES);
-    d->writingModeCombo->addItem(i18n("Write to XMP sidecar only"),                    MetaEngine::WRITE_TO_SIDECAR_ONLY);
-    d->writingModeCombo->addItem(i18n("Write to item and XMP Sidecar"),                MetaEngine::WRITE_TO_SIDECAR_AND_FILE);
-    d->writingModeCombo->setToolTip(i18nc("@info:tooltip", "Specify the exact mode of XMP sidecar writing"));
-    d->writingModeCombo->setEnabled(false);
-
-    d->sidecarFileNameBox = new QCheckBox;
-    d->sidecarFileNameBox->setText(i18nc("@option:check", "Sidecar file names are compatible with commercial programs"));
-    d->sidecarFileNameBox->setWhatsThis(i18nc("@info:whatsthis",
-                                              "Turn on this option to create the XMP sidecar files with a compatible "
-                                              "file name (BASENAME.xmp) used by many commercial programs. "
-                                              "For Darktable do not enable this option."));
-    d->sidecarFileNameBox->setEnabled(false);
-
-    connect(d->writeXMPSidecarBox, SIGNAL(toggled(bool)),
-            d->writingModeCombo, SLOT(setEnabled(bool)));
-
-    connect(d->writeXMPSidecarBox, SIGNAL(toggled(bool)),
-            d->sidecarFileNameBox, SLOT(setEnabled(bool)));
-
-    rwSidecarsLayout->addWidget(rwSidecarsLabel,       0, 0, 1, 3);
-    rwSidecarsLayout->addWidget(d->readXMPSidecarBox,  1, 0, 1, 3);
-    rwSidecarsLayout->addWidget(d->writeXMPSidecarBox, 2, 0, 1, 3);
-    rwSidecarsLayout->addWidget(d->writingModeCombo,   3, 1, 1, 2);
-    rwSidecarsLayout->addWidget(d->sidecarFileNameBox, 4, 0, 1, 3);
-    rwSidecarsLayout->setColumnStretch(3, 10);
-    rwSidecarsGroup->setLayout(rwSidecarsLayout);
-
-    // --------------------------------------------------------
-
-    QGroupBox* const extensionsGroup  = new QGroupBox(sidecarsPanel);
-    QGridLayout* const extensionsGrid = new QGridLayout(extensionsGroup);
-
-    QLabel* extensionsGroupLabel = new QLabel(
-                i18n("<p>Add file types to be recognised as sidecars.</p>"
-                     "<p>digiKam (optionally) writes metadata to *.xmp sidecar "
-                     "files. Other programs might use different types, which "
-                     "can be specified below. digiKam will neither display these "
-                     "nor read from or write to them. But whenever a matching album "
-                     "item (e.g. \"image.dng\" for \"image.dng.pp3\") is renamed, "
-                     "moved, copied or deleted, the same operation will be done "
-                     "on these sidecar files.</p>"
-                     "<p>Multiple extensions must be separated by a semicolon "
-                     "or a space.</p>"));
-    extensionsGroupLabel->setWordWrap(true);
-
-    QLabel* const extensionsLogo = new QLabel(extensionsGroup);
-    extensionsLogo->setPixmap(QIcon::fromTheme(QLatin1String("text-x-texinfo")).pixmap(48));
-
-    d->extensionsEdit            = new QLineEdit(extensionsGroup);
-    d->extensionsEdit->setWhatsThis(i18n("<p>Here you can add extra extensions "
-                                         "of sidecars files to be processed alongside "
-                                         "regular items. These files will not be visible, "
-                                         "but regarded as an extension of the main file. "
-                                         "Just write \"xyz abc\" to support files with "
-                                         "the *.xyz and *.abc extensions. The internally "
-                                         "used sidecars type *.xmp is always included.</p>"));
-    d->extensionsEdit->setClearButtonEnabled(true);
-    d->extensionsEdit->setPlaceholderText(i18n("Enter additional sidecars file extensions."));
-
-    QLabel* const extensionsLabel = new QLabel(extensionsGroup);
-    extensionsLabel->setText(i18n("Additional &sidecar file extensions"));
-    extensionsLabel->setBuddy(d->extensionsEdit);
-
-    extensionsGrid->addWidget(extensionsGroupLabel, 0, 0, 1, -1);
-    extensionsGrid->addWidget(extensionsLogo,       1, 0, 2, 1);
-    extensionsGrid->addWidget(extensionsLabel,      1, 1, 1, -1);
-    extensionsGrid->addWidget(d->extensionsEdit,    2, 1, 1, -1);
-    extensionsGrid->setColumnStretch(1, 10);
-
-    // --------------------------------------------------------
-
-    sidecarsLayout->addWidget(rwSidecarsGroup);
-    sidecarsLayout->addWidget(extensionsGroup);
-    sidecarsLayout->addStretch();
-
-    d->tab->insertTab(Sidecars, sidecarsPanel, i18nc("@title:tab", "Sidecars"));
-
-    // --------------------------------------------------------
-
-    readSettings();
-
-    connect(d->exifRotateBox, SIGNAL(toggled(bool)),
-            this, SLOT(slotExifAutoRotateToggled(bool)));
-
-    connect(d->clearMetadataIfRescanBox, SIGNAL(toggled(bool)),
-            this, SLOT(slotClearMetadataToggled(bool)));
-
-    connect(d->writeRawFilesBox, SIGNAL(toggled(bool)),
-            this, SLOT(slotWriteRawFilesToggled(bool)));
-}
-
-SetupMetadata::~SetupMetadata()
-{
-    delete d;
-}
-
-void SetupMetadata::setActiveMainTab(MetadataTab tab)
-{
-    d->tab->setCurrentIndex(tab);
-}
-
-void SetupMetadata::setActiveSubTab(int tab)
-{
-    d->displaySubTab->setCurrentIndex(tab);
-}
-
-void SetupMetadata::applySettings()
-{
-    MetaEngineSettings* const mSettings = MetaEngineSettings::instance();
-
-    if (!mSettings)
-    {
-        return;
-    }
-
-    MetaEngineSettingsContainer set;
-
-    set.rotationBehavior = MetaEngineSettingsContainer::RotateByInternalFlag;
-
-    if (d->allowRotateByMetadata->isChecked())
-    {
-        set.rotationBehavior |= MetaEngineSettingsContainer::RotateByMetadataFlag;
-    }
-
-    if (d->rotateByContents->isChecked())
-    {
-        set.rotationBehavior |= MetaEngineSettingsContainer::RotateByLosslessRotation;
-
-        if (d->allowLossyRotate->isChecked())
-        {
-            set.rotationBehavior |= MetaEngineSettingsContainer::RotateByLossyRotation;
-        }
-    }
-
-    set.exifRotate            = d->exifRotateBox->isChecked();
-    set.exifSetOrientation    = d->exifSetOrientationBox->isChecked();
-
-    set.saveComments          = d->saveCommentsBox->isChecked();
-    set.saveDateTime          = d->saveDateTimeBox->isChecked();
-    set.savePickLabel         = d->savePickLabelBox->isChecked();
-    set.saveColorLabel        = d->saveColorLabelBox->isChecked();
-    set.saveRating            = d->saveRatingBox->isChecked();
-    set.saveTags              = d->saveTagsBox->isChecked();
-    set.saveTemplate          = d->saveTemplateBox->isChecked();
-    set.saveFaceTags          = d->saveFaceTags->isChecked();
-
-    set.useLazySync           = d->useLazySync->isChecked();
-    set.writeRawFiles         = d->writeRawFilesBox->isChecked();
-    set.useXMPSidecar4Reading = d->readXMPSidecarBox->isChecked();
-    set.useCompatibleFileName = d->sidecarFileNameBox->isChecked();
-
-    if (d->writeXMPSidecarBox->isChecked())
-    {
-        set.metadataWritingMode = (MetaEngine::MetadataWritingMode)
-                                  d->writingModeCombo->itemData(d->writingModeCombo->currentIndex()).toInt();
-    }
-    else
-    {
-        set.metadataWritingMode = MetaEngine::WRITE_TO_FILE_ONLY;
-    }
-
-    set.updateFileTimeStamp   = d->updateFileTimeStampBox->isChecked();
-    set.rescanImageIfModified = d->rescanImageIfModifiedBox->isChecked();
-    set.clearMetadataIfRescan = d->clearMetadataIfRescanBox->isChecked();
-
-    set.sidecarExtensions     = cleanUserFilterString(d->extensionsEdit->text());
-    set.sidecarExtensions.removeAll(QLatin1String("xmp"));
-    set.sidecarExtensions.removeDuplicates();
-
-    mSettings->setSettings(set);
-
-
-#ifdef HAVE_KFILEMETADATA
-
-    ApplicationSettings* const aSettings = ApplicationSettings::instance();
-
-    if (!aSettings)
-    {
-        return;
-    }
-
-    aSettings->setSyncDigikamToBaloo(d->saveToBalooBox->isChecked());
-    aSettings->setSyncBalooToDigikam(d->readFromBalooBox->isChecked());
-
-    aSettings->saveSettings();
-
-#endif // HAVE_KFILEMETADATA
-
-    d->tagsCfgPanel->applySettings();
-
-    d->advTab->applySettings();
-}
-
-void SetupMetadata::readSettings()
-{
-    MetaEngineSettings* const mSettings = MetaEngineSettings::instance();
-
-    if (!mSettings)
-    {
-        return;
-    }
-
-    MetaEngineSettingsContainer set = mSettings->settings();
-
-    if (set.rotationBehavior & MetaEngineSettingsContainer::RotatingPixels)
-    {
-        d->rotateByContents->setChecked(true);
-    }
-    else
-    {
-        d->rotateByFlag->setChecked(true);
-    }
-
-    d->allowRotateByMetadata->setChecked(set.rotationBehavior & MetaEngineSettingsContainer::RotateByMetadataFlag);
-    d->allowLossyRotate->setChecked(set.rotationBehavior & MetaEngineSettingsContainer::RotateByLossyRotation);
-
-    d->exifAutoRotateOriginal       = set.exifRotate;
-    d->exifRotateBox->setChecked(d->exifAutoRotateOriginal);
-    d->exifSetOrientationBox->setChecked(set.exifSetOrientation);
-
-    d->saveTagsBox->setChecked(set.saveTags);
-    d->saveCommentsBox->setChecked(set.saveComments);
-    d->saveRatingBox->setChecked(set.saveRating);
-    d->savePickLabelBox->setChecked(set.savePickLabel);
-    d->saveColorLabelBox->setChecked(set.saveColorLabel);
-    d->saveDateTimeBox->setChecked(set.saveDateTime);
-    d->saveTemplateBox->setChecked(set.saveTemplate);
-    d->saveFaceTags->setChecked(set.saveFaceTags);
-
-    d->useLazySync->setChecked(set.useLazySync);
-    d->writeRawFilesBox->setChecked(set.writeRawFiles);
-    d->readXMPSidecarBox->setChecked(set.useXMPSidecar4Reading);
-    d->sidecarFileNameBox->setChecked(set.useCompatibleFileName);
-    d->updateFileTimeStampBox->setChecked(set.updateFileTimeStamp);
-    d->rescanImageIfModifiedBox->setChecked(set.rescanImageIfModified);
-    d->clearMetadataIfRescanBox->setChecked(set.clearMetadataIfRescan);
-
-    if (set.metadataWritingMode == MetaEngine::WRITE_TO_FILE_ONLY)
-    {
-        d->writeXMPSidecarBox->setChecked(false);
-    }
-    else
-    {
-        d->writeXMPSidecarBox->setChecked(true);
-        d->writingModeCombo->setCurrentIndex(d->writingModeCombo->findData(set.metadataWritingMode));
-    }
-
-    d->extensionsEdit->setText(set.sidecarExtensions.join(QLatin1Char(' ')));
-
-#ifdef HAVE_KFILEMETADATA
-
-    ApplicationSettings* const aSettings = ApplicationSettings::instance();
-
-    if (!aSettings)
-    {
-        return;
-    }
-
-    d->saveToBalooBox->setChecked(aSettings->getSyncDigikamToBaloo());
-    d->readFromBalooBox->setChecked(aSettings->getSyncBalooToDigikam());
-
-#endif // HAVE_KFILEMETADATA
-
-}
-
-bool SetupMetadata::exifAutoRotateHasChanged() const
-{
-    return (d->exifAutoRotateOriginal != d->exifRotateBox->isChecked());
-}
-
-void SetupMetadata::slotExifAutoRotateToggled(bool b)
-{
-    // Show info if rotation was switched off, and only once.
-
-    if (!b && !d->exifAutoRotateShowedInfo && exifAutoRotateHasChanged())
-    {
-        d->exifAutoRotateShowedInfo = true;
-        QMessageBox::information(this, qApp->applicationName(),
-                                 i18nc("@info",
-                                       "Switching off exif auto rotation will most probably show "
-                                       "your images in a wrong orientation, so only change this "
-                                       "option if you explicitly require this."));
-    }
-}
-
-void SetupMetadata::slotClearMetadataToggled(bool b)
-{
-    // Show info if delete metadata from the database was switched on, and only once.
-
-    if (b && !d->clearMetadataShowedInfo)
-    {
-        d->clearMetadataShowedInfo = true;
-        QMessageBox::information(this, qApp->applicationName(),
-                                 i18nc("@info",
-                                       "Switching on this option and your metadata has been written to the "
-                                       "database only and not to the file or sidecar, you will be able to "
-                                       "lose inserted metadata such as tags, keywords, or geographic "
-                                       "coordinates."));
-    }
-}
-
-void SetupMetadata::slotWriteRawFilesToggled(bool b)
-{
-    // Show info if write metadata to raw files was switched on
-
-    if (b)
-    {
-        QApplication::beep();
-
-        QPointer<QMessageBox> msgBox = new QMessageBox(QMessageBox::Warning,<--- Shadowed declaration
-                 qApp->applicationName(),
-                 i18n("<p><b>Do you really want to enable metadata writing to RAW files?</b></p>"
-                      "<p>DigiKam delegates this task to the Exiv2 library. With different RAW "
-                      "formats, problems are known which can lead to the destruction of RAW "
-                      "files. If you decide to do so, make a backup of your RAW files.</p>"
-                      "<p><b>We strongly recommend not to enable this option.</b></p>"),
-                 QMessageBox::Yes | QMessageBox::No, this);
-
-        msgBox->button(QMessageBox::Yes)->setText(i18n("Yes I understand"));
-        msgBox->setDefaultButton(QMessageBox::No);
-
-        int result1 = msgBox->exec();
-        delete msgBox;
-
-        if (result1 == QMessageBox::Yes)
-        {
-            QPointer<QMessageBox> msgBox = new QMessageBox(QMessageBox::Warning,<--- Shadow variable
-                     qApp->applicationName(),
-                     i18n("You would rather disable writing metadata to RAW files?"),
-                     QMessageBox::Yes | QMessageBox::No, this);
-
-            int result2 = msgBox->exec();
-            delete msgBox;
-
-            if (result2 == QMessageBox::No)
-            {
-                return;
-            }
-        }
-
-        d->writeRawFilesBox->setChecked(false);
-    }
-}
-
-} // namespace Digikam
-
-
-
- - - diff --git a/static/reports/cppcheck/master/2.html b/static/reports/cppcheck/master/2.html index 0c67d0457..0fb0bab01 100644 --- a/static/reports/cppcheck/master/2.html +++ b/static/reports/cppcheck/master/2.html @@ -1,1245 +1,1319 @@ - Cppcheck - HTML report - digiKam-master-rev-907aafb5fa + Cppcheck - HTML report - digiKam-master-rev-e85fcd090f
  1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
-550
/* ============================================================
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
/* ============================================================
  *
  * This file is a part of digiKam project
  * https://www.digikam.org
  *
- * Date        : 2007-10-24
- * Description : XMP workflow status properties settings page.
+ * Date        : 2018-05-20
+ * Description : a tool to export images to Onedrive web service
  *
- * Copyright (C) 2007-2020 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ * Copyright (C) 2018      by Tarek Talaat <tarektalaat93 at gmail dot com>
  *
  * This program is free software; you can redistribute it
  * and/or modify it under the terms of the GNU General
  * Public License as published by the Free Software Foundation;
  * either version 2, or (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
  *
  * ============================================================ */
 
-#include "xmpproperties.h"
+#include "odtalker.h"
 
 // Qt includes
 
-#include <QCheckBox>
-#include <QPushButton>
-#include <QGridLayout>
-#include <QApplication>
-#include <QStyle>
-#include <QComboBox>
-#include <QLineEdit>
-#include <QTextEdit>
-
-// KDE includes
-
-#include <klocalizedstring.h>
-
-// Local includes
-
-#include "dlayoutbox.h"
-#include "squeezedcombobox.h"
-#include "digikam_debug.h"
-#include "altlangstringedit.h"
-#include "metadatacheckbox.h"
-#include "multivaluesedit.h"
-#include "objectattributesedit.h"
-#include "dmetadata.h"
-#include "dexpanderbox.h"
-
-using namespace Digikam;
-
-namespace DigikamGenericMetadataEditPlugin
-{
-
-class Q_DECL_HIDDEN XMPProperties::Private
-{
-public:
-
-    explicit Private()
-    {
-        priorityCB           = nullptr;
-        objectTypeCB         = nullptr;
-        priorityCheck        = nullptr;
-        objectAttributeCheck = nullptr;
-        sceneEdit            = nullptr;
-        objectTypeEdit       = nullptr;
-        objectAttributeEdit  = nullptr;
-        objectAttributeCB    = nullptr;
-        languageEdit         = nullptr;
-        originalTransEdit    = nullptr;
-        originalTransCheck   = nullptr;
+#include <QJsonDocument>
+#include <QJsonParseError>
+#include <QJsonObject>
+#include <QJsonValue>
+#include <QJsonArray>
+#include <QByteArray>
+#include <QList>
+#include <QPair>
+#include <QFileInfo>
+#include <QWidget>
+#include <QMessageBox>
+#include <QApplication>
+#include <QMimeDatabase>
+#include <QDesktopServices>
+#include <QUrlQuery>
+#include <QNetworkAccessManager>
+
+// KDE includes
+
+#include <klocalizedstring.h>
+#include <kwindowconfig.h>
+
+// Local includes
+
+#include "digikam_debug.h"
+#include "digikam_version.h"
+#include "wstoolutils.h"
+#include "odwindow.h"
+#include "oditem.h"
+#include "odmpform.h"
+#include "webbrowserdlg.h"
+#include "previewloadthread.h"
+
+namespace DigikamGenericOneDrivePlugin
+{
+
+class Q_DECL_HIDDEN ODTalker::Private
+{
+public:
+
+    enum State
+    {
+        OD_USERNAME = 0,
+        OD_LISTFOLDERS,
+        OD_CREATEFOLDER,
+        OD_ADDPHOTO
+    };
 
-        sceneCodeMap.insert( QLatin1String("010100"), i18n("Headshot") );
-        sceneCodeMap.insert( QLatin1String("010200"), i18n("Half-length") );
-        sceneCodeMap.insert( QLatin1String("010300"), i18n("Full-length") );
-        sceneCodeMap.insert( QLatin1String("010400"), i18nc("Side view of a person", "Profile") );
-        sceneCodeMap.insert( QLatin1String("010500"), i18n("Rear view") );
-        sceneCodeMap.insert( QLatin1String("010600"), i18n("Single") );
-        sceneCodeMap.insert( QLatin1String("010700"), i18n("Couple") );
-        sceneCodeMap.insert( QLatin1String("010800"), i18n("Two") );
-        sceneCodeMap.insert( QLatin1String("010900"), i18nc("group of people", "Group") );
-        sceneCodeMap.insert( QLatin1String("011000"), i18n("General view") );
-        sceneCodeMap.insert( QLatin1String("011100"), i18n("Panoramic view") );
-        sceneCodeMap.insert( QLatin1String("011200"), i18n("Aerial view") );
-        sceneCodeMap.insert( QLatin1String("011300"), i18n("Under-water") );
-        sceneCodeMap.insert( QLatin1String("011400"), i18n("Night scene") );
-        sceneCodeMap.insert( QLatin1String("011500"), i18n("Satellite") );
-        sceneCodeMap.insert( QLatin1String("011600"), i18n("Exterior view") );
-        sceneCodeMap.insert( QLatin1String("011700"), i18n("Interior view") );
-        sceneCodeMap.insert( QLatin1String("011800"), i18n("Close-up") );
-        sceneCodeMap.insert( QLatin1String("011900"), i18n("Action") );
-        sceneCodeMap.insert( QLatin1String("012000"), i18n("Performing") );
-        sceneCodeMap.insert( QLatin1String("012100"), i18n("Posing") );
-        sceneCodeMap.insert( QLatin1String("012200"), i18n("Symbolic") );
-        sceneCodeMap.insert( QLatin1String("012300"), i18n("Off-beat") );
-        sceneCodeMap.insert( QLatin1String("012400"), i18n("Movie scene") );
-
-        typeCodeMap.insert( QLatin1String("Advisory"),           i18n("Advisory") );
-        typeCodeMap.insert( QLatin1String("Alert"),              i18n("Alert") );
-        typeCodeMap.insert( QLatin1String("Catalog"),            i18n("Catalog") );
-        typeCodeMap.insert( QLatin1String("Data"),               i18n("Data") );
-        typeCodeMap.insert( QLatin1String("Document"),           i18nc("type is a document", "Document") );
-        typeCodeMap.insert( QLatin1String("DTD"),                i18n("DTD") );
-        typeCodeMap.insert( QLatin1String("Maintenance"),        i18n("Maintenance") );
-        typeCodeMap.insert( QLatin1String("News"),               i18n("News") );
-        typeCodeMap.insert( QLatin1String("NewsManagementMode"), i18n("News Management Mode") );
-        typeCodeMap.insert( QLatin1String("Package"),            i18n("Package") );
-        typeCodeMap.insert( QLatin1String("Schema"),             i18n("Schema") );
-        typeCodeMap.insert( QLatin1String("Topic"),              i18n("Topic") );
-        typeCodeMap.insert( QLatin1String("TopicSet"),           i18n("Topic Set") );
+public:
+
+    explicit Private()
+      : state(OD_USERNAME),
+        parent(nullptr),
+        netMngr(nullptr),
+        reply(nullptr),
+        settings(nullptr),
+        browser(nullptr)
+    {
+        clientId     = QLatin1String("4c20a541-2ca8-4b98-8847-a375e4d33f34");
+        clientSecret = QLatin1String("wtdcaXADCZ0|tcDA7633|@*");
+
+        authUrl      = QLatin1String("https://login.live.com/oauth20_authorize.srf");
+        tokenUrl     = QLatin1String("https://login.live.com/oauth20_token.srf");
+        scope        = QLatin1String("Files.ReadWrite User.Read");
+        redirectUrl  = QLatin1String("https://login.live.com/oauth20_desktop.srf");
+        serviceName  = QLatin1String("Onedrive");
+        serviceTime  = QLatin1String("token_time");
+        serviceKey   = QLatin1String("access_token");
+    }
+
+public:
+
+    QString                         clientId;
+    QString                         clientSecret;
+    QString                         authUrl;
+    QString                         tokenUrl;
+    QString                         scope;
+    QString                         redirectUrl;
+    QString                         accessToken;
+    QString                         serviceName;
+    QString                         serviceTime;
+    QString                         serviceKey;
+
+    QDateTime                       expiryTime;
+
+    State                           state;
 
-        DMetadata::CountryCodeMap map = DMetadata::countryCodeMap();
+    QWidget*                        parent;
 
-        for (DMetadata::CountryCodeMap::Iterator it = map.begin() ; it != map.end() ; ++it)
-        {
-            languageCodeMap.insert(it.key(), it.value());
-        }
-    }
-
-    typedef QMap<QString, QString>  SceneCodeMap;
-    typedef QMap<QString, QString>  TypeCodeMap;
-    typedef QMap<QString, QString>  LanguageCodeMap;
-
-    SceneCodeMap                    sceneCodeMap;
-    TypeCodeMap                     typeCodeMap;
-    LanguageCodeMap                 languageCodeMap;
-
-    QCheckBox*                      originalTransCheck;
-
-    QComboBox*                      priorityCB;
-    QComboBox*                      objectTypeCB;
-
-    QLineEdit*                      objectAttributeEdit;
-    QLineEdit*                      originalTransEdit;
-
-    MetadataCheckBox*               priorityCheck;
-    MetadataCheckBox*               objectAttributeCheck;
-
-    MultiValuesEdit*                sceneEdit;
-    MultiValuesEdit*                objectTypeEdit;
-    MultiValuesEdit*                languageEdit;
-
-    SqueezedComboBox*               objectAttributeCB;
-};
-
-XMPProperties::XMPProperties(QWidget* const parent)
-    : QWidget(parent),
-      d(new Private)
-{
-    QGridLayout* const grid = new QGridLayout(this);
-
-    // --------------------------------------------------------
+    QNetworkAccessManager*          netMngr;
+    QNetworkReply*                  reply;
+
+    QSettings*                      settings;
+
+    WebBrowserDlg*                  browser;
+
+    QList<QPair<QString, QString> > folderList;
+    QList<QString>                  nextFolder;
+};
+
+ODTalker::ODTalker(QWidget* const parent)
+    : d(new Private)
+{
+    d->parent   = parent;
+    d->netMngr  = new QNetworkAccessManager(this);
+    d->settings = WSToolUtils::getOauthSettings(this);
+
+    connect(this, SIGNAL(oneDriveLinkingFailed()),
+            this, SLOT(slotLinkingFailed()));
+
+    connect(this, SIGNAL(oneDriveLinkingSucceeded()),
+            this, SLOT(slotLinkingSucceeded()));
+
+    connect(d->netMngr, SIGNAL(finished(QNetworkReply*)),
+            this, SLOT(slotFinished(QNetworkReply*)));
+}
+
+ODTalker::~ODTalker()
+{
+    if (d->reply)
+    {
+        d->reply->abort();
+    }
+
+    WSToolUtils::removeTemporaryDir("onedrive");
+
+    delete d;
+}
 
-    d->languageEdit = new MultiValuesEdit(this, i18n("Language:"),
-                          i18n("Select here the language of content."));
-
-    QStringList list;
-
-    for (Private::LanguageCodeMap::Iterator it = d->languageCodeMap.begin();
-         it != d->languageCodeMap.end(); ++it)
-        list.append(QString::fromUtf8("%1 - %2").arg(it.key()).arg(it.value()));
-
-    d->languageEdit->setData(list);
-
-    // --------------------------------------------------------
-
-    d->priorityCheck = new MetadataCheckBox(i18n("Priority:"), this);
-    d->priorityCB    = new QComboBox(this);
-    d->priorityCB->insertItem(0, i18nc("editorial urgency of content", "0: None"));
-    d->priorityCB->insertItem(1, i18nc("editorial urgency of content", "1: High"));
-    d->priorityCB->insertItem(2, QLatin1String("2"));
-    d->priorityCB->insertItem(3, QLatin1String("3"));
-    d->priorityCB->insertItem(4, QLatin1String("4"));
-    d->priorityCB->insertItem(5, i18nc("editorial urgency of content", "5: Normal"));
-    d->priorityCB->insertItem(6, QLatin1String("6"));
-    d->priorityCB->insertItem(7, QLatin1String("7"));
-    d->priorityCB->insertItem(8, i18nc("editorial urgency of content", "8: Low"));
-    d->priorityCB->insertItem(9, i18nc("editorial urgency of content", "9: User-defined"));
-    d->priorityCB->setWhatsThis(i18n("Select here the editorial urgency of content."));
-
-    // --------------------------------------------------------
+void ODTalker::link()
+{
+    emit signalBusy(true);
+
+    QUrl url(d->authUrl);
+    QUrlQuery query(url);
+    query.addQueryItem(QLatin1String("client_id"), d->clientId);
+    query.addQueryItem(QLatin1String("scope"), d->scope);
+    query.addQueryItem(QLatin1String("redirect_uri"), d->redirectUrl);
+    query.addQueryItem(QLatin1String("response_type"), QLatin1String("token"));
+    url.setQuery(query);
+
+    delete d->browser;
+    d->browser = new WebBrowserDlg(url, d->parent, true);
+    d->browser->setModal(true);
+
+    connect(d->browser, SIGNAL(urlChanged(QUrl)),
+            this, SLOT(slotCatchUrl(QUrl)));
+
+    connect(d->browser, SIGNAL(closeView(bool)),
+            this, SIGNAL(signalBusy(bool)));
+
+    d->browser->show();
+}
+
+void ODTalker::unLink()
+{
+    d->accessToken = QString();
 
-    d->sceneEdit = new MultiValuesEdit(this, i18n("Scene:"),
-                       i18n("Select here the scene type of the content."));
-
-    QStringList list2;
-
-    for (Private::SceneCodeMap::Iterator it = d->sceneCodeMap.begin();
-         it != d->sceneCodeMap.end(); ++it)
-        list2.append(QString::fromUtf8("%1 - %2").arg(it.key()).arg(it.value()));
-
-    d->sceneEdit->setData(list2);
+    d->settings->beginGroup(d->serviceName);
+    d->settings->remove(QString());
+    d->settings->endGroup();
+
+    emit oneDriveLinkingSucceeded();
+}
+
+void ODTalker::slotCatchUrl(const QUrl& url)
+{
+    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Received URL from webview:" << url;
 
-    // --------------------------------------------------------
-
-    d->objectTypeEdit = new MultiValuesEdit(this, i18n("Type:"),
-                            i18n("Select here the editorial type of the content."));
-
-    QStringList list3;
-
-    for (Private::TypeCodeMap::Iterator it = d->typeCodeMap.begin();
-         it != d->typeCodeMap.end(); ++it)
-        list3.append(it.value());
+    QString   str = url.toString();
+    QUrlQuery query(str.section(QLatin1Char('#'), -1, -1));
+
+    if (query.hasQueryItem(QLatin1String("access_token")))
+    {
+        d->accessToken = query.queryItemValue(QLatin1String("access_token"));
+        int seconds    = query.queryItemValue(QLatin1String("expires_in")).toInt();
+        d->expiryTime  = QDateTime::currentDateTime().addSecs(seconds);
+
+        writeSettings();
 
-    d->objectTypeEdit->setData(list3);
-
-    // --------------------------------------------------------
-
-    d->objectAttributeCheck = new MetadataCheckBox(i18n("Attribute:"), this);
-    d->objectAttributeCB    = new SqueezedComboBox(this);
-    d->objectAttributeEdit  = new QLineEdit(this);
-    d->objectAttributeEdit->setClearButtonEnabled(true);
-    d->objectAttributeEdit->setWhatsThis(i18n("Set here the editorial attribute description of the content."));
-
-    d->objectAttributeCB->setWhatsThis(i18n("Select here the editorial attribute of the content."));
-    d->objectAttributeCB->addSqueezedItem(QLatin1String("001 - ") + i18nc("editorial content attribute", "Current"));
-    d->objectAttributeCB->addSqueezedItem(QLatin1String("002 - ") + i18nc("editorial content attribute", "Analysis"));
-    d->objectAttributeCB->addSqueezedItem(QLatin1String("003 - ") + i18nc("editorial content attribute", "Archive material"));
-    d->objectAttributeCB->addSqueezedItem(QLatin1String("004 - ") + i18nc("editorial content attribute", "Background"));
-    d->objectAttributeCB->addSqueezedItem(QLatin1String("005 - ") + i18nc("editorial content attribute", "Feature"));
-    d->objectAttributeCB->addSqueezedItem(QLatin1String("006 - ") + i18nc("editorial content attribute", "Forecast"));
-    d->objectAttributeCB->addSqueezedItem(QLatin1String("007 - ") + i18nc("editorial content attribute", "History"));
-    d->objectAttributeCB->addSqueezedItem(QLatin1String("008 - ") + i18nc("editorial content attribute", "Obituary"));
-    d->objectAttributeCB->addSqueezedItem(QLatin1String("009 - ") + i18nc("editorial content attribute", "Opinion"));
-    d->objectAttributeCB->addSqueezedItem(QLatin1String("010 - ") + i18nc("editorial content attribute", "Polls & Surveys"));
-    d->objectAttributeCB->addSqueezedItem(QLatin1String("011 - ") + i18nc("editorial content attribute", "Profile"));
-    d->objectAttributeCB->addSqueezedItem(QLatin1String("012 - ") + i18nc("editorial content attribute", "Results Listings & Table"));
-    d->objectAttributeCB->addSqueezedItem(QLatin1String("013 - ") + i18nc("editorial content attribute", "Side bar & Supporting information"));
-    d->objectAttributeCB->addSqueezedItem(QLatin1String("014 - ") + i18nc("editorial content attribute", "Summary"));
-    d->objectAttributeCB->addSqueezedItem(QLatin1String("015 - ") + i18nc("editorial content attribute", "Transcript & Verbatim"));
-    d->objectAttributeCB->addSqueezedItem(QLatin1String("016 - ") + i18nc("editorial content attribute", "Interview"));
-    d->objectAttributeCB->addSqueezedItem(QLatin1String("017 - ") + i18nc("editorial content attribute", "From the Scene"));
-    d->objectAttributeCB->addSqueezedItem(QLatin1String("018 - ") + i18nc("editorial content attribute", "Retrospective"));
-    d->objectAttributeCB->addSqueezedItem(QLatin1String("019 - ") + i18nc("editorial content attribute", "Statistics"));
-    d->objectAttributeCB->addSqueezedItem(QLatin1String("020 - ") + i18nc("editorial content attribute", "Update"));
-    d->objectAttributeCB->addSqueezedItem(QLatin1String("021 - ") + i18nc("editorial content attribute", "Wrap-up"));
-    d->objectAttributeCB->addSqueezedItem(QLatin1String("022 - ") + i18nc("editorial content attribute", "Press Release"));
+        qDebug(DIGIKAM_WEBSERVICES_LOG) << "Access token received";
+        emit oneDriveLinkingSucceeded();
+    }
+    else
+    {
+        emit oneDriveLinkingFailed();
+    }
+}
+
+void ODTalker::slotLinkingFailed()
+{
+    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "LINK to Onedrive fail";
+    emit signalBusy(false);
+}
+
+void ODTalker::slotLinkingSucceeded()
+{
+    if (d->accessToken.isEmpty())
+    {
+        qCDebug(DIGIKAM_WEBSERVICES_LOG) << "UNLINK to Onedrive";
+        emit signalBusy(false);
+        return;
+    }
+
+    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "LINK to Onedrive";
+
+    if (d->browser)
+    {
+        d->browser->close();
+    }
+
+    emit signalLinkingSucceeded();
+}
 
-    // --------------------------------------------------------
-
-    d->originalTransCheck = new QCheckBox(i18n("Reference:"), this);
-    d->originalTransEdit  = new QLineEdit(this);
-    d->originalTransEdit->setClearButtonEnabled(true);
-    d->originalTransEdit->setWhatsThis(i18n("Set here the original content transmission reference."));
-
-    // --------------------------------------------------------
-
-    grid->addWidget(d->languageEdit,                        0, 0, 1, 5);
-    grid->addWidget(d->priorityCheck,                       1, 0, 1, 1);
-    grid->addWidget(d->priorityCB,                          1, 1, 1, 1);
-    grid->addWidget(d->sceneEdit,                           2, 0, 1, 5);
-    grid->addWidget(d->objectTypeEdit,                      3, 0, 1, 5);
-    grid->addWidget(new DLineWidget(Qt::Horizontal, this),  4, 0, 1, 5);
-    grid->addWidget(d->objectAttributeCheck,                5, 0, 1, 1);
-    grid->addWidget(d->objectAttributeCB,                   5, 1, 1, 2);
-    grid->addWidget(d->objectAttributeEdit,                 5, 3, 1, 2);
-    grid->addWidget(new DLineWidget(Qt::Horizontal, this),  6, 0, 1, 5);
-    grid->addWidget(d->originalTransCheck,                  7, 0, 1, 1);
-    grid->addWidget(d->originalTransEdit,                   7, 1, 1, 4);
-    grid->setRowStretch(8, 10);
-    grid->setColumnStretch(4, 10);
-    grid->setContentsMargins(QMargins());
-    grid->setSpacing(QApplication::style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing));
-
-    // --------------------------------------------------------
-
-    connect(d->priorityCheck, SIGNAL(toggled(bool)),
-            d->priorityCB, SLOT(setEnabled(bool)));
-
-    connect(d->objectAttributeCheck, SIGNAL(toggled(bool)),
-            d->objectAttributeCB, SLOT(setEnabled(bool)));
+bool ODTalker::authenticated()
+{
+    return (!d->accessToken.isEmpty());
+}
+
+void ODTalker::cancel()
+{
+    if (d->reply)
+    {
+        d->reply->abort();
+        d->reply = nullptr;
+    }
+
+    emit signalBusy(false);
+}
+
+void ODTalker::createFolder(QString& path)
+{
+    //path also has name of new folder so send path parameter accordingly
+    QString name       = QUrl(path).fileName();
+    QString folderPath = QUrl(path).adjusted(QUrl::RemoveFilename |
+                                             QUrl::StripTrailingSlash).path();
+
+    QUrl url;
+
+    if (folderPath == QLatin1String("/"))
+    {
+        url = QUrl(QLatin1String("https://graph.microsoft.com/v1.0/me/drive/root/children"));
+    }
+    else
+    {
+        url = QUrl(QString::fromUtf8("https://graph.microsoft.com/v1.0/me/drive/root:/%1:/children").arg(folderPath));
+    }
 
-    connect(d->objectAttributeCheck, SIGNAL(toggled(bool)),
-            d->objectAttributeEdit, SLOT(setEnabled(bool)));
-
-    connect(d->originalTransCheck, SIGNAL(toggled(bool)),
-            d->originalTransEdit, SLOT(setEnabled(bool)));
-
-    // --------------------------------------------------------
-
-    connect(d->languageEdit, SIGNAL(signalModified()),
-            this, SIGNAL(signalModified()));
+    QNetworkRequest netRequest(url);
+    netRequest.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("application/json"));
+    netRequest.setRawHeader("Authorization", QString::fromLatin1("bearer %1").arg(d->accessToken).toUtf8());
+
+    QByteArray postData = QString::fromUtf8("{\"name\": \"%1\",\"folder\": {}}").arg(name).toUtf8();
+    d->reply = d->netMngr->post(netRequest, postData);
+
+    d->state = Private::OD_CREATEFOLDER;
+    emit signalBusy(true);
+}
 
-    connect(d->priorityCheck, SIGNAL(toggled(bool)),
-            this, SIGNAL(signalModified()));
-
-    connect(d->sceneEdit, SIGNAL(signalModified()),
-            this, SIGNAL(signalModified()));
-
-    connect(d->objectTypeEdit, SIGNAL(signalModified()),
-            this, SIGNAL(signalModified()));
-
-    connect(d->objectAttributeCheck, SIGNAL(toggled(bool)),
-            this, SIGNAL(signalModified()));
-
-    connect(d->originalTransCheck, SIGNAL(toggled(bool)),
-            this, SIGNAL(signalModified()));
-
-    // --------------------------------------------------------
-
-    connect(d->priorityCB, SIGNAL(activated(int)),
-            this, SIGNAL(signalModified()));
-
-    connect(d->objectAttributeCB, SIGNAL(activated(int)),
-            this, SIGNAL(signalModified()));
-
-    connect(d->objectAttributeEdit, SIGNAL(textChanged(QString)),
-            this, SIGNAL(signalModified()));
-
-    connect(d->originalTransEdit, SIGNAL(textChanged(QString)),
-            this, SIGNAL(signalModified()));
-}
-
-XMPProperties::~XMPProperties()
-{
-    delete d;
-}
-
-void XMPProperties::readMetadata(QByteArray& xmpData)
-{
-    blockSignals(true);
-    DMetadata meta;
-    meta.setXmp(xmpData);
-
-    int         val;
-    QString     data;<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration
-    QStringList code, list, list2;
-    QString     dateStr, timeStr;
-    DMetadata::AltLangMap map;
-
-    // ---------------------------------------------------------------
-
-    code = meta.getXmpTagStringBag("Xmp.dc.language", false);
-
-    for (QStringList::Iterator it = code.begin(); it != code.end(); ++it)
-    {
-        QStringList data = d->languageEdit->getData();<--- Shadow variable
-        QStringList::Iterator it2;
-
-        for (it2 = data.begin(); it2 != data.end(); ++it2)
-        {
-            if ((*it2).left(2) == (*it))
-            {
-                list.append(*it2);
-                break;
-            }
-        }
-
-        if (it2 == data.end())
-            d->languageEdit->setValid(false);
-    }
-
-    d->languageEdit->setValues(list);
-
-    // ---------------------------------------------------------------
-
-    d->priorityCB->setCurrentIndex(0);
-    d->priorityCheck->setChecked(false);
-    data = meta.getXmpTagString("Xmp.photoshop.Urgency", false);
+void ODTalker::getUserName()
+{
+    QUrl url(QLatin1String("https://graph.microsoft.com/v1.0/me"));
+
+    QNetworkRequest netRequest(url);
+    netRequest.setRawHeader("Authorization", QString::fromLatin1("bearer %1").arg(d->accessToken).toUtf8());
+    netRequest.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("application/json"));
+
+    d->reply = d->netMngr->get(netRequest);
+    d->state = Private::OD_USERNAME;
+    emit signalBusy(true);
+}
+
+/** Get list of folders by parsing json sent by onedrive
+ */
+void ODTalker::listFolders(const QString& folder)
+{
+    QString nextFolder;
+
+    if (folder.isEmpty())
+    {
+        d->folderList.clear();
+        d->nextFolder.clear();
+    }
+    else
+    {
+        nextFolder = QLatin1Char(':') + folder + QLatin1Char(':');
+    }
+
+    QUrl url(QString::fromLatin1("https://graph.microsoft.com/v1.0/me/drive/root%1/"
+                                 "children?select=name,folder,path,parentReference").arg(nextFolder));
+
+    QNetworkRequest netRequest(url);
+    netRequest.setRawHeader("Authorization", QString::fromLatin1("bearer %1").arg(d->accessToken).toUtf8());
+    netRequest.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("application/json"));
+
+    d->reply = d->netMngr->get(netRequest);
+
+    d->state = Private::OD_LISTFOLDERS;
+    emit signalBusy(true);
+}
+
+bool ODTalker::addPhoto(const QString& imgPath, const QString& uploadFolder, bool rescale, int maxDim, int imageQuality)
+{
+    if (d->reply)
+    {
+        d->reply->abort();
+        d->reply = nullptr;
+    }
+
+    emit signalBusy(true);
+
+    ODMPForm form;
+    QString path = imgPath;
+
+    QMimeDatabase mimeDB;
+
+    if (mimeDB.mimeTypeForFile(imgPath).name().startsWith(QLatin1String("image/")))
+    {
+        QImage image = PreviewLoadThread::loadHighQualitySynchronously(imgPath).copyQImage();
+
+        if (image.isNull())
+        {
+            emit signalBusy(false);
+            return false;
+        }
+
+        path = WSToolUtils::makeTemporaryDir("onedrive").filePath(QFileInfo(imgPath)
+                                             .baseName().trimmed() + QLatin1String(".jpg"));
+
+        if (rescale && (image.width() > maxDim || image.height() > maxDim))
+        {
+            image = image.scaled(maxDim, maxDim, Qt::KeepAspectRatio, Qt::SmoothTransformation);
+        }
+
+        image.save(path, "JPEG", imageQuality);
 
-    if (!data.isNull())
-    {
-        val = data.toInt();
-
-        if (val >= 0 && val <= 9)
-        {
-            d->priorityCB->setCurrentIndex(val);
-            d->priorityCheck->setChecked(true);
+        DMetadata meta;
+
+        if (meta.load(imgPath))
+        {
+            meta.setItemDimensions(image.size());
+            meta.setItemOrientation(DMetadata::ORIENTATION_NORMAL);
+            meta.setMetadataWritingMode((int)DMetadata::WRITE_TO_FILE_ONLY);
+            meta.save(path, true);
         }
-        else
-            d->priorityCheck->setValid(false);
-    }
-
-    d->priorityCB->setEnabled(d->priorityCheck->isChecked());
-
-    // ---------------------------------------------------------------
+    }
+
+    if (!form.addFile(path))
+    {
+        emit signalBusy(false);
+        return false;
+    }
 
-    code = meta.getXmpTagStringBag("Xmp.iptc.Scene", false);
-
-    for (QStringList::Iterator it = code.begin(); it != code.end(); ++it)
-    {
-        QStringList data = d->sceneEdit->getData();<--- Shadow variable
-        QStringList::Iterator it2;
+    QString uploadPath = uploadFolder + QUrl(imgPath).fileName();
+    QUrl url(QString::fromLatin1("https://graph.microsoft.com/v1.0/me/drive/root:/%1:/content").arg(uploadPath));
+
+    QNetworkRequest netRequest(url);
+    netRequest.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("application/octet-stream"));
+    netRequest.setRawHeader("Authorization", QString::fromLatin1("bearer {%1}").arg(d->accessToken).toUtf8());
 
-        for (it2 = data.begin(); it2 != data.end(); ++it2)
-        {
-            if ((*it2).left(6) == (*it))
-            {
-                list.append(*it2);
-                break;
-            }
-        }
-
-        if (it2 == data.end())
-            d->sceneEdit->setValid(false);
-    }
-
-    d->sceneEdit->setValues(list);
-
-    // ---------------------------------------------------------------
-
-    code = meta.getXmpTagStringBag("Xmp.dc.type", false);
-
-    for (QStringList::Iterator it3 = code.begin(); it3 != code.end(); ++it3)
-    {
-        QStringList data = d->objectTypeEdit->getData();<--- Shadow variable
-        QStringList::Iterator it4;
+    d->reply = d->netMngr->put(netRequest, form.formData());
+
+    d->state = Private::OD_ADDPHOTO;
+
+    return true;
+}
+
+void ODTalker::slotFinished(QNetworkReply* reply)
+{
+    if (reply != d->reply)
+    {
+        return;
+    }
+
+    d->reply = nullptr;
+
+    if (reply->error() != QNetworkReply::NoError)
+    {
+        if (d->state != Private::OD_CREATEFOLDER)
+        {
+            emit signalBusy(false);
+            QMessageBox::critical(QApplication::activeWindow(),
+                                  i18n("Error"), reply->errorString());
 
-        for (it4 = data.begin(); it4 != data.end(); ++it4)
-        {
-            if ((*it4) == (*it3))
-            {
-                list2.append(*it4);
-                break;
-            }
-        }
-
-        if (it4 == data.end())
-            d->objectTypeEdit->setValid(false);
-    }
-
-    d->objectTypeEdit->setValues(list2);
-
-    // ---------------------------------------------------------------
-
-    d->objectAttributeCB->setCurrentIndex(0);
-    d->objectAttributeEdit->clear();
-    d->objectAttributeCheck->setChecked(false);
-    data = meta.getXmpTagString("Xmp.iptc.IntellectualGenre", false);
-
-    if (!data.isNull())
-    {
-        QString attrSec = data.section(QLatin1Char(':'), 0, 0);
-
-        if (!attrSec.isEmpty())
-        {
-            int attr = attrSec.toInt()-1;
-
-            if (attr >= 0 && attr < 23)
-            {
-                d->objectAttributeCB->setCurrentIndex(attr);
-                d->objectAttributeEdit->setText(data.section(QLatin1Char(':'), -1));
-                d->objectAttributeCheck->setChecked(true);
-            }
-            else
-                d->objectAttributeCheck->setValid(false);
-        }
-    }
-
-    d->objectAttributeCB->setEnabled(d->objectAttributeCheck->isChecked());
-    d->objectAttributeEdit->setEnabled(d->objectAttributeCheck->isChecked());
-
-    // ---------------------------------------------------------------
-
-    d->originalTransEdit->clear();
-    d->originalTransCheck->setChecked(false);
-    data = meta.getXmpTagString("Xmp.photoshop.TransmissionReference", false);
-
-    if (!data.isNull())
-    {
-        d->originalTransEdit->setText(data);
-        d->originalTransCheck->setChecked(true);
-    }
-
-    d->originalTransEdit->setEnabled(d->originalTransCheck->isChecked());
-
-    // ---------------------------------------------------------------
-
-    blockSignals(false);
-}
-
-void XMPProperties::applyMetadata(QByteArray& xmpData)
-{
-    QStringList oldList, newList;
-    DMetadata meta;
-    meta.setXmp(xmpData);
+            reply->deleteLater();
+            return;
+        }
+    }
+
+    QByteArray buffer = reply->readAll();
+
+    switch (d->state)
+    {
+        case Private::OD_LISTFOLDERS:
+            qCDebug(DIGIKAM_WEBSERVICES_LOG) << "In OD_LISTFOLDERS";
+            parseResponseListFolders(buffer);
+            break;
+        case Private::OD_CREATEFOLDER:
+            qCDebug(DIGIKAM_WEBSERVICES_LOG) << "In OD_CREATEFOLDER";
+            parseResponseCreateFolder(buffer);
+            break;
+        case Private::OD_ADDPHOTO:
+            qCDebug(DIGIKAM_WEBSERVICES_LOG) << "In OD_ADDPHOTO";
+            parseResponseAddPhoto(buffer);
+            break;
+        case Private::OD_USERNAME:
+            qCDebug(DIGIKAM_WEBSERVICES_LOG) << "In OD_USERNAME";
+            parseResponseUserName(buffer);
+            break;
+        default:
+            break;
+    }
+
+    reply->deleteLater();
+}
+
+void ODTalker::parseResponseAddPhoto(const QByteArray& data)
+{
+    QJsonDocument doc      = QJsonDocument::fromJson(data);
+    QJsonObject jsonObject = doc.object();
+    bool success           = jsonObject.contains(QLatin1String("size"));
+    emit signalBusy(false);
+
+    if (!success)
+    {
+        emit signalAddPhotoFailed(i18n("Failed to upload photo"));
+    }
+    else
+    {
+        emit signalAddPhotoSucceeded();
+    }
+}
+
+void ODTalker::parseResponseUserName(const QByteArray& data)
+{
+    QJsonDocument doc = QJsonDocument::fromJson(data);
+    QString name      = doc.object()[QLatin1String("displayName")].toString();
+    emit signalBusy(false);
+    emit signalSetUserName(name);
+}
+
+void ODTalker::parseResponseListFolders(const QByteArray& data)
+{
+    QJsonParseError err;
+    QJsonDocument doc = QJsonDocument::fromJson(data, &err);
+
+    if (err.error != QJsonParseError::NoError)
+    {
+        emit signalBusy(false);
+        emit signalListAlbumsFailed(i18n("Failed to list folders"));
+        return;
+    }
 
-    // ---------------------------------------------------------------
-
-    if (d->languageEdit->getValues(oldList, newList))
-    {
-        QStringList newCode;
-
-        for (QStringList::Iterator it2 = newList.begin(); it2 != newList.end(); ++it2)
-            newCode.append((*it2).left(2));
+    QJsonObject jsonObject = doc.object();
+    //qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Json: " << doc;
+    QJsonArray jsonArray   = jsonObject[QLatin1String("value")].toArray();
+
+    if (d->folderList.isEmpty())
+    {
+        d->folderList.append(qMakePair(QLatin1String(""), QLatin1String("root")));
+    }
 
-        meta.setXmpTagStringBag("Xmp.dc.language", newCode);
-    }
-    else
-    {
-        meta.removeXmpTag("Xmp.dc.language");
-    }
-
-    // ---------------------------------------------------------------
+    foreach (const QJsonValue& value, jsonArray)
+    {
+        QString path;
+        QString listName;
+        QString folderPath;
+        QString folderName;
+        QJsonObject folder;
+        QJsonObject parent;
 
-    if (d->priorityCheck->isChecked())
-        meta.setXmpTagString("Xmp.photoshop.Urgency", QString::number(d->priorityCB->currentIndex()));
-    else if (d->priorityCheck->isValid())
-        meta.removeXmpTag("Xmp.photoshop.Urgency");
-
-    // ---------------------------------------------------------------
-
-    if (d->sceneEdit->getValues(oldList, newList))
-    {
-        QStringList newCode;
-
-        for (QStringList::Iterator it2 = newList.begin(); it2 != newList.end(); ++it2)
-            newCode.append((*it2).left(6));
+        QJsonObject obj = value.toObject();
+        folder          = obj[QLatin1String("folder")].toObject();
+        parent          = obj[QLatin1String("parentReference")].toObject();
+
+        if (!folder.isEmpty())
+        {
+            folderPath  = parent[QLatin1String("path")].toString();
+            folderName  = obj[QLatin1String("name")].toString();
+
+            path        = folderPath.section(QLatin1String("root:"), -1, -1) +
+                                             QLatin1Char('/') + folderName;
+            path        = QUrl(path).toString(QUrl::FullyDecoded);
+            listName    = path.section(QLatin1Char('/'), 1);
 
-        meta.setXmpTagStringBag("Xmp.iptc.Scene", newCode);
-    }
-    else
-    {
-        meta.removeXmpTag("Xmp.iptc.Scene");
-    }
-
-    // ---------------------------------------------------------------
+            d->folderList.append(qMakePair(path, listName));
+
+            if (folder[QLatin1String("childCount")].toInt() > 0)
+            {
+                d->nextFolder << path;
+            }
+        }
+    }
 
-    if (d->objectTypeEdit->getValues(oldList, newList))
-        meta.setXmpTagStringBag("Xmp.dc.type", newList);
-    else
-        meta.removeXmpTag("Xmp.dc.type");
-
-    // ---------------------------------------------------------------
-
-    if (d->objectAttributeCheck->isChecked())
-    {
-        QString objectAttribute;
-        objectAttribute.asprintf("%3d", d->objectAttributeCB->currentIndex()+1);
-        objectAttribute.append(QString::fromUtf8(":%1").arg(d->objectAttributeEdit->text()));
-        meta.setXmpTagString("Xmp.iptc.IntellectualGenre", objectAttribute);
-    }
-    else if (d->objectAttributeCheck->isValid())
-    {
-        meta.removeXmpTag("Xmp.iptc.IntellectualGenre");
-    }
+    if (!d->nextFolder.isEmpty())
+    {
+        listFolders(d->nextFolder.takeLast());
+    }
+    else
+    {
+        std::sort(d->folderList.begin(), d->folderList.end());
+
+        emit signalBusy(false);
+        emit signalListAlbumsDone(d->folderList);
+    }
+}
+
+void ODTalker::parseResponseCreateFolder(const QByteArray& data)
+{
+    QJsonDocument doc      = QJsonDocument::fromJson(data);<--- Shadowed declaration
+    QJsonObject jsonObject = doc.object();
+    bool fail              = jsonObject.contains(QLatin1String("error"));
 
-    // ---------------------------------------------------------------
+    emit signalBusy(false);
 
-    if (d->originalTransCheck->isChecked())
-        meta.setXmpTagString("Xmp.photoshop.TransmissionReference", d->originalTransEdit->text());
-    else
-        meta.removeXmpTag("Xmp.photoshop.TransmissionReference");
-
-    xmpData = meta.getXmp();
-}
-
-} // namespace DigikamGenericMetadataEditPlugin
+    if (fail)
+    {
+        QJsonParseError err;
+        QJsonDocument doc = QJsonDocument::fromJson(data, &err);<--- Shadow variable
+        emit signalCreateFolderFailed(jsonObject[QLatin1String("error_summary")].toString());
+    }
+    else
+    {
+        emit signalCreateFolderSucceeded();
+    }
+}
+
+void ODTalker::writeSettings()
+{
+    d->settings->beginGroup(d->serviceName);
+    d->settings->setValue(d->serviceTime, d->expiryTime);
+    d->settings->setValue(d->serviceKey,  d->accessToken);
+    d->settings->endGroup();
+}
+
+void ODTalker::readSettings()
+{
+    d->settings->beginGroup(d->serviceName);
+    d->expiryTime  = d->settings->value(d->serviceTime).toDateTime();
+    d->accessToken = d->settings->value(d->serviceKey).toString();
+    d->settings->endGroup();
+
+    if (d->accessToken.isEmpty())
+    {
+        qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Linking...";
+        link();
+    }
+    else if (QDateTime::currentDateTime() > d->expiryTime)
+    {
+        qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Access token has expired";
+        d->accessToken = QString();
+        link();
+    }
+    else
+    {
+        qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Already Linked";
+        emit oneDriveLinkingSucceeded();
+    }
+}
+
+} // namespace DigikamGenericOneDrivePlugin
 
diff --git a/static/reports/cppcheck/master/3.html b/static/reports/cppcheck/master/3.html index b88102bd8..ba3df6e31 100644 --- a/static/reports/cppcheck/master/3.html +++ b/static/reports/cppcheck/master/3.html @@ -1,1181 +1,1391 @@ - Cppcheck - HTML report - digiKam-master-rev-907aafb5fa + Cppcheck - HTML report - digiKam-master-rev-e85fcd090f
  1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
-518
/* ============================================================
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
/* ============================================================
  *
  * This file is a part of digiKam project
  * https://www.digikam.org
  *
  * Date        : 2018-05-20
- * Description : a tool to export images to Box web service
+ * Description : a tool to export images to Pinterest web service
  *
  * Copyright (C) 2018      by Tarek Talaat <tarektalaat93 at gmail dot com>
  *
  * This program is free software; you can redistribute it
  * and/or modify it under the terms of the GNU General
  * Public License as published by the Free Software Foundation;
  * either version 2, or (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
  *
  * ============================================================ */
 
-#include "boxtalker.h"
+#include "ptalker.h"
 
 // Qt includes
 
-#include <QMimeDatabase>
-#include <QJsonDocument>
-#include <QJsonParseError>
-#include <QJsonObject>
-#include <QJsonValue>
-#include <QJsonArray>
-#include <QByteArray>
-#include <QList>
-#include <QPair>
-#include <QFileInfo>
-#include <QWidget>
-#include <QSettings>
-#include <QMessageBox>
-#include <QApplication>
-#include <QDesktopServices>
-#include <QHttpMultiPart>
-#include <QNetworkAccessManager>
-
-// KDE includes
-
-#include <klocalizedstring.h>
+#include <QJsonDocument>
+#include <QJsonParseError>
+#include <QJsonObject>
+#include <QJsonValue>
+#include <QJsonArray>
+#include <QByteArray>
+#include <QList>
+#include <QPair>
+#include <QFileInfo>
+#include <QWidget>
+#include <QMessageBox>
+#include <QApplication>
+#include <QDesktopServices>
+#include <QUrlQuery>
+#include <QHttpMultiPart>
+#include <QNetworkAccessManager>
+
+// KDE includes
+
+#include <klocalizedstring.h>
+#include <kwindowconfig.h>
 
 // Local includes
 
 #include "digikam_debug.h"
 #include "digikam_version.h"
 #include "wstoolutils.h"
-#include "boxwindow.h"
-#include "boxitem.h"
-#include "previewloadthread.h"
-#include "o0settingsstore.h"
+#include "pwindow.h"
+#include "pitem.h"
+#include "webbrowserdlg.h"
+#include "previewloadthread.h"
 
-namespace DigikamGenericBoxPlugin
+namespace DigikamGenericPinterestPlugin
 {
 
-class Q_DECL_HIDDEN BOXTalker::Private
+class Q_DECL_HIDDEN PTalker::Private
 {
 public:
 
     enum State
     {
-        BOX_USERNAME = 0,
-        BOX_LISTFOLDERS,
-        BOX_CREATEFOLDER,
-        BOX_ADDPHOTO
-    };
-
-public:
-
-    explicit Private()
-    {
-        clientId     = QLatin1String("yvd43v8av9zgg9phig80m2dc3r7mks4t");
-        clientSecret = QLatin1String("KJkuMjvzOKDMyp3oxweQBEYixg678Fh5");
-
-        authUrl      = QLatin1String("https://account.box.com/api/oauth2/authorize");
-        tokenUrl     = QLatin1String("https://api.box.com/oauth2/token");
-        redirectUrl  = QLatin1String("https://app.box.com");
-
-        state        = BOX_USERNAME;
-
-        parent       = nullptr;
-        netMngr      = nullptr;
-        reply        = nullptr;
-        settings     = nullptr;
-        o2           = nullptr;
-    }
-
-public:
+        P_USERNAME = 0,
+        P_LISTBOARDS,
+        P_CREATEBOARD,
+        P_ADDPIN,
+        P_ACCESSTOKEN
+    };
+
+public:
+
+    explicit Private()
+      : parent(nullptr),
+        netMngr(nullptr),
+        reply(nullptr),
+        settings(nullptr),
+        state(P_USERNAME),
+        browser(nullptr)
+    {
+        clientId     = QLatin1String("4983380570301022071");
+        clientSecret = QLatin1String("2a698db679125930d922a2dfb897e16b668a67c6f614593636e83fc3d8d9b47d");
+
+        authUrl      = QLatin1String("https://api.pinterest.com/oauth/");
+        tokenUrl     = QLatin1String("https://api.pinterest.com/v1/oauth/token");
+        redirectUrl  = QLatin1String("https://login.live.com/oauth20_desktop.srf");
+        scope        = QLatin1String("read_public,write_public");
+        serviceName  = QLatin1String("Pinterest");
+        serviceKey   = QLatin1String("access_token");
+    }
 
-    QString                         clientId;
-    QString                         clientSecret;
-    QString                         authUrl;
-    QString                         tokenUrl;
-    QString                         redirectUrl;
-
-    State                           state;
-
-    QWidget*                        parent;
-
-    QNetworkAccessManager*          netMngr;
-    QNetworkReply*                  reply;
+public:
+
+    QString                clientId;
+    QString                clientSecret;
+    QString                authUrl;
+    QString                tokenUrl;
+    QString                redirectUrl;
+    QString                accessToken;
+    QString                scope;
+    QString                userName;
+    QString                serviceName;
+    QString                serviceKey;
 
-    QSettings*                      settings;
+    QWidget*               parent;
 
-    O2*                             o2;
-
-    QList<QPair<QString, QString> > foldersList;
-};
+    QNetworkAccessManager* netMngr;
+    QNetworkReply*         reply;
+
+    QSettings*             settings;
 
-BOXTalker::BOXTalker(QWidget* const parent)
-    : d(new Private)
-{
-    d->parent  = parent;
-    d->netMngr = new QNetworkAccessManager(this);
+    State                  state;
+
+    DMetadata              meta;
+
+    QMap<QString, QString> urlParametersMap;
 
-    connect(this, SIGNAL(boxLinkingFailed()),
-            this, SLOT(slotLinkingFailed()));
+    WebBrowserDlg*         browser;
+};
 
-    connect(this, SIGNAL(boxLinkingSucceeded()),
-            this, SLOT(slotLinkingSucceeded()));
-
-    connect(d->netMngr, SIGNAL(finished(QNetworkReply*)),
-            this, SLOT(slotFinished(QNetworkReply*)));
-
-    d->o2      = new O2(this);
-
-    d->o2->setClientId(d->clientId);
-    d->o2->setClientSecret(d->clientSecret);
-    d->o2->setRefreshTokenUrl(d->tokenUrl);
-    d->o2->setRequestUrl(d->authUrl);
-    d->o2->setTokenUrl(d->tokenUrl);
-    d->o2->setLocalPort(8000);
-
-    d->settings                  = WSToolUtils::getOauthSettings(this);
-    O0SettingsStore* const store = new O0SettingsStore(d->settings, QLatin1String(O2_ENCRYPTION_KEY), this);
-    store->setGroupKey(QLatin1String("Box"));
-    d->o2->setStore(store);
-
-    connect(d->o2, SIGNAL(linkingFailed()),
-            this, SLOT(slotLinkingFailed()));
-
-    connect(d->o2, SIGNAL(linkingSucceeded()),
-            this, SLOT(slotLinkingSucceeded()));
+PTalker::PTalker(QWidget* const parent)
+    : d(new Private)
+{
+    d->parent   = parent;
+    d->netMngr  = new QNetworkAccessManager(this);
+    d->settings = WSToolUtils::getOauthSettings(this);
+
+    connect(d->netMngr, SIGNAL(finished(QNetworkReply*)),
+            this, SLOT(slotFinished(QNetworkReply*)));
+
+    connect(this, SIGNAL(pinterestLinkingFailed()),
+            this, SLOT(slotLinkingFailed()));
+
+    connect(this, SIGNAL(pinterestLinkingSucceeded()),
+            this, SLOT(slotLinkingSucceeded()));
+}
+
+PTalker::~PTalker()
+{
+    if (d->reply)
+    {
+        d->reply->abort();
+    }
+
+    WSToolUtils::removeTemporaryDir("pinterest");
 
-    connect(d->o2, SIGNAL(openBrowser(QUrl)),
-            this, SLOT(slotOpenBrowser(QUrl)));
-}
-
-BOXTalker::~BOXTalker()
-{
-    if (d->reply)
-    {
-        d->reply->abort();
-    }
-
-    WSToolUtils::removeTemporaryDir("box");
-
-    delete d;
-}
-
-void BOXTalker::link()
-{
-    emit signalBusy(true);
-    d->o2->link();
-}
+    delete d;
+}
+
+void PTalker::link()
+{
+    emit signalBusy(true);
+
+    QUrl url(d->authUrl);
+    QUrlQuery query(url);
+    query.addQueryItem(QLatin1String("client_id"),     d->clientId);
+    query.addQueryItem(QLatin1String("scope"),         d->scope);
+    query.addQueryItem(QLatin1String("redirect_uri"),  d->redirectUrl);
+    query.addQueryItem(QLatin1String("response_type"), QLatin1String("code"));
+    url.setQuery(query);
+
+    delete d->browser;
+    d->browser = new WebBrowserDlg(url, d->parent, true);
+    d->browser->setModal(true);
+
+    connect(d->browser, SIGNAL(urlChanged(QUrl)),
+            this, SLOT(slotCatchUrl(QUrl)));
 
-void BOXTalker::unLink()
-{
-    d->o2->unlink();
-    d->settings->beginGroup(QLatin1String("Box"));
-    d->settings->remove(QString());
-    d->settings->endGroup();
-}
-
-void BOXTalker::slotLinkingFailed()
-{
-    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "LINK to Box fail";
-    emit signalBusy(false);
-}
+    connect(d->browser, SIGNAL(closeView(bool)),
+            this, SIGNAL(signalBusy(bool)));
+
+    d->browser->show();
+}
+
+void PTalker::unLink()
+{
+    d->accessToken = QString();
+
+    d->settings->beginGroup(d->serviceName);
+    d->settings->remove(QString());
+    d->settings->endGroup();
 
-void BOXTalker::slotLinkingSucceeded()
-{
-    if (!d->o2->linked())
-    {
-        qCDebug(DIGIKAM_WEBSERVICES_LOG) << "UNLINK to Box ok";
-        emit signalBusy(false);
-        return;
-    }
+    emit pinterestLinkingSucceeded();
+}
+
+void PTalker::slotCatchUrl(const QUrl& url)
+{
+    d->urlParametersMap = ParseUrlParameters(url.toString());
+    QString code        = d->urlParametersMap.value(QLatin1String("code"));
+    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Received URL from webview in link function: " << url ;
 
-    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "LINK to Box ok";
-    emit signalLinkingSucceeded();
-}
-
-bool BOXTalker::authenticated()
-{
-    return d->o2->linked();
+    if (!code.isEmpty())
+    {
+        qCDebug(DIGIKAM_WEBSERVICES_LOG) << "CODE Received";
+        d->browser->close();
+        getToken(code);
+        emit signalBusy(false);
+    }
 }
 
-void BOXTalker::cancel()
+void PTalker::getToken(const QString& code)
 {
-    if (d->reply)
-    {
-        d->reply->abort();
-        d->reply = nullptr;
-    }
-
-    emit signalBusy(false);
-}
-
-void BOXTalker::slotOpenBrowser(const QUrl& url)
-{
-    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Open Browser...";
-    QDesktopServices::openUrl(url);
-}
-
-void BOXTalker::createFolder(QString& path)
-{
-    QString name       = path.section(QLatin1Char('/'), -1);
-    QString folderPath = path.section(QLatin1Char('/'), -2, -2);
-
-    QString id;
-
-    for (int i = 0 ; i < d->foldersList.size() ; ++i)
-    {
-        if (d->foldersList.value(i).second == folderPath)
-        {
-            id = d->foldersList.value(i).first;
-        }
-    }
-
-    QUrl url(QLatin1String("https://api.box.com/2.0/folders"));
-    QNetworkRequest netRequest(url);
-    netRequest.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("application/json"));
-    netRequest.setRawHeader("Authorization", QString::fromLatin1("Bearer %1").arg(d->o2->token()).toUtf8());
+    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Code: " << code;
+    QUrl url(d->tokenUrl);
+    QUrlQuery query(url);
+    query.addQueryItem(QLatin1String("grant_type"),    QLatin1String("authorization_code"));
+    query.addQueryItem(QLatin1String("client_id"),     d->clientId);
+    query.addQueryItem(QLatin1String("client_secret"), d->clientSecret);
+    query.addQueryItem(QLatin1String("code"),          code);
+    url.setQuery(query);
+    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Token Request URL:    " << url.toString();
+
+    QNetworkRequest netRequest(url);
+    netRequest.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("application/x-www-form-urlencoded"));
+    netRequest.setRawHeader("Accept", "application/json");
+
+    d->reply = d->netMngr->post(netRequest, QByteArray());
+
+    d->state = Private::P_ACCESSTOKEN;
+}
+
+QMap<QString, QString> PTalker::ParseUrlParameters(const QString& url)
+{
+    QMap<QString, QString> urlParameters;
+
+    if (url.indexOf(QLatin1Char('?')) == -1)
+    {
+        return urlParameters;
+    }
+
+    QString tmp           = url.right(url.length()-url.indexOf(QLatin1Char('?')) - 1);
+    QStringList paramlist = tmp.split(QLatin1Char('&'));
+
+    for (int i = 0 ; i < paramlist.count() ; ++i)
+    {
+        QStringList paramarg = paramlist.at(i).split(QLatin1Char('='));
 
-    QByteArray postData = QString::fromUtf8("{\"name\": \"%1\",\"parent\": {\"id\": \"%2\"}}").arg(name).arg(id).toUtf8();
-
-    d->reply = d->netMngr->post(netRequest, postData);
-    d->state = Private::BOX_CREATEFOLDER;
-
-    emit signalBusy(true);
-}
-
-void BOXTalker::getUserName()
-{
-    QUrl url(QLatin1String("https://api.box.com/2.0/users/me"));
-
-    QNetworkRequest netRequest(url);
-    netRequest.setRawHeader("Authorization", QString::fromLatin1("Bearer %1").arg(d->o2->token()).toUtf8());
-    netRequest.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("application/json"));
-
-    d->reply = d->netMngr->get(netRequest);
-    d->state = Private::BOX_USERNAME;
-
-    emit signalBusy(true);
-}
-
-void BOXTalker::listFolders(const QString& /*path*/)
-{
-    QUrl url(QLatin1String("https://api.box.com/2.0/folders/0/items"));;
-
-    QNetworkRequest netRequest(url);
-    netRequest.setRawHeader("Authorization", QString::fromLatin1("Bearer %1").arg(d->o2->token()).toUtf8());
-    netRequest.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("application/json"));
-
-    d->reply = d->netMngr->get(netRequest);
-    d->state = Private::BOX_LISTFOLDERS;
-
-    emit signalBusy(true);
-}
-
-bool BOXTalker::addPhoto(const QString& imgPath, const QString& uploadFolder, bool rescale, int maxDim, int imageQuality)
-{
-    if (d->reply)
-    {
-        d->reply->abort();
-        d->reply = nullptr;
-    }
-
-    emit signalBusy(true);
-
-    QMimeDatabase mimeDB;
-    QString path     = imgPath;
-    QString mimeType = mimeDB.mimeTypeForFile(path).name();
-
-    if (mimeType.startsWith(QLatin1String("image/")))
-    {
-        QImage image = PreviewLoadThread::loadHighQualitySynchronously(imgPath).copyQImage();
-
-        if (image.isNull())
-        {
-            emit signalBusy(false);
-            return false;
-        }
-
-        path = WSToolUtils::makeTemporaryDir("box").filePath(QFileInfo(imgPath)
-                                             .baseName().trimmed() + QLatin1String(".jpg"));
-
-        if (rescale && (image.width() > maxDim || image.height() > maxDim))
-        {
-            image = image.scaled(maxDim, maxDim, Qt::KeepAspectRatio, Qt::SmoothTransformation);
-        }
-
-        image.save(path, "JPEG", imageQuality);
-
-        DMetadata meta;
-
-        if (meta.load(imgPath))
-        {
-            meta.setItemDimensions(image.size());
-            meta.setItemOrientation(DMetadata::ORIENTATION_NORMAL);
-            meta.setMetadataWritingMode((int)DMetadata::WRITE_TO_FILE_ONLY);
-            meta.save(path, true);
-        }
-    }
+        if (paramarg.count() == 2)
+        {
+            urlParameters.insert(paramarg.at(0), paramarg.at(1));
+        }
+    }
+
+    return urlParameters;
+}
+
+void PTalker::slotLinkingFailed()
+{
+    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "LINK to Pinterest fail";
+    emit signalBusy(false);
+}
+
+void PTalker::slotLinkingSucceeded()
+{
+    if (d->accessToken.isEmpty())
+    {
+        qCDebug(DIGIKAM_WEBSERVICES_LOG) << "UNLINK to Pinterest ok";
+        emit signalBusy(false);
+        return;
+    }
+
+    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "LINK to Pinterest ok";
+    writeSettings();
+    emit signalLinkingSucceeded();
+}
+
+bool PTalker::authenticated()
+{
+    return (!d->accessToken.isEmpty());
+}
+
+void PTalker::cancel()
+{
+    if (d->reply)
+    {
+        d->reply->abort();
+        d->reply = nullptr;
+    }
+
+    emit signalBusy(false);
+}
+
+void PTalker::createBoard(QString& boardName)
+{
+    QUrl url(QLatin1String("https://api.pinterest.com/v1/boards/"));
+    QNetworkRequest netRequest(url);
+    netRequest.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("application/json"));
+    netRequest.setRawHeader("Authorization", QString::fromLatin1("Bearer %1").arg(d->accessToken).toUtf8());
+
+    QByteArray postData = QString::fromUtf8("{\"name\": \"%1\"}").arg(boardName).toUtf8();
+/*
+    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "createBoard:" << postData;
+*/
+    d->reply = d->netMngr->post(netRequest, postData);
+
+    d->state = Private::P_CREATEBOARD;
+    emit signalBusy(true);
+}
+
+void PTalker::getUserName()
+{
+    QUrl url(QLatin1String("https://api.pinterest.com/v1/me/?fields=username"));
+
+    QNetworkRequest netRequest(url);
+    netRequest.setRawHeader("Authorization", QString::fromLatin1("Bearer %1").arg(d->accessToken).toUtf8());
+
+    d->reply = d->netMngr->get(netRequest);
+    d->state = Private::P_USERNAME;
+    emit signalBusy(true);
+}
+
+/**
+ * Get list of boards by parsing json sent by pinterest
+ */
+void PTalker::listBoards(const QString& /*path*/)
+{
+    QUrl url(QLatin1String("https://api.pinterest.com/v1/me/boards/"));;
 
-    QString id;
-
-    for (int i = 0 ; i < d->foldersList.size() ; ++i)
-    {
-        if (d->foldersList.value(i).second == uploadFolder)
-        {
-            id = d->foldersList.value(i).first;
-        }
-    }
+    QNetworkRequest netRequest(url);
+    netRequest.setRawHeader("Authorization", QString::fromLatin1("Bearer %1").arg(d->accessToken).toUtf8());
+    //netRequest.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("application/json"));
+
+    d->reply = d->netMngr->get(netRequest);
+
+    d->state = Private::P_LISTBOARDS;
+    emit signalBusy(true);
+}
 
-    QHttpMultiPart* const multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
-
-    QHttpPart attributes;
-    QString attributesHeader  = QLatin1String("form-data; name=\"attributes\"");
-    attributes.setHeader(QNetworkRequest::ContentDispositionHeader, attributesHeader);
-
-    QString postData = QLatin1String("{\"name\":\"") + QFileInfo(imgPath).fileName() + QLatin1Char('"') +
-                       QLatin1String(", \"parent\":{\"id\":\"") + id + QLatin1String("\"}}");
-    attributes.setBody(postData.toUtf8());
-    multiPart->append(attributes);
-
-    QFile* const file = new QFile(path);
-
-    if (!file)
-    {
-        return false;
-    }
-
-    if (!file->open(QIODevice::ReadOnly))
-    {
-        return false;
-    }
-
-    QHttpPart imagePart;
-    QString imagePartHeader = QLatin1String("form-data; name=\"file\"; filename=\"") +
-                              QFileInfo(imgPath).fileName() + QLatin1Char('"');
-
-    imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, imagePartHeader);
-    imagePart.setHeader(QNetworkRequest::ContentTypeHeader, mimeType);
+bool PTalker::addPin(const QString& imgPath,
+                     const QString& uploadBoard,
+                     bool rescale,
+                     int maxDim,
+                     int imageQuality)
+{
+    if (d->reply)
+    {
+        d->reply->abort();
+        d->reply = nullptr;
+    }
+
+    emit signalBusy(true);
+
+    QImage image = PreviewLoadThread::loadHighQualitySynchronously(imgPath).copyQImage();
+
+    if (image.isNull())
+    {
+        emit signalBusy(false);
+        return false;
+    }
+
+    QString path = WSToolUtils::makeTemporaryDir("pinterest").filePath(QFileInfo(imgPath)
+                                                 .baseName().trimmed() + QLatin1String(".jpg"));
+
+    if (rescale && (image.width() > maxDim || image.height() > maxDim))
+    {
+        image = image.scaled(maxDim, maxDim, Qt::KeepAspectRatio, Qt::SmoothTransformation);
+    }
 
-    imagePart.setBodyDevice(file);
-    multiPart->append(imagePart);
-
-    QUrl url(QString::fromLatin1("https://upload.box.com/api/2.0/files/content?access_token=%1").arg(d->o2->token()));
-
-    QNetworkRequest netRequest(url);
-    QString content = QLatin1String("multipart/form-data;boundary=") + QString::fromUtf8(multiPart->boundary());
-    netRequest.setHeader(QNetworkRequest::ContentTypeHeader, content);
-    d->reply        = d->netMngr->post(netRequest, multiPart);
+    image.save(path, "JPEG", imageQuality);
+
+    if (d->meta.load(imgPath))
+    {
+        d->meta.setItemDimensions(image.size());
+        d->meta.setItemOrientation(DMetadata::ORIENTATION_NORMAL);
+        d->meta.setMetadataWritingMode((int)DMetadata::WRITE_TO_FILE_ONLY);
+        d->meta.save(path, true);
+    }
 
-    // delete the multiPart and file with the reply
+    QString boardParam              = d->userName + QLatin1Char('/') + uploadBoard;
 
-    multiPart->setParent(d->reply);
+    QUrl url(QString::fromLatin1("https://api.pinterest.com/v1/pins/?access_token=%1").arg(d->accessToken));
 
-    d->state        = Private::BOX_ADDPHOTO;
+    QHttpMultiPart* const multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
 
-    return true;
-}
-
-void BOXTalker::slotFinished(QNetworkReply* reply)
-{
-    if (reply != d->reply)
-    {
-        return;
-    }
+    // Board Section
+
+    QHttpPart board;
+    QString boardHeader = QLatin1String("form-data; name=\"board\"") ;
+    board.setHeader(QNetworkRequest::ContentDispositionHeader, boardHeader);
+
+    QByteArray postData = boardParam.toUtf8();
+    board.setBody(postData);
+    multiPart->append(board);
 
-    d->reply = nullptr;
+    // Note section
 
-    if (reply->error() != QNetworkReply::NoError)
-    {
-        if (d->state != Private::BOX_CREATEFOLDER)
-        {
-            emit signalBusy(false);
-            QMessageBox::critical(QApplication::activeWindow(),
-                                  i18n("Error"), reply->errorString());
-            reply->deleteLater();
-            return;
-        }
-    }
-
-    QByteArray buffer = reply->readAll();
-
-    switch (d->state)
-    {
-        case Private::BOX_LISTFOLDERS:
-            qCDebug(DIGIKAM_WEBSERVICES_LOG) << "In BOX_LISTFOLDERS";
-            parseResponseListFolders(buffer);
-            break;
-
-        case Private::BOX_CREATEFOLDER:
-            qCDebug(DIGIKAM_WEBSERVICES_LOG) << "In BOX_CREATEFOLDER";
-            parseResponseCreateFolder(buffer);
-            break;
-
-        case Private::BOX_ADDPHOTO:
-            qCDebug(DIGIKAM_WEBSERVICES_LOG) << "In BOX_ADDPHOTO";
-            parseResponseAddPhoto(buffer);
-            break;
-
-        case Private::BOX_USERNAME:
-            qCDebug(DIGIKAM_WEBSERVICES_LOG) << "In BOX_USERNAME";
-            parseResponseUserName(buffer);
-            break;
-
-        default:
-            break;
-    }
-
-    reply->deleteLater();
-}
-
-void BOXTalker::parseResponseAddPhoto(const QByteArray& data)
-{
-    QJsonDocument doc      = QJsonDocument::fromJson(data);
-    QJsonObject jsonObject = doc.object();
-    bool success           = jsonObject.contains(QLatin1String("total_count"));
-    emit signalBusy(false);
-
-    if (!success)
-    {
-        emit signalAddPhotoFailed(i18n("Failed to upload photo"));
-    }
-    else
-    {
-        emit signalAddPhotoSucceeded();
-    }
-}
-
-void BOXTalker::parseResponseUserName(const QByteArray& data)
-{
-    QJsonDocument doc = QJsonDocument::fromJson(data);
-    QString name      = doc.object()[QLatin1String("name")].toString();
-    emit signalBusy(false);
-    emit signalSetUserName(name);
-}
-
-void BOXTalker::parseResponseListFolders(const QByteArray& data)
-{
-    QJsonParseError err;
-    QJsonDocument doc = QJsonDocument::fromJson(data, &err);
-
-    if (err.error != QJsonParseError::NoError)
-    {
-        emit signalBusy(false);
-        emit signalListAlbumsFailed(i18n("Failed to list folders"));
-        return;
-    }
-
-    QJsonObject jsonObject = doc.object();
-    QJsonArray jsonArray   = jsonObject[QLatin1String("entries")].toArray();
-
-    d->foldersList.clear();
-    d->foldersList.append(qMakePair(QLatin1String("0"), QLatin1String("root")));
-
-    foreach (const QJsonValue& value, jsonArray)
-    {
-        QString folderName;
-        QString type;
-        QString id;
-
-        QJsonObject obj = value.toObject();
-        type            = obj[QLatin1String("type")].toString();
-
-        if (type == QLatin1String("folder"))
-        {
-            folderName = obj[QLatin1String("name")].toString();
-            id         = obj[QLatin1String("id")].toString();
-            d->foldersList.append(qMakePair(id, folderName));
-        }
-    }
-
-    emit signalBusy(false);
-    emit signalListAlbumsDone(d->foldersList);
-}
-
-void BOXTalker::parseResponseCreateFolder(const QByteArray& data)
-{
-    QJsonDocument doc      = QJsonDocument::fromJson(data);<--- Shadowed declaration
-    QJsonObject jsonObject = doc.object();
-    bool fail              = jsonObject.contains(QLatin1String("error"));
-
-    emit signalBusy(false);
-
-    if (fail)
+    QHttpPart note;
+    QString noteHeader = QLatin1String("form-data; name=\"note\"") ;
+    note.setHeader(QNetworkRequest::ContentDispositionHeader, noteHeader);
+
+    postData           = QByteArray();
+
+    note.setBody(postData);
+    multiPart->append(note);
+
+    // image section
+
+    QFile* const file  = new QFile(imgPath);
+
+    if (!file)
+    {
+        return false;
+    }
+
+    if (!file->open(QIODevice::ReadOnly))
+    {
+        return false;
+    }
+
+    QHttpPart imagePart;
+    QString imagePartHeader = QLatin1String("form-data; name=\"image\"; filename=\"") +
+                              QFileInfo(imgPath).fileName() + QLatin1Char('"');
+
+    imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, imagePartHeader);
+    imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("image/jpeg"));
+
+    imagePart.setBodyDevice(file);
+    multiPart->append(imagePart);
+
+    QString content = QLatin1String("multipart/form-data;boundary=") + QString::fromUtf8(multiPart->boundary());
+    QNetworkRequest netRequest(url);
+    netRequest.setHeader(QNetworkRequest::ContentTypeHeader, content);
+
+    d->reply = d->netMngr->post(netRequest, multiPart);
+
+    // delete the multiPart and file with the reply
+
+    multiPart->setParent(d->reply);
+    d->state = Private::P_ADDPIN;
+
+    return true;
+}
+
+void PTalker::slotFinished(QNetworkReply* reply)
+{
+    if (reply != d->reply)
+    {
+        return;
+    }
+
+    d->reply = nullptr;
+
+    if (reply->error() != QNetworkReply::NoError)
+    {
+        if (d->state != Private::P_CREATEBOARD)
+        {
+            emit signalBusy(false);
+            QMessageBox::critical(QApplication::activeWindow(),
+                                  i18n("Error"), reply->errorString());
+/*
+            qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Error content: " << QString(reply->readAll());
+*/
+            reply->deleteLater();
+            return;
+        }
+    }
+
+    QByteArray buffer = reply->readAll();
+/*
+    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "BUFFER" << QString(buffer);
+*/
+    switch (d->state)
+    {
+        case Private::P_LISTBOARDS:
+            qCDebug(DIGIKAM_WEBSERVICES_LOG) << "In P_LISTBOARDS";
+            parseResponseListBoards(buffer);
+            break;
+        case Private::P_CREATEBOARD:
+            qCDebug(DIGIKAM_WEBSERVICES_LOG) << "In P_CREATEBOARD";
+            parseResponseCreateBoard(buffer);
+            break;
+        case Private::P_ADDPIN:
+            qCDebug(DIGIKAM_WEBSERVICES_LOG) << "In P_ADDPIN";
+            parseResponseAddPin(buffer);
+            break;
+        case Private::P_USERNAME:
+            qCDebug(DIGIKAM_WEBSERVICES_LOG) << "In P_USERNAME";
+            parseResponseUserName(buffer);
+            break;
+        case Private::P_ACCESSTOKEN:
+            qCDebug(DIGIKAM_WEBSERVICES_LOG) << "In P_ACCESSTOKEN";
+            parseResponseAccessToken(buffer);
+            break;
+        default:
+            break;
+    }
+
+    reply->deleteLater();
+}
+
+void PTalker::parseResponseAccessToken(const QByteArray& data)
+{
+    QJsonDocument doc      = QJsonDocument::fromJson(data);
+    QJsonObject jsonObject = doc.object();
+    d->accessToken         = jsonObject[QLatin1String("access_token")].toString();
+
+    if (!d->accessToken.isEmpty())
+    {
+        qDebug(DIGIKAM_WEBSERVICES_LOG) << "Access token Received: " << d->accessToken;
+        emit pinterestLinkingSucceeded();
+    }
+    else
     {
-        QJsonParseError err;
-        QJsonDocument doc = QJsonDocument::fromJson(data, &err);<--- Shadow variable
-        emit signalCreateFolderFailed(jsonObject[QLatin1String("error_summary")].toString());
-    }
-    else
-    {
-        emit signalCreateFolderSucceeded();
-    }
-}
-
-} // namespace DigikamGenericBoxPlugin
+        emit pinterestLinkingFailed();
+    }
+
+    emit signalBusy(false);
+}
+
+void PTalker::parseResponseAddPin(const QByteArray& data)
+{
+    QJsonDocument doc      = QJsonDocument::fromJson(data);
+    QJsonObject jsonObject = doc.object()[QLatin1String("data")].toObject();
+    bool success           = jsonObject.contains(QLatin1String("id"));
+    emit signalBusy(false);
+
+    if (!success)
+    {
+        emit signalAddPinFailed(i18n("Failed to upload Pin"));
+    }
+    else
+    {
+        emit signalAddPinSucceeded();
+    }
+}
+
+void PTalker::parseResponseUserName(const QByteArray& data)
+{
+    QJsonDocument doc      = QJsonDocument::fromJson(data);
+    QJsonObject jsonObject = doc.object()[QLatin1String("data")].toObject();
+    d->userName            = jsonObject[QLatin1String("username")].toString();
+
+    emit signalBusy(false);
+    emit signalSetUserName(d->userName);
+}
+
+void PTalker::parseResponseListBoards(const QByteArray& data)
+{
+    QJsonParseError err;
+    QJsonDocument doc = QJsonDocument::fromJson(data, &err);
+
+    if (err.error != QJsonParseError::NoError)
+    {
+        emit signalBusy(false);
+        emit signalListBoardsFailed(i18n("Failed to list boards"));
+        return;
+    }
+
+    QJsonObject jsonObject = doc.object();
+/*
+    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Json Listing Boards : " << doc;
+*/
+    QJsonArray jsonArray   = jsonObject[QLatin1String("data")].toArray();
+
+    QList<QPair<QString, QString> > list;
+    QString boardID;<--- Shadowed declaration
+    QString boardName;<--- Shadowed declaration
+
+    foreach (const QJsonValue& value, jsonArray)
+    {
+        QString boardID;<--- Shadow variable
+        QString boardName;<--- Shadow variable
+        QJsonObject obj = value.toObject();
+        boardID         = obj[QLatin1String("id")].toString();
+        boardName       = obj[QLatin1String("name")].toString();
+
+        list.append(qMakePair(boardID, boardName));
+    }
+
+    emit signalBusy(false);
+    emit signalListBoardsDone(list);
+}
+
+void PTalker::parseResponseCreateBoard(const QByteArray& data)
+{
+    QJsonDocument doc      = QJsonDocument::fromJson(data);<--- Shadowed declaration
+    QJsonObject jsonObject = doc.object();
+    bool fail              = jsonObject.contains(QLatin1String("error"));
+
+    emit signalBusy(false);
+
+    if (fail)
+    {
+        QJsonParseError err;
+        QJsonDocument doc = QJsonDocument::fromJson(data, &err);<--- Shadow variable
+        emit signalCreateBoardFailed(jsonObject[QLatin1String("error_summary")].toString());
+    }
+    else
+    {
+        emit signalCreateBoardSucceeded();
+    }
+}
+
+void PTalker::writeSettings()
+{
+    d->settings->beginGroup(d->serviceName);
+    d->settings->setValue(d->serviceKey, d->accessToken);
+    d->settings->endGroup();
+}
+
+void PTalker::readSettings()
+{
+    d->settings->beginGroup(d->serviceName);
+    d->accessToken = d->settings->value(d->serviceKey).toString();
+    d->settings->endGroup();
+
+    if (d->accessToken.isEmpty())
+    {
+        qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Linking...";
+        link();
+    }
+    else
+    {
+        qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Already Linked";
+        emit pinterestLinkingSucceeded();
+    }
+}
+
+} // namespace DigikamGenericPinterestPlugin
 
diff --git a/static/reports/cppcheck/master/4.html b/static/reports/cppcheck/master/4.html index b1c9a0201..25806aa45 100644 --- a/static/reports/cppcheck/master/4.html +++ b/static/reports/cppcheck/master/4.html @@ -1,1967 +1,1815 @@ - Cppcheck - HTML report - digiKam-master-rev-907aafb5fa + Cppcheck - HTML report - digiKam-master-rev-e85fcd090f
  1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
-835
-836
-837
-838
-839
-840
-841
-842
-843
-844
-845
-846
-847
-848
-849
-850
-851
-852
-853
-854
-855
-856
-857
-858
-859
-860
-861
-862
-863
-864
-865
-866
-867
-868
-869
-870
-871
-872
-873
-874
-875
-876
-877
-878
-879
-880
-881
-882
-883
-884
-885
-886
-887
-888
-889
-890
-891
-892
-893
-894
-895
-896
-897
-898
-899
-900
-901
-902
-903
-904
-905
-906
-907
-908
-909
-910
-911
/* ============================================================
+835
/* ============================================================
  *
  * This file is a part of digiKam project
  * https://www.digikam.org
  *
- * Date        : 2005-17-06
- * Description : a tool to export images to Flickr web service
+ * Date        : 2009-12-11
+ * Description : test cases for the various album models
  *
- * Copyright (C) 2005-2008 by Vardhman Jain <vardhman at gmail dot com>
- * Copyright (C) 2008-2020 by Gilles Caulier <caulier dot gilles at gmail dot com>
- * Copyright (C) 2009      by Luka Renko <lure at kubuntu dot org>
- *
- * This program is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General
- * Public License as published by the Free Software Foundation;
- * either version 2, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * ============================================================ */
-
-#include "flickrwindow.h"
-
-// Qt includes
-
-#include <QPushButton>
-#include <QProgressDialog>
-#include <QPixmap>
-#include <QCheckBox>
-#include <QStringList>
-#include <QSpinBox>
-#include <QPointer>
-#include <QApplication>
-#include <QMenu>
-#include <QMessageBox>
-#include <QWindow>
-
-// KDE includes
-
-#include <kconfig.h>
-#include <kwindowconfig.h>
-
-// Local includes
-
-#include "dprogresswdg.h"
-#include "flickrtalker.h"
-#include "flickritem.h"
-#include "flickrlist.h"
-#include "wsselectuserdlg.h"
-#include "digikam_debug.h"
-#include "flickrnewalbumdlg.h"
-#include "previewloadthread.h"
-#include "flickrwidget_p.h"
-
-namespace DigikamGenericFlickrPlugin
-{
-
-class Q_DECL_HIDDEN FlickrWindow::Private
-{
-public:
-
-    explicit Private()
-      : uploadCount(0),
-        uploadTotal(0),
-        newAlbumBtn(nullptr),
-        changeUserButton(nullptr),
-        removeAccount(nullptr),
-        albumsListComboBox(nullptr),
-        publicCheckBox(nullptr),
-        familyCheckBox(nullptr),
-        friendsCheckBox(nullptr),
-        exportHostTagsCheckBox(nullptr),
-        stripSpaceTagsCheckBox(nullptr),
-        addExtraTagsCheckBox(nullptr),
-        originalCheckBox(nullptr),
-        resizeCheckBox(nullptr),
-        dimensionSpinBox(nullptr),
-        imageQualitySpinBox(nullptr),
-        extendedPublicationButton(nullptr),
-        extendedTagsButton(nullptr),
-        contentTypeComboBox(nullptr),
-        safetyLevelComboBox(nullptr),
-        userNameDisplayLabel(nullptr),
-        authProgressDlg(nullptr),
-        tagsLineEdit(nullptr),
-        widget(nullptr),
-        talker(nullptr),
-        imglst(nullptr),
-        select(nullptr),
-        albumDlg(nullptr),
-        iface(nullptr)
-    {
-    }
+ * Copyright (C) 2009 by Johannes Wienke <languitar at semipol dot de>
+ *
+ * This program is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation;
+ * either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * ============================================================ */
+
+#include "albummodeltest.h"
+
+// Qt includes
+
+#include <QDir>
+#include <QTest>
+#include <QDebug>
+#include <QUrl>
+
+// Local includes
+
+#include "albumfiltermodel.h"
+#include "albummanager.h"
+#include "albummodel.h"
+#include "applicationsettings.h"
+#include "albumthumbnailloader.h"
+#include "collectionlocation.h"
+#include "collectionmanager.h"
+#include "loadingcacheinterface.h"
+#include "scancontroller.h"
+#include "thumbnailloadthread.h"
+#include "modeltest.h"
+
+using namespace Digikam;
+
+const QString IMAGE_PATH(QFINDTESTDATA("data/"));
+
+QTEST_MAIN(AlbumModelTest)
+
+AlbumModelTest::AlbumModelTest()
+    : albumCategory(QLatin1String("DummyCategory")),
+      palbumRoot0(nullptr),
+      palbumRoot1(nullptr),
+      palbumRoot2(nullptr),
+      palbumChild0Root0(nullptr),
+      palbumChild1Root0(nullptr),
+      palbumChild2Root0(nullptr),
+      palbumChild0Root1(nullptr),
+      rootTag(nullptr),
+      talbumRoot0(nullptr),
+      talbumRoot1(nullptr),
+      talbumChild0Root0(nullptr),
+      talbumChild1Root0(nullptr),
+      talbumChild0Child1Root0(nullptr),
+      talbumChild0Root1(nullptr),
+      startModel(nullptr)
+{
+}
+
+AlbumModelTest::~AlbumModelTest()
+{
+}
+
+void AlbumModelTest::initTestCase()
+{
+    tempSuffix = QLatin1String("albummodeltest-") + QTime::currentTime().toString();
+    dbPath     = QDir::temp().absolutePath() + QLatin1Char('/') + tempSuffix;
+
+    if (QDir::temp().exists(tempSuffix))
+    {
+        QString msg = QLatin1String("Error creating temp path") + dbPath;
+        QVERIFY2(false, msg.toLatin1().constData());
+    }
+
+    QDir::temp().mkdir(tempSuffix);
+
+    qDebug() << "Using database path for test: " << dbPath;
+
+    ApplicationSettings::instance()->setShowFolderTreeViewItemsCount(true);
+
+    // use a testing database
+
+    AlbumManager::instance();
 
-    unsigned int                     uploadCount;
-    unsigned int                     uploadTotal;
-
-    QString                          serviceName;
+    // catch palbum counts for waiting
+
+    connect(AlbumManager::instance(), SIGNAL(signalPAlbumsDirty(QMap<int,int>)),
+            this, SLOT(setLastPAlbumCountMap(QMap<int,int>)));
 
-    QPushButton*                     newAlbumBtn;
-    QPushButton*                     changeUserButton;
-    QPushButton*                     removeAccount;
-
-    QComboBox*                       albumsListComboBox;
-    QCheckBox*                       publicCheckBox;
-    QCheckBox*                       familyCheckBox;
-    QCheckBox*                       friendsCheckBox;
-    QCheckBox*                       exportHostTagsCheckBox;
-    QCheckBox*                       stripSpaceTagsCheckBox;
-    QCheckBox*                       addExtraTagsCheckBox;
-    QCheckBox*                       originalCheckBox;
-    QCheckBox*                       resizeCheckBox;
-
-    QSpinBox*                        dimensionSpinBox;
-    QSpinBox*                        imageQualitySpinBox;
-
-    QPushButton*                     extendedPublicationButton;
-    QPushButton*                     extendedTagsButton;
-    WSComboBoxIntermediate*          contentTypeComboBox;
-    WSComboBoxIntermediate*          safetyLevelComboBox;
-
-    QString                          username;
-    QString                          userId;
-    QString                          lastSelectedAlbum;
-
-    QLabel*                          userNameDisplayLabel;
-
-    QProgressDialog*                 authProgressDlg;
-
-    QList< QPair<QUrl, FPhotoInfo> > uploadQueue;
-
-    QLineEdit*                       tagsLineEdit;
-
-    FlickrWidget*                    widget;
-    FlickrTalker*                    talker;
+    AlbumManager::checkDatabaseDirsAfterFirstRun(QDir::temp().absoluteFilePath(
+                                                 tempSuffix), QDir::temp().absoluteFilePath(tempSuffix));
+    DbEngineParameters params(QLatin1String("QSQLITE"), QDir::temp().absoluteFilePath(tempSuffix + QLatin1String("/digikam4.db")),
+                              QString(), QString(), -1, false, QString(), QString());
+    bool dbChangeGood = AlbumManager::instance()->setDatabase(params, false,
+                        QDir::temp().absoluteFilePath(tempSuffix));
+    QVERIFY2(dbChangeGood, "Could not set temp album db");
+    QList<CollectionLocation> locs = CollectionManager::instance()->allAvailableLocations();
+    QVERIFY2(locs.size(), "Failed to auto-create one collection in setDatabase");
+
+    ScanController::instance()->completeCollectionScan();
+    AlbumManager::instance()->startScan();
+
+    AlbumList all = AlbumManager::instance()->allPAlbums();
+    qDebug() << "PAlbum registered : " << all.size();
+
+    foreach (Album* const a, all)
+    {
+        if (a)
+        {
+            qDebug() << " ==> Id : " << a->id() << " , is root : " << a->isRoot() << " , title : " << a->title();
+        }
+    }
+
+    QVERIFY2( all.size() == 3, "Failed to scan empty directory. We must have one root album, one album, and one trash.");
+}
+
+void AlbumModelTest::cleanupTestCase()
+{
+    qDebug() << "Start AlbumModelTest::cleanupTestCase()";
+
+    ScanController::instance()->shutDown();
+    AlbumManager::instance()->cleanUp();
+    ThumbnailLoadThread::cleanUp();
+    AlbumThumbnailLoader::instance()->cleanUp();
+    LoadingCacheInterface::cleanUp();
 
-    FlickrList*                      imglst;
-    WSSelectUserDlg*                 select;
-    FlickrNewAlbumDlg*               albumDlg;
-
-    DInfoInterface*                  iface;
-};
-
-FlickrWindow::FlickrWindow(DInfoInterface* const iface,
-                           QWidget* const /*parent*/,
-                           const QString& serviceName)
-    : WSToolDialog(nullptr, QString::fromLatin1("%1Export Dialog").arg(serviceName)),
-      d(new Private)
-{
-    d->iface       = iface;
-    d->serviceName = serviceName;
-    setWindowTitle(i18n("Export to %1 Web Service", d->serviceName));
-    setModal(false);
+    QDir dir(dbPath);
+    dir.removeRecursively();
+
+    qDebug() << "deleted test folder " << dbPath;
+}
+
+// Qt test doesn't use exceptions, so using assertion macros in methods called
+// from a test slot doesn't stop the test method and may result in inconsistent
+// data or segfaults. Therefore use macros for these functions.
+
+#define safeCreatePAlbum(parent, name, result) \
+{ \
+    QString error; \
+    result = AlbumManager::instance()->createPAlbum(parent, name, name, \
+                    QDate::currentDate(), albumCategory, error); \
+    QVERIFY2(result, QString::fromUtf8("Error creating PAlbum for test: %1").arg(error).toLatin1().constData()); \
+}
 
-    KConfig config;
-    KConfigGroup grp = config.group(QString::fromLatin1("%1Export Settings").arg(d->serviceName));
-
-    if (grp.exists())
-    {
-        qCDebug(DIGIKAM_WEBSERVICES_LOG) << QString::fromLatin1("%1Export Settings").arg(d->serviceName) << " exists, deleting it";
-        grp.deleteGroup();
-    }
-
-    d->select                    = new WSSelectUserDlg(nullptr, serviceName);
-    d->uploadCount               = 0;
-    d->uploadTotal               = 0;
-    d->widget                    = new FlickrWidget(this, iface, serviceName);
-    d->albumDlg                  = new FlickrNewAlbumDlg(this, QLatin1String("Flickr"));
-    d->albumsListComboBox        = d->widget->getAlbumsCoB();
-    d->newAlbumBtn               = d->widget->getNewAlbmBtn();
-    d->originalCheckBox          = d->widget->getOriginalCheckBox();
-    d->resizeCheckBox            = d->widget->getResizeCheckBox();
-    d->publicCheckBox            = d->widget->d->publicCheckBox;
-    d->familyCheckBox            = d->widget->d->familyCheckBox;
-    d->friendsCheckBox           = d->widget->d->friendsCheckBox;
-    d->dimensionSpinBox          = d->widget->getDimensionSpB();
-    d->imageQualitySpinBox       = d->widget->getImgQualitySpB();
-    d->extendedTagsButton        = d->widget->d->extendedTagsButton;
-    d->addExtraTagsCheckBox      = d->widget->d->addExtraTagsCheckBox;
-    d->extendedPublicationButton = d->widget->d->extendedPublicationButton;
-    d->safetyLevelComboBox       = d->widget->d->safetyLevelComboBox;
-    d->contentTypeComboBox       = d->widget->d->contentTypeComboBox;
-    d->tagsLineEdit              = d->widget->d->tagsLineEdit;
-    d->exportHostTagsCheckBox    = d->widget->d->exportHostTagsCheckBox;
-    d->stripSpaceTagsCheckBox    = d->widget->d->stripSpaceTagsCheckBox;
-    d->changeUserButton          = d->widget->getChangeUserBtn();
-    d->removeAccount             = d->widget->d->removeAccount;
-    d->userNameDisplayLabel      = d->widget->getUserNameLabel();
-    d->imglst                    = d->widget->d->imglst;
+#define safeCreateTAlbum(parent, name, result) \
+{ \
+    QString error; \
+    result = AlbumManager::instance()->createTAlbum(parent, name, QLatin1String(""), error); \
+    QVERIFY2(result, QString::fromUtf8("Error creating TAlbum for test: %1").arg(error).toLatin1().constData()); \
+}
+
+void AlbumModelTest::init()
+{
+    qDebug() << "Start AlbumModelTest::init()";
+
+    palbumCountMap.clear();
+
+    // create a model to check that model work is done correctly while scanning
+
+    addedIds.clear();
+    startModel = new AlbumModel;
+    startModel->setShowCount(true);
+
+    connect(startModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
+            this, SLOT(slotStartModelRowsInserted(QModelIndex,int,int)));
+
+    connect(startModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
+            this, SLOT(slotStartModelDataChanged(QModelIndex,QModelIndex)));
+
+    qDebug() << "Created startModel" << startModel;
+
+    // ensure that this model is empty in the beginning except for the root
+    // album and the collection that include trash
+
+    QCOMPARE(startModel->rowCount(), 1);
+    QModelIndex rootIndex = startModel->index(0, 0);
+    QCOMPARE(startModel->rowCount(rootIndex), 1);
+    QModelIndex collectionIndex = startModel->index(0, 0, rootIndex);
+    QCOMPARE(startModel->rowCount(collectionIndex), 1);
 
-    startButton()->setText(i18n("Start Uploading"));
-    startButton()->setToolTip(QString());
-
-    setMainWidget(d->widget);
-    d->widget->setMinimumSize(800, 600);
+    // insert some test data
+
+    // physical albums
+
+    // create two of them by creating directories and scanning
 
-    connect(d->imglst, SIGNAL(signalImageListChanged()),
-            this, SLOT(slotImageListChanged()));
-
-    // --------------------------------------------------------------------------
-
-    d->talker = new FlickrTalker(this, serviceName, d->iface);
+    QDir dir(dbPath);
+    dir.mkdir(QLatin1String("root0"));
+    dir.mkdir(QLatin1String("root1"));
+
+    ScanController::instance()->completeCollectionScan();
+    AlbumManager::instance()->refresh();
 
-    connect(d->talker, SIGNAL(signalError(QString)),
-            d->talker, SLOT(slotError(QString)));
-
-    connect(d->talker, SIGNAL(signalBusy(bool)),
-            this, SLOT(slotBusy(bool)));
-
-    connect(d->talker, SIGNAL(signalAddPhotoSucceeded(QString)),
-            this, SLOT(slotAddPhotoSucceeded(QString)));
-
-    connect(d->talker, SIGNAL(signalAddPhotoFailed(QString)),
-            this, SLOT(slotAddPhotoFailed(QString)));
-
-    connect(d->talker, SIGNAL(signalAddPhotoSetSucceeded()),
-            this, SLOT(slotAddPhotoSetSucceeded()));
-
-    connect(d->talker, SIGNAL(signalListPhotoSetsSucceeded()),
-            this, SLOT(slotPopulatePhotoSetComboBox()));
-
-    connect(d->talker, SIGNAL(signalListPhotoSetsFailed(QString)),
-            this, SLOT(slotListPhotoSetsFailed(QString)));
-
-    connect(d->talker, SIGNAL(signalLinkingSucceeded()),
-            this, SLOT(slotLinkingSucceeded()));
-
-    connect(d->widget->progressBar(), SIGNAL(signalProgressCanceled()),
-            this, SLOT(slotAddPhotoCancelAndClose()));
-
-    connect(d->widget->getReloadBtn(), SIGNAL(clicked()),
-            this, SLOT(slotReloadPhotoSetRequest()));
+    QCOMPARE(AlbumManager::instance()->allPAlbums().size(), 5);
+
+    QString error;<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration
+    palbumRoot0 = AlbumManager::instance()->findPAlbum(QUrl::fromLocalFile(dbPath + QLatin1String("/root0")));
+    QVERIFY2(palbumRoot0, "Error having PAlbum root0 in AlbumManager");
+    palbumRoot1 = AlbumManager::instance()->findPAlbum(QUrl::fromLocalFile(dbPath + QLatin1String("/root1")));
+    QVERIFY2(palbumRoot1, "Error having PAlbum root1 in AlbumManager");
+
+    // Create some more through AlbumManager
+
+    palbumRoot2 = AlbumManager::instance()->createPAlbum(dbPath, QLatin1String("root2"),
+                  QLatin1String("root album 2"), QDate::currentDate(), albumCategory, error);
+    QVERIFY2(palbumRoot2, QString::fromUtf8("Error creating PAlbum for test: %1").arg(error).toLatin1().constData());
+
+    safeCreatePAlbum(palbumRoot0, QLatin1String("root0child0"), palbumChild0Root0);<--- Shadow variable
+    safeCreatePAlbum(palbumRoot0, QLatin1String("root0child1"), palbumChild1Root0);<--- Shadow variable
+    const QString sameName = QLatin1String("sameName Album");
+    safeCreatePAlbum(palbumRoot0, sameName, palbumChild2Root0);<--- Shadow variable
+
+    safeCreatePAlbum(palbumRoot1, sameName, palbumChild0Root1);<--- Shadow variable
+
+    qDebug() << "AlbumManager now knows these PAlbums:";
+
+    foreach (Album* const a, AlbumManager::instance()->allPAlbums())
+    {
+        qDebug() << "\t" << a->title();
+    }
+
+    // tags
 
-    // --------------------------------------------------------------------------
-
-    connect(d->changeUserButton, SIGNAL(clicked()),
-            this, SLOT(slotUserChangeRequest()));
-
-    connect(d->removeAccount, SIGNAL(clicked()),
-            this, SLOT(slotRemoveAccount()));
-
-    connect(d->newAlbumBtn, SIGNAL(clicked()),
-            this, SLOT(slotCreateNewPhotoSet()));
-
-    // --------------------------------------------------------------------------
-
-    d->authProgressDlg = new QProgressDialog(this);
-    d->authProgressDlg->setModal(true);
-    d->authProgressDlg->setAutoReset(true);
-    d->authProgressDlg->setAutoClose(true);
-    d->authProgressDlg->setMaximum(0);
-    d->authProgressDlg->reset();
-
-    connect(d->authProgressDlg, SIGNAL(canceled()),
-            this, SLOT(slotAuthCancel()));
-
-    d->talker->m_authProgressDlg = d->authProgressDlg;
-
-    // --------------------------------------------------------------------------
-
-    connect(this, &QDialog::finished,
-            this, &FlickrWindow::slotFinished);
-
-    connect(this, SIGNAL(cancelClicked()),
-            this, SLOT(slotCancelClicked()));
-
-    connect(startButton(), &QPushButton::clicked,
-            this, &FlickrWindow::slotUser1);
-
-    d->select->reactivate();
-    readSettings(d->select->getUserName());
-    d->talker->link(d->select->getUserName());
-}
+    rootTag = AlbumManager::instance()->findTAlbum(0);
+    QVERIFY(rootTag);
+
+    safeCreateTAlbum(rootTag, QLatin1String("root0"), talbumRoot0);<--- Shadow variable
+    safeCreateTAlbum(rootTag, QLatin1String("root1"), talbumRoot1);<--- Shadow variable
+
+    safeCreateTAlbum(talbumRoot0, QLatin1String("child0 root 0"), talbumChild0Root0);<--- Shadow variable
+    safeCreateTAlbum(talbumRoot0, QLatin1String("child1 root 0"), talbumChild1Root0);<--- Shadow variable
+
+    safeCreateTAlbum(talbumChild1Root0, sameName, talbumChild0Child1Root0);<--- Shadow variable
+
+    safeCreateTAlbum(talbumRoot1, sameName, talbumChild0Root1);<--- Shadow variable
+
+    qDebug() << "created tags";
+
+    // add some images for having date albums
+
+    QDir imageDir(IMAGE_PATH);
+    imageDir.setNameFilters(QStringList() << QLatin1String("*.jpg"));
+    QStringList imageFiles = imageDir.entryList();
+
+    qDebug() << "copying images " << imageFiles << " to "
+             << palbumChild0Root0->fileUrl();
+
+    foreach (const QString& imageFile, imageFiles)
+    {
+        QString src = IMAGE_PATH + QLatin1Char('/') + imageFile;
+        QString dst = palbumChild0Root0->fileUrl().toLocalFile() + QLatin1Char('/') + imageFile;
+        bool copied = QFile::copy(src, dst);
+        QVERIFY2(copied, "Test images must be copied");
+    }
+
+    ScanController::instance()->completeCollectionScan();
+
+    if (AlbumManager::instance()->allDAlbums().count() <= 1)
+    {
+        ensureItemCounts();
+    }
+
+    qDebug() << "date albums: " << AlbumManager::instance()->allDAlbums();
 
-FlickrWindow::~FlickrWindow()
-{
-    delete d->select;
-    delete d->authProgressDlg;
-    delete d->talker;
-    delete d->widget;
-    delete d;
-}
-
-void FlickrWindow::setItemsList(const QList<QUrl>& urls)
-{
-    d->widget->imagesList()->slotAddImages(urls);
-}
-
-void FlickrWindow::closeEvent(QCloseEvent* e)
-{
-    if (!e)
-    {
-        return;
+    // root + 2 years + 2 and 3 months per year + (1997 as test year for date ordering with 12 months) = 21
+
+    QCOMPARE(AlbumManager::instance()->allDAlbums().size(), 21);
+
+    // ensure that there is a root date album
+
+    DAlbum* const rootFromAlbumManager = AlbumManager::instance()->findDAlbum(0);
+    QVERIFY(rootFromAlbumManager);
+    DAlbum* rootFromList               = nullptr;
+
+    foreach (Album* const album, AlbumManager::instance()->allDAlbums())
+    {
+        DAlbum* const dAlbum = dynamic_cast<DAlbum*> (album);
+        QVERIFY(dAlbum);
+
+        if (dAlbum->isRoot())
+        {
+            rootFromList = dAlbum;
+        }
     }
 
-    slotFinished();
-    e->accept();
+    QVERIFY(rootFromList);
+    QVERIFY(rootFromList == rootFromAlbumManager);
 }
 
-void FlickrWindow::slotFinished()
+void AlbumModelTest::testStartAlbumModel()
 {
-    writeSettings();
-    d->imglst->listView()->clear();
-}
+    qDebug() << "Start AlbumModelTest::testStartAlbumModel()";
+
+    // verify that the start album model got all these changes
 
-void FlickrWindow::setUiInProgressState(bool inProgress)
-{
-    setRejectButtonMode(inProgress ? QDialogButtonBox::Cancel : QDialogButtonBox::Close);
+    // one root
+
+    QCOMPARE(startModel->rowCount(), 1);
 
-    if (inProgress)
-    {
-        d->widget->progressBar()->show();
-    }
-    else
-    {
-        d->widget->progressBar()->hide();
-        d->widget->progressBar()->progressCompleted();
-    }
-}
-
-void FlickrWindow::slotCancelClicked()
-{
-    d->talker->cancel();
-    d->uploadQueue.clear();
-    setUiInProgressState(false);
+    // one collection
+
+    QModelIndex rootIndex = startModel->index(0, 0);
+    QCOMPARE(startModel->rowCount(rootIndex), 1);
+
+    // two albums in the collection
+
+    QModelIndex collectionIndex = startModel->index(0, 0, rootIndex);
+    QCOMPARE(startModel->rowCount(collectionIndex), 3);
+
+    // this is should be enough for now
+
+    // We must have received an added notation for everything except album root
+    // and collection
+
+    QCOMPARE(addedIds.size(), 7);
 }
 
-void FlickrWindow::slotAddPhotoCancelAndClose()
+void AlbumModelTest::ensureItemCounts()
 {
-    writeSettings();
-    d->imglst->listView()->clear();
-    d->uploadQueue.clear();
-    d->widget->progressBar()->reset();
-    setUiInProgressState(false);
-    d->talker->cancel();
-    reject();
-}
-
-void FlickrWindow::reactivate()
-{
-    d->userNameDisplayLabel->setText(QString());
-    readSettings(d->select->getUserName());
-    d->talker->link(d->select->getUserName());
-
-    d->widget->d->imglst->loadImagesFromCurrentSelection();
-    show();
-}
+    // trigger listing job
+
+    QEventLoop dAlbumLoop;
+
+    connect(AlbumManager::instance(), SIGNAL(signalAllDAlbumsLoaded()),
+            &dAlbumLoop, SLOT(quit()));
+
+    AlbumManager::instance()->prepareItemCounts();
+    qDebug() << "Waiting for AlbumManager to create DAlbums...";
+    dAlbumLoop.exec();
+    qDebug() << "DAlbums were created";
+
+    while (palbumCountMap.size() < 8)
+    {
+        QEventLoop pAlbumLoop;
+
+        connect(AlbumManager::instance(), SIGNAL(signalPAlbumsDirty(QMap<int,int>)),
+                &pAlbumLoop, SLOT(quit()));
 
-void FlickrWindow::readSettings(QString uname)
-{
-    KConfig config;
-    QString groupName = QString::fromLatin1("%1%2Export Settings").arg(d->serviceName, uname);
-    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Group name is:" << groupName;
-    KConfigGroup grp  = config.group(groupName);
-
-    d->exportHostTagsCheckBox->setChecked(grp.readEntry("Export Host Tags",                     false));
-    d->extendedTagsButton->setChecked(grp.readEntry("Show Extended Tag Options",                false));
-    d->addExtraTagsCheckBox->setChecked(grp.readEntry("Add Extra Tags",                         false));
-    d->stripSpaceTagsCheckBox->setChecked(grp.readEntry("Strip Space From Tags",                false));
-    d->publicCheckBox->setChecked(grp.readEntry("Public Sharing",                               false));
-    d->familyCheckBox->setChecked(grp.readEntry("Family Sharing",                               false));
-    d->friendsCheckBox->setChecked(grp.readEntry("Friends Sharing",                             false));
-    d->extendedPublicationButton->setChecked(grp.readEntry("Show Extended Publication Options", false));
-
-    int safetyLevel = d->safetyLevelComboBox->findData(QVariant(grp.readEntry("Safety Level", 0)));
-
-    if (safetyLevel == -1)
-    {
-        safetyLevel = 0;
+        qDebug() << "Waiting for first PAlbum count map";
+        pAlbumLoop.exec();
+        qDebug() << "Got new PAlbum count map";
+    }
+}
+
+void AlbumModelTest::slotStartModelRowsInserted(const QModelIndex& parent, int start, int end)
+{
+    qDebug() << "called, parent:" << parent << ", start:" << start << ", end:" << end;
+
+    for (int row = start ; row <= end ; ++row)
+    {
+        QModelIndex child = startModel->index(row, 0, parent);
+        QVERIFY(child.isValid());
+        Album* album      = startModel->albumForIndex(child);
+        const int id      = child.data(AbstractAlbumModel::AlbumIdRole).toInt();
+        QVERIFY(album);
+        qDebug() << "added album with id"
+                 << id
+                 << "and name" << album->title();
+        addedIds << id;
     }
-
-    d->safetyLevelComboBox->setCurrentIndex(safetyLevel);
-
-    int contentType = d->contentTypeComboBox->findData(QVariant(grp.readEntry("Content Type", 0)));
-
-    if (contentType == -1)
-    {
-        contentType = 0;
-    }
-
-    d->contentTypeComboBox->setCurrentIndex(contentType);
-
-    d->originalCheckBox->setChecked(grp.readEntry("Upload Original", false));
-    d->resizeCheckBox->setChecked(grp.readEntry("Resize",            false));
-    d->dimensionSpinBox->setValue(grp.readEntry("Maximum Width",     1600));
-    d->imageQualitySpinBox->setValue(grp.readEntry("Image Quality",  85));
-
-    winId();
-    KConfigGroup dialogGroup = config.group(QString::fromLatin1("%1Export Dialog").arg(d->serviceName));
-    KWindowConfig::restoreWindowSize(windowHandle(), dialogGroup);
-    resize(windowHandle()->size());
-}
-
-void FlickrWindow::writeSettings()
-{
-    KConfig config;
-    QString groupName = QString::fromLatin1("%1%2Export Settings").arg(d->serviceName, d->username);
-    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Group name is:" << groupName;
-
-    if (QString::compare(QString::fromLatin1("%1Export Settings").arg(d->serviceName), groupName) == 0)
-    {
-        qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Not writing entry of group" << groupName;
-        return;
-    }
-
-    KConfigGroup grp = config.group(groupName);
-
-    grp.writeEntry("username",                          d->username);
-    grp.writeEntry("Export Host Tags",                  d->exportHostTagsCheckBox->isChecked());
-    grp.writeEntry("Show Extended Tag Options",         d->extendedTagsButton->isChecked());
-    grp.writeEntry("Add Extra Tags",                    d->addExtraTagsCheckBox->isChecked());
-    grp.writeEntry("Strip Space From Tags",             d->stripSpaceTagsCheckBox->isChecked());
-    grp.writeEntry("Public Sharing",                    d->publicCheckBox->isChecked());
-    grp.writeEntry("Family Sharing",                    d->familyCheckBox->isChecked());
-    grp.writeEntry("Friends Sharing",                   d->friendsCheckBox->isChecked());
-    grp.writeEntry("Show Extended Publication Options", d->extendedPublicationButton->isChecked());
-    int safetyLevel = d->safetyLevelComboBox->itemData(d->safetyLevelComboBox->currentIndex()).toInt();
-    grp.writeEntry("Safety Level",                      safetyLevel);
-    int contentType = d->contentTypeComboBox->itemData(d->contentTypeComboBox->currentIndex()).toInt();
-    grp.writeEntry("Content Type",                      contentType);
-    grp.writeEntry("Resize",                            d->resizeCheckBox->isChecked());
-    grp.writeEntry("Upload Original",                   d->originalCheckBox->isChecked());
-    grp.writeEntry("Maximum Width",                     d->dimensionSpinBox->value());
-    grp.writeEntry("Image Quality",                     d->imageQualitySpinBox->value());
-    KConfigGroup dialogGroup = config.group(QString::fromLatin1("%1Export Dialog").arg(d->serviceName));
-    KWindowConfig::saveWindowSize(windowHandle(), dialogGroup);
-    config.sync();
-}
-
-void FlickrWindow::slotLinkingSucceeded()
-{
-    d->username = d->talker->getUserName();
-    d->userId   = d->talker->getUserId();
-    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "SlotLinkingSucceeded invoked setting user Display name to" << d->username;
-    d->userNameDisplayLabel->setText(QString::fromLatin1("<b>%1</b>").arg(d->username));
+}
+
+void AlbumModelTest::slotStartModelDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight)
+{
+    for (int row = topLeft.row() ; row <= bottomRight.row() ; ++row)
+    {
+        QModelIndex index = startModel->index(row, topLeft.column(), topLeft.parent());
+
+        if (!index.isValid())
+        {
+            qDebug() << "Illegal index received";
+            continue;
+        }
+
+        int albumId = index.data(AbstractAlbumModel::AlbumIdRole).toInt();
+
+        if (!addedIds.contains(albumId))
+        {
+            QString message = QLatin1String("Album id ") + QString::number(albumId) +
+                              QLatin1String(" was changed before adding signal was received");
+            QFAIL(message.toLatin1().constData());
+            qDebug() << message;
+        }
+    }
+}
+
+void AlbumModelTest::deletePAlbum(PAlbum* album)
+{
+    QDir dir(album->folderPath());
+    dir.removeRecursively();
+}
+
+void AlbumModelTest::setLastPAlbumCountMap(const QMap<int, int> &map)
+{
+    qDebug() << "Receiving new count map "<< map;
+    palbumCountMap = map;
+}
+
+void AlbumModelTest::cleanup()
+{
+    if (startModel)
+    {
+        disconnect(startModel);
+    }
+
+    delete startModel;
+    addedIds.clear();
+
+    // remove all test data
+
+    AlbumManager::instance()->refresh();
+
+    // remove all palbums' directories
+
+    deletePAlbum(palbumRoot0);
+    deletePAlbum(palbumRoot1);
+    deletePAlbum(palbumRoot2);
+
+    // take over changes to database
+
+    ScanController::instance()->completeCollectionScan();
+
+    // reread from database
+
+    AlbumManager::instance()->refresh();
 
-    KConfig config;
+    // root + one collection
 
-    foreach (const QString& group, config.groupList())
-    {
-        if (!(group.contains(d->serviceName)))
-        {
-            continue;
-        }
-
-        KConfigGroup grp = config.group(group);
-
-        if (group.contains(d->username))
-        {
-            readSettings(d->username);
-            break;
-        }
-    }
-
-    writeSettings();
-    d->talker->listPhotoSets();
-}
-
-void FlickrWindow::slotBusy(bool val)
-{
-    if (val)
-    {
-        setCursor(Qt::WaitCursor);
-    }
-    else
-    {
-        setCursor(Qt::ArrowCursor);
-    }
-}
+    QCOMPARE(AlbumManager::instance()->allPAlbums().size(), 2);
+
+    // remove all tags
+
+    QString error;
+    bool removed = AlbumManager::instance()->deleteTAlbum(talbumRoot0, error, false);
+    QVERIFY2(removed, QString::fromUtf8("Error removing a tag: %1").arg(error).toLatin1().constData());
+    removed      = AlbumManager::instance()->deleteTAlbum(talbumRoot1, error, false);
+    QVERIFY2(removed, QString::fromUtf8("Error removing a tag: %1").arg(error).toLatin1().constData());
+
+    QCOMPARE(AlbumManager::instance()->allTAlbums().size(), 1);
+}
+
+void AlbumModelTest::testPAlbumModel()
+{
+    qDebug() << "Start AlbumModelTest::testPAlbumModel()";
+
+    AlbumModel* albumModel = new AlbumModel();
+    ModelTest* test        = new ModelTest(albumModel, nullptr);
+    delete test;
+    delete albumModel;
+
+    albumModel = new AlbumModel(AbstractAlbumModel::IgnoreRootAlbum);
+    test       = new ModelTest(albumModel, nullptr);
+    delete test;
+    delete albumModel;
+}
+
+void AlbumModelTest::testDisablePAlbumCount()
+{
+    qDebug() << "Start AlbumModelTest::testDisablePAlbumCount()";
 
-void FlickrWindow::slotError(const QString& msg)
-{
-    QMessageBox::critical(this, i18n("Error"), msg);
-}
-
-void FlickrWindow::slotUserChangeRequest()
-{
-    writeSettings();
-    d->userNameDisplayLabel->setText(QString());
-    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Slot Change User Request";
-    d->select->reactivate();
-    readSettings(d->select->getUserName());
+    AlbumModel albumModel;
+    albumModel.setCountMap(palbumCountMap);
+    albumModel.setShowCount(true);
+
+    QRegExp countRegEx(QLatin1String(".+ \\(\\d+\\)"));
+    countRegEx.setMinimal(true);
+    QVERIFY(countRegEx.exactMatch(QLatin1String("test (10)")));
+    QVERIFY(countRegEx.exactMatch(QLatin1String("te st (10)")));
+    QVERIFY(countRegEx.exactMatch(QLatin1String("te st (0)")));
+    QVERIFY(!countRegEx.exactMatch(QLatin1String("te st ()")));
+    QVERIFY(!countRegEx.exactMatch(QLatin1String("te st")));
+    QVERIFY(!countRegEx.exactMatch(QLatin1String("te st (10) bla")));
 
-    d->talker->link(d->select->getUserName());
-}
-
-void FlickrWindow::slotRemoveAccount()
-{
-    KConfig config;
-    QString groupName = QString::fromLatin1("%1%2Export Settings").arg(d->serviceName, d->username);
-    KConfigGroup grp  = config.group(groupName);
-
-    if (grp.exists())
-    {
-        qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Removing Account having group" << groupName;
-        grp.deleteGroup();
-    }
-
-    d->talker->unLink();
-    d->talker->removeUserName(d->serviceName + d->username);
-
-    d->userNameDisplayLabel->setText(QString());
-    d->username = QString();
-}
-
-/**
- * Try to guess a sensible set name from the urls given.
- * Currently, it extracs the last path name component, and returns the most
- * frequently seen. The function could be expanded to, for example, only
- * accept the path if it occurs at least 50% of the time. It could also look
- * further up in the path name.
- */
-QString FlickrWindow::guessSensibleSetName(const QList<QUrl>& urlList) const
-{
-    QMap<QString, int> nrFolderOccurences;
-
-    // Extract last component of directory
-
-    foreach (const QUrl& url, urlList)
-    {
-        QString dir      = url.adjusted(QUrl::RemoveFilename | QUrl::StripTrailingSlash).toLocalFile();
-        QStringList list = dir.split(QLatin1Char('/'));
-
-        if (list.isEmpty())
-        {
-            continue;
-        }
+    // ensure that all albums except the root album have a count attached
+
+    QModelIndex rootIndex = albumModel.index(0, 0, QModelIndex());
+    QString rootTitle     = albumModel.data(rootIndex, Qt::DisplayRole).toString();
+    QVERIFY(!countRegEx.exactMatch(rootTitle));
+
+    for (int collectionRow = 0; collectionRow < albumModel.rowCount(rootIndex); ++collectionRow)
+    {
+        QModelIndex collectionIndex = albumModel.index(collectionRow, 0, rootIndex);
+        QString collectionTitle = albumModel.data(collectionIndex, Qt::DisplayRole).toString();
+        QVERIFY2(countRegEx.exactMatch(collectionTitle), QString::fromUtf8("%1 matching error").arg(collectionTitle).toLatin1().constData());
+
+        for (int albumRow = 0; albumRow < albumModel.rowCount(collectionIndex); ++albumRow)
+        {
+            QModelIndex albumIndex = albumModel.index(albumRow, 0, collectionIndex);
+            QString albumTitle     = albumModel.data(albumIndex, Qt::DisplayRole).toString();
+            QVERIFY2(countRegEx.exactMatch(albumTitle), QString::fromUtf8("%1 matching error").arg(albumTitle).toLatin1().constData());
+        }
+
+    }
+
+    // now disable showing the count
+
+    albumModel.setShowCount(false);
+
+    // ensure that no album has a count attached
+
+    rootTitle = albumModel.data(rootIndex, Qt::DisplayRole).toString();
+    QVERIFY(!countRegEx.exactMatch(rootTitle));
+
+    for (int collectionRow = 0; collectionRow < albumModel.rowCount(rootIndex); ++collectionRow)
+    {
+        QModelIndex collectionIndex = albumModel.index(collectionRow, 0, rootIndex);
+        QString collectionTitle     = albumModel.data(collectionIndex, Qt::DisplayRole).toString();
+        QVERIFY2(!countRegEx.exactMatch(collectionTitle), QString::fromUtf8("%1 matching error").arg(collectionTitle).toLatin1().constData());
+
+        for (int albumRow = 0; albumRow < albumModel.rowCount(collectionIndex); ++albumRow)
+        {
+            QModelIndex albumIndex = albumModel.index(albumRow, 0, collectionIndex);
+            QString albumTitle     = albumModel.data(albumIndex, Qt::DisplayRole).toString();
+            QVERIFY2(!countRegEx.exactMatch(albumTitle), QString::fromUtf8("%1 matching error").arg(albumTitle).toLatin1().constData());
+        }
+    }
+}
 
-        nrFolderOccurences[list.last()]++;
-    }
-
-    int maxCount   = 0;
-    int totalCount = 0;
-    QString name;
-
-    for (QMap<QString, int>::const_iterator it = nrFolderOccurences.constBegin() ;
-         it != nrFolderOccurences.constEnd() ; ++it)
-    {
-        totalCount += it.value();
-
-        if (it.value() > maxCount)
-        {
-            maxCount = it.value();
-            name     = it.key();
-        }
-    }
-
-    // If there is only one entry or one name appears at least twice, return the suggestion
-
-    if ((totalCount == 1) || (maxCount > 1))
-    {
-        return name;
-    }
-
-    return QString();
-}
+void AlbumModelTest::testDAlbumModel()
+{
+    qDebug() << "Start AlbumModelTest::testDAlbumModel()";
+
+    DateAlbumModel* const albumModel = new DateAlbumModel();
+    ensureItemCounts();
+    ModelTest* const test            = new ModelTest(albumModel, nullptr);
+    delete test;
+    delete albumModel;
+}
+
+void AlbumModelTest::testDAlbumContainsAlbums()
+{
+    qDebug() << "Start AlbumModelTest::testDAlbumContainsAlbums()";
+
+    DateAlbumModel* const albumModel = new DateAlbumModel();
+    ensureItemCounts();
+
+    QVERIFY(albumModel->rootAlbum());
+
+    foreach (Album* const album, AlbumManager::instance()->allDAlbums())
+    {
+        DAlbum* const dAlbum = dynamic_cast<DAlbum*> (album);
+        QVERIFY(dAlbum);
+
+        qDebug() << "checking album for date " << dAlbum->date() << ", range = " << dAlbum->range();
+
+        QModelIndex index = albumModel->indexForAlbum(dAlbum);
 
-/**
- * This method is called when the photo set creation button is pressed. It
- * summons a creation dialog for user input. When that is closed, it
- * creates a new photo set in the local list. The id gets the form of
- * UNDEFINED_ followed by a number, to indicate that it doesn't exist on
- * Flickr yet.
- */
-void FlickrWindow::slotCreateNewPhotoSet()
-{
-    if (d->albumDlg->exec() == QDialog::Accepted)
-    {
-        FPhotoSet fps;<--- Shadowed declaration
-        d->albumDlg->getFolderProperties(fps);
-        qCDebug(DIGIKAM_WEBSERVICES_LOG) << "in slotCreateNewPhotoSet()" << fps.title;
-
-        // Lets find an UNDEFINED_ style id that isn't taken yet.s
-
-        QString id;
-        int i                               = 0;
-        id                                  = QLatin1String("UNDEFINED_") + QString::number(i);
-        QLinkedList<FPhotoSet>::iterator it = d->talker->m_photoSetsList->begin();
-
-        while (it != d->talker->m_photoSetsList->end())
-        {
-            FPhotoSet fps = *it;<--- Shadow variable
-
-            if (fps.id == id)
-            {
-                id = QLatin1String("UNDEFINED_") + QString::number(++i);
-                it = d->talker->m_photoSetsList->begin();
-            }
-
-            ++it;
-        }
-
-        fps.id = id;
-
-        qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Created new photoset with temporary id" << id;
-
-        // Append the new photoset to the list.
-
-        d->talker->m_photoSetsList->prepend(fps);
-        d->talker->m_selectedPhotoSet = fps;
-
-        // Re-populate the photo sets combo box.
-
-        slotPopulatePhotoSetComboBox();
-    }
-    else
-    {
-        qCDebug(DIGIKAM_WEBSERVICES_LOG) << "New Photoset creation aborted";
-    }
-}
-
-void FlickrWindow::slotAuthCancel()
-{
-    d->talker->cancel();
-    d->authProgressDlg->hide();
-}
-
-void FlickrWindow::slotPopulatePhotoSetComboBox()
-{
-    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "slotPopulatePhotoSetComboBox invoked";
-
-    if (d->talker && d->talker->m_photoSetsList)
-    {
-        QLinkedList <FPhotoSet>* const list = d->talker->m_photoSetsList;
-        d->albumsListComboBox->clear();
-        d->albumsListComboBox->insertItem(0, i18n("Photostream Only"));
-        d->albumsListComboBox->insertSeparator(1);
-        QLinkedList<FPhotoSet>::iterator it = list->begin();
-        int index                           = 2;
-        int curr_index                      = 0;
+        if (!dAlbum->isRoot())
+        {
+            QVERIFY(index.isValid());
+        }
+
+        if (dAlbum->isRoot())
+        {
+            // root album
+
+            QVERIFY(dAlbum->isRoot());
+            QCOMPARE(albumModel->rowCount(index), 3);
+            QCOMPARE(index, albumModel->rootAlbumIndex());
+        }
+        else if (dAlbum->range() == DAlbum::Year && dAlbum->date().year() == 2007)
+        {
+            QCOMPARE(albumModel->rowCount(index), 2);
+        }
+        else if (dAlbum->range() == DAlbum::Year && dAlbum->date().year() == 2009)
+        {
+            QCOMPARE(albumModel->rowCount(index), 3);
+        }
+        else if (dAlbum->range() == DAlbum::Month && dAlbum->date().year() == 2007 && dAlbum->date().month() == 3)
+        {
+            QCOMPARE(albumModel->rowCount(index), 0);
+        }
+        else if (dAlbum->range() == DAlbum::Month && dAlbum->date().year() == 2007 && dAlbum->date().month() == 4)
+        {
+            QCOMPARE(albumModel->rowCount(index), 0);
+        }
+        else if (dAlbum->range() == DAlbum::Month && dAlbum->date().year() == 2009 && dAlbum->date().month() == 3)
+        {
+            QCOMPARE(albumModel->rowCount(index), 0);
+        }
+        else if (dAlbum->range() == DAlbum::Month && dAlbum->date().year() == 2009 && dAlbum->date().month() == 4)
+        {
+            QCOMPARE(albumModel->rowCount(index), 0);
+        }
+        else if (dAlbum->range() == DAlbum::Month && dAlbum->date().year() == 2009 && dAlbum->date().month() == 5)
+        {
+            QCOMPARE(albumModel->rowCount(index), 0);
+        }
+        else if (dAlbum->date().year() == 1997)
+        {
+            // Ignore these albums for order testing
+        }
+        else
+        {
+            qDebug() << "Unexpected album: " << dAlbum->title();
+            QFAIL("Unexpected album returned from model");
+        }
+    }
+
+    delete albumModel;
+}
+
+void AlbumModelTest::testDAlbumSorting()
+{
+    qDebug() << "Start AlbumModelTest::testDAlbumSorting()";
+
+    DateAlbumModel dateAlbumModel;
+    AlbumFilterModel albumModel;
+    albumModel.setSourceAlbumModel(&dateAlbumModel);
+
+    // first check ascending order
+
+    albumModel.sort(0, Qt::AscendingOrder);
+    int previousYear = 0;
+
+    for (int yearRow = 0; yearRow < albumModel.rowCount(); ++yearRow)
+    {
+        QModelIndex yearIndex   = albumModel.index(yearRow, 0);
+        DAlbum* const yearAlbum = dynamic_cast<DAlbum*> (albumModel.albumForIndex(yearIndex));
+        QVERIFY(yearAlbum);
 
-        while (it != list->end())
-        {
-            FPhotoSet photoSet = *it;
-            QString name       = photoSet.title;
+        QVERIFY(yearAlbum->date().year() > previousYear);
+        previousYear = yearAlbum->date().year();
+
+        int previousMonth = 0;
 
-            // Store the id as user data, because the title is not unique.
-
-            QVariant id        = QVariant(photoSet.id);
-
-            if (id == d->talker->m_selectedPhotoSet.id)
-            {
-                curr_index = index;
-            }
-
-            d->albumsListComboBox->insertItem(index++, name, id);
-            ++it;
-        }
+        for (int monthRow = 0; monthRow < albumModel.rowCount(yearIndex); ++monthRow)
+        {
+            QModelIndex monthIndex   = albumModel.index(monthRow, 0, yearIndex);
+            DAlbum* const monthAlbum = dynamic_cast<DAlbum*> (albumModel.albumForIndex(monthIndex));
+            QVERIFY(monthAlbum);
+
+            QVERIFY(monthAlbum->date().month() > previousMonth);
+            previousMonth = monthAlbum->date().month();
+        }
+    }
+
+    // then check descending order
 
-        d->albumsListComboBox->setCurrentIndex(curr_index);
-    }
-}
-
-/**
- * This slot is call when 'Start Uploading' button is pressed.
- */
-void FlickrWindow::slotUser1()
-{
-    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "SlotUploadImages invoked";
-/*
-    d->widget->d->tab->setCurrentIndex(FlickrWidget::FILELIST);
-*/
-    if (d->imglst->imageUrls().isEmpty())
-    {
-        return;
-    }
-
-    typedef QPair<QUrl, FPhotoInfo> Pair;
+    albumModel.sort(0, Qt::DescendingOrder);
+    previousYear = 1000000;
+
+    for (int yearRow = 0; yearRow < albumModel.rowCount(); ++yearRow)
+    {
+        QModelIndex yearIndex   = albumModel.index(yearRow, 0);
+        DAlbum* const yearAlbum = dynamic_cast<DAlbum*> (albumModel.albumForIndex(yearIndex));
+        QVERIFY(yearAlbum);
+
+        QVERIFY(yearAlbum->date().year() < previousYear);
+        previousYear          = yearAlbum->date().year();
+
+        int previousMonth     = 13;
+
+        for (int monthRow = 0; monthRow < albumModel.rowCount(yearIndex); ++monthRow)
+        {
+            QModelIndex monthIndex   = albumModel.index(monthRow, 0, yearIndex);
+            DAlbum* const monthAlbum = dynamic_cast<DAlbum*> (albumModel.albumForIndex(monthIndex));
+            QVERIFY(monthAlbum);
 
-    d->uploadQueue.clear();
-
-    for (int i = 0 ; i < d->imglst->listView()->topLevelItemCount() ; ++i)
-    {
-        FlickrListViewItem* const lvItem = dynamic_cast<FlickrListViewItem*>(d->imglst->listView()->topLevelItem(i));
+            QVERIFY(monthAlbum->date().month() < previousMonth);
+            previousMonth          = monthAlbum->date().month();
+        }
+    }
+}
 
-        if (lvItem)
-        {
-            DItemInfo info(d->iface->itemInfo(lvItem->url()));
-            qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Adding images" << lvItem->url() << " to the list";
-            FPhotoInfo temp;
-
-            temp.title                 = info.title();
-            temp.description           = info.comment();
-            temp.size                  = info.fileSize();
-            temp.is_public             = lvItem->isPublic()  ? 1 : 0;
-            temp.is_family             = lvItem->isFamily()  ? 1 : 0;
-            temp.is_friend             = lvItem->isFriends() ? 1 : 0;
-            temp.safety_level          = lvItem->safetyLevel();
-            temp.content_type          = lvItem->contentType();
-            QStringList tagsFromDialog = d->tagsLineEdit->text().split(QLatin1Char(','), QString::SkipEmptyParts);
-            QStringList tagsFromList   = lvItem->extraTags();
-
-            QStringList           allTags;
-            QStringList::Iterator itTags;
+void AlbumModelTest::testDAlbumCount()
+{
+    qDebug() << "Start AlbumModelTest::testDAlbumCount()";
+
+    DateAlbumModel* const albumModel = new DateAlbumModel();
+    albumModel->setShowCount(true);
+    ensureItemCounts();
+
+    qDebug() << "iterating over root indices";
+
+    // check year albums
+
+    for (int yearRow = 0; yearRow < albumModel->rowCount(albumModel->rootAlbumIndex()); ++yearRow)
+    {
+        QModelIndex yearIndex    = albumModel->index(yearRow, 0);
+        DAlbum* const yearDAlbum = albumModel->albumForIndex(yearIndex);
+        QVERIFY(yearDAlbum);
+
+        QVERIFY(yearDAlbum->range() == DAlbum::Year);
 
-            // Tags from the dialog
-
-            itTags = tagsFromDialog.begin();
-
-            while (itTags != tagsFromDialog.end())
-            {
-                allTags.append(*itTags);
-                ++itTags;
-            }
+        if (yearDAlbum->date().year() == 2007)
+        {
+            const int imagesInYear = 7;
+            albumModel->includeChildrenCount(yearIndex);
+            QCOMPARE(albumModel->albumCount(yearDAlbum), imagesInYear);
+            albumModel->excludeChildrenCount(yearIndex);
+            QCOMPARE(albumModel->albumCount(yearDAlbum), 0);
+            albumModel->includeChildrenCount(yearIndex);
+            QCOMPARE(albumModel->albumCount(yearDAlbum), imagesInYear);
 
-            // Tags from the database
-
-            if (d->exportHostTagsCheckBox->isChecked())
-            {
-                QStringList tagsFromDatabase;
+            for (int monthRow = 0; monthRow < albumModel->rowCount(yearIndex); ++monthRow)
+            {
+                QModelIndex monthIndex = albumModel->index(monthRow, 0, yearIndex);
+                DAlbum* monthDAlbum    = albumModel->albumForIndex(monthIndex);
+                QVERIFY(monthDAlbum);
 
-                tagsFromDatabase = info.keywords();
-                itTags           = tagsFromDatabase.begin();
+                QVERIFY(monthDAlbum->range() == DAlbum::Month);
+                QVERIFY(monthDAlbum->date().year() == 2007);
 
-                while (itTags != tagsFromDatabase.end())
+                if (monthDAlbum->date().month() == 3)
                 {
-                    allTags.append(*itTags);
-                    ++itTags;
-                }
-            }
-
-            // Tags from the list view.
-
-            itTags = tagsFromList.begin();
-
-            while (itTags != tagsFromList.end())
-            {
-                allTags.append(*itTags);
-                ++itTags;
-            }
-
-            // Remove spaces if the user doesn't like them.
-
-            if (d->stripSpaceTagsCheckBox->isChecked())
-            {
-                for (QStringList::iterator it = allTags.begin() ; it != allTags.end() ; ++it)
-                {
-                    *it = (*it).trimmed().remove(QLatin1Char(' '));
-                }
-            }
-
-            // Debug the tag list.
-
-            itTags = allTags.begin();
-
-            while (itTags != allTags.end())
-            {
-                qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Tags list:" << (*itTags);
-                ++itTags;
-            }
-
-            temp.tags = allTags;
-            d->uploadQueue.append(Pair(lvItem->url(), temp));
-        }
-    }
+                    const int imagesInMonth = 3;
+                    albumModel->includeChildrenCount(monthIndex);
+                    QCOMPARE(albumModel->albumCount(monthDAlbum), imagesInMonth);
+                    albumModel->excludeChildrenCount(monthIndex);
+                    QCOMPARE(albumModel->albumCount(monthDAlbum), imagesInMonth);
+                    albumModel->includeChildrenCount(monthIndex);
+                    QCOMPARE(albumModel->albumCount(monthDAlbum), imagesInMonth);
+                }
+                else if (monthDAlbum->date().month() == 4)
+                {
+                    const int imagesInMonth = 4;
+                    albumModel->includeChildrenCount(monthIndex);
+                    QCOMPARE(albumModel->albumCount(monthDAlbum), imagesInMonth);
+                    albumModel->excludeChildrenCount(monthIndex);
+                    QCOMPARE(albumModel->albumCount(monthDAlbum), imagesInMonth);
+                    albumModel->includeChildrenCount(monthIndex);
+                    QCOMPARE(albumModel->albumCount(monthDAlbum), imagesInMonth);
+                }
+                else
+                {
+                    QFAIL("unexpected month album in 2007");
+                }
+            }
+        }
+        else if (yearDAlbum->date().year() == 2009)
+        {
+            const int imagesInYear = 5;
+            albumModel->includeChildrenCount(yearIndex);
+            QCOMPARE(albumModel->albumCount(yearDAlbum), imagesInYear);
+            albumModel->excludeChildrenCount(yearIndex);
+            QCOMPARE(albumModel->albumCount(yearDAlbum), 0);
+            albumModel->includeChildrenCount(yearIndex);
+            QCOMPARE(albumModel->albumCount(yearDAlbum), imagesInYear);
+
+            for (int monthRow = 0; monthRow < albumModel->rowCount(yearIndex); ++monthRow)
+            {
+                QModelIndex monthIndex = albumModel->index(monthRow, 0, yearIndex);
+                DAlbum* monthDAlbum    = albumModel->albumForIndex(monthIndex);
+                QVERIFY(monthDAlbum);
 
-    d->uploadTotal = d->uploadQueue.count();
-    d->uploadCount = 0;
-    d->widget->progressBar()->reset();
-    slotAddPhotoNext();
-    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "SlotUploadImages done";
-}
-
-void FlickrWindow::slotAddPhotoNext()
-{
-    if (d->uploadQueue.isEmpty())
-    {
-        d->widget->progressBar()->reset();
-        setUiInProgressState(false);
-        return;
-    }
-
-    typedef QPair<QUrl, FPhotoInfo> Pair;
-    Pair pathComments = d->uploadQueue.first();
-    FPhotoInfo info   = pathComments.second;
-
-    QString selectedPhotoSetId = d->albumsListComboBox->itemData(d->albumsListComboBox->currentIndex()).toString();
-
-    if (selectedPhotoSetId.isEmpty())
-    {
-        d->talker->m_selectedPhotoSet = FPhotoSet();
-    }
-    else
-    {
-        QLinkedList<FPhotoSet>::iterator it = d->talker->m_photoSetsList->begin();
-
-        while (it != d->talker->m_photoSetsList->end())
-        {
-            if (it->id == selectedPhotoSetId)
-            {
-                d->talker->m_selectedPhotoSet = *it;
-                break;
-            }
-
-            ++it;
-        }
-    }
-
-    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Max allowed file size is:"
-                                     << d->talker->getMaxAllowedFileSize().toLongLong()
-                                     << "File Size is" << info.size;
-
-    bool res = d->talker->addPhoto(pathComments.first.toLocalFile(), //the file path
-                                   info,
-                                   d->originalCheckBox->isChecked(),
-                                   d->resizeCheckBox->isChecked(),
-                                   d->dimensionSpinBox->value(),
-                                   d->imageQualitySpinBox->value());
-
-    if (!res)
-    {
-        slotAddPhotoFailed(QLatin1String(""));
-        return;
-    }
-
-    if (d->widget->progressBar()->isHidden())
-    {
-        setUiInProgressState(true);
-        d->widget->progressBar()->progressScheduled(i18n("Flickr Export"), true, true);
-        d->widget->progressBar()->progressThumbnailChanged(
-            QIcon::fromTheme(QLatin1String("dk-flickr")).pixmap(22, 22));
-    }
-}
-
-void FlickrWindow::slotAddPhotoSucceeded(const QString& photoId)
-{
-    QUrl photoUrl = d->uploadQueue.first().first;
-
-    // Set location for uploaded photo
-
-    DItemInfo info(d->iface->itemInfo(photoUrl));
-
-    if (info.hasGeolocationInfo() && !photoId.isEmpty())
-    {
-        d->talker->setGeoLocation(photoId,
-                                  QString::number(info.latitude()),
-                                  QString::number(info.longitude()));
-        return;
-    }
-
-    // Remove photo uploaded from the list
-
-    d->imglst->removeItemByUrl(photoUrl);
-    d->uploadQueue.removeFirst();
-    d->uploadCount++;
-    d->widget->progressBar()->setMaximum(d->uploadTotal);
-    d->widget->progressBar()->setValue(d->uploadCount);
-    slotAddPhotoNext();
-}
-
-void FlickrWindow::slotListPhotoSetsFailed(const QString& msg)
-{
-    QMessageBox::critical(this, QLatin1String("Error"),
-                          i18n("Failed to Fetch Photoset information from %1. %2\n",
-                               d->serviceName, msg));
-}
-
-void FlickrWindow::slotAddPhotoFailed(const QString& msg)
-{
-    QPointer<QMessageBox> warn = new QMessageBox(QMessageBox::Warning,
-                     i18n("Warning"),
-                     i18n("Failed to upload photo into %1. %2\nDo you want to continue?",
-                          d->serviceName, msg),
-                     QMessageBox::Yes | QMessageBox::No);
-
-    (warn->button(QMessageBox::Yes))->setText(i18n("Continue"));
-    (warn->button(QMessageBox::No))->setText(i18n("Cancel"));
-
-    if (warn->exec() != QMessageBox::Yes)
-    {
-        d->uploadQueue.clear();
-        d->widget->progressBar()->reset();
-        setUiInProgressState(false);
-    }
-    else
-    {
-        d->uploadQueue.removeFirst();
-        d->uploadTotal--;
-        d->widget->progressBar()->setMaximum(d->uploadTotal);
-        d->widget->progressBar()->setValue(d->uploadCount);
-        slotAddPhotoNext();
-    }
-
-    delete warn;
-}
-
-/**
- * Method called when a photo set has been successfully created on Flickr.
- * It functions to restart the normal flow after a photo set has been created
- * on Flickr.
- */
-void FlickrWindow::slotAddPhotoSetSucceeded()
-{
-    slotPopulatePhotoSetComboBox();
-    slotAddPhotoSucceeded(QLatin1String(""));
-}
-
-void FlickrWindow::slotImageListChanged()
-{
-    startButton()->setEnabled(!(d->widget->d->imglst->imageUrls().isEmpty()));
-}
-
-void FlickrWindow::slotReloadPhotoSetRequest()
-{
-    d->talker->listPhotoSets();
-}
-
-} // namespace DigikamGenericFlickrPlugin
+                QVERIFY(monthDAlbum->range() == DAlbum::Month);
+                QVERIFY(monthDAlbum->date().year() == 2009);
+
+                if (monthDAlbum->date().month() == 3)
+                {
+                    const int imagesInMonth = 2;
+                    albumModel->includeChildrenCount(monthIndex);
+                    QCOMPARE(albumModel->albumCount(monthDAlbum), imagesInMonth);
+                    albumModel->excludeChildrenCount(monthIndex);
+                    QCOMPARE(albumModel->albumCount(monthDAlbum), imagesInMonth);
+                    albumModel->includeChildrenCount(monthIndex);
+                    QCOMPARE(albumModel->albumCount(monthDAlbum), imagesInMonth);
+                }
+                else if (monthDAlbum->date().month() == 4)
+                {
+                    const int imagesInMonth = 2;
+                    albumModel->includeChildrenCount(monthIndex);
+                    QCOMPARE(albumModel->albumCount(monthDAlbum), imagesInMonth);
+                    albumModel->excludeChildrenCount(monthIndex);
+                    QCOMPARE(albumModel->albumCount(monthDAlbum), imagesInMonth);
+                    albumModel->includeChildrenCount(monthIndex);
+                    QCOMPARE(albumModel->albumCount(monthDAlbum), imagesInMonth);
+                }
+                else if (monthDAlbum->date().month() == 5)
+                {
+                    const int imagesInMonth = 1;
+                    albumModel->includeChildrenCount(monthIndex);
+                    QCOMPARE(albumModel->albumCount(monthDAlbum), imagesInMonth);
+                    albumModel->excludeChildrenCount(monthIndex);
+                    QCOMPARE(albumModel->albumCount(monthDAlbum), imagesInMonth);
+                    albumModel->includeChildrenCount(monthIndex);
+                    QCOMPARE(albumModel->albumCount(monthDAlbum), imagesInMonth);
+                }
+                else
+                {
+                    QFAIL("unexpected month album in 2009");
+                }
+            }
+        }
+        else if (yearDAlbum->date().year() == 1997)
+        {
+            // Nothing to do here, ignore the albums for ordering tests
+        }
+        else
+        {
+            QFAIL("Received unexpected album from model");
+        }
+    }
+
+    delete albumModel;
+}
+
+void AlbumModelTest::testTAlbumModel()
+{
+    qDebug() << "Start AlbumModelTest::testTAlbumModel()";
+
+    TagModel* albumModel = new TagModel();
+    ModelTest* test      = new ModelTest(albumModel, nullptr);
+    delete test;
+    delete albumModel;
+
+    albumModel = new TagModel(AbstractAlbumModel::IgnoreRootAlbum);
+    test       = new ModelTest(albumModel, nullptr);
+    delete test;
+    delete albumModel;
+}
+
+void AlbumModelTest::testSAlbumModel()
+{
+    qDebug() << "Start AlbumModelTest::testSAlbumModel()";
+
+    SearchModel* const albumModel = new SearchModel();
+    ModelTest* const test         = new ModelTest(albumModel, nullptr);
+    delete test;
+    delete albumModel;
+}
 
diff --git a/static/reports/cppcheck/master/5.html b/static/reports/cppcheck/master/5.html index 4f3798911..15eb5c0d1 100644 --- a/static/reports/cppcheck/master/5.html +++ b/static/reports/cppcheck/master/5.html @@ -1,1037 +1,387 @@ - Cppcheck - HTML report - digiKam-master-rev-907aafb5fa + Cppcheck - HTML report - digiKam-master-rev-e85fcd090f
  1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-172
-173
-174
-175
-176
-177
-178
-179
-180
-181
-182
-183
-184
-185
-186
-187
-188
-189
-190
-191
-192
-193
-194
-195
-196
-197
-198
-199
-200
-201
-202
-203
-204
-205
-206
-207
-208
-209
-210
-211
-212
-213
-214
-215
-216
-217
-218
-219
-220
-221
-222
-223
-224
-225
-226
-227
-228
-229
-230
-231
-232
-233
-234
-235
-236
-237
-238
-239
-240
-241
-242
-243
-244
-245
-246
-247
-248
-249
-250
-251
-252
-253
-254
-255
-256
-257
-258
-259
-260
-261
-262
-263
-264
-265
-266
-267
-268
-269
-270
-271
-272
-273
-274
-275
-276
-277
-278
-279
-280
-281
-282
-283
-284
-285
-286
-287
-288
-289
-290
-291
-292
-293
-294
-295
-296
-297
-298
-299
-300
-301
-302
-303
-304
-305
-306
-307
-308
-309
-310
-311
-312
-313
-314
-315
-316
-317
-318
-319
-320
-321
-322
-323
-324
-325
-326
-327
-328
-329
-330
-331
-332
-333
-334
-335
-336
-337
-338
-339
-340
-341
-342
-343
-344
-345
-346
-347
-348
-349
-350
-351
-352
-353
-354
-355
-356
-357
-358
-359
-360
-361
-362
-363
-364
-365
-366
-367
-368
-369
-370
-371
-372
-373
-374
-375
-376
-377
-378
-379
-380
-381
-382
-383
-384
-385
-386
-387
-388
-389
-390
-391
-392
-393
-394
-395
-396
-397
-398
-399
-400
-401
-402
-403
-404
-405
-406
-407
-408
-409
-410
-411
-412
-413
-414
-415
-416
-417
-418
-419
-420
-421
-422
-423
-424
-425
-426
-427
-428
-429
-430
-431
-432
-433
-434
-435
-436
-437
-438
-439
-440
-441
-442
-443
-444
-445
-446
/* ============================================================
+121
/* ============================================================
  *
  * This file is a part of digiKam project
  * https://www.digikam.org
  *
- * Date        : 2011-03-22
- * Description : a Iface C++ interface
+ * Date        : 2010-06-21
+ * Description : Test for SimpleTreeModel.
  *
- * Copyright (C) 2011-2020 by Gilles Caulier <caulier dot gilles at gmail dot com>
- * Copyright (C) 2011      by Alexandre Mendes <alex dot mendes1988 at gmail dot com>
- * Copyright (C) 2011      by Hormiere Guillaume <hormiere dot guillaume at gmail dot com>
- * Copyright (C) 2011      by Manuel Campomanes <campomanes dot manuel at gmail dot com>
- *
- * This program is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General
- * Public License as published by the Free Software Foundation;
- * either version 2, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * ============================================================ */
+ * Copyright (C) 2010 by Michael G. Hansen <mike at mghansen dot de>
+ *
+ * This program is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation;
+ * either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * ============================================================ */
+
+#include "test_simpletreemodel.h"
 
-#include "mediawiki_edit.h"
+// Qt includes
 
-// Qt includes
-
-#include <QTimer>
-#include <QUrl>
-#include <QUrlQuery>
-#include <QXmlStreamReader>
-#include <QCryptographicHash>
-#include <QStringList>
-
-#include <QNetworkCookie>
-#include <QNetworkCookieJar>
-#include <QNetworkReply>
-#include <QNetworkRequest>
-
-// Local includes
-
-#include "mediawiki_iface.h"
-#include "mediawiki_queryinfo.h"
-#include "mediawiki_job_p.h"
-
-namespace MediaWiki
-{
-
-class Q_DECL_HIDDEN Result
-{
-public:
+#include <QUrl>
+#include <QDebug>
+
+// local includes
+
+#include "simpletreemodel.h"
+#include "modeltest.h"
+
+using namespace Digikam;
+
+/**
+ * Description : Dummy test that does nothing
+ */
+void TestSimpleTreeModel::testNoOp()
+{
+}
+
+void TestSimpleTreeModel::testModel1()
+{
+    SimpleTreeModel* const treeModel = new SimpleTreeModel(1, this);
+    new ModelTest(treeModel, this);
+    Q_ASSERT(!treeModel->index(0, 0).isValid());
+    Q_ASSERT(treeModel->indexToItem(QModelIndex())==treeModel->rootItem());
+    Q_ASSERT(!treeModel->itemToIndex(treeModel->rootItem()).isValid());
+    Q_ASSERT(!treeModel->itemToIndex(nullptr).isValid());
+    Q_ASSERT(!treeModel->parent(QModelIndex()).isValid());
 
-    explicit Result()
-    {
-        m_captchaId = -1;
-    }
-
-    unsigned int m_captchaId;
-    QVariant     m_captchaQuestion;
-    QString      m_captchaAnswer;
-};
-
-class Q_DECL_HIDDEN EditPrivate : public JobPrivate
-{
-public:
+    SimpleTreeModel::Item* const item1 = treeModel->addItem();
+    Q_ASSERT(item1!=nullptr);
+    const QPersistentModelIndex item1Index = treeModel->itemToIndex(item1);
+    Q_ASSERT(item1Index.isValid());
+    Q_ASSERT(treeModel->indexToItem(item1Index)==item1);
+    Q_ASSERT(!treeModel->parent(item1Index).isValid());
+
+    SimpleTreeModel::Item* const item2 = treeModel->addItem();
+    Q_ASSERT(item2!=nullptr);
+    const QModelIndex item2Index = treeModel->itemToIndex(item2);
+    Q_ASSERT(item2Index.isValid());
+    Q_ASSERT(treeModel->indexToItem(item2Index)==item2);
+    Q_ASSERT(!treeModel->parent(item2Index).isValid());
 
-    explicit EditPrivate(Iface& MediaWiki)
-        : JobPrivate(MediaWiki)
-    {
-    }
-
-    static int error(const QString& error)
-    {
-        QString temp = error;
-        int ret      = 0;
-        QStringList list;
-        list    << QStringLiteral("notext")
-                << QStringLiteral("invalidsection")
-                << QStringLiteral("protectedtitle")
-                << QStringLiteral("cantcreate")
-                << QStringLiteral("cantcreateanon")
-                << QStringLiteral("articleexists")
-                << QStringLiteral("noimageredirectanon")
-                << QStringLiteral("noimageredirect")
-                << QStringLiteral("spamdetected")
-                << QStringLiteral("filtered")
-                << QStringLiteral("contenttoobig")
-                << QStringLiteral("noeditanon")
-                << QStringLiteral("noedit")
-                << QStringLiteral("pagedeleted")
-                << QStringLiteral("emptypage")
-                << QStringLiteral("emptynewsection")
-                << QStringLiteral("editconflict")
-                << QStringLiteral("revwrongpage")
-                << QStringLiteral("undofailure");
-
-        ret = list.indexOf(temp.remove(QChar::fromLatin1('-')));
-
-        if (ret == -1)
-        {
-            ret = 0;
-        }
+    SimpleTreeModel::Item* const item21 = treeModel->addItem(item2);<--- Shadowed declaration<--- Shadowed declaration
+    Q_ASSERT(item21!=nullptr);
+    const QModelIndex item21Index = treeModel->itemToIndex(item21);<--- Shadowed declaration<--- Shadowed declaration
+    Q_ASSERT(item21Index.isValid());
+    Q_ASSERT(treeModel->indexToItem(item21Index)==item21);
+    Q_ASSERT(treeModel->parent(item21Index)==item2Index);
+    Q_ASSERT(treeModel->index(0, 0, item2Index)==item21Index);
+
+    // just make sure another modeltest will test things for consistency in case a signal went missing
+    new ModelTest(treeModel, this);
+
+    Q_ASSERT(treeModel->rootItem() == treeModel->indexToItem(QModelIndex()));
+    Q_ASSERT(treeModel->indexToItem(treeModel->itemToIndex(item1))==item1);
+    Q_ASSERT(treeModel->hasIndex(0, 0) == true);
+
+    QModelIndex topIndex = treeModel->index(0, 0, QModelIndex());
+
+    if (treeModel->rowCount(topIndex) > 0)
+    {
+        QModelIndex childIndex = treeModel->index(0, 0, topIndex);
+        qDebug() << childIndex;
+        qDebug() << treeModel->parent(childIndex);
+        Q_ASSERT(treeModel->parent(childIndex) == topIndex);
+    }
+
+    // add another few items:
+    {
+        SimpleTreeModel::Item* const item21 = treeModel->addItem(item2, 0);<--- Shadow variable
+        Q_ASSERT(item21!=nullptr);
+        const QModelIndex item21Index = treeModel->itemToIndex(item21);<--- Shadow variable
+        Q_ASSERT(item21Index.isValid());
+        Q_ASSERT(treeModel->indexToItem(item21Index)==item21);
+        Q_ASSERT(treeModel->parent(item21Index)==item2Index);
+        Q_ASSERT(treeModel->index(0, 0, item2Index)==item21Index);
+        Q_ASSERT(item21Index.row()==0);
+    }
 
-        return  ret + (int)Edit::TextMissing ;
-    }
-
-    QUrl                   baseUrl;
-    QMap<QString, QString> requestParameter;
-    Result                 result;
-};
-
-Edit::Edit(Iface& media, QObject* const parent)
-    : Job(*new EditPrivate(media), parent)
-{
-}
-
-void Edit::setUndoAfter(int undoafter)
-{
-    Q_D(Edit);
-    d->requestParameter[QStringLiteral("undoafter")] = QString::number(undoafter);
-}
-
-void Edit::setUndo(int undo)
-{
-    Q_D(Edit);
-    d->requestParameter[QStringLiteral("undo")] = QString::number(undo);
-}
-
-void Edit::setPrependText(const QString& prependText)
-{
-    Q_D(Edit);
-    d->requestParameter[QStringLiteral("prependtext")] = prependText;
-    d->requestParameter[QStringLiteral("md5")]         = QString();
-}
-
-void Edit::setAppendText(const QString& appendText)
-{
-    Q_D(Edit);
-    d->requestParameter[QStringLiteral("appendtext")] = appendText;
-    d->requestParameter[QStringLiteral("md5")]        = QString();
-}
-
-void Edit::setPageName(const QString& pageName)
-{
-    Q_D(Edit);
-    d->requestParameter[QStringLiteral("title")] = pageName;
-}
-
-void Edit::setToken(const QString& token)
-{
-    Q_D(Edit);
-    d->requestParameter[QStringLiteral("token")] = token;
-}
-
-void Edit::setBaseTimestamp(const QDateTime& baseTimestamp)
-{
-    Q_D(Edit);
-    d->requestParameter[QStringLiteral("basetimestamp")] = baseTimestamp.toString(QStringLiteral("yyyy-MM-ddThh:mm:ssZ"));
-}
-
-void Edit::setStartTimestamp(const QDateTime& startTimestamp)
-{
-    Q_D(Edit);
-    d->requestParameter[QStringLiteral("starttimestamp")] = startTimestamp.toString(QStringLiteral("yyyy-MM-ddThh:mm:ssZ"));
-}
-
-void Edit::setText(const QString& text)
-{
-    Q_D(Edit);
-    d->requestParameter[QStringLiteral("text")] = text;
-    d->requestParameter[QStringLiteral("md5")]  = QString();
-}
-
-void Edit::setRecreate(bool recreate)
-{
-    Q_D(Edit);
-
-    if (recreate)
-    {
-        d->requestParameter[QStringLiteral("recreate")] = QStringLiteral("on");
-        d->requestParameter[QStringLiteral("md5")]      = QString();
-    }
-}
-
-void Edit::setCreateonly(bool createonly)
-{
-    Q_D(Edit);
-
-    if (createonly)
-    {
-        d->requestParameter[QStringLiteral("createonly")] = QStringLiteral("on");
-        d->requestParameter[QStringLiteral("md5")]        = QString();
-    }
-}
-
-void Edit::setNocreate(bool norecreate)
-{
-    Q_D(Edit);
-
-    if (norecreate)
-    {
-        d->requestParameter[QStringLiteral("nocreate")] = QStringLiteral("on");
-        d->requestParameter[QStringLiteral("md5")]      = QString();
-    }
-}
-
-void Edit::setMinor(bool minor)
-{
-    Q_D(Edit);
-
-    if (minor)
-        d->requestParameter[QStringLiteral("minor")]    = QStringLiteral("on");
-    else
-        d->requestParameter[QStringLiteral("notminor")] = QStringLiteral("on");
-}
-
-void Edit::setSection(const QString& section)
-{
-    Q_D(Edit);
-    d->requestParameter[QStringLiteral("section")] = section;
-}
-
-void Edit::setSummary(const QString& summary)
-{
-    Q_D(Edit);
-    d->requestParameter[QStringLiteral("summary")] = summary;
-}
-
-void Edit::setWatchList(Edit::Watchlist watchlist)
-{
-    Q_D(Edit);
-
-    switch (watchlist)
-    {
-        case Edit::watch:
-            d->requestParameter[QStringLiteral("watchlist")] = QString(QStringLiteral("watch"));
-            break;
-        case Edit::unwatch:
-            d->requestParameter[QStringLiteral("watchlist")] = QString(QStringLiteral("unwatch"));
-            break;
-        case Edit::nochange:
-            d->requestParameter[QStringLiteral("watchlist")] = QString(QStringLiteral("nochange"));
-            break;
-        case Edit::preferences:
-            d->requestParameter[QStringLiteral("watchlist")] = QString(QStringLiteral("preferences"));
-            break;
-    }
-}
-
-Edit::~Edit()
-{
-}
-
-void Edit::start()
-{
-    Q_D(Edit);
-    QueryInfo* const info = new QueryInfo(d->MediaWiki,this);
-    info->setPageName(d->requestParameter[QStringLiteral("title")]);
-    info->setToken(QStringLiteral("edit"));
-
-    connect(info, SIGNAL(page(Page)),
-            this, SLOT(doWorkSendRequest(Page)));
-
-    info->start();
-}
-
-void Edit::doWorkSendRequest(Page page)
-{
-    Q_D(Edit);
-    d->requestParameter[QStringLiteral("token")] = page.pageEditToken();
-    // Set the url
-    QUrl    url                                  = d->MediaWiki.url();
-    QUrlQuery query;
-    query.addQueryItem(QStringLiteral("format"), QStringLiteral("xml"));
-    query.addQueryItem(QStringLiteral("action"), QStringLiteral("edit"));
-
-    // Add params
-    if (d->requestParameter.contains(QStringLiteral("md5")))
-    {
-        QString text;
-
-        if (d->requestParameter.contains(QStringLiteral("prependtext")))
-            text += d->requestParameter[QStringLiteral("prependtext")];
-
-        if (d->requestParameter.contains(QStringLiteral("appendtext")))
-            text += d->requestParameter[QStringLiteral("appendtext")];
-
-        if (d->requestParameter.contains(QStringLiteral("text")))
-            text = d->requestParameter[QStringLiteral("text")];
-
-        QByteArray hash                            = QCryptographicHash::hash(text.toUtf8(),QCryptographicHash::Md5);
-        d->requestParameter[QStringLiteral("md5")] = QString::fromLatin1(hash.toHex());
-    }
-
-    QMapIterator<QString, QString> i(d->requestParameter);<--- Shadowed declaration
-
-    while (i.hasNext())
-    {
-        i.next();
-
-        if (i.key() != QStringLiteral("token"))
-            query.addQueryItem(i.key(),i.value());
-    }
-
-    QByteArray cookie;
-    QList<QNetworkCookie> MediaWikiCookies = d->manager->cookieJar()->cookiesForUrl(d->MediaWiki.url());
-
-    for (int i = 0 ; i < MediaWikiCookies.size() ; ++i)<--- Shadow variable
-    {
-        cookie += MediaWikiCookies.at(i).toRawForm(QNetworkCookie::NameAndValueOnly);
-        cookie += ';';
-    }
-
-    // Add the token
-    query.addQueryItem(QStringLiteral("token"), d->requestParameter[QStringLiteral("token")]);
-    url.setQuery(query);
-    d->baseUrl = url;
-
-    // Set the request
-    QNetworkRequest request( url );
-    request.setRawHeader("User-Agent", d->MediaWiki.userAgent().toUtf8());
-    request.setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("application/x-www-form-urlencoded"));
-    request.setRawHeader("Cookie", cookie);
-
-    setPercent(25); // Request ready.
-
-    // Send the request
-    d->reply = d->manager->post( request, url.toString().toUtf8() );
-    connectReply();
-
-    connect( d->reply, SIGNAL(finished()),
-             this, SLOT(finishedEdit()) );
-
-    setPercent(50); // Request sent.
-}
-
-void Edit::finishedEdit()
-{
-    Q_D(Edit);
-
-    disconnect(d->reply, SIGNAL(finished()),
-               this, SLOT(finishedEdit()));
-
-    setPercent(75); // Response received.
-
-    if (d->reply->error() != QNetworkReply::NoError)
-    {
-        this->setError(this->NetworkError);
-        d->reply->close();
-        d->reply->deleteLater();
-        emitResult();
-        return;
-    }
-
-    QXmlStreamReader reader( d->reply );
-
-    while (!reader.atEnd() && !reader.hasError())
-    {
-        QXmlStreamReader::TokenType token = reader.readNext();
-
-        if (token == QXmlStreamReader::StartElement)
-        {
-            QXmlStreamAttributes attrs = reader.attributes();
-
-            if (reader.name() == QStringLiteral("edit"))
-            {
-                if (attrs.value( QStringLiteral("result") ).toString() == QLatin1String("Success"))
-                {
-                    setPercent(100); // Response parsed successfully.
-                    this->setError(KJob::NoError);
-                    d->reply->close();
-                    d->reply->deleteLater();
-                    emitResult();
-                    return;
-                }
-                else if (attrs.value( QStringLiteral("result") ).toString() == QLatin1String("Failure"))
-                {
-                    this->setError(KJob::NoError);
-                    reader.readNext();
-                    attrs = reader.attributes();
-                    d->result.m_captchaId = attrs.value( QStringLiteral("id") ).toString().toUInt();
-
-                    if (!attrs.value( QStringLiteral("question") ).isEmpty())
-                        d->result.m_captchaQuestion = QVariant(attrs.value( QStringLiteral("question") ).toString()) ;
-                    else if (!attrs.value( QStringLiteral("url") ).isEmpty())
-                        d->result.m_captchaQuestion = QVariant(attrs.value( QStringLiteral("url") ).toString()) ;
-                }
-            }
-            else if (reader.name() == QStringLiteral("error"))
-            {
-                this->setError(EditPrivate::error(attrs.value( QStringLiteral("code") ).toString()));
-                d->reply->close();
-                d->reply->deleteLater();
-                emitResult();
-                return;
-            }
-        }
-        else if (token == QXmlStreamReader::Invalid && reader.error() != QXmlStreamReader::PrematureEndOfDocumentError)
-        {
-            this->setError(this->XmlError);
-            d->reply->close();
-            d->reply->deleteLater();
-            emitResult();
-            return;
-        }
-    }
-
-    d->reply->close();
-    d->reply->deleteLater();
-    emit resultCaptcha(d->result.m_captchaQuestion);
-}
-
-void Edit::finishedCaptcha(const QString& captcha)
-{
-    Q_D(Edit);
-    d->result.m_captchaAnswer = captcha;
-    QUrl url                  = d->baseUrl;
-    QUrlQuery query;
-    query.addQueryItem(QStringLiteral("CaptchaId"),     QString::number(d->result.m_captchaId));
-    query.addQueryItem(QStringLiteral("CaptchaAnswer"), d->result.m_captchaAnswer);
-    url.setQuery(query);
-    QString data              = url.toString();
-    QByteArray cookie;
-    QList<QNetworkCookie> MediaWikiCookies = d->manager->cookieJar()->cookiesForUrl(d->MediaWiki.url());
-
-    for (int i = 0 ; i < MediaWikiCookies.size() ; ++i)
-    {
-        cookie += MediaWikiCookies.at(i).toRawForm(QNetworkCookie::NameAndValueOnly);
-        cookie += ';';
-    }
-
-    // Set the request
-    QNetworkRequest request(url);
-    request.setRawHeader("User-Agent", d->MediaWiki.userAgent().toUtf8());
-    request.setRawHeader("Cookie", cookie);
-    request.setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("application/x-www-form-urlencoded"));
-    // Send the request
-    d->reply = d->manager->post(request, data.toUtf8());
-
-    connect( d->reply, SIGNAL(finished()),
-             this, SLOT(finishedEdit()) );
-}
-
-} // namespace MediaWiki
+    // add another few items:
+    {
+        SimpleTreeModel::Item* const item21 = treeModel->addItem(item2, 1);<--- Shadow variable
+        Q_ASSERT(item21!=nullptr);
+        const QModelIndex item21Index = treeModel->itemToIndex(item21);<--- Shadow variable
+        Q_ASSERT(item21Index.isValid());
+        Q_ASSERT(treeModel->indexToItem(item21Index)==item21);
+        Q_ASSERT(treeModel->parent(item21Index)==item2Index);
+        Q_ASSERT(treeModel->index(1, 0, item2Index)==item21Index);
+        Q_ASSERT(item21Index.row()==1);
+    }
+
+    new ModelTest(treeModel, this);
+}
+
+QTEST_GUILESS_MAIN(TestSimpleTreeModel)
 
diff --git a/static/reports/cppcheck/master/6.html b/static/reports/cppcheck/master/6.html index 73942f26b..1810a34d5 100644 --- a/static/reports/cppcheck/master/6.html +++ b/static/reports/cppcheck/master/6.html @@ -1,617 +1,379 @@ - Cppcheck - HTML report - digiKam-master-rev-907aafb5fa + Cppcheck - HTML report - digiKam-master-rev-e85fcd090f
  1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-172
-173
-174
-175
-176
-177
-178
-179
-180
-181
-182
-183
-184
-185
-186
-187
-188
-189
-190
-191
-192
-193
-194
-195
-196
-197
-198
-199
-200
-201
-202
-203
-204
-205
-206
-207
-208
-209
-210
-211
-212
-213
-214
-215
-216
-217
-218
-219
-220
-221
-222
-223
-224
-225
-226
-227
-228
-229
-230
-231
-232
-233
-234
-235
-236
/* ============================================================
+117
/* ============================================================
  *
  * This file is a part of digiKam project
  * https://www.digikam.org
  *
  * Date        : 2011-03-22
- * Description : a Iface C++ interface
+ * Description : a MediaWiki C++ interface
  *
  * Copyright (C) 2011-2020 by Gilles Caulier <caulier dot gilles at gmail dot com>
  * Copyright (C) 2011      by Alexandre Mendes <alex dot mendes1988 at gmail dot com>
- *
- * This program is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General
- * Public License as published by the Free Software Foundation;
- * either version 2, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * ============================================================ */
-
-#include "mediawiki_queryinfo.h"
+ * Copyright (C) 2011      by Hormiere Guillaume <hormiere dot guillaume at gmail dot com>
+ * Copyright (C) 2011      by Manuel Campomanes <campomanes dot manuel at gmail dot com>
+ *
+ * This program is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * ============================================================ */
 
 // Qt includes
 
-#include <QDateTime>
-#include <QTimer>
-#include <QUrl>
-#include <QUrlQuery>
-#include <QXmlStreamReader>
-#include <QRegExp>
-#include <QNetworkAccessManager>
-#include <QNetworkCookie>
-#include <QNetworkReply>
-#include <QNetworkRequest>
-
-// Local includes
+#include <QObject>
+#include <QtTest>
+
+// KDE includes
+
+#include <kjob.h>
+
+// Local includes
+
+#include "mediawiki_iface.h"
+#include "mediawiki_logout.h"
+#include "fakeserver/fakeserver.h"
 
-#include "mediawiki_iface.h"
-#include "mediawiki_job_p.h"
+using MediaWiki::Iface;
+using MediaWiki::Logout;
 
-namespace MediaWiki
+class Q_DECL_HIDDEN LogoutTest : public QObject
 {
-
-class Q_DECL_HIDDEN QueryInfoPrivate : public JobPrivate
-{
-public:
-
-    explicit QueryInfoPrivate(Iface& MediaWiki)
-        : JobPrivate(MediaWiki)
-    {
-    }
-
-    QVector<Protection>    protections;
-    QMap<QString, QString> requestParameter;
-    Page                   page;
-};
-
-QueryInfo::QueryInfo(Iface& MediaWiki, QObject* const parent)
-    : Job(*new QueryInfoPrivate(MediaWiki), parent)
-{
-}
-
-QueryInfo::~QueryInfo()
-{
-}
-
-void QueryInfo::setPageName(const QString& title)
-{
-    Q_D(QueryInfo);
-    d->requestParameter[QStringLiteral("titles")] = title;
-}
-
-void QueryInfo::setToken(const QString& token)
-{
-    Q_D(QueryInfo);
-    d->requestParameter[QStringLiteral("intoken")] = token;
-}
+    Q_OBJECT
+
+public:
+
+    LogoutTest()
+    {
+        logoutCount = 0;
+        m_mediaWiki = nullptr;
+        m_server    = nullptr;
+    }
+
+public Q_SLOTS:
+
+    void logoutHandle(KJob* job)
+    {
+        Q_UNUSED(job)
+        logoutCount++;
+    }
+
+private Q_SLOTS:
+
+    void initTestCase()
+    {
+        logoutCount       = 0;
+        this->m_mediaWiki = new Iface(QUrl(QStringLiteral("http://127.0.0.1:12566")));
+        this->m_server    = new FakeServer;
+        this->request     = QStringLiteral("/?format=xml&action=logout");
+    }
+
+    void logoutTestConnectTrue()
+    {
+        QString senario(QStringLiteral("<api />") );
+        QString cookie( QStringLiteral("cookieprefix=\"enwiki\" sessionid=\"17ab96bd8ffbe8ca58a78657a918558e\" expires=\"Sat, 12-Feb-2011 21:39:30 GMT\""));
+        m_server->setScenario(senario, cookie);
+        m_server->startAndWait();
 
-void QueryInfo::setPageId(unsigned int id)
-{
-    Q_D(QueryInfo);
-    d->requestParameter[QStringLiteral("pageids")] = QString::number(id);
-}
+        logoutCount = 0;
+        Logout logout(*m_mediaWiki);
+
+        connect(&logout, SIGNAL(result(KJob*)),
+                this, SLOT(logoutHandle(KJob*)));
 
-void QueryInfo::setRevisionId(unsigned int id)
-{
-    Q_D(QueryInfo);
-    d->requestParameter[QStringLiteral("revids")] = QString::number(id);
-}
-
-void QueryInfo::start()
-{
-    QTimer::singleShot(0, this, SLOT(doWorkSendRequest()));
-}
-
-void QueryInfo::doWorkSendRequest()
-{
-    Q_D(QueryInfo);
-
-    // Set the url
-    QUrl url = d->MediaWiki.url();
-    QUrlQuery query;
-    query.addQueryItem(QStringLiteral("format"), QStringLiteral("xml"));
-    query.addQueryItem(QStringLiteral("action"), QStringLiteral("query"));
-    query.addQueryItem(QStringLiteral("prop"),   QStringLiteral("info"));
-    query.addQueryItem(QStringLiteral("inprop"), QStringLiteral("protection|talkid|watched|subjectid|url|readable|preload"));
-
-    QMapIterator<QString, QString> i(d->requestParameter);<--- Shadowed declaration
-
-    while (i.hasNext())
-    {
-        i.next();
-        query.addQueryItem(i.key(), i.value());
-    }
-    url.setQuery(query);
-
-    // Set the request
-    QNetworkRequest request(url);
-    request.setRawHeader("User-Agent", d->MediaWiki.userAgent().toUtf8());
-    QByteArray cookie = "";
-    QList<QNetworkCookie> MediaWikiCookies = d->manager->cookieJar()->cookiesForUrl(d->MediaWiki.url());
-
-    for (int i = 0 ; i < MediaWikiCookies.size() ; ++i)<--- Shadow variable
-    {
-        cookie += MediaWikiCookies.at(i).toRawForm(QNetworkCookie::NameAndValueOnly);
-        cookie += ';';
-    }
-    request.setRawHeader( "Cookie", cookie );
-
-    // Send the request
-    d->reply = d->manager->get(request);
-    connectReply();
-
-    connect(d->reply, SIGNAL(finished()),
-            this, SLOT(doWorkProcessReply()));
-}
-
-void QueryInfo::doWorkProcessReply()
-{
-    Q_D(QueryInfo);
-
-    disconnect(d->reply, SIGNAL(finished()), 
-               this, SLOT(doWorkProcessReply()));
-
-    if (d->reply->error() == QNetworkReply::NoError)
-    {
-        // Replace & in &amp;
-        QString content = QString::fromUtf8(d->reply->readAll());
-        QRegExp regex(QStringLiteral("&(?!\\w+;)"));
-        content.replace(regex, QStringLiteral("&amp;"));
-        QXmlStreamReader reader(content);
-        QVector<Protection> protect;
-
-        while (!reader.atEnd() && !reader.hasError())
-        {
-            QXmlStreamReader::TokenType token = reader.readNext();
-            QXmlStreamAttributes attrs = reader.attributes();
-
-            if (token == QXmlStreamReader::StartElement)
-            {
-                if (reader.name() == QLatin1String("page"))
-                {
-                    d->page.setPageId(attrs.value(QStringLiteral("pageid")).toString().toUInt());
-                    d->page.setTitle(attrs.value(QStringLiteral("title")).toString());
-                    d->page.setNs(attrs.value(QStringLiteral("ns")).toString().toUInt());
-                    d->page.setTouched(QDateTime::fromString(attrs.value(QStringLiteral("touched")).toString(), QStringLiteral("yyyy'-'MM'-'dd'T'hh':'mm':'ss'Z'")));
-                    d->page.setLastRevId(attrs.value(QStringLiteral("lastrevid")).toString().toUInt());
-                    d->page.setCounter(attrs.value(QStringLiteral("counter")).toString().toUInt());
-                    d->page.setLength(attrs.value(QStringLiteral("length")).toString().toUInt());
-                    d->page.setStarttimestamp(QDateTime::fromString(attrs.value(QStringLiteral("starttimestamp")).toString(), QStringLiteral("yyyy'-'MM'-'dd'T'hh':'mm':'ss'Z'")));
-                    d->page.setEditToken(attrs.value(QStringLiteral("edittoken")).toString());
-                    d->page.setTalkid(attrs.value(QStringLiteral("talkid")).toString().toUInt());
-                    d->page.setFullurl(QUrl(attrs.value(QStringLiteral("fullurl")).toString()));
-                    d->page.setEditurl(QUrl(attrs.value(QStringLiteral("editurl")).toString()));
-                    d->page.setReadable(attrs.value(QStringLiteral("readable")).toString());
-                    d->page.setPreload(attrs.value(QStringLiteral("preload")).toString());
-                }
-                else if (reader.name() == QLatin1String("protection"))
-                {
-                    protect.clear();
-                }
-                else if (reader.name() == QLatin1String("pr"))
-                {
-                    QString expiry(attrs.value(QStringLiteral("expiry")).toString());
-                    QString level(attrs.value(QStringLiteral("level")).toString());
-                    QString type(attrs.value(QStringLiteral("type")).toString());
-                    QString source;
-
-                    if (!attrs.value(QStringLiteral("source")).toString().isEmpty())
-                    {
-                        source = attrs.value(QStringLiteral("source")).toString();
-                    }
-                    else if (!attrs.value(QStringLiteral("cascade")).toString().isEmpty())
-                    {
-                        source = attrs.value(QStringLiteral("cascade")).toString();
-                    }
-
-                    Protection p;
-                    p.setExpiry(expiry);
-                    p.setLevel(level);
-                    p.setType(type);
-                    p.setSource(source);
-                    protect.push_back(p);
-                }
-            }
-            else if (token == QXmlStreamReader::EndElement)
-            {
-                if (reader.name() == QLatin1String("page"))
-                {
-                    d->protections = protect;
-                }
-            }
-        }
-        if (!reader.hasError())
-        {
-            setError(KJob::NoError);
-            emit protection(protect);
-            emit page(d->page);
-        }
-        else
-        {
-            setError(Job::XmlError);
-        }
-    }
-    else
-    {
-        setError(Job::NetworkError);
-    }
-
-    emitResult();
-}
-
-} // namespace MediaWiki
+        logout.exec();   // krazy:exclude=crashy
+        QCOMPARE(this->logoutCount, 1);
+        QCOMPARE(logout.error(), (int)Logout::NoError);
+
+        QList<FakeServer::Request> requests = m_server->getRequest();
+        QCOMPARE(requests.size(), 1);
+
+        FakeServer::Request request = requests[0];<--- Shadow variable
+        QCOMPARE(request.agent, m_mediaWiki->userAgent());
+        QCOMPARE(request.type, QStringLiteral("GET"));
+        QCOMPARE(request.value, QStringLiteral("/?format=xml&action=logout"));
+    }
+
+    void cleanupTestCase()
+    {
+        delete this->m_mediaWiki;
+        delete this->m_server;
+    }
+
+private:
+
+    int         logoutCount;
+    QString     request;<--- Shadowed declaration
+    Iface*      m_mediaWiki;
+    FakeServer* m_server;
+};
+
+QTEST_MAIN(LogoutTest)
+
+#include "logouttest.moc"
 
diff --git a/static/reports/cppcheck/master/7.html b/static/reports/cppcheck/master/7.html deleted file mode 100644 index 43f87f127..000000000 --- a/static/reports/cppcheck/master/7.html +++ /dev/null @@ -1,1319 +0,0 @@ - - - - - - Cppcheck - HTML report - digiKam-master-rev-907aafb5fa - - - - - - - -
-
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-172
-173
-174
-175
-176
-177
-178
-179
-180
-181
-182
-183
-184
-185
-186
-187
-188
-189
-190
-191
-192
-193
-194
-195
-196
-197
-198
-199
-200
-201
-202
-203
-204
-205
-206
-207
-208
-209
-210
-211
-212
-213
-214
-215
-216
-217
-218
-219
-220
-221
-222
-223
-224
-225
-226
-227
-228
-229
-230
-231
-232
-233
-234
-235
-236
-237
-238
-239
-240
-241
-242
-243
-244
-245
-246
-247
-248
-249
-250
-251
-252
-253
-254
-255
-256
-257
-258
-259
-260
-261
-262
-263
-264
-265
-266
-267
-268
-269
-270
-271
-272
-273
-274
-275
-276
-277
-278
-279
-280
-281
-282
-283
-284
-285
-286
-287
-288
-289
-290
-291
-292
-293
-294
-295
-296
-297
-298
-299
-300
-301
-302
-303
-304
-305
-306
-307
-308
-309
-310
-311
-312
-313
-314
-315
-316
-317
-318
-319
-320
-321
-322
-323
-324
-325
-326
-327
-328
-329
-330
-331
-332
-333
-334
-335
-336
-337
-338
-339
-340
-341
-342
-343
-344
-345
-346
-347
-348
-349
-350
-351
-352
-353
-354
-355
-356
-357
-358
-359
-360
-361
-362
-363
-364
-365
-366
-367
-368
-369
-370
-371
-372
-373
-374
-375
-376
-377
-378
-379
-380
-381
-382
-383
-384
-385
-386
-387
-388
-389
-390
-391
-392
-393
-394
-395
-396
-397
-398
-399
-400
-401
-402
-403
-404
-405
-406
-407
-408
-409
-410
-411
-412
-413
-414
-415
-416
-417
-418
-419
-420
-421
-422
-423
-424
-425
-426
-427
-428
-429
-430
-431
-432
-433
-434
-435
-436
-437
-438
-439
-440
-441
-442
-443
-444
-445
-446
-447
-448
-449
-450
-451
-452
-453
-454
-455
-456
-457
-458
-459
-460
-461
-462
-463
-464
-465
-466
-467
-468
-469
-470
-471
-472
-473
-474
-475
-476
-477
-478
-479
-480
-481
-482
-483
-484
-485
-486
-487
-488
-489
-490
-491
-492
-493
-494
-495
-496
-497
-498
-499
-500
-501
-502
-503
-504
-505
-506
-507
-508
-509
-510
-511
-512
-513
-514
-515
-516
-517
-518
-519
-520
-521
-522
-523
-524
-525
-526
-527
-528
-529
-530
-531
-532
-533
-534
-535
-536
-537
-538
-539
-540
-541
-542
-543
-544
-545
-546
-547
-548
-549
-550
-551
-552
-553
-554
-555
-556
-557
-558
-559
-560
-561
-562
-563
-564
-565
-566
-567
-568
-569
-570
-571
-572
-573
-574
-575
-576
-577
-578
-579
-580
-581
-582
-583
-584
-585
-586
-587
/* ============================================================
- *
- * This file is a part of digiKam project
- * https://www.digikam.org
- *
- * Date        : 2018-05-20
- * Description : a tool to export images to Onedrive web service
- *
- * Copyright (C) 2018      by Tarek Talaat <tarektalaat93 at gmail dot com>
- *
- * This program is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General
- * Public License as published by the Free Software Foundation;
- * either version 2, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * ============================================================ */
-
-#include "odtalker.h"
-
-// Qt includes
-
-#include <QJsonDocument>
-#include <QJsonParseError>
-#include <QJsonObject>
-#include <QJsonValue>
-#include <QJsonArray>
-#include <QByteArray>
-#include <QList>
-#include <QPair>
-#include <QFileInfo>
-#include <QWidget>
-#include <QMessageBox>
-#include <QApplication>
-#include <QMimeDatabase>
-#include <QDesktopServices>
-#include <QUrlQuery>
-#include <QNetworkAccessManager>
-
-// KDE includes
-
-#include <klocalizedstring.h>
-#include <kwindowconfig.h>
-
-// Local includes
-
-#include "digikam_debug.h"
-#include "digikam_version.h"
-#include "wstoolutils.h"
-#include "odwindow.h"
-#include "oditem.h"
-#include "odmpform.h"
-#include "webbrowserdlg.h"
-#include "previewloadthread.h"
-
-namespace DigikamGenericOneDrivePlugin
-{
-
-class Q_DECL_HIDDEN ODTalker::Private
-{
-public:
-
-    enum State
-    {
-        OD_USERNAME = 0,
-        OD_LISTFOLDERS,
-        OD_CREATEFOLDER,
-        OD_ADDPHOTO
-    };
-
-public:
-
-    explicit Private()
-      : state(OD_USERNAME),
-        parent(nullptr),
-        netMngr(nullptr),
-        reply(nullptr),
-        settings(nullptr),
-        browser(nullptr)
-    {
-        clientId     = QLatin1String("4c20a541-2ca8-4b98-8847-a375e4d33f34");
-        clientSecret = QLatin1String("wtdcaXADCZ0|tcDA7633|@*");
-
-        authUrl      = QLatin1String("https://login.live.com/oauth20_authorize.srf");
-        tokenUrl     = QLatin1String("https://login.live.com/oauth20_token.srf");
-        scope        = QLatin1String("Files.ReadWrite User.Read");
-        redirectUrl  = QLatin1String("https://login.live.com/oauth20_desktop.srf");
-        serviceName  = QLatin1String("Onedrive");
-        serviceTime  = QLatin1String("token_time");
-        serviceKey   = QLatin1String("access_token");
-    }
-
-public:
-
-    QString                         clientId;
-    QString                         clientSecret;
-    QString                         authUrl;
-    QString                         tokenUrl;
-    QString                         scope;
-    QString                         redirectUrl;
-    QString                         accessToken;
-    QString                         serviceName;
-    QString                         serviceTime;
-    QString                         serviceKey;
-
-    QDateTime                       expiryTime;
-
-    State                           state;
-
-    QWidget*                        parent;
-
-    QNetworkAccessManager*          netMngr;
-    QNetworkReply*                  reply;
-
-    QSettings*                      settings;
-
-    WebBrowserDlg*                  browser;
-
-    QList<QPair<QString, QString> > folderList;
-    QList<QString>                  nextFolder;
-};
-
-ODTalker::ODTalker(QWidget* const parent)
-    : d(new Private)
-{
-    d->parent   = parent;
-    d->netMngr  = new QNetworkAccessManager(this);
-    d->settings = WSToolUtils::getOauthSettings(this);
-
-    connect(this, SIGNAL(oneDriveLinkingFailed()),
-            this, SLOT(slotLinkingFailed()));
-
-    connect(this, SIGNAL(oneDriveLinkingSucceeded()),
-            this, SLOT(slotLinkingSucceeded()));
-
-    connect(d->netMngr, SIGNAL(finished(QNetworkReply*)),
-            this, SLOT(slotFinished(QNetworkReply*)));
-}
-
-ODTalker::~ODTalker()
-{
-    if (d->reply)
-    {
-        d->reply->abort();
-    }
-
-    WSToolUtils::removeTemporaryDir("onedrive");
-
-    delete d;
-}
-
-void ODTalker::link()
-{
-    emit signalBusy(true);
-
-    QUrl url(d->authUrl);
-    QUrlQuery query(url);
-    query.addQueryItem(QLatin1String("client_id"), d->clientId);
-    query.addQueryItem(QLatin1String("scope"), d->scope);
-    query.addQueryItem(QLatin1String("redirect_uri"), d->redirectUrl);
-    query.addQueryItem(QLatin1String("response_type"), QLatin1String("token"));
-    url.setQuery(query);
-
-    delete d->browser;
-    d->browser = new WebBrowserDlg(url, d->parent, true);
-    d->browser->setModal(true);
-
-    connect(d->browser, SIGNAL(urlChanged(QUrl)),
-            this, SLOT(slotCatchUrl(QUrl)));
-
-    connect(d->browser, SIGNAL(closeView(bool)),
-            this, SIGNAL(signalBusy(bool)));
-
-    d->browser->show();
-}
-
-void ODTalker::unLink()
-{
-    d->accessToken = QString();
-
-    d->settings->beginGroup(d->serviceName);
-    d->settings->remove(QString());
-    d->settings->endGroup();
-
-    emit oneDriveLinkingSucceeded();
-}
-
-void ODTalker::slotCatchUrl(const QUrl& url)
-{
-    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Received URL from webview:" << url;
-
-    QString   str = url.toString();
-    QUrlQuery query(str.section(QLatin1Char('#'), -1, -1));
-
-    if (query.hasQueryItem(QLatin1String("access_token")))
-    {
-        d->accessToken = query.queryItemValue(QLatin1String("access_token"));
-        int seconds    = query.queryItemValue(QLatin1String("expires_in")).toInt();
-        d->expiryTime  = QDateTime::currentDateTime().addSecs(seconds);
-
-        writeSettings();
-
-        qDebug(DIGIKAM_WEBSERVICES_LOG) << "Access token received";
-        emit oneDriveLinkingSucceeded();
-    }
-    else
-    {
-        emit oneDriveLinkingFailed();
-    }
-}
-
-void ODTalker::slotLinkingFailed()
-{
-    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "LINK to Onedrive fail";
-    emit signalBusy(false);
-}
-
-void ODTalker::slotLinkingSucceeded()
-{
-    if (d->accessToken.isEmpty())
-    {
-        qCDebug(DIGIKAM_WEBSERVICES_LOG) << "UNLINK to Onedrive";
-        emit signalBusy(false);
-        return;
-    }
-
-    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "LINK to Onedrive";
-
-    if (d->browser)
-    {
-        d->browser->close();
-    }
-
-    emit signalLinkingSucceeded();
-}
-
-bool ODTalker::authenticated()
-{
-    return (!d->accessToken.isEmpty());
-}
-
-void ODTalker::cancel()
-{
-    if (d->reply)
-    {
-        d->reply->abort();
-        d->reply = nullptr;
-    }
-
-    emit signalBusy(false);
-}
-
-void ODTalker::createFolder(QString& path)
-{
-    //path also has name of new folder so send path parameter accordingly
-    QString name       = QUrl(path).fileName();
-    QString folderPath = QUrl(path).adjusted(QUrl::RemoveFilename |
-                                             QUrl::StripTrailingSlash).path();
-
-    QUrl url;
-
-    if (folderPath == QLatin1String("/"))
-    {
-        url = QUrl(QLatin1String("https://graph.microsoft.com/v1.0/me/drive/root/children"));
-    }
-    else
-    {
-        url = QUrl(QString::fromUtf8("https://graph.microsoft.com/v1.0/me/drive/root:/%1:/children").arg(folderPath));
-    }
-
-    QNetworkRequest netRequest(url);
-    netRequest.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("application/json"));
-    netRequest.setRawHeader("Authorization", QString::fromLatin1("bearer %1").arg(d->accessToken).toUtf8());
-
-    QByteArray postData = QString::fromUtf8("{\"name\": \"%1\",\"folder\": {}}").arg(name).toUtf8();
-    d->reply = d->netMngr->post(netRequest, postData);
-
-    d->state = Private::OD_CREATEFOLDER;
-    emit signalBusy(true);
-}
-
-void ODTalker::getUserName()
-{
-    QUrl url(QLatin1String("https://graph.microsoft.com/v1.0/me"));
-
-    QNetworkRequest netRequest(url);
-    netRequest.setRawHeader("Authorization", QString::fromLatin1("bearer %1").arg(d->accessToken).toUtf8());
-    netRequest.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("application/json"));
-
-    d->reply = d->netMngr->get(netRequest);
-    d->state = Private::OD_USERNAME;
-    emit signalBusy(true);
-}
-
-/** Get list of folders by parsing json sent by onedrive
- */
-void ODTalker::listFolders(const QString& folder)
-{
-    QString nextFolder;
-
-    if (folder.isEmpty())
-    {
-        d->folderList.clear();
-        d->nextFolder.clear();
-    }
-    else
-    {
-        nextFolder = QLatin1Char(':') + folder + QLatin1Char(':');
-    }
-
-    QUrl url(QString::fromLatin1("https://graph.microsoft.com/v1.0/me/drive/root%1/"
-                                 "children?select=name,folder,path,parentReference").arg(nextFolder));
-
-    QNetworkRequest netRequest(url);
-    netRequest.setRawHeader("Authorization", QString::fromLatin1("bearer %1").arg(d->accessToken).toUtf8());
-    netRequest.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("application/json"));
-
-    d->reply = d->netMngr->get(netRequest);
-
-    d->state = Private::OD_LISTFOLDERS;
-    emit signalBusy(true);
-}
-
-bool ODTalker::addPhoto(const QString& imgPath, const QString& uploadFolder, bool rescale, int maxDim, int imageQuality)
-{
-    if (d->reply)
-    {
-        d->reply->abort();
-        d->reply = nullptr;
-    }
-
-    emit signalBusy(true);
-
-    ODMPForm form;
-    QString path = imgPath;
-
-    QMimeDatabase mimeDB;
-
-    if (mimeDB.mimeTypeForFile(imgPath).name().startsWith(QLatin1String("image/")))
-    {
-        QImage image = PreviewLoadThread::loadHighQualitySynchronously(imgPath).copyQImage();
-
-        if (image.isNull())
-        {
-            emit signalBusy(false);
-            return false;
-        }
-
-        path = WSToolUtils::makeTemporaryDir("onedrive").filePath(QFileInfo(imgPath)
-                                             .baseName().trimmed() + QLatin1String(".jpg"));
-
-        if (rescale && (image.width() > maxDim || image.height() > maxDim))
-        {
-            image = image.scaled(maxDim, maxDim, Qt::KeepAspectRatio, Qt::SmoothTransformation);
-        }
-
-        image.save(path, "JPEG", imageQuality);
-
-        DMetadata meta;
-
-        if (meta.load(imgPath))
-        {
-            meta.setItemDimensions(image.size());
-            meta.setItemOrientation(DMetadata::ORIENTATION_NORMAL);
-            meta.setMetadataWritingMode((int)DMetadata::WRITE_TO_FILE_ONLY);
-            meta.save(path, true);
-        }
-    }
-
-    if (!form.addFile(path))
-    {
-        emit signalBusy(false);
-        return false;
-    }
-
-    QString uploadPath = uploadFolder + QUrl(imgPath).fileName();
-    QUrl url(QString::fromLatin1("https://graph.microsoft.com/v1.0/me/drive/root:/%1:/content").arg(uploadPath));
-
-    QNetworkRequest netRequest(url);
-    netRequest.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("application/octet-stream"));
-    netRequest.setRawHeader("Authorization", QString::fromLatin1("bearer {%1}").arg(d->accessToken).toUtf8());
-
-    d->reply = d->netMngr->put(netRequest, form.formData());
-
-    d->state = Private::OD_ADDPHOTO;
-
-    return true;
-}
-
-void ODTalker::slotFinished(QNetworkReply* reply)
-{
-    if (reply != d->reply)
-    {
-        return;
-    }
-
-    d->reply = nullptr;
-
-    if (reply->error() != QNetworkReply::NoError)
-    {
-        if (d->state != Private::OD_CREATEFOLDER)
-        {
-            emit signalBusy(false);
-            QMessageBox::critical(QApplication::activeWindow(),
-                                  i18n("Error"), reply->errorString());
-
-            reply->deleteLater();
-            return;
-        }
-    }
-
-    QByteArray buffer = reply->readAll();
-
-    switch (d->state)
-    {
-        case Private::OD_LISTFOLDERS:
-            qCDebug(DIGIKAM_WEBSERVICES_LOG) << "In OD_LISTFOLDERS";
-            parseResponseListFolders(buffer);
-            break;
-        case Private::OD_CREATEFOLDER:
-            qCDebug(DIGIKAM_WEBSERVICES_LOG) << "In OD_CREATEFOLDER";
-            parseResponseCreateFolder(buffer);
-            break;
-        case Private::OD_ADDPHOTO:
-            qCDebug(DIGIKAM_WEBSERVICES_LOG) << "In OD_ADDPHOTO";
-            parseResponseAddPhoto(buffer);
-            break;
-        case Private::OD_USERNAME:
-            qCDebug(DIGIKAM_WEBSERVICES_LOG) << "In OD_USERNAME";
-            parseResponseUserName(buffer);
-            break;
-        default:
-            break;
-    }
-
-    reply->deleteLater();
-}
-
-void ODTalker::parseResponseAddPhoto(const QByteArray& data)
-{
-    QJsonDocument doc      = QJsonDocument::fromJson(data);
-    QJsonObject jsonObject = doc.object();
-    bool success           = jsonObject.contains(QLatin1String("size"));
-    emit signalBusy(false);
-
-    if (!success)
-    {
-        emit signalAddPhotoFailed(i18n("Failed to upload photo"));
-    }
-    else
-    {
-        emit signalAddPhotoSucceeded();
-    }
-}
-
-void ODTalker::parseResponseUserName(const QByteArray& data)
-{
-    QJsonDocument doc = QJsonDocument::fromJson(data);
-    QString name      = doc.object()[QLatin1String("displayName")].toString();
-    emit signalBusy(false);
-    emit signalSetUserName(name);
-}
-
-void ODTalker::parseResponseListFolders(const QByteArray& data)
-{
-    QJsonParseError err;
-    QJsonDocument doc = QJsonDocument::fromJson(data, &err);
-
-    if (err.error != QJsonParseError::NoError)
-    {
-        emit signalBusy(false);
-        emit signalListAlbumsFailed(i18n("Failed to list folders"));
-        return;
-    }
-
-    QJsonObject jsonObject = doc.object();
-    //qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Json: " << doc;
-    QJsonArray jsonArray   = jsonObject[QLatin1String("value")].toArray();
-
-    if (d->folderList.isEmpty())
-    {
-        d->folderList.append(qMakePair(QLatin1String(""), QLatin1String("root")));
-    }
-
-    foreach (const QJsonValue& value, jsonArray)
-    {
-        QString path;
-        QString listName;
-        QString folderPath;
-        QString folderName;
-        QJsonObject folder;
-        QJsonObject parent;
-
-        QJsonObject obj = value.toObject();
-        folder          = obj[QLatin1String("folder")].toObject();
-        parent          = obj[QLatin1String("parentReference")].toObject();
-
-        if (!folder.isEmpty())
-        {
-            folderPath  = parent[QLatin1String("path")].toString();
-            folderName  = obj[QLatin1String("name")].toString();
-
-            path        = folderPath.section(QLatin1String("root:"), -1, -1) +
-                                             QLatin1Char('/') + folderName;
-            path        = QUrl(path).toString(QUrl::FullyDecoded);
-            listName    = path.section(QLatin1Char('/'), 1);
-
-            d->folderList.append(qMakePair(path, listName));
-
-            if (folder[QLatin1String("childCount")].toInt() > 0)
-            {
-                d->nextFolder << path;
-            }
-        }
-    }
-
-    if (!d->nextFolder.isEmpty())
-    {
-        listFolders(d->nextFolder.takeLast());
-    }
-    else
-    {
-        std::sort(d->folderList.begin(), d->folderList.end());
-
-        emit signalBusy(false);
-        emit signalListAlbumsDone(d->folderList);
-    }
-}
-
-void ODTalker::parseResponseCreateFolder(const QByteArray& data)
-{
-    QJsonDocument doc      = QJsonDocument::fromJson(data);<--- Shadowed declaration
-    QJsonObject jsonObject = doc.object();
-    bool fail              = jsonObject.contains(QLatin1String("error"));
-
-    emit signalBusy(false);
-
-    if (fail)
-    {
-        QJsonParseError err;
-        QJsonDocument doc = QJsonDocument::fromJson(data, &err);<--- Shadow variable
-        emit signalCreateFolderFailed(jsonObject[QLatin1String("error_summary")].toString());
-    }
-    else
-    {
-        emit signalCreateFolderSucceeded();
-    }
-}
-
-void ODTalker::writeSettings()
-{
-    d->settings->beginGroup(d->serviceName);
-    d->settings->setValue(d->serviceTime, d->expiryTime);
-    d->settings->setValue(d->serviceKey,  d->accessToken);
-    d->settings->endGroup();
-}
-
-void ODTalker::readSettings()
-{
-    d->settings->beginGroup(d->serviceName);
-    d->expiryTime  = d->settings->value(d->serviceTime).toDateTime();
-    d->accessToken = d->settings->value(d->serviceKey).toString();
-    d->settings->endGroup();
-
-    if (d->accessToken.isEmpty())
-    {
-        qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Linking...";
-        link();
-    }
-    else if (QDateTime::currentDateTime() > d->expiryTime)
-    {
-        qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Access token has expired";
-        d->accessToken = QString();
-        link();
-    }
-    else
-    {
-        qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Already Linked";
-        emit oneDriveLinkingSucceeded();
-    }
-}
-
-} // namespace DigikamGenericOneDrivePlugin
-
-
-
- - - diff --git a/static/reports/cppcheck/master/8.html b/static/reports/cppcheck/master/8.html deleted file mode 100644 index ff04fb4b2..000000000 --- a/static/reports/cppcheck/master/8.html +++ /dev/null @@ -1,1391 +0,0 @@ - - - - - - Cppcheck - HTML report - digiKam-master-rev-907aafb5fa - - - - - - - -
-
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-172
-173
-174
-175
-176
-177
-178
-179
-180
-181
-182
-183
-184
-185
-186
-187
-188
-189
-190
-191
-192
-193
-194
-195
-196
-197
-198
-199
-200
-201
-202
-203
-204
-205
-206
-207
-208
-209
-210
-211
-212
-213
-214
-215
-216
-217
-218
-219
-220
-221
-222
-223
-224
-225
-226
-227
-228
-229
-230
-231
-232
-233
-234
-235
-236
-237
-238
-239
-240
-241
-242
-243
-244
-245
-246
-247
-248
-249
-250
-251
-252
-253
-254
-255
-256
-257
-258
-259
-260
-261
-262
-263
-264
-265
-266
-267
-268
-269
-270
-271
-272
-273
-274
-275
-276
-277
-278
-279
-280
-281
-282
-283
-284
-285
-286
-287
-288
-289
-290
-291
-292
-293
-294
-295
-296
-297
-298
-299
-300
-301
-302
-303
-304
-305
-306
-307
-308
-309
-310
-311
-312
-313
-314
-315
-316
-317
-318
-319
-320
-321
-322
-323
-324
-325
-326
-327
-328
-329
-330
-331
-332
-333
-334
-335
-336
-337
-338
-339
-340
-341
-342
-343
-344
-345
-346
-347
-348
-349
-350
-351
-352
-353
-354
-355
-356
-357
-358
-359
-360
-361
-362
-363
-364
-365
-366
-367
-368
-369
-370
-371
-372
-373
-374
-375
-376
-377
-378
-379
-380
-381
-382
-383
-384
-385
-386
-387
-388
-389
-390
-391
-392
-393
-394
-395
-396
-397
-398
-399
-400
-401
-402
-403
-404
-405
-406
-407
-408
-409
-410
-411
-412
-413
-414
-415
-416
-417
-418
-419
-420
-421
-422
-423
-424
-425
-426
-427
-428
-429
-430
-431
-432
-433
-434
-435
-436
-437
-438
-439
-440
-441
-442
-443
-444
-445
-446
-447
-448
-449
-450
-451
-452
-453
-454
-455
-456
-457
-458
-459
-460
-461
-462
-463
-464
-465
-466
-467
-468
-469
-470
-471
-472
-473
-474
-475
-476
-477
-478
-479
-480
-481
-482
-483
-484
-485
-486
-487
-488
-489
-490
-491
-492
-493
-494
-495
-496
-497
-498
-499
-500
-501
-502
-503
-504
-505
-506
-507
-508
-509
-510
-511
-512
-513
-514
-515
-516
-517
-518
-519
-520
-521
-522
-523
-524
-525
-526
-527
-528
-529
-530
-531
-532
-533
-534
-535
-536
-537
-538
-539
-540
-541
-542
-543
-544
-545
-546
-547
-548
-549
-550
-551
-552
-553
-554
-555
-556
-557
-558
-559
-560
-561
-562
-563
-564
-565
-566
-567
-568
-569
-570
-571
-572
-573
-574
-575
-576
-577
-578
-579
-580
-581
-582
-583
-584
-585
-586
-587
-588
-589
-590
-591
-592
-593
-594
-595
-596
-597
-598
-599
-600
-601
-602
-603
-604
-605
-606
-607
-608
-609
-610
-611
-612
-613
-614
-615
-616
-617
-618
-619
-620
-621
-622
-623
/* ============================================================
- *
- * This file is a part of digiKam project
- * https://www.digikam.org
- *
- * Date        : 2018-05-20
- * Description : a tool to export images to Pinterest web service
- *
- * Copyright (C) 2018      by Tarek Talaat <tarektalaat93 at gmail dot com>
- *
- * This program is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General
- * Public License as published by the Free Software Foundation;
- * either version 2, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * ============================================================ */
-
-#include "ptalker.h"
-
-// Qt includes
-
-#include <QJsonDocument>
-#include <QJsonParseError>
-#include <QJsonObject>
-#include <QJsonValue>
-#include <QJsonArray>
-#include <QByteArray>
-#include <QList>
-#include <QPair>
-#include <QFileInfo>
-#include <QWidget>
-#include <QMessageBox>
-#include <QApplication>
-#include <QDesktopServices>
-#include <QUrlQuery>
-#include <QHttpMultiPart>
-#include <QNetworkAccessManager>
-
-// KDE includes
-
-#include <klocalizedstring.h>
-#include <kwindowconfig.h>
-
-// Local includes
-
-#include "digikam_debug.h"
-#include "digikam_version.h"
-#include "wstoolutils.h"
-#include "pwindow.h"
-#include "pitem.h"
-#include "webbrowserdlg.h"
-#include "previewloadthread.h"
-
-namespace DigikamGenericPinterestPlugin
-{
-
-class Q_DECL_HIDDEN PTalker::Private
-{
-public:
-
-    enum State
-    {
-        P_USERNAME = 0,
-        P_LISTBOARDS,
-        P_CREATEBOARD,
-        P_ADDPIN,
-        P_ACCESSTOKEN
-    };
-
-public:
-
-    explicit Private()
-      : parent(nullptr),
-        netMngr(nullptr),
-        reply(nullptr),
-        settings(nullptr),
-        state(P_USERNAME),
-        browser(nullptr)
-    {
-        clientId     = QLatin1String("4983380570301022071");
-        clientSecret = QLatin1String("2a698db679125930d922a2dfb897e16b668a67c6f614593636e83fc3d8d9b47d");
-
-        authUrl      = QLatin1String("https://api.pinterest.com/oauth/");
-        tokenUrl     = QLatin1String("https://api.pinterest.com/v1/oauth/token");
-        redirectUrl  = QLatin1String("https://login.live.com/oauth20_desktop.srf");
-        scope        = QLatin1String("read_public,write_public");
-        serviceName  = QLatin1String("Pinterest");
-        serviceKey   = QLatin1String("access_token");
-    }
-
-public:
-
-    QString                clientId;
-    QString                clientSecret;
-    QString                authUrl;
-    QString                tokenUrl;
-    QString                redirectUrl;
-    QString                accessToken;
-    QString                scope;
-    QString                userName;
-    QString                serviceName;
-    QString                serviceKey;
-
-    QWidget*               parent;
-
-    QNetworkAccessManager* netMngr;
-    QNetworkReply*         reply;
-
-    QSettings*             settings;
-
-    State                  state;
-
-    DMetadata              meta;
-
-    QMap<QString, QString> urlParametersMap;
-
-    WebBrowserDlg*         browser;
-};
-
-PTalker::PTalker(QWidget* const parent)
-    : d(new Private)
-{
-    d->parent   = parent;
-    d->netMngr  = new QNetworkAccessManager(this);
-    d->settings = WSToolUtils::getOauthSettings(this);
-
-    connect(d->netMngr, SIGNAL(finished(QNetworkReply*)),
-            this, SLOT(slotFinished(QNetworkReply*)));
-
-    connect(this, SIGNAL(pinterestLinkingFailed()),
-            this, SLOT(slotLinkingFailed()));
-
-    connect(this, SIGNAL(pinterestLinkingSucceeded()),
-            this, SLOT(slotLinkingSucceeded()));
-}
-
-PTalker::~PTalker()
-{
-    if (d->reply)
-    {
-        d->reply->abort();
-    }
-
-    WSToolUtils::removeTemporaryDir("pinterest");
-
-    delete d;
-}
-
-void PTalker::link()
-{
-    emit signalBusy(true);
-
-    QUrl url(d->authUrl);
-    QUrlQuery query(url);
-    query.addQueryItem(QLatin1String("client_id"),     d->clientId);
-    query.addQueryItem(QLatin1String("scope"),         d->scope);
-    query.addQueryItem(QLatin1String("redirect_uri"),  d->redirectUrl);
-    query.addQueryItem(QLatin1String("response_type"), QLatin1String("code"));
-    url.setQuery(query);
-
-    delete d->browser;
-    d->browser = new WebBrowserDlg(url, d->parent, true);
-    d->browser->setModal(true);
-
-    connect(d->browser, SIGNAL(urlChanged(QUrl)),
-            this, SLOT(slotCatchUrl(QUrl)));
-
-    connect(d->browser, SIGNAL(closeView(bool)),
-            this, SIGNAL(signalBusy(bool)));
-
-    d->browser->show();
-}
-
-void PTalker::unLink()
-{
-    d->accessToken = QString();
-
-    d->settings->beginGroup(d->serviceName);
-    d->settings->remove(QString());
-    d->settings->endGroup();
-
-    emit pinterestLinkingSucceeded();
-}
-
-void PTalker::slotCatchUrl(const QUrl& url)
-{
-    d->urlParametersMap = ParseUrlParameters(url.toString());
-    QString code        = d->urlParametersMap.value(QLatin1String("code"));
-    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Received URL from webview in link function: " << url ;
-
-    if (!code.isEmpty())
-    {
-        qCDebug(DIGIKAM_WEBSERVICES_LOG) << "CODE Received";
-        d->browser->close();
-        getToken(code);
-        emit signalBusy(false);
-    }
-}
-
-void PTalker::getToken(const QString& code)
-{
-    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Code: " << code;
-    QUrl url(d->tokenUrl);
-    QUrlQuery query(url);
-    query.addQueryItem(QLatin1String("grant_type"),    QLatin1String("authorization_code"));
-    query.addQueryItem(QLatin1String("client_id"),     d->clientId);
-    query.addQueryItem(QLatin1String("client_secret"), d->clientSecret);
-    query.addQueryItem(QLatin1String("code"),          code);
-    url.setQuery(query);
-    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Token Request URL:    " << url.toString();
-
-    QNetworkRequest netRequest(url);
-    netRequest.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("application/x-www-form-urlencoded"));
-    netRequest.setRawHeader("Accept", "application/json");
-
-    d->reply = d->netMngr->post(netRequest, QByteArray());
-
-    d->state = Private::P_ACCESSTOKEN;
-}
-
-QMap<QString, QString> PTalker::ParseUrlParameters(const QString& url)
-{
-    QMap<QString, QString> urlParameters;
-
-    if (url.indexOf(QLatin1Char('?')) == -1)
-    {
-        return urlParameters;
-    }
-
-    QString tmp           = url.right(url.length()-url.indexOf(QLatin1Char('?')) - 1);
-    QStringList paramlist = tmp.split(QLatin1Char('&'));
-
-    for (int i = 0 ; i < paramlist.count() ; ++i)
-    {
-        QStringList paramarg = paramlist.at(i).split(QLatin1Char('='));
-
-        if (paramarg.count() == 2)
-        {
-            urlParameters.insert(paramarg.at(0), paramarg.at(1));
-        }
-    }
-
-    return urlParameters;
-}
-
-void PTalker::slotLinkingFailed()
-{
-    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "LINK to Pinterest fail";
-    emit signalBusy(false);
-}
-
-void PTalker::slotLinkingSucceeded()
-{
-    if (d->accessToken.isEmpty())
-    {
-        qCDebug(DIGIKAM_WEBSERVICES_LOG) << "UNLINK to Pinterest ok";
-        emit signalBusy(false);
-        return;
-    }
-
-    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "LINK to Pinterest ok";
-    writeSettings();
-    emit signalLinkingSucceeded();
-}
-
-bool PTalker::authenticated()
-{
-    return (!d->accessToken.isEmpty());
-}
-
-void PTalker::cancel()
-{
-    if (d->reply)
-    {
-        d->reply->abort();
-        d->reply = nullptr;
-    }
-
-    emit signalBusy(false);
-}
-
-void PTalker::createBoard(QString& boardName)
-{
-    QUrl url(QLatin1String("https://api.pinterest.com/v1/boards/"));
-    QNetworkRequest netRequest(url);
-    netRequest.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("application/json"));
-    netRequest.setRawHeader("Authorization", QString::fromLatin1("Bearer %1").arg(d->accessToken).toUtf8());
-
-    QByteArray postData = QString::fromUtf8("{\"name\": \"%1\"}").arg(boardName).toUtf8();
-/*
-    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "createBoard:" << postData;
-*/
-    d->reply = d->netMngr->post(netRequest, postData);
-
-    d->state = Private::P_CREATEBOARD;
-    emit signalBusy(true);
-}
-
-void PTalker::getUserName()
-{
-    QUrl url(QLatin1String("https://api.pinterest.com/v1/me/?fields=username"));
-
-    QNetworkRequest netRequest(url);
-    netRequest.setRawHeader("Authorization", QString::fromLatin1("Bearer %1").arg(d->accessToken).toUtf8());
-
-    d->reply = d->netMngr->get(netRequest);
-    d->state = Private::P_USERNAME;
-    emit signalBusy(true);
-}
-
-/**
- * Get list of boards by parsing json sent by pinterest
- */
-void PTalker::listBoards(const QString& /*path*/)
-{
-    QUrl url(QLatin1String("https://api.pinterest.com/v1/me/boards/"));;
-
-    QNetworkRequest netRequest(url);
-    netRequest.setRawHeader("Authorization", QString::fromLatin1("Bearer %1").arg(d->accessToken).toUtf8());
-    //netRequest.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("application/json"));
-
-    d->reply = d->netMngr->get(netRequest);
-
-    d->state = Private::P_LISTBOARDS;
-    emit signalBusy(true);
-}
-
-bool PTalker::addPin(const QString& imgPath,
-                     const QString& uploadBoard,
-                     bool rescale,
-                     int maxDim,
-                     int imageQuality)
-{
-    if (d->reply)
-    {
-        d->reply->abort();
-        d->reply = nullptr;
-    }
-
-    emit signalBusy(true);
-
-    QImage image = PreviewLoadThread::loadHighQualitySynchronously(imgPath).copyQImage();
-
-    if (image.isNull())
-    {
-        emit signalBusy(false);
-        return false;
-    }
-
-    QString path = WSToolUtils::makeTemporaryDir("pinterest").filePath(QFileInfo(imgPath)
-                                                 .baseName().trimmed() + QLatin1String(".jpg"));
-
-    if (rescale && (image.width() > maxDim || image.height() > maxDim))
-    {
-        image = image.scaled(maxDim, maxDim, Qt::KeepAspectRatio, Qt::SmoothTransformation);
-    }
-
-    image.save(path, "JPEG", imageQuality);
-
-    if (d->meta.load(imgPath))
-    {
-        d->meta.setItemDimensions(image.size());
-        d->meta.setItemOrientation(DMetadata::ORIENTATION_NORMAL);
-        d->meta.setMetadataWritingMode((int)DMetadata::WRITE_TO_FILE_ONLY);
-        d->meta.save(path, true);
-    }
-
-    QString boardParam              = d->userName + QLatin1Char('/') + uploadBoard;
-
-    QUrl url(QString::fromLatin1("https://api.pinterest.com/v1/pins/?access_token=%1").arg(d->accessToken));
-
-    QHttpMultiPart* const multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
-
-    // Board Section
-
-    QHttpPart board;
-    QString boardHeader = QLatin1String("form-data; name=\"board\"") ;
-    board.setHeader(QNetworkRequest::ContentDispositionHeader, boardHeader);
-
-    QByteArray postData = boardParam.toUtf8();
-    board.setBody(postData);
-    multiPart->append(board);
-
-    // Note section
-
-    QHttpPart note;
-    QString noteHeader = QLatin1String("form-data; name=\"note\"") ;
-    note.setHeader(QNetworkRequest::ContentDispositionHeader, noteHeader);
-
-    postData           = QByteArray();
-
-    note.setBody(postData);
-    multiPart->append(note);
-
-    // image section
-
-    QFile* const file  = new QFile(imgPath);
-
-    if (!file)
-    {
-        return false;
-    }
-
-    if (!file->open(QIODevice::ReadOnly))
-    {
-        return false;
-    }
-
-    QHttpPart imagePart;
-    QString imagePartHeader = QLatin1String("form-data; name=\"image\"; filename=\"") +
-                              QFileInfo(imgPath).fileName() + QLatin1Char('"');
-
-    imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, imagePartHeader);
-    imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("image/jpeg"));
-
-    imagePart.setBodyDevice(file);
-    multiPart->append(imagePart);
-
-    QString content = QLatin1String("multipart/form-data;boundary=") + QString::fromUtf8(multiPart->boundary());
-    QNetworkRequest netRequest(url);
-    netRequest.setHeader(QNetworkRequest::ContentTypeHeader, content);
-
-    d->reply = d->netMngr->post(netRequest, multiPart);
-
-    // delete the multiPart and file with the reply
-
-    multiPart->setParent(d->reply);
-    d->state = Private::P_ADDPIN;
-
-    return true;
-}
-
-void PTalker::slotFinished(QNetworkReply* reply)
-{
-    if (reply != d->reply)
-    {
-        return;
-    }
-
-    d->reply = nullptr;
-
-    if (reply->error() != QNetworkReply::NoError)
-    {
-        if (d->state != Private::P_CREATEBOARD)
-        {
-            emit signalBusy(false);
-            QMessageBox::critical(QApplication::activeWindow(),
-                                  i18n("Error"), reply->errorString());
-/*
-            qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Error content: " << QString(reply->readAll());
-*/
-            reply->deleteLater();
-            return;
-        }
-    }
-
-    QByteArray buffer = reply->readAll();
-/*
-    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "BUFFER" << QString(buffer);
-*/
-    switch (d->state)
-    {
-        case Private::P_LISTBOARDS:
-            qCDebug(DIGIKAM_WEBSERVICES_LOG) << "In P_LISTBOARDS";
-            parseResponseListBoards(buffer);
-            break;
-        case Private::P_CREATEBOARD:
-            qCDebug(DIGIKAM_WEBSERVICES_LOG) << "In P_CREATEBOARD";
-            parseResponseCreateBoard(buffer);
-            break;
-        case Private::P_ADDPIN:
-            qCDebug(DIGIKAM_WEBSERVICES_LOG) << "In P_ADDPIN";
-            parseResponseAddPin(buffer);
-            break;
-        case Private::P_USERNAME:
-            qCDebug(DIGIKAM_WEBSERVICES_LOG) << "In P_USERNAME";
-            parseResponseUserName(buffer);
-            break;
-        case Private::P_ACCESSTOKEN:
-            qCDebug(DIGIKAM_WEBSERVICES_LOG) << "In P_ACCESSTOKEN";
-            parseResponseAccessToken(buffer);
-            break;
-        default:
-            break;
-    }
-
-    reply->deleteLater();
-}
-
-void PTalker::parseResponseAccessToken(const QByteArray& data)
-{
-    QJsonDocument doc      = QJsonDocument::fromJson(data);
-    QJsonObject jsonObject = doc.object();
-    d->accessToken         = jsonObject[QLatin1String("access_token")].toString();
-
-    if (!d->accessToken.isEmpty())
-    {
-        qDebug(DIGIKAM_WEBSERVICES_LOG) << "Access token Received: " << d->accessToken;
-        emit pinterestLinkingSucceeded();
-    }
-    else
-    {
-        emit pinterestLinkingFailed();
-    }
-
-    emit signalBusy(false);
-}
-
-void PTalker::parseResponseAddPin(const QByteArray& data)
-{
-    QJsonDocument doc      = QJsonDocument::fromJson(data);
-    QJsonObject jsonObject = doc.object()[QLatin1String("data")].toObject();
-    bool success           = jsonObject.contains(QLatin1String("id"));
-    emit signalBusy(false);
-
-    if (!success)
-    {
-        emit signalAddPinFailed(i18n("Failed to upload Pin"));
-    }
-    else
-    {
-        emit signalAddPinSucceeded();
-    }
-}
-
-void PTalker::parseResponseUserName(const QByteArray& data)
-{
-    QJsonDocument doc      = QJsonDocument::fromJson(data);
-    QJsonObject jsonObject = doc.object()[QLatin1String("data")].toObject();
-    d->userName            = jsonObject[QLatin1String("username")].toString();
-
-    emit signalBusy(false);
-    emit signalSetUserName(d->userName);
-}
-
-void PTalker::parseResponseListBoards(const QByteArray& data)
-{
-    QJsonParseError err;
-    QJsonDocument doc = QJsonDocument::fromJson(data, &err);
-
-    if (err.error != QJsonParseError::NoError)
-    {
-        emit signalBusy(false);
-        emit signalListBoardsFailed(i18n("Failed to list boards"));
-        return;
-    }
-
-    QJsonObject jsonObject = doc.object();
-/*
-    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Json Listing Boards : " << doc;
-*/
-    QJsonArray jsonArray   = jsonObject[QLatin1String("data")].toArray();
-
-    QList<QPair<QString, QString> > list;
-    QString boardID;<--- Shadowed declaration
-    QString boardName;<--- Shadowed declaration
-
-    foreach (const QJsonValue& value, jsonArray)
-    {
-        QString boardID;<--- Shadow variable
-        QString boardName;<--- Shadow variable
-        QJsonObject obj = value.toObject();
-        boardID         = obj[QLatin1String("id")].toString();
-        boardName       = obj[QLatin1String("name")].toString();
-
-        list.append(qMakePair(boardID, boardName));
-    }
-
-    emit signalBusy(false);
-    emit signalListBoardsDone(list);
-}
-
-void PTalker::parseResponseCreateBoard(const QByteArray& data)
-{
-    QJsonDocument doc      = QJsonDocument::fromJson(data);<--- Shadowed declaration
-    QJsonObject jsonObject = doc.object();
-    bool fail              = jsonObject.contains(QLatin1String("error"));
-
-    emit signalBusy(false);
-
-    if (fail)
-    {
-        QJsonParseError err;
-        QJsonDocument doc = QJsonDocument::fromJson(data, &err);<--- Shadow variable
-        emit signalCreateBoardFailed(jsonObject[QLatin1String("error_summary")].toString());
-    }
-    else
-    {
-        emit signalCreateBoardSucceeded();
-    }
-}
-
-void PTalker::writeSettings()
-{
-    d->settings->beginGroup(d->serviceName);
-    d->settings->setValue(d->serviceKey, d->accessToken);
-    d->settings->endGroup();
-}
-
-void PTalker::readSettings()
-{
-    d->settings->beginGroup(d->serviceName);
-    d->accessToken = d->settings->value(d->serviceKey).toString();
-    d->settings->endGroup();
-
-    if (d->accessToken.isEmpty())
-    {
-        qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Linking...";
-        link();
-    }
-    else
-    {
-        qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Already Linked";
-        emit pinterestLinkingSucceeded();
-    }
-}
-
-} // namespace DigikamGenericPinterestPlugin
-
-
-
- - - diff --git a/static/reports/cppcheck/master/9.html b/static/reports/cppcheck/master/9.html deleted file mode 100644 index 3838959fc..000000000 --- a/static/reports/cppcheck/master/9.html +++ /dev/null @@ -1,1815 +0,0 @@ - - - - - - Cppcheck - HTML report - digiKam-master-rev-907aafb5fa - - - - - - - -
-
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-172
-173
-174
-175
-176
-177
-178
-179
-180
-181
-182
-183
-184
-185
-186
-187
-188
-189
-190
-191
-192
-193
-194
-195
-196
-197
-198
-199
-200
-201
-202
-203
-204
-205
-206
-207
-208
-209
-210
-211
-212
-213
-214
-215
-216
-217
-218
-219
-220
-221
-222
-223
-224
-225
-226
-227
-228
-229
-230
-231
-232
-233
-234
-235
-236
-237
-238
-239
-240
-241
-242
-243
-244
-245
-246
-247
-248
-249
-250
-251
-252
-253
-254
-255
-256
-257
-258
-259
-260
-261
-262
-263
-264
-265
-266
-267
-268
-269
-270
-271
-272
-273
-274
-275
-276
-277
-278
-279
-280
-281
-282
-283
-284
-285
-286
-287
-288
-289
-290
-291
-292
-293
-294
-295
-296
-297
-298
-299
-300
-301
-302
-303
-304
-305
-306
-307
-308
-309
-310
-311
-312
-313
-314
-315
-316
-317
-318
-319
-320
-321
-322
-323
-324
-325
-326
-327
-328
-329
-330
-331
-332
-333
-334
-335
-336
-337
-338
-339
-340
-341
-342
-343
-344
-345
-346
-347
-348
-349
-350
-351
-352
-353
-354
-355
-356
-357
-358
-359
-360
-361
-362
-363
-364
-365
-366
-367
-368
-369
-370
-371
-372
-373
-374
-375
-376
-377
-378
-379
-380
-381
-382
-383
-384
-385
-386
-387
-388
-389
-390
-391
-392
-393
-394
-395
-396
-397
-398
-399
-400
-401
-402
-403
-404
-405
-406
-407
-408
-409
-410
-411
-412
-413
-414
-415
-416
-417
-418
-419
-420
-421
-422
-423
-424
-425
-426
-427
-428
-429
-430
-431
-432
-433
-434
-435
-436
-437
-438
-439
-440
-441
-442
-443
-444
-445
-446
-447
-448
-449
-450
-451
-452
-453
-454
-455
-456
-457
-458
-459
-460
-461
-462
-463
-464
-465
-466
-467
-468
-469
-470
-471
-472
-473
-474
-475
-476
-477
-478
-479
-480
-481
-482
-483
-484
-485
-486
-487
-488
-489
-490
-491
-492
-493
-494
-495
-496
-497
-498
-499
-500
-501
-502
-503
-504
-505
-506
-507
-508
-509
-510
-511
-512
-513
-514
-515
-516
-517
-518
-519
-520
-521
-522
-523
-524
-525
-526
-527
-528
-529
-530
-531
-532
-533
-534
-535
-536
-537
-538
-539
-540
-541
-542
-543
-544
-545
-546
-547
-548
-549
-550
-551
-552
-553
-554
-555
-556
-557
-558
-559
-560
-561
-562
-563
-564
-565
-566
-567
-568
-569
-570
-571
-572
-573
-574
-575
-576
-577
-578
-579
-580
-581
-582
-583
-584
-585
-586
-587
-588
-589
-590
-591
-592
-593
-594
-595
-596
-597
-598
-599
-600
-601
-602
-603
-604
-605
-606
-607
-608
-609
-610
-611
-612
-613
-614
-615
-616
-617
-618
-619
-620
-621
-622
-623
-624
-625
-626
-627
-628
-629
-630
-631
-632
-633
-634
-635
-636
-637
-638
-639
-640
-641
-642
-643
-644
-645
-646
-647
-648
-649
-650
-651
-652
-653
-654
-655
-656
-657
-658
-659
-660
-661
-662
-663
-664
-665
-666
-667
-668
-669
-670
-671
-672
-673
-674
-675
-676
-677
-678
-679
-680
-681
-682
-683
-684
-685
-686
-687
-688
-689
-690
-691
-692
-693
-694
-695
-696
-697
-698
-699
-700
-701
-702
-703
-704
-705
-706
-707
-708
-709
-710
-711
-712
-713
-714
-715
-716
-717
-718
-719
-720
-721
-722
-723
-724
-725
-726
-727
-728
-729
-730
-731
-732
-733
-734
-735
-736
-737
-738
-739
-740
-741
-742
-743
-744
-745
-746
-747
-748
-749
-750
-751
-752
-753
-754
-755
-756
-757
-758
-759
-760
-761
-762
-763
-764
-765
-766
-767
-768
-769
-770
-771
-772
-773
-774
-775
-776
-777
-778
-779
-780
-781
-782
-783
-784
-785
-786
-787
-788
-789
-790
-791
-792
-793
-794
-795
-796
-797
-798
-799
-800
-801
-802
-803
-804
-805
-806
-807
-808
-809
-810
-811
-812
-813
-814
-815
-816
-817
-818
-819
-820
-821
-822
-823
-824
-825
-826
-827
-828
-829
-830
-831
-832
-833
-834
-835
/* ============================================================
- *
- * This file is a part of digiKam project
- * https://www.digikam.org
- *
- * Date        : 2009-12-11
- * Description : test cases for the various album models
- *
- * Copyright (C) 2009 by Johannes Wienke <languitar at semipol dot de>
- *
- * This program is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General
- * Public License as published by the Free Software Foundation;
- * either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * ============================================================ */
-
-#include "albummodeltest.h"
-
-// Qt includes
-
-#include <QDir>
-#include <QTest>
-#include <QDebug>
-#include <QUrl>
-
-// Local includes
-
-#include "albumfiltermodel.h"
-#include "albummanager.h"
-#include "albummodel.h"
-#include "applicationsettings.h"
-#include "albumthumbnailloader.h"
-#include "collectionlocation.h"
-#include "collectionmanager.h"
-#include "loadingcacheinterface.h"
-#include "scancontroller.h"
-#include "thumbnailloadthread.h"
-#include "modeltest.h"
-
-using namespace Digikam;
-
-const QString IMAGE_PATH(QFINDTESTDATA("data/"));
-
-QTEST_MAIN(AlbumModelTest)
-
-AlbumModelTest::AlbumModelTest()
-    : albumCategory(QLatin1String("DummyCategory")),
-      palbumRoot0(nullptr),
-      palbumRoot1(nullptr),
-      palbumRoot2(nullptr),
-      palbumChild0Root0(nullptr),
-      palbumChild1Root0(nullptr),
-      palbumChild2Root0(nullptr),
-      palbumChild0Root1(nullptr),
-      rootTag(nullptr),
-      talbumRoot0(nullptr),
-      talbumRoot1(nullptr),
-      talbumChild0Root0(nullptr),
-      talbumChild1Root0(nullptr),
-      talbumChild0Child1Root0(nullptr),
-      talbumChild0Root1(nullptr),
-      startModel(nullptr)
-{
-}
-
-AlbumModelTest::~AlbumModelTest()
-{
-}
-
-void AlbumModelTest::initTestCase()
-{
-    tempSuffix = QLatin1String("albummodeltest-") + QTime::currentTime().toString();
-    dbPath     = QDir::temp().absolutePath() + QLatin1Char('/') + tempSuffix;
-
-    if (QDir::temp().exists(tempSuffix))
-    {
-        QString msg = QLatin1String("Error creating temp path") + dbPath;
-        QVERIFY2(false, msg.toLatin1().constData());
-    }
-
-    QDir::temp().mkdir(tempSuffix);
-
-    qDebug() << "Using database path for test: " << dbPath;
-
-    ApplicationSettings::instance()->setShowFolderTreeViewItemsCount(true);
-
-    // use a testing database
-
-    AlbumManager::instance();
-
-    // catch palbum counts for waiting
-
-    connect(AlbumManager::instance(), SIGNAL(signalPAlbumsDirty(QMap<int,int>)),
-            this, SLOT(setLastPAlbumCountMap(QMap<int,int>)));
-
-    AlbumManager::checkDatabaseDirsAfterFirstRun(QDir::temp().absoluteFilePath(
-                                                 tempSuffix), QDir::temp().absoluteFilePath(tempSuffix));
-    DbEngineParameters params(QLatin1String("QSQLITE"), QDir::temp().absoluteFilePath(tempSuffix + QLatin1String("/digikam4.db")),
-                              QString(), QString(), -1, false, QString(), QString());
-    bool dbChangeGood = AlbumManager::instance()->setDatabase(params, false,
-                        QDir::temp().absoluteFilePath(tempSuffix));
-    QVERIFY2(dbChangeGood, "Could not set temp album db");
-    QList<CollectionLocation> locs = CollectionManager::instance()->allAvailableLocations();
-    QVERIFY2(locs.size(), "Failed to auto-create one collection in setDatabase");
-
-    ScanController::instance()->completeCollectionScan();
-    AlbumManager::instance()->startScan();
-
-    AlbumList all = AlbumManager::instance()->allPAlbums();
-    qDebug() << "PAlbum registered : " << all.size();
-
-    foreach (Album* const a, all)
-    {
-        if (a)
-        {
-            qDebug() << " ==> Id : " << a->id() << " , is root : " << a->isRoot() << " , title : " << a->title();
-        }
-    }
-
-    QVERIFY2( all.size() == 3, "Failed to scan empty directory. We must have one root album, one album, and one trash.");
-}
-
-void AlbumModelTest::cleanupTestCase()
-{
-    qDebug() << "Start AlbumModelTest::cleanupTestCase()";
-
-    ScanController::instance()->shutDown();
-    AlbumManager::instance()->cleanUp();
-    ThumbnailLoadThread::cleanUp();
-    AlbumThumbnailLoader::instance()->cleanUp();
-    LoadingCacheInterface::cleanUp();
-
-    QDir dir(dbPath);
-    dir.removeRecursively();
-
-    qDebug() << "deleted test folder " << dbPath;
-}
-
-// Qt test doesn't use exceptions, so using assertion macros in methods called
-// from a test slot doesn't stop the test method and may result in inconsistent
-// data or segfaults. Therefore use macros for these functions.
-
-#define safeCreatePAlbum(parent, name, result) \
-{ \
-    QString error; \
-    result = AlbumManager::instance()->createPAlbum(parent, name, name, \
-                    QDate::currentDate(), albumCategory, error); \
-    QVERIFY2(result, QString::fromUtf8("Error creating PAlbum for test: %1").arg(error).toLatin1().constData()); \
-}
-
-#define safeCreateTAlbum(parent, name, result) \
-{ \
-    QString error; \
-    result = AlbumManager::instance()->createTAlbum(parent, name, QLatin1String(""), error); \
-    QVERIFY2(result, QString::fromUtf8("Error creating TAlbum for test: %1").arg(error).toLatin1().constData()); \
-}
-
-void AlbumModelTest::init()
-{
-    qDebug() << "Start AlbumModelTest::init()";
-
-    palbumCountMap.clear();
-
-    // create a model to check that model work is done correctly while scanning
-
-    addedIds.clear();
-    startModel = new AlbumModel;
-    startModel->setShowCount(true);
-
-    connect(startModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
-            this, SLOT(slotStartModelRowsInserted(QModelIndex,int,int)));
-
-    connect(startModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
-            this, SLOT(slotStartModelDataChanged(QModelIndex,QModelIndex)));
-
-    qDebug() << "Created startModel" << startModel;
-
-    // ensure that this model is empty in the beginning except for the root
-    // album and the collection that include trash
-
-    QCOMPARE(startModel->rowCount(), 1);
-    QModelIndex rootIndex = startModel->index(0, 0);
-    QCOMPARE(startModel->rowCount(rootIndex), 1);
-    QModelIndex collectionIndex = startModel->index(0, 0, rootIndex);
-    QCOMPARE(startModel->rowCount(collectionIndex), 1);
-
-    // insert some test data
-
-    // physical albums
-
-    // create two of them by creating directories and scanning
-
-    QDir dir(dbPath);
-    dir.mkdir(QLatin1String("root0"));
-    dir.mkdir(QLatin1String("root1"));
-
-    ScanController::instance()->completeCollectionScan();
-    AlbumManager::instance()->refresh();
-
-    QCOMPARE(AlbumManager::instance()->allPAlbums().size(), 5);
-
-    QString error;<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration
-    palbumRoot0 = AlbumManager::instance()->findPAlbum(QUrl::fromLocalFile(dbPath + QLatin1String("/root0")));
-    QVERIFY2(palbumRoot0, "Error having PAlbum root0 in AlbumManager");
-    palbumRoot1 = AlbumManager::instance()->findPAlbum(QUrl::fromLocalFile(dbPath + QLatin1String("/root1")));
-    QVERIFY2(palbumRoot1, "Error having PAlbum root1 in AlbumManager");
-
-    // Create some more through AlbumManager
-
-    palbumRoot2 = AlbumManager::instance()->createPAlbum(dbPath, QLatin1String("root2"),
-                  QLatin1String("root album 2"), QDate::currentDate(), albumCategory, error);
-    QVERIFY2(palbumRoot2, QString::fromUtf8("Error creating PAlbum for test: %1").arg(error).toLatin1().constData());
-
-    safeCreatePAlbum(palbumRoot0, QLatin1String("root0child0"), palbumChild0Root0);<--- Shadow variable
-    safeCreatePAlbum(palbumRoot0, QLatin1String("root0child1"), palbumChild1Root0);<--- Shadow variable
-    const QString sameName = QLatin1String("sameName Album");
-    safeCreatePAlbum(palbumRoot0, sameName, palbumChild2Root0);<--- Shadow variable
-
-    safeCreatePAlbum(palbumRoot1, sameName, palbumChild0Root1);<--- Shadow variable
-
-    qDebug() << "AlbumManager now knows these PAlbums:";
-
-    foreach (Album* const a, AlbumManager::instance()->allPAlbums())
-    {
-        qDebug() << "\t" << a->title();
-    }
-
-    // tags
-
-    rootTag = AlbumManager::instance()->findTAlbum(0);
-    QVERIFY(rootTag);
-
-    safeCreateTAlbum(rootTag, QLatin1String("root0"), talbumRoot0);<--- Shadow variable
-    safeCreateTAlbum(rootTag, QLatin1String("root1"), talbumRoot1);<--- Shadow variable
-
-    safeCreateTAlbum(talbumRoot0, QLatin1String("child0 root 0"), talbumChild0Root0);<--- Shadow variable
-    safeCreateTAlbum(talbumRoot0, QLatin1String("child1 root 0"), talbumChild1Root0);<--- Shadow variable
-
-    safeCreateTAlbum(talbumChild1Root0, sameName, talbumChild0Child1Root0);<--- Shadow variable
-
-    safeCreateTAlbum(talbumRoot1, sameName, talbumChild0Root1);<--- Shadow variable
-
-    qDebug() << "created tags";
-
-    // add some images for having date albums
-
-    QDir imageDir(IMAGE_PATH);
-    imageDir.setNameFilters(QStringList() << QLatin1String("*.jpg"));
-    QStringList imageFiles = imageDir.entryList();
-
-    qDebug() << "copying images " << imageFiles << " to "
-             << palbumChild0Root0->fileUrl();
-
-    foreach (const QString& imageFile, imageFiles)
-    {
-        QString src = IMAGE_PATH + QLatin1Char('/') + imageFile;
-        QString dst = palbumChild0Root0->fileUrl().toLocalFile() + QLatin1Char('/') + imageFile;
-        bool copied = QFile::copy(src, dst);
-        QVERIFY2(copied, "Test images must be copied");
-    }
-
-    ScanController::instance()->completeCollectionScan();
-
-    if (AlbumManager::instance()->allDAlbums().count() <= 1)
-    {
-        ensureItemCounts();
-    }
-
-    qDebug() << "date albums: " << AlbumManager::instance()->allDAlbums();
-
-    // root + 2 years + 2 and 3 months per year + (1997 as test year for date ordering with 12 months) = 21
-
-    QCOMPARE(AlbumManager::instance()->allDAlbums().size(), 21);
-
-    // ensure that there is a root date album
-
-    DAlbum* const rootFromAlbumManager = AlbumManager::instance()->findDAlbum(0);
-    QVERIFY(rootFromAlbumManager);
-    DAlbum* rootFromList               = nullptr;
-
-    foreach (Album* const album, AlbumManager::instance()->allDAlbums())
-    {
-        DAlbum* const dAlbum = dynamic_cast<DAlbum*> (album);
-        QVERIFY(dAlbum);
-
-        if (dAlbum->isRoot())
-        {
-            rootFromList = dAlbum;
-        }
-    }
-
-    QVERIFY(rootFromList);
-    QVERIFY(rootFromList == rootFromAlbumManager);
-}
-
-void AlbumModelTest::testStartAlbumModel()
-{
-    qDebug() << "Start AlbumModelTest::testStartAlbumModel()";
-
-    // verify that the start album model got all these changes
-
-    // one root
-
-    QCOMPARE(startModel->rowCount(), 1);
-
-    // one collection
-
-    QModelIndex rootIndex = startModel->index(0, 0);
-    QCOMPARE(startModel->rowCount(rootIndex), 1);
-
-    // two albums in the collection
-
-    QModelIndex collectionIndex = startModel->index(0, 0, rootIndex);
-    QCOMPARE(startModel->rowCount(collectionIndex), 3);
-
-    // this is should be enough for now
-
-    // We must have received an added notation for everything except album root
-    // and collection
-
-    QCOMPARE(addedIds.size(), 7);
-}
-
-void AlbumModelTest::ensureItemCounts()
-{
-    // trigger listing job
-
-    QEventLoop dAlbumLoop;
-
-    connect(AlbumManager::instance(), SIGNAL(signalAllDAlbumsLoaded()),
-            &dAlbumLoop, SLOT(quit()));
-
-    AlbumManager::instance()->prepareItemCounts();
-    qDebug() << "Waiting for AlbumManager to create DAlbums...";
-    dAlbumLoop.exec();
-    qDebug() << "DAlbums were created";
-
-    while (palbumCountMap.size() < 8)
-    {
-        QEventLoop pAlbumLoop;
-
-        connect(AlbumManager::instance(), SIGNAL(signalPAlbumsDirty(QMap<int,int>)),
-                &pAlbumLoop, SLOT(quit()));
-
-        qDebug() << "Waiting for first PAlbum count map";
-        pAlbumLoop.exec();
-        qDebug() << "Got new PAlbum count map";
-    }
-}
-
-void AlbumModelTest::slotStartModelRowsInserted(const QModelIndex& parent, int start, int end)
-{
-    qDebug() << "called, parent:" << parent << ", start:" << start << ", end:" << end;
-
-    for (int row = start ; row <= end ; ++row)
-    {
-        QModelIndex child = startModel->index(row, 0, parent);
-        QVERIFY(child.isValid());
-        Album* album      = startModel->albumForIndex(child);
-        const int id      = child.data(AbstractAlbumModel::AlbumIdRole).toInt();
-        QVERIFY(album);
-        qDebug() << "added album with id"
-                 << id
-                 << "and name" << album->title();
-        addedIds << id;
-    }
-}
-
-void AlbumModelTest::slotStartModelDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight)
-{
-    for (int row = topLeft.row() ; row <= bottomRight.row() ; ++row)
-    {
-        QModelIndex index = startModel->index(row, topLeft.column(), topLeft.parent());
-
-        if (!index.isValid())
-        {
-            qDebug() << "Illegal index received";
-            continue;
-        }
-
-        int albumId = index.data(AbstractAlbumModel::AlbumIdRole).toInt();
-
-        if (!addedIds.contains(albumId))
-        {
-            QString message = QLatin1String("Album id ") + QString::number(albumId) +
-                              QLatin1String(" was changed before adding signal was received");
-            QFAIL(message.toLatin1().constData());
-            qDebug() << message;
-        }
-    }
-}
-
-void AlbumModelTest::deletePAlbum(PAlbum* album)
-{
-    QDir dir(album->folderPath());
-    dir.removeRecursively();
-}
-
-void AlbumModelTest::setLastPAlbumCountMap(const QMap<int, int> &map)
-{
-    qDebug() << "Receiving new count map "<< map;
-    palbumCountMap = map;
-}
-
-void AlbumModelTest::cleanup()
-{
-    if (startModel)
-    {
-        disconnect(startModel);
-    }
-
-    delete startModel;
-    addedIds.clear();
-
-    // remove all test data
-
-    AlbumManager::instance()->refresh();
-
-    // remove all palbums' directories
-
-    deletePAlbum(palbumRoot0);
-    deletePAlbum(palbumRoot1);
-    deletePAlbum(palbumRoot2);
-
-    // take over changes to database
-
-    ScanController::instance()->completeCollectionScan();
-
-    // reread from database
-
-    AlbumManager::instance()->refresh();
-
-    // root + one collection
-
-    QCOMPARE(AlbumManager::instance()->allPAlbums().size(), 2);
-
-    // remove all tags
-
-    QString error;
-    bool removed = AlbumManager::instance()->deleteTAlbum(talbumRoot0, error, false);
-    QVERIFY2(removed, QString::fromUtf8("Error removing a tag: %1").arg(error).toLatin1().constData());
-    removed      = AlbumManager::instance()->deleteTAlbum(talbumRoot1, error, false);
-    QVERIFY2(removed, QString::fromUtf8("Error removing a tag: %1").arg(error).toLatin1().constData());
-
-    QCOMPARE(AlbumManager::instance()->allTAlbums().size(), 1);
-}
-
-void AlbumModelTest::testPAlbumModel()
-{
-    qDebug() << "Start AlbumModelTest::testPAlbumModel()";
-
-    AlbumModel* albumModel = new AlbumModel();
-    ModelTest* test        = new ModelTest(albumModel, nullptr);
-    delete test;
-    delete albumModel;
-
-    albumModel = new AlbumModel(AbstractAlbumModel::IgnoreRootAlbum);
-    test       = new ModelTest(albumModel, nullptr);
-    delete test;
-    delete albumModel;
-}
-
-void AlbumModelTest::testDisablePAlbumCount()
-{
-    qDebug() << "Start AlbumModelTest::testDisablePAlbumCount()";
-
-    AlbumModel albumModel;
-    albumModel.setCountMap(palbumCountMap);
-    albumModel.setShowCount(true);
-
-    QRegExp countRegEx(QLatin1String(".+ \\(\\d+\\)"));
-    countRegEx.setMinimal(true);
-    QVERIFY(countRegEx.exactMatch(QLatin1String("test (10)")));
-    QVERIFY(countRegEx.exactMatch(QLatin1String("te st (10)")));
-    QVERIFY(countRegEx.exactMatch(QLatin1String("te st (0)")));
-    QVERIFY(!countRegEx.exactMatch(QLatin1String("te st ()")));
-    QVERIFY(!countRegEx.exactMatch(QLatin1String("te st")));
-    QVERIFY(!countRegEx.exactMatch(QLatin1String("te st (10) bla")));
-
-    // ensure that all albums except the root album have a count attached
-
-    QModelIndex rootIndex = albumModel.index(0, 0, QModelIndex());
-    QString rootTitle     = albumModel.data(rootIndex, Qt::DisplayRole).toString();
-    QVERIFY(!countRegEx.exactMatch(rootTitle));
-
-    for (int collectionRow = 0; collectionRow < albumModel.rowCount(rootIndex); ++collectionRow)
-    {
-        QModelIndex collectionIndex = albumModel.index(collectionRow, 0, rootIndex);
-        QString collectionTitle = albumModel.data(collectionIndex, Qt::DisplayRole).toString();
-        QVERIFY2(countRegEx.exactMatch(collectionTitle), QString::fromUtf8("%1 matching error").arg(collectionTitle).toLatin1().constData());
-
-        for (int albumRow = 0; albumRow < albumModel.rowCount(collectionIndex); ++albumRow)
-        {
-            QModelIndex albumIndex = albumModel.index(albumRow, 0, collectionIndex);
-            QString albumTitle     = albumModel.data(albumIndex, Qt::DisplayRole).toString();
-            QVERIFY2(countRegEx.exactMatch(albumTitle), QString::fromUtf8("%1 matching error").arg(albumTitle).toLatin1().constData());
-        }
-
-    }
-
-    // now disable showing the count
-
-    albumModel.setShowCount(false);
-
-    // ensure that no album has a count attached
-
-    rootTitle = albumModel.data(rootIndex, Qt::DisplayRole).toString();
-    QVERIFY(!countRegEx.exactMatch(rootTitle));
-
-    for (int collectionRow = 0; collectionRow < albumModel.rowCount(rootIndex); ++collectionRow)
-    {
-        QModelIndex collectionIndex = albumModel.index(collectionRow, 0, rootIndex);
-        QString collectionTitle     = albumModel.data(collectionIndex, Qt::DisplayRole).toString();
-        QVERIFY2(!countRegEx.exactMatch(collectionTitle), QString::fromUtf8("%1 matching error").arg(collectionTitle).toLatin1().constData());
-
-        for (int albumRow = 0; albumRow < albumModel.rowCount(collectionIndex); ++albumRow)
-        {
-            QModelIndex albumIndex = albumModel.index(albumRow, 0, collectionIndex);
-            QString albumTitle     = albumModel.data(albumIndex, Qt::DisplayRole).toString();
-            QVERIFY2(!countRegEx.exactMatch(albumTitle), QString::fromUtf8("%1 matching error").arg(albumTitle).toLatin1().constData());
-        }
-    }
-}
-
-void AlbumModelTest::testDAlbumModel()
-{
-    qDebug() << "Start AlbumModelTest::testDAlbumModel()";
-
-    DateAlbumModel* const albumModel = new DateAlbumModel();
-    ensureItemCounts();
-    ModelTest* const test            = new ModelTest(albumModel, nullptr);
-    delete test;
-    delete albumModel;
-}
-
-void AlbumModelTest::testDAlbumContainsAlbums()
-{
-    qDebug() << "Start AlbumModelTest::testDAlbumContainsAlbums()";
-
-    DateAlbumModel* const albumModel = new DateAlbumModel();
-    ensureItemCounts();
-
-    QVERIFY(albumModel->rootAlbum());
-
-    foreach (Album* const album, AlbumManager::instance()->allDAlbums())
-    {
-        DAlbum* const dAlbum = dynamic_cast<DAlbum*> (album);
-        QVERIFY(dAlbum);
-
-        qDebug() << "checking album for date " << dAlbum->date() << ", range = " << dAlbum->range();
-
-        QModelIndex index = albumModel->indexForAlbum(dAlbum);
-
-        if (!dAlbum->isRoot())
-        {
-            QVERIFY(index.isValid());
-        }
-
-        if (dAlbum->isRoot())
-        {
-            // root album
-
-            QVERIFY(dAlbum->isRoot());
-            QCOMPARE(albumModel->rowCount(index), 3);
-            QCOMPARE(index, albumModel->rootAlbumIndex());
-        }
-        else if (dAlbum->range() == DAlbum::Year && dAlbum->date().year() == 2007)
-        {
-            QCOMPARE(albumModel->rowCount(index), 2);
-        }
-        else if (dAlbum->range() == DAlbum::Year && dAlbum->date().year() == 2009)
-        {
-            QCOMPARE(albumModel->rowCount(index), 3);
-        }
-        else if (dAlbum->range() == DAlbum::Month && dAlbum->date().year() == 2007 && dAlbum->date().month() == 3)
-        {
-            QCOMPARE(albumModel->rowCount(index), 0);
-        }
-        else if (dAlbum->range() == DAlbum::Month && dAlbum->date().year() == 2007 && dAlbum->date().month() == 4)
-        {
-            QCOMPARE(albumModel->rowCount(index), 0);
-        }
-        else if (dAlbum->range() == DAlbum::Month && dAlbum->date().year() == 2009 && dAlbum->date().month() == 3)
-        {
-            QCOMPARE(albumModel->rowCount(index), 0);
-        }
-        else if (dAlbum->range() == DAlbum::Month && dAlbum->date().year() == 2009 && dAlbum->date().month() == 4)
-        {
-            QCOMPARE(albumModel->rowCount(index), 0);
-        }
-        else if (dAlbum->range() == DAlbum::Month && dAlbum->date().year() == 2009 && dAlbum->date().month() == 5)
-        {
-            QCOMPARE(albumModel->rowCount(index), 0);
-        }
-        else if (dAlbum->date().year() == 1997)
-        {
-            // Ignore these albums for order testing
-        }
-        else
-        {
-            qDebug() << "Unexpected album: " << dAlbum->title();
-            QFAIL("Unexpected album returned from model");
-        }
-    }
-
-    delete albumModel;
-}
-
-void AlbumModelTest::testDAlbumSorting()
-{
-    qDebug() << "Start AlbumModelTest::testDAlbumSorting()";
-
-    DateAlbumModel dateAlbumModel;
-    AlbumFilterModel albumModel;
-    albumModel.setSourceAlbumModel(&dateAlbumModel);
-
-    // first check ascending order
-
-    albumModel.sort(0, Qt::AscendingOrder);
-    int previousYear = 0;
-
-    for (int yearRow = 0; yearRow < albumModel.rowCount(); ++yearRow)
-    {
-        QModelIndex yearIndex   = albumModel.index(yearRow, 0);
-        DAlbum* const yearAlbum = dynamic_cast<DAlbum*> (albumModel.albumForIndex(yearIndex));
-        QVERIFY(yearAlbum);
-
-        QVERIFY(yearAlbum->date().year() > previousYear);
-        previousYear = yearAlbum->date().year();
-
-        int previousMonth = 0;
-
-        for (int monthRow = 0; monthRow < albumModel.rowCount(yearIndex); ++monthRow)
-        {
-            QModelIndex monthIndex   = albumModel.index(monthRow, 0, yearIndex);
-            DAlbum* const monthAlbum = dynamic_cast<DAlbum*> (albumModel.albumForIndex(monthIndex));
-            QVERIFY(monthAlbum);
-
-            QVERIFY(monthAlbum->date().month() > previousMonth);
-            previousMonth = monthAlbum->date().month();
-        }
-    }
-
-    // then check descending order
-
-    albumModel.sort(0, Qt::DescendingOrder);
-    previousYear = 1000000;
-
-    for (int yearRow = 0; yearRow < albumModel.rowCount(); ++yearRow)
-    {
-        QModelIndex yearIndex   = albumModel.index(yearRow, 0);
-        DAlbum* const yearAlbum = dynamic_cast<DAlbum*> (albumModel.albumForIndex(yearIndex));
-        QVERIFY(yearAlbum);
-
-        QVERIFY(yearAlbum->date().year() < previousYear);
-        previousYear          = yearAlbum->date().year();
-
-        int previousMonth     = 13;
-
-        for (int monthRow = 0; monthRow < albumModel.rowCount(yearIndex); ++monthRow)
-        {
-            QModelIndex monthIndex   = albumModel.index(monthRow, 0, yearIndex);
-            DAlbum* const monthAlbum = dynamic_cast<DAlbum*> (albumModel.albumForIndex(monthIndex));
-            QVERIFY(monthAlbum);
-
-            QVERIFY(monthAlbum->date().month() < previousMonth);
-            previousMonth          = monthAlbum->date().month();
-        }
-    }
-}
-
-void AlbumModelTest::testDAlbumCount()
-{
-    qDebug() << "Start AlbumModelTest::testDAlbumCount()";
-
-    DateAlbumModel* const albumModel = new DateAlbumModel();
-    albumModel->setShowCount(true);
-    ensureItemCounts();
-
-    qDebug() << "iterating over root indices";
-
-    // check year albums
-
-    for (int yearRow = 0; yearRow < albumModel->rowCount(albumModel->rootAlbumIndex()); ++yearRow)
-    {
-        QModelIndex yearIndex    = albumModel->index(yearRow, 0);
-        DAlbum* const yearDAlbum = albumModel->albumForIndex(yearIndex);
-        QVERIFY(yearDAlbum);
-
-        QVERIFY(yearDAlbum->range() == DAlbum::Year);
-
-        if (yearDAlbum->date().year() == 2007)
-        {
-            const int imagesInYear = 7;
-            albumModel->includeChildrenCount(yearIndex);
-            QCOMPARE(albumModel->albumCount(yearDAlbum), imagesInYear);
-            albumModel->excludeChildrenCount(yearIndex);
-            QCOMPARE(albumModel->albumCount(yearDAlbum), 0);
-            albumModel->includeChildrenCount(yearIndex);
-            QCOMPARE(albumModel->albumCount(yearDAlbum), imagesInYear);
-
-            for (int monthRow = 0; monthRow < albumModel->rowCount(yearIndex); ++monthRow)
-            {
-                QModelIndex monthIndex = albumModel->index(monthRow, 0, yearIndex);
-                DAlbum* monthDAlbum    = albumModel->albumForIndex(monthIndex);
-                QVERIFY(monthDAlbum);
-
-                QVERIFY(monthDAlbum->range() == DAlbum::Month);
-                QVERIFY(monthDAlbum->date().year() == 2007);
-
-                if (monthDAlbum->date().month() == 3)
-                {
-                    const int imagesInMonth = 3;
-                    albumModel->includeChildrenCount(monthIndex);
-                    QCOMPARE(albumModel->albumCount(monthDAlbum), imagesInMonth);
-                    albumModel->excludeChildrenCount(monthIndex);
-                    QCOMPARE(albumModel->albumCount(monthDAlbum), imagesInMonth);
-                    albumModel->includeChildrenCount(monthIndex);
-                    QCOMPARE(albumModel->albumCount(monthDAlbum), imagesInMonth);
-                }
-                else if (monthDAlbum->date().month() == 4)
-                {
-                    const int imagesInMonth = 4;
-                    albumModel->includeChildrenCount(monthIndex);
-                    QCOMPARE(albumModel->albumCount(monthDAlbum), imagesInMonth);
-                    albumModel->excludeChildrenCount(monthIndex);
-                    QCOMPARE(albumModel->albumCount(monthDAlbum), imagesInMonth);
-                    albumModel->includeChildrenCount(monthIndex);
-                    QCOMPARE(albumModel->albumCount(monthDAlbum), imagesInMonth);
-                }
-                else
-                {
-                    QFAIL("unexpected month album in 2007");
-                }
-            }
-        }
-        else if (yearDAlbum->date().year() == 2009)
-        {
-            const int imagesInYear = 5;
-            albumModel->includeChildrenCount(yearIndex);
-            QCOMPARE(albumModel->albumCount(yearDAlbum), imagesInYear);
-            albumModel->excludeChildrenCount(yearIndex);
-            QCOMPARE(albumModel->albumCount(yearDAlbum), 0);
-            albumModel->includeChildrenCount(yearIndex);
-            QCOMPARE(albumModel->albumCount(yearDAlbum), imagesInYear);
-
-            for (int monthRow = 0; monthRow < albumModel->rowCount(yearIndex); ++monthRow)
-            {
-                QModelIndex monthIndex = albumModel->index(monthRow, 0, yearIndex);
-                DAlbum* monthDAlbum    = albumModel->albumForIndex(monthIndex);
-                QVERIFY(monthDAlbum);
-
-                QVERIFY(monthDAlbum->range() == DAlbum::Month);
-                QVERIFY(monthDAlbum->date().year() == 2009);
-
-                if (monthDAlbum->date().month() == 3)
-                {
-                    const int imagesInMonth = 2;
-                    albumModel->includeChildrenCount(monthIndex);
-                    QCOMPARE(albumModel->albumCount(monthDAlbum), imagesInMonth);
-                    albumModel->excludeChildrenCount(monthIndex);
-                    QCOMPARE(albumModel->albumCount(monthDAlbum), imagesInMonth);
-                    albumModel->includeChildrenCount(monthIndex);
-                    QCOMPARE(albumModel->albumCount(monthDAlbum), imagesInMonth);
-                }
-                else if (monthDAlbum->date().month() == 4)
-                {
-                    const int imagesInMonth = 2;
-                    albumModel->includeChildrenCount(monthIndex);
-                    QCOMPARE(albumModel->albumCount(monthDAlbum), imagesInMonth);
-                    albumModel->excludeChildrenCount(monthIndex);
-                    QCOMPARE(albumModel->albumCount(monthDAlbum), imagesInMonth);
-                    albumModel->includeChildrenCount(monthIndex);
-                    QCOMPARE(albumModel->albumCount(monthDAlbum), imagesInMonth);
-                }
-                else if (monthDAlbum->date().month() == 5)
-                {
-                    const int imagesInMonth = 1;
-                    albumModel->includeChildrenCount(monthIndex);
-                    QCOMPARE(albumModel->albumCount(monthDAlbum), imagesInMonth);
-                    albumModel->excludeChildrenCount(monthIndex);
-                    QCOMPARE(albumModel->albumCount(monthDAlbum), imagesInMonth);
-                    albumModel->includeChildrenCount(monthIndex);
-                    QCOMPARE(albumModel->albumCount(monthDAlbum), imagesInMonth);
-                }
-                else
-                {
-                    QFAIL("unexpected month album in 2009");
-                }
-            }
-        }
-        else if (yearDAlbum->date().year() == 1997)
-        {
-            // Nothing to do here, ignore the albums for ordering tests
-        }
-        else
-        {
-            QFAIL("Received unexpected album from model");
-        }
-    }
-
-    delete albumModel;
-}
-
-void AlbumModelTest::testTAlbumModel()
-{
-    qDebug() << "Start AlbumModelTest::testTAlbumModel()";
-
-    TagModel* albumModel = new TagModel();
-    ModelTest* test      = new ModelTest(albumModel, nullptr);
-    delete test;
-    delete albumModel;
-
-    albumModel = new TagModel(AbstractAlbumModel::IgnoreRootAlbum);
-    test       = new ModelTest(albumModel, nullptr);
-    delete test;
-    delete albumModel;
-}
-
-void AlbumModelTest::testSAlbumModel()
-{
-    qDebug() << "Start AlbumModelTest::testSAlbumModel()";
-
-    SearchModel* const albumModel = new SearchModel();
-    ModelTest* const test         = new ModelTest(albumModel, nullptr);
-    delete test;
-    delete albumModel;
-}
-
-
-
- - - diff --git a/static/reports/cppcheck/master/index.html b/static/reports/cppcheck/master/index.html index 222c49b57..708c3e737 100644 --- a/static/reports/cppcheck/master/index.html +++ b/static/reports/cppcheck/master/index.html @@ -1,128 +1,113 @@ - Cppcheck - HTML report - digiKam-master-rev-907aafb5fa + Cppcheck - HTML report - digiKam-master-rev-e85fcd090f
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineIdCWESeverityMessage
0unmatchedSuppressioninformationUnmatched suppression: purgedConfiguration
0unmatchedSuppressioninformationUnmatched suppression: toomanyconfigs
0unmatchedSuppressioninformationUnmatched suppression: unusedVariable
0unmatchedSuppressioninformationUnmatched suppression: unusedStructMember
0unmatchedSuppressioninformationUnmatched suppression: ConfigurationNotChecked
../../core/dplugins/generic/metadata/geolocationedit/dialog/geolocationedit.cpp
712shadowVar398styleLocal variable groupMapWidget shadows outer variable
731shadowVar398styleLocal variable groupMapWidget shadows outer variable
../../core/dplugins/generic/metadata/metadataedit/iptc/iptcorigin.cpp
522shadowVar398styleLocal variable data shadows outer variable
../../core/dplugins/generic/metadata/metadataedit/xmp/xmpproperties.cpp
339shadowVar398styleLocal variable data shadows outer variable
384shadowVar398styleLocal variable data shadows outer variable
408shadowVar398styleLocal variable data shadows outer variable
../../core/dplugins/generic/webservices/box/boxtalker.cpp
509shadowVar398styleLocal variable doc shadows outer variable
../../core/dplugins/generic/webservices/flickr/flickrwindow.cpp
585shadowVar398styleLocal variable fps shadows outer variable
../../core/dplugins/generic/webservices/mediawiki/backend/mediawiki_edit.cpp
310shadowVar398styleLocal variable i shadows outer variable
../../core/dplugins/generic/webservices/mediawiki/backend/mediawiki_queryinfo.cpp
126shadowVar398styleLocal variable i shadows outer variable
../../core/dplugins/generic/webservices/onedrive/odtalker.cpp
545shadowVar398styleLocal variable doc shadows outer variable
../../core/dplugins/generic/webservices/pinterest/ptalker.cpp
565shadowVar398styleLocal variable boardID shadows outer variable
566shadowVar398styleLocal variable boardName shadows outer variable
589shadowVar398styleLocal variable doc shadows outer variable
../../core/tests/albummodel/albummodeltest.cpp
221shadowVar398styleLocal variable error shadows outer variable
222shadowVar398styleLocal variable error shadows outer variable
224shadowVar398styleLocal variable error shadows outer variable
226shadowVar398styleLocal variable error shadows outer variable
240shadowVar398styleLocal variable error shadows outer variable
241shadowVar398styleLocal variable error shadows outer variable
243shadowVar398styleLocal variable error shadows outer variable
244shadowVar398styleLocal variable error shadows outer variable
246shadowVar398styleLocal variable error shadows outer variable
248shadowVar398styleLocal variable error shadows outer variable
../../core/tests/geolocation/editor/test_simpletreemodel.cpp
96shadowVar398styleLocal variable item21 shadows outer variable
98shadowVar398styleLocal variable item21Index shadows outer variable
108shadowVar398styleLocal variable item21 shadows outer variable
110shadowVar398styleLocal variable item21Index shadows outer variable
../../core/tests/mediawiki/logouttest.cpp
95shadowVar398styleLocal variable request shadows outer variable
../../core/utilities/setup/metadata/setupmetadata.cpp
903shadowVar398styleLocal variable msgBox shadows outer variable
0unmatchedSuppressioninformationUnmatched suppression: purgedConfiguration
0unmatchedSuppressioninformationUnmatched suppression: toomanyconfigs
0unmatchedSuppressioninformationUnmatched suppression: unusedVariable
0unmatchedSuppressioninformationUnmatched suppression: unusedStructMember
0unmatchedSuppressioninformationUnmatched suppression: ConfigurationNotChecked
../../core/dplugins/generic/webservices/mediawiki/backend/mediawiki_edit.cpp
310shadowVar398styleLocal variable i shadows outer variable
../../core/dplugins/generic/webservices/mediawiki/backend/mediawiki_queryinfo.cpp
126shadowVar398styleLocal variable i shadows outer variable
../../core/dplugins/generic/webservices/onedrive/odtalker.cpp
545shadowVar398styleLocal variable doc shadows outer variable
../../core/dplugins/generic/webservices/pinterest/ptalker.cpp
565shadowVar398styleLocal variable boardID shadows outer variable
566shadowVar398styleLocal variable boardName shadows outer variable
589shadowVar398styleLocal variable doc shadows outer variable
../../core/tests/albummodel/albummodeltest.cpp
221shadowVar398styleLocal variable error shadows outer variable
222shadowVar398styleLocal variable error shadows outer variable
224shadowVar398styleLocal variable error shadows outer variable
226shadowVar398styleLocal variable error shadows outer variable
240shadowVar398styleLocal variable error shadows outer variable
241shadowVar398styleLocal variable error shadows outer variable
243shadowVar398styleLocal variable error shadows outer variable
244shadowVar398styleLocal variable error shadows outer variable
246shadowVar398styleLocal variable error shadows outer variable
248shadowVar398styleLocal variable error shadows outer variable
../../core/tests/geolocation/editor/test_simpletreemodel.cpp
96shadowVar398styleLocal variable item21 shadows outer variable
98shadowVar398styleLocal variable item21Index shadows outer variable
108shadowVar398styleLocal variable item21 shadows outer variable
110shadowVar398styleLocal variable item21Index shadows outer variable
../../core/tests/mediawiki/logouttest.cpp
95shadowVar398styleLocal variable request shadows outer variable
diff --git a/static/reports/cppcheck/master/stats.html b/static/reports/cppcheck/master/stats.html index 4b932b2bd..855ac9c46 100644 --- a/static/reports/cppcheck/master/stats.html +++ b/static/reports/cppcheck/master/stats.html @@ -1,65 +1,65 @@ - Cppcheck - HTML report - digiKam-master-rev-907aafb5fa + Cppcheck - HTML report - digiKam-master-rev-e85fcd090f