diff --git a/NEWS b/NEWS index fd49e0eab3..df7e00bb9c 100644 --- a/NEWS +++ b/NEWS @@ -1,636 +1,637 @@ digiKam 7.0.0-beta3 - Release date: 2020-02-23 ***************************************************************************************************** NEW FEATURES: FaceManagement: New Neural Network engine based on OpenCV Deep Learning module to detect and recognize faces. FaceManagement: Face Scan dialog contents is now simplified and embeded into left side-bar tab. SlideShow : Add new shuffle mode. HTMLGallery : Add new theme "Html5Responsive". General : Update internal libraw engine to last 201910 snapshot aka next 0.20.0 release (https://www.libraw.org/news/libraw-snapshot-201910) General : All bundles have switched to last Qt 5.14.0. Linux and MacOS use QtWebEngine instead QtWebKit. General : Add Microsoft Visual C++ support and a Continuous Integration workflow to check code with this compiler. General : Table-view is now able to show Tag-Paths properties. ***************************************************************************************************** BUGFIXES: 001 ==> 384401 - Various recognition algorithm improvements for face detection. 002 ==> 413701 - DigiKam 6.3.0 does not build against current plasma. 003 ==> 413748 - Broken theme on Windows 10 after Digikam update. 004 ==> 413738 - Video Preview changes VLC volume. 005 ==> 382311 - Photos in collapsed groups are incorrectly excluded if first photo in group does not match filter. 006 ==> 396337 - In tag filter view (or any other filitered view), grouped photos should not always have "group" thumbnail 007 ==> 413704 - Filters do not work on hidden grouped images. 007 ==> 413233 - Application crashes when click in Albums left panel. 008 ==> 413759 - Tarball is missing translations. 009 ==> 413879 - Buttons without theme colors. 010 ==> 392015 - Show "Unknown" faces in a more visible and preeminent place in the "People" list. 011 ==> 413837 - Reverse geolocation deletes previous tags from the picture. 012 ==> 376629 - Face tagging dropdown: "Add in persons" adds person not label. 013 ==> 413923 - The peoples list shows just one line of height (one name) when expanded for the first time. 014 ==> 413924 - The face rectangle behavior when show face tags is OFF. 015 ==> 341111 - MYSQL : deleting an image involves "too many" queries. 016 ==> 413938 - Metadata is not written to all pictures in a tag hierarchy. 017 ==> 413916 - Compile Error with lqr on neon. 018 ==> 413972 - align_image_stack and enfuse use only 1 CPU core if called by digiKam plugin, 4 CPU core on command line. 019 ==> 413981 - Refresh has no effect in Preview mode. 020 ==> 413985 - Can't move an album too far down - no treeview scrolling. 021 ==> 412678 - Renaming folder leads to an error. 022 ==> 303239 - GROUP : grouped images are found, but do not show in searches. 023 ==> 321339 - GROUP : suppress display of albums containing only grouped images. 024 ==> 289911 - 23HQ should be split from flickr uploader as a new export tool. 025 ==> 414112 - Rounding problems in Resize Image function. 026 ==> 414052 - Packaging error of digikam-6.4.0.tar.xz, archive file contains a huge number of unnecessary files. 027 ==> 404667 - Bug of proofing for illuminant A and color cast. 028 ==> 414247 - digikam: error while loading shared libraries: libcudart.so.8.0. 029 ==> 392758 - Slideshow with random pictures [patch]. 030 ==> 414300 - Buttons on either side completely unresponsive. 031 ==> 414320 - Performance regression when scanning directories with many sub-directories. 032 ==> 414284 - Improve Setup/Slideshow View Options Layout. 033 ==> 414420 - Date/time in sidecar files for Videos seems to be ignored by digikam. 034 ==> 414340 - RawTherapee plugin. 035 ==> 414473 - Importing problem with M2Ts video files. 036 ==> 414521 - File management is broken. 037 ==> 205406 - Add Javascript to scaling images in html gallery [patch]. 038 ==> 334680 - Allow to limit exported files by type-mime in html gallery. 039 ==> 092462 - Add a new option to limit amount of thumbnails per index page. 040 ==> 136389 - Add new option to show image date and time in html gallery. 041 ==> 305167 - Add back filenames in html gallery. 042 ==> 114216 - Add a new option to export and merge more than one album in html gallery. 043 ==> 414516 - digikam crash when double-clicking on Google Maps when editing geolocation. 044 ==> 414603 - Pictures sort by freehand - drag & drop. 045 ==> 414630 - Shortcut bug in caption (tag). 046 ==> 414484 - Cannot use Rawtherapee or Darktable for raw image import on Windows. 047 ==> 166577 - List of available cameras in search. 048 ==> 414637 - New option for search. 049 ==> 414401 - RawTherapee does not work as Raw Import Tool if both are AppImages. 050 ==> 412067 - I get a error message: "Error while opening the database". 051 ==> 414902 - After using the "healing clone" tool only preview is available from other tools. 052 ==> 402894 - Display of original image. 053 ==> 380345 - Batch converting RAW to JPEG saves as new version. 054 ==> 383716 - "Save Changes" button same as "Save As New Version" Button. 055 ==> 307374 - Wrong image count in album view with versioning. 056 ==> 412961 - All image versions remain visible. 057 ==> 399923 - Segmentation fault during face detection. 058 ==> 392651 - Digikam crashes when Face scanning reaches 29%. 059 ==> 397919 - Segmentation fault during maintenance. 060 ==> 365354 - MYSQL : Application crash on scanning for faces in large picture set. 061 ==> 391014 - Crashes on close. 062 ==> 387821 - Face Recognition and Finding crashs after reaching 50%. 063 ==> 414749 - Export google photos: error transmission date creation. 064 ==> 377127 - Wrong item count on years in Dates View. 065 ==> 350350 - Moving images notifies me moving finished when it did not finish yet. 066 ==> 342191 - digiKam keeps crashing after crash with face-detection and manual tagging at the same time. 067 ==> 309769 - Crash on startup: 'Program received signal SIGILL, Illegal instruction.' (libopencv_nonfree). 068 ==> 286418 - digikam crashed during face recognition. 069 ==> 402470 - Crashed While I Walked Away During Face Detection. 070 ==> 415046 - Facial Recognition crash during scan. 071 ==> 360477 - Crash when adding a new face tag. 072 ==> 351638 - digiKam crash after facemarking. 073 ==> 350599 - Crash after maintenance. 074 ==> 350549 - Massive memory usage when assigning a tag to a recognized face. 075 ==> 312243 - digiKam crash when detected face moved or resized. 076 ==> 329108 - Crash when running Scanning faces/Clear and rebuild all training data. 077 ==> 280958 - Removing non-faces crashes digiKam. 078 ==> 312289 - Face Scan Crash. 079 ==> 285444 - Crash when adding face tag. 080 ==> 328413 - Crash while tagging faces - no background detection in process. 081 ==> 303328 - digiKam crashes repeatedly while tagging faces. 082 ==> 307554 - digiKam crash when scanning faces. 083 ==> 301506 - Crash while Tagging and Grouping Faces. 084 ==> 309306 - Crash during face-recognition. 085 ==> 284137 - digiKam crashed while moving a face tag after rotating a picture. 086 ==> 299173 - Crash during face tagging. 087 ==> 328560 - Crash when attempting to exit digiKam after aborted face recognition. 088 ==> 323828 - Crash when assigning a name to a single unknown face. 089 ==> 344735 - Crash if I name a face. 090 ==> 275688 - Crash during face detection, whilst tagging. 091 ==> 322022 - Faces and crash. 092 ==> 326750 - digiKam sometimes crashes when tagging recogniced faces with names. 093 ==> 314877 - Face Scan Crash. 094 ==> 271791 - digiKam crashes when removing a "face image" from the current list when the list is not yet loaded completely. 095 ==> 270410 - digiKam crashes when confirming faces. 096 ==> 283197 - Crash during tagging faces. 097 ==> 326689 - digiKam crashes while tagging faces. 098 ==> 284398 - Crash while tagging persons. 099 ==> 334158 - digiKam crash while tagging faces. 100 ==> 321851 - Face scan crash but only on multithread. 101 ==> 308393 - Crash while scanning faces. 102 ==> 326570 - digiKam crashes while recognizing/tagging faces. 103 ==> 343014 - Crashed when select another tag (face tag management). 104 ==> 327699 - Crashing while face detection. 105 ==> 308645 - digiKam crashed when I clicked scan faces while another scan was already running. 106 ==> 287961 - Crash while face-tagging pictures and doing import. 107 ==> 317863 - digiKam crashes as detected faces are being assigned to people or being removed while face detection is running. 108 ==> 302354 - Crash finding again faces (probably a duplicate of 262596). 109 ==> 320861 - Crash when adding tag to photo of the face scan result. 110 ==> 326794 - Tagging faces crashed digiKam. 111 ==> 274850 - digiKam crash on face scanning. 112 ==> 283165 - Crash happened while running face recognition. 113 ==> 280521 - digiKam crashes when deselecting two pictures in in quick succession from the face view. 114 ==> 303304 - Crash during face detection. 115 ==> 329596 - digiKam crashes during face recognition. 116 ==> 298599 - digiKam crashed while scaning for faces in the background. 117 ==> 304360 - Crash during face tagging. 118 ==> 280620 - digiKam crashes when tagging multiple non-faces. 119 ==> 302437 - Crash when re-searching for faces. 120 ==> 274727 - Crash on scan of faces. 121 ==> 333582 - Scanning for faces crashes. 122 ==> 290826 - digiKam crashed while tagging faces. 123 ==> 289003 - Crash when trying to face-scan all images. 124 ==> 280618 - digiKam crashes when tagging multiple faces. 125 ==> 329651 - Face detection crashes when reaches 3 GB of Memory, the computer has 6GB and 2 are still free. 126 ==> 294452 - digiKam crash in "Scan collection for faces". 127 ==> 268102 - Crash when finding faces. 128 ==> 323823 - Crash while first face detection after update. 129 ==> 336236 - Crash while tagging faces on more than one image at same time. 130 ==> 279266 - digiKam crashes while trying to tag faces. 131 ==> 312442 - digiKam crashed when editing face tags. 132 ==> 275827 - digiKam crash whilst scanning for faces, starting to enter tag. 133 ==> 330828 - Crash while detecting faces. 134 ==> 324711 - Crash when scaning faces. 135 ==> 323654 - digiKam crashed while i was tagging faces. 136 ==> 283540 - digiKam crashes on entering people tages (face recognition). 137 ==> 277099 - digiKam crash when adding a tag to a face. 138 ==> 296281 - digiKam crashed while manually adding a face. 139 ==> 325526 - Crash while tagging faces. 140 ==> 275637 - Performing multiple scans and recognises causes crash. 141 ==> 289228 - Crash when detecting faces. 142 ==> 317413 - digiKam crashed while tagging faces. 143 ==> 334580 - Face detection crashes digiKam. 144 ==> 301781 - digiKam crashed while scanning photos for faces. 145 ==> 321273 - crash during face scan. 146 ==> 296784 - digiKam crashes while tagging faces. 147 ==> 285517 - digiKam crashed when tagging faces. 148 ==> 290818 - digiKam crash during face scanning. 149 ==> 271375 - digiKam crashed when unchecking face. 150 ==> 317290 - Crashes during face scan. 151 ==> 308575 - digiKam crashes while scanning for faces. 152 ==> 301832 - digiKam crashes a while after starting face detection scan. 153 ==> 300357 - digiKam crashes on Face Recognition scan. 154 ==> 309142 - Face Crash. 155 ==> 279781 - digiKam crashes while using face detection tool. 156 ==> 275387 - digiKam crashes on face recognition. 157 ==> 311934 - digiKam was crashing when I was face-tagging photos. 158 ==> 323428 - Crash while tagging a lot of faces at the same time. 159 ==> 262873 - digiKam crashes on scanning for faces. 160 ==> 280520 - Crash while running a face detection, and marking some of the faces. 161 ==> 322187 - Crash while 'detect and recognize faces'. 162 ==> 334337 - Crash when tagging faces in RAW picture files. 163 ==> 301856 - digiKam crashes during face tagging. 164 ==> 275541 - digiKam crashed while doing face recognition. 165 ==> 324093 - digiKam crashed when I clicked the check mark to assign an existing name to several selected face images. No background tasks were running. 166 ==> 286071 - Crash while adding face tags. 167 ==> 280901 - Crash when rejecting faces in different albums. 168 ==> 290891 - digiKam Crash while Face Recognition. 169 ==> 293418 - Crashes when scanning for faces. 170 ==> 273161 - digiKam: malloc(): smallbin double linked list corrupted. 171 ==> 268046 - Switch foto with face recognition. 172 ==> 277163 - digikam valgrind issues during face recognition testing. 173 ==> 302359 - Crash creating a tag while scanning faces. 174 ==> 307110 - digiKam crashes when manually adding face tags, then moving to next image. 175 ==> 339263 - digiKam crash. 176 ==> 379470 - Crash when performing face detection or recognition on large collection. 177 ==> 284154 - Crash upon exit. 178 ==> 392142 - Use Tensorflow for face and object recognition. 179 ==> 303501 - Double free or corruption during face tagging. 180 ==> 314646 - digikam crash when (tagging) scanning collection for faces. 181 ==> 317450 - Attempting to name a person while face tagging is in progress. 182 ==> 318640 - Face detection crash. 183 ==> 325385 - Face scan and using all processor cores. 184 ==> 325712 - Face tagging has massive memory leak. 185 ==> 326323 - Running Face Scan. 186 ==> 329164 - Changing face tags in an image causes digiKam to eat up all the virtual memory. 187 ==> 331912 - Face detection and recognition dos not work, tags and factags counts for one person are different, memory goes up and up without any result. 188 ==> 334509 - Person Detection. 189 ==> 337936 - Assigning a new person. 190 ==> 342144 - Face detection. 191 ==> 344661 - Face recognition makes digikam fill all the available memory. 192 ==> 345395 - Face Management the Memory and Swap growed to max. 193 ==> 365669 - Face Recognition improvement suggestion. 194 ==> 376901 - Face Recognition Algorithm Improvements. 195 ==> 338072 - digiKam face detection. 196 ==> 387870 - undefined reference to typeinfo for cv::face::FaceRecognizer. 197 ==> 327197 - When add one face tag in mainview/albums/one pictures view digikam and/or opencv fullfill the memory. 198 ==> 353859 - FaceEngine multi threaded ? 199 ==> 342004 - FacesEngine header and pkgconfig files not installed. 200 ==> 406838 - digiKam crashes while labeling unconfirmed faces. 201 ==> 409437 - Crash when doing any face detection. 202 ==> 404853 - digiKam faces engine fails to compile on PowerPC. 203 ==> 405625 - digiKam faces engine fails to compile on PowerPC with AltiVec enabled. 204 ==> 194401 - Face detection / recognition for digiKam for tags. 205 ==> 339823 - Detect and recognice faces crashes. 206 ==> 351077 - Crash during facial detection and recognition. 207 ==> 375317 - MYSQL: digikam crashes during face recognition. 208 ==> 299066 - digiKam crashed while tagging a large amount of people. 209 ==> 268761 - Segfault when tagging people without existing tag in preview mode. 210 ==> 374165 - Tag Change in Menu Person search crashes. 211 ==> 347753 - Surface freezes after some faces tagged. 212 ==> 375945 - Face detection not scanning my images. 213 ==> 343314 - Mass face tagging pictures when writing the tags into the files often crashes at the end of the writing. 214 ==> 345909 - digiKam crashed when face taging multiple photos. 215 ==> 401306 - digiKam doesn't compile with Opencv 4. 216 ==> 376766 - Face detection is using all CPU cores regardless of the checked option. 217 ==> 402320 - Memory hole (>1.5GB resident after 2 minutes) when detecting faces. 218 ==> 389031 - Scanning collection for faces causes produces lots of OpenCV errors. 219 ==> 325331 - MySQL : when adding a new face, tag is created with a new _Digikam_root_ tag in database. 220 ==> 262577 - Scanning collection for new faces (skip already scanned images) does not do anything. 221 ==> 330143 - "Detect and recognize faces" does no detection. 222 ==> 392527 - "Add A Face Tag" Dialogue Is Too Small. 223 ==> 372761 - Face Tag selection needs extra confirm now. 224 ==> 375418 - Glitch in face selection in album view. 225 ==> 281792 - When tagging with 'Return', too many faces are tagged. 226 ==> 282592 - Rejecting multiple faces at a time doesn't work properly. 227 ==> 376681 - Region Coordinates Are Sometimes inf / Large Numbers. 228 ==> 380251 - "Show only face tags..." not working properly. 229 ==> 326538 - When a picture is in portrait, face thumbnails are not rotated. 230 ==> 279208 - After the upgrade to Plasma and digiKam Faces Are Not Detected Anymore. 231 ==> 316856 - I suggest to extend face recognition to text-recognition system. 232 ==> 381378 - Face rectangle from XMP sidecar drawn incorrectly for EXIF rotated images. 233 ==> 326035 - Stepping through previews with "show face tags" enabled does not always show the tags. 234 ==> 326033 - Adding or changing face tag in preview window causes all tags on that preview to "hide". 235 ==> 265022 - UI's handling of People tags is confusing. 236 ==> 262180 - The toggle button to show/hide faces is difficult to see. 237 ==> 316161 - Reuse face tags from another picture. 238 ==> 412999 - Some photos downloaded in previous version of digikam no more recognized as already downloaded. 239 ==> 334215 - Cannot open RAW files from Sony A7R. 240 ==> 340595 - Convertion Sony A7 raw file turns to red the result. 241 ==> 307313 - digiKam uses wrong darkness/saturation values. 242 ==> 315156 - CR2 files from Canon PowerShot G1 X the colours are messed up. 243 ==> 332126 - LibRaw_r_LIBRARIES CMake Error: The following variables are used in this project, but they are set to NOTFOUND. 244 ==> 352996 - digiKam crashes while scanning for new files in Collection. 245 ==> 362779 - Can't decode PEF image from Pentax K-1 (36mp). 246 ==> 364063 - Crash on startup (related to crashing on conversion to DNG?). 247 ==> 221984 - Choosing manual WB does not allow user to tweak the previously selected WB setting. 248 ==> 182611 - Segfault with Samsung S85 RAW images. 249 ==> 178760 - Conversion of Canon .cr2 files broken as used in Darkroom. 250 ==> 364230 - Crash on startup. 251 ==> 244142 - digiKam crash. 252 ==> 362418 - Crashes on launch. 253 ==> 253091 - digiKam will not launch. 254 ==> 338075 - Tagging RAW images for Canon EOS-1Ds corrupts them. 255 ==> 205006 - On first run, digikam crashes while creating the index. 256 ==> 409148 - Sony A7r3 ARW files are displayed blurred in preview. 257 ==> 388339 - Crash when importing Pentax DNG file. 258 ==> 329230 - Crash when tuning a raw image. 259 ==> 253877 - digiKam Crash when loading. 260 ==> 134700 - CR2 thumbnails are not rotated. 261 ==> 090875 - Preview of RAW-Files in album. 262 ==> 143681 - Can't edit/view NEF anymore. 263 ==> 341024 - digiKam crash in a dir with only Canon Raw and JPEG files. 264 ==> 132695 - CR2 RAW files do not open. 265 ==> 339924 - RAW preview using embedded JPG. 266 ==> 142057 - Speed to view raw pictures. 267 ==> 187015 - Libraw breaks RW2 file handling. 268 ==> 126151 - Raw (NEF) thumbnail not correctly showed. 269 ==> 143244 - Error processing RAW files. 270 ==> 235321 - Tried to open X3F file. Was showing up in preview but crashed while opening in editor. 271 ==> 306843 - Raw-pics rotating. 272 ==> 149328 - Let RawEngine use raw decoding options when generating thumbnails. 273 ==> 150872 - Crash during during RAW conversion. 274 ==> 182013 - Sensitivity is not shown for rw2 files. 275 ==> 157619 - Let digiKam use preview images from raw files for more speed. 276 ==> 220322 - Crash when reading nef data: Warning: Exif tag Exif.NikonPreview.JPEGInterchangeFormatLength not encoded. 277 ==> 165176 - Previews of raw pics are not created when "create all previews new" is selected. 278 ==> 149086 - RAF-picture finepix not show in Imageeditor (thumbnails are displayed). 279 ==> 123950 - Crashing on raw files (.nef). 280 ==> 320049 - RawEngine is crashing on decoding some sigma raw files. 281 ==> 277707 - Easy way to convert Raw, to get same image as seen in preview. 282 ==> 146738 - Fuji *.RAF files aren't recognized as RAW files. 283 ==> 331397 - Preview and thumbnails colors are wrong for cr2. 284 ==> 210659 - Inconsistent Save / Save As handling in image editor after raw import. 285 ==> 155950 - Raw file open with action causes two instances. 286 ==> 337601 - digiKam crashed on closing after interrupted raw processing. 287 ==> 219748 - Image editor doesn't import raw images twice. 288 ==> 272725 - Some PEF/jpeg files not recognized as raw/non raw 289 ==> 154922 - Start to use libopenraw instead of libraw. 290 ==> 359949 - Bad canon raw file makes digikam to crash at startup. 291 ==> 101281 - EXIF info from RAW images not woking properly. 292 ==> 342233 - Crash when decoding pentax k-r raw photo. 293 ==> 139550 - Autocorrect levels for raw photos (which are shown too dark). 294 ==> 099437 - Incorrect Libraw option. 295 ==> 155156 - Raw file conversion crash single/batch mode. 296 ==> 146259 - Raw Converter won't convert to 16bit PNG. 297 ==> 151523 - RAW converter crashes on startup. 298 ==> 242479 - Crashes on appling refocus tool to raw image. 299 ==> 361678 - Dng Converter crashes when opening a raw file (*.NEF in my case). 300 ==> 382576 - DNG Image Converter crashed trying to convert a RAW image. 301 ==> 326268 - SONY SLT A58. 302 ==> 140087 - Sony Alpha Super SteadyShot Meta Info. 303 ==> 282116 - DNG Converter fails to convert Nikon NEF to DNG. 304 ==> 270457 - Crash when opening a NIKON-jpg with 1.3 MB. 305 ==> 135011 - Sort images by EXIF date seems buggy for Nikon (or not just Nikon?). 306 ==> 141249 - CANON EOS 5D not support. 307 ==> 240750 - DNG Converter produces black files (Canon 5D mkII) 308 ==> 361660 - DNG Image Converter crashes when converting Canon cr2 file. 309 ==> 211908 - TIF (RAW from Phase One and old Canon, not TIFF/EP) opens as thumbnail. 310 ==> 388222 - high RAM memory consumption of digiKam. 311 ==> 338249 - digiKam uses all free memory and gets terminated. 312 ==> 131277 - Memory leak in image editor. 313 ==> 252443 - digiKam leaves a zombie after quit. doesn't free memory. 314 ==> 321784 - Recreating fingerprints leaks memory. 315 ==> 381877 - digiKam start allocating all memory when scans a new collection. 316 ==> 098227 - Huge memory leak when downloading from camera. 317 ==> 330227 - Image quality sorter leaks memory. 318 ==> 412893 - Application windows are incorrectly magnified in macOS. 319 ==> 413656 - Manage Tags window appears with messed up double size graphics. 320 ==> 092783 - Usabilitiy of RAW file support. 321 ==> 158911 - digiKam crashes before RAW convert. 322 ==> 362870 - DNG Convert crash on convert NEF file. 323 ==> 367859 - DNG Converter crashed after trying to nconvert CR2 file. 324 ==> 369289 - DNG converter crashes when converting Olympus (.ORF) files. 325 ==> 407203 - Crash on trying to convert a .NEF file. 326 ==> 370623 - digiKam converter to DNG report an error while to process NEF image. 327 ==> 354364 - Crash of DNG converter. 328 ==> 338842 - Moving DNG images to another album corrupts DNG properties. 329 ==> 401849 - Cannot Save Current Search. 330 ==> 372972 - Find duplicates "search in drop down" only shows 1 item. 331 ==> 351521 - digiKam crashes when searching by date. 332 ==> 335978 - digiKam crashes when using timeline. 333 ==> 335052 - Crash on looking for duplicate. 334 ==> 333952 - Crashed when trying to search for duplicates. 335 ==> 218022 - Albums are sorted alphabetically within the month. 336 ==> 326495 - Calendar: higher flexibility in the layout. 337 ==> 281848 - Search for images with no goelocation. 338 ==> 283045 - Crash when searching with timeline. 339 ==> 281895 - digiKam crashed the selection date in the calendar. 340 ==> 280760 - Find duplicates should handle raw files more intelligently. 341 ==> 182029 - Duplicate item count not changed after duplicates deleted. 342 ==> 182043 - Duplicates search result in an inconsistent/broken state. 343 ==> 182492 - No photos are displayed when selecting a timeframe in the timeline. 344 ==> 140732 - Show all pictures of year when selecting year in date-tree. 345 ==> 240738 - Batch deletion of duplicate or similar files. 346 ==> 241536 - Reproducible crash when bilding fingerprint. 347 ==> 242438 - Crashes while creating fingerprints. 348 ==> 246500 - Fingerprint. 349 ==> 246635 - Crash when rebuilding fingerprints. 350 ==> 253382 - digiKam crashs creating fingerprints. 351 ==> 265670 - digiKam crashes when generating thumbnails and fingerprints in parallel. 352 ==> 265245 - Crash upon selecting certain month in timeline. 353 ==> 261418 - Improved handling of duplicate images. 354 ==> 263002 - Crash during browsing timeline. 355 ==> 147981 - Ability to move images to different albums from seach results. 356 ==> 149025 - Do not sort images in Search by album. 357 ==> 147407 - Root folders/years should display all child images. 358 ==> 155286 - Crash during duplicate search. 359 ==> 169404 - Color selector in fuzzy search is black. 360 ==> 214665 - Crash when cleaning duplicated images. 361 ==> 243136 - Fingerprints. 362 ==> 247550 - digiKam does not quit gracefully. 363 ==> 406228 - Getting random unextpected 'Database is locked' events. 364 ==> 409884 - digiKam Crash. 365 ==> 413944 - digiKam crashes while album browsing. 366 ==> 134817 - Introduce symlinks for album collection. 367 ==> 149983 - Show recursively sub-album images. 268 ==> 226770 - digiKam edit photo shift+space. 369 ==> 237161 - digiKam crashes on album viewing. 370 ==> 240436 - digiKam crashes when selecting a photo in an album. 371 ==> 291514 - Suggestions for improving face recognition performance. 372 ==> 271679 - digiKam detects but does not recognize faces. 373 ==> 292248 - Recognize faces does nothing. 374 ==> 321297 - Name not set on face recognition run. 375 ==> 314744 - Face do not recognize. 376 ==> 402021 - Face recognition not working. 377 ==> 392518 - Face recognition using the deep learning algo, dont move faces to Unconfirmed. 378 ==> 391671 - Face recognition fails giving a lot of addition effort to correct the errors. 379 ==> 392010 - Face recognition assigns faces to people without confirmation, leading to false positives. 380 ==> 277620 - Face recognition should propose the tagged name as default in the face identification page. 381 ==> 414308 - On a person, be able to view only the news found. 382 ==> 404167 - Improve confirmation process. 383 ==> 247571 - Crash while browsing in album view. 384 ==> 263209 - New Album crash. 385 ==> 275684 - Crash during tagging. 386 ==> 297044 - digiKam crashes when moving images to a new Album. 387 ==> 305108 - Crash during import of images. 388 ==> 317440 - digiKam crashes after deleting a tag. 389 ==> 335708 - Crash on image import. 390 ==> 337839 - I experience many crashes, without precise action. 391 ==> 339720 - Very slow tagging when missing Plasma icons have been used for tags. 392 ==> 343026 - Crashes when downloading. 393 ==> 361084 - Crash while importing. 394 ==> 117561 - Should store hashes of files if file is moved. 395 ==> 186920 - Too many open files. 396 ==> 135051 - digiKam crashes when building database from existing directory. 397 ==> 135689 - New folders not visible. 398 ==> 150181 - digiKam wants to delete the whole database (24.000Images) at startup when USB-Disk with the Photos is not connected. 399 ==> 194630 - digiKam fails to start ? after Plasma update. 400 ==> 202956 - Crashing on start up. 401 ==> 204071 - Just started digiKam and it crashed. 402 ==> 218726 - digiKam always crashes at startup with segmentation fault. 403 ==> 218860 - digiKam crashes when starting from krunner. 404 ==> 220172 - digiKam crash on scanning directories [mem2chunk_check, free_check, QHashData::free_helper]. 405 ==> 242305 - digiKam Crash. 406 ==> 242818 - digiKam crash at startup. 407 ==> 246065 - digiKam crashes at startup. 408 ==> 246534 - digiKam crashes at every start. 409 ==> 250418 - digiKam crashes on startup. 410 ==> 261624 - Moving an album from one collection to another doesn't update the source collection. 411 ==> 338171 - When automatic recognition guesses the same name for multiple faces in one picture, assigning a different name deletes all the face boxes except one. 412 ==> 392016 - Confirmed and unconfirmed faces look the same in a person's face list. 413 ==> 286452 - No way to scan untagged photos for faces, or scan ALL folders. 414 ==> 411732 - UI for assigning people tag is very fragile. 415 ==> 365668 - Face tagger allows text input when hovered over, then does crazy stuff. 416 ==> 413923 - The peoples list shows just one line of height (one name) when expanded for the first time. 417 ==> 326034 - Allow to add "unknown" face tags in Preview mode. 418 ==> 388649 - Face tag rectangle cursor sometimes disappear. 419 ==> 415560 - No default selection for Scan Collection. 420 ==> 415460 - JFIF files have APP0 marker after SOI where there should be APP1. 421 ==> 415582 - People Unknown faces does not decrease to zero. 422 ==> 415599 - Add date to help DNN face recognition for baby/kid/adult distinction. 423 ==> 415602 - How to erase faces rectangles for an album. 424 ==> 316897 - Face Detection improvements by colors filtering and using EXIF orientation. 425 ==> 088895 - Stops after a few percent with: Unknown event: 3. 426 ==> 091548 - Find duplicate images claims no album is selected although one is 427 ==> 101958 - Can not select duplicate images by clicking on a line instead of the select box of 6 pix square. 428 ==> 107095 - Double image removal: Use trashcan. 429 ==> 113557 - digiKam crashes during "Find Duplicate Images" with SIGSEGV. 430 ==> 117578 - Bad UI fpr searching duplicate images. 431 ==> 181698 - Cannot delete fuzzy searches. 432 ==> 181720 - Can't rename fuzzy searches. 433 ==> 183008 - Fuzzy image search requires two clicks to navigate back. 434 ==> 199045 - Find duplicates in a directory/directories. 435 ==> 199732 - Deleting duplicated images crashes digiKam. 436 ==> 222273 - Run fingerprint scan on new images. 437 ==> 231047 - Crash when updating fingerprints on a large photo collection (100GB). 438 ==> 235763 - Reproducible crash, when attempting to rebuild all fingerprints. 439 ==> 167168 - Timeline view shows redundant extra sections. 440 ==> 168004 - Timeline gives zero height column for dates with a single entry. 441 ==> 279674 - Incorporate "event view". 442 ==> 261216 - Debugging doesn´t work with installed. 443 ==> 109022 - Iphoto like calendar search. 444 ==> 109703 - Updating of calendar view in Date panel. 445 ==> 109705 - When quit date panel with day selected no images in other panels. 446 ==> 130230 - Wrong date in header using date-view. 447 ==> 213619 - Add a new view of albums based on due date. 448 ==> 375306 - Add 'Go to album' in search results. 449 ==> 128101 - Crash when selecting "Comments&Tags" tab, after selecting "Search" tab, with no search results selected. 450 ==> 146091 - Displaying raw photos by Tag or Date takes very long to load. 451 ==> 091372 - Make searching for multiple tags possible. 452 ==> 098846 - Searching photos with no tag. 453 ==> 113806 - Is it possible to have the size of the quick search window saved? 454 ==> 114848 - Search dialog: images not rotated correctly. 455 ==> 115536 - Quick search dialog box: wrong attached tips. 456 ==> 133294 - Advanced search dialog - combo box with tag names (when tag is to be matched) doesn't stretch with the dialog. 457 ==> 149555 - Always present search box instead of search by right-clicking and selecting simple or advanced search. 458 ==> 185106 - Advanced search is not saved/restored correctly. 459 ==> 120922 - Clicking on Advanced search crashes application. 460 ==> 141035 - Advanced Search gives error when trying to search by rating. 461 ==> 147429 - "and not" option in search function. 462 ==> 415489 - Win32 7.0.0 Beta 1 Crash On Opening Preview. 463 ==> 407540 - Missing EXIF parameter in DNG when converting Panasonic RW2 images. 464 ==> 399159 - Lenses name lost on converting to DNG. 465 ==> 118396 - Ability to search through image comments. 466 ==> 139283 - IPTC Caption comment in search function 467 ==> 155735 - Make it possible to seach on IPTC-text. 468 ==> 095584 - No indication of the end of download from camera. 469 ==> 179712 - Open image in embeded editor lead to digikam crash. 470 ==> 297293 - Option to use libnotify for non-blocking errors/message. 471 ==> 316928 - Servicing: statut of each servicing option should be searchable. 472 ==> 375521 - Progress bars waste useful space. 473 ==> 218583 - Showfoto customizing toolbar freerotation. 474 ==> 228879 - Geolocation Editor: Missing progress bar. 475 ==> 272158 - More user feedback about background operations. 476 ==> 301064 - Async task UI persists on leaving geolocation UI. 477 ==> 164600 - No picture in view pane. 478 ==> 297295 - Zooming: full picture thumbnail to show position. 479 ==> 160894 - Add new picLens like 3D view mode. 480 ==> 325530 - Preview and Editor return "Failed to Load Image" error when viewing JPEG (only) files. 481 ==> 256309 - Wish to save settings in batch queue manager. 482 ==> 271198 - Make queues saveable and use them as single action. 483 ==> 287407 - Save tools with settings in BQM. 484 ==> 318771 - Saved process don't remember settings in BQM. 485 ==> 320358 - Files randomly fail to process. 486 ==> 342433 - Crashes after tagging a few batches of photos. 487 ==> 171073 - Statistic of database, all pictures? 488 ==> 119228 - Storage of images on removable media. 489 ==> 144724 - Freezing by using NAS. 490 ==> 189362 - After moving the collection on a new HD, Digikam doesn't find it. 491 ==> 249375 - Crash when device with open window is removed. 492 ==> 272918 - digiKam crash after scanning ssh network drive. 493 ==> 275559 - digiKam crashes while browsing over NFS. 494 ==> 415679 - Faces are not recognized. 495 ==> 220903 - Duplicate records in ImageComments table after migration. 496 ==> 267800 - Keywords from IPTC-Metadata are not imported. 497 ==> 280678 - MIGRATION : cannot migrate from sqlite database. 498 ==> 301075 - MySQL : external database empty after migration. 499 ==> 328729 - digiKam crash while switching MySQL to SQLite 500 ==> 329849 - MIGRATION : db conversion fails. 501 ==> 361809 - Migration failed from SQLite to MySQL. 502 ==> 415700 - "Welcome to" screen still mentions v5.0. 503 ==> 415566 - Use existing face rectangles to improve recognition. 504 ==> 415603 - Add "Face Recognition" optional item in toolbar. 505 ==> 415592 - When renaming a tag, if I say no to updating, clicking Save won't trigger update again. 506 ==> 415766 - HEIF thumbnails are not shown in Timeline view. 507 ==> 396734 - Error while executing DBAction [ "UpdateSchemaFromV7ToV9" ] Statement [ "DROP TRIGGER IF EXISTS delete_image;" ]. 508 ==> 268204 - MYSQL : file-names are case-INsensitive. 509 ==> 383927 - OpenSuse digikam.coredb: Core database: schema update to V 8 failed! 510 ==> 319420 - Failed to update the database schema from version 5 to version 6. 511 ==> 288599 - Schema update to V6 failed. 512 ==> 218571 - Schema update version 4 to 5 failed. 513 ==> 230606 - digiKam doesn’t display images imported from database. 514 ==> 288839 - Failed to update the database schema from version 5 to version 6. 515 ==> 392179 - Database Upgrade to v9 fails. 516 ==> 396765 - Schema update to V 9 failed. 517 ==> 190411 - Metadata are invisible on older pictures. 518 ==> 110066 - Md5 Checksums to identify pictures. 519 ==> 415767 - Thumbnails for Portrait oriented images aren't rotated properly. 520 ==> 415791 - TimeAdjust can not adjust time by 1 unit - only by 2. 521 ==> 415557 - Face detection - Advanced settings : restricted folder scope not taken into account. 522 ==> 415702 - Cannot abort or stop find Duplicate process. 523 ==> 415796 - Face thumbnail zoom level too wide. 524 ==> 366551 - Unclear icon-item overlay when associating people to faces. 525 ==> 415535 - Import from a local/remote folder. 526 ==> 415643 - digiKam crashes Face detection. 527 ==> 415685 - digiKam crashes when scanning faces. 528 ==> 415877 - "Reset" button in Tag Manager not always working to reset icon. 529 ==> 415561 - Face detection based on deep learning leads to no result under Windows. 530 ==> 415920 - The unconfirmed faces count in the left sidebar is missing. 531 ==> 415944 - 7.0.0beta2 removed all my Geolocation bookmarks. 532 ==> 414016 - Log file /var/log/syslog grows in size very fast. 533 ==> 414028 - digiKam spamming journal with details of almost everything it does... 534 ==> 415882 - digiKam 6.4 crashes on processing a large number of new HEIC/HEIF files. 535 ==> 414115 - G'mic plugin not available on Mac. 536 ==> 416018 - Face detection: specified list of albums not taken into account. 537 ==> 416028 - "Search in Tags" selection for Face detection/recognition unduly changes. 538 ==> 416120 - Error transfering. 539 ==> 392304 - digiKam crash on exit (accessing stale QScreen instance during global destruction). 540 ==> 397694 - Missing text on selected tabs from QTabWidget. 541 ==> 380969 - Copy and paste text to comment field. 542 ==> 402914 - Crash when selecting custom icon for tag. 543 ==> 406507 - digiKam crashes when trying to select custom icon in the tag manager a second time. 544 ==> 401912 - Crash on adding GPS coordinates to multiple images. 545 ==> 412679 - Scrolling to a illogical place in the main view. 546 ==> 397761 - Tags are not written. 547 ==> 416231 - Exif date not written to sidecar file when modified, nor is it updated in the metadata sidebar. 548 ==> 402620 - AppImage digiKam does not respect desktop default application setting. 549 ==> 385953 - Reduce installed footprint under Windows. 550 ==> 416289 - 7.0.0-beta2 crash when closing Geolocation Editor. 551 ==> 413855 - digiKam crashes when deleting a letter in the login window (QtWebkit + libicu). 552 ==> 411619 - Crash when tagging, switching to map view (QtWebKit + libicu). 553 ==> 416345 - Proper OpenCV minimum version must be specified. 554 ==> 416289 - 7.0.0-beta2 crash when closing Geolocation Editor. 555 ==> 406809 - digikam-6.2.0-git-20190421T121202-qtwebengine-x86-64.appimage crashes on startup. 556 ==> 411891 - digiKam crashes if compiled with QWebEngine. 557 ==> 409906 - Crash at Startup in geolocation about QtWebEngine. 558 ==> 416371 - 7.0.0-beta bug in Album tree view sorting order. 559 ==> 404901 - Google auth dialog => firefox google auth window not closed. 560 ==> 372340 - Tagged face areas on portait (vertical) oriented images are mispositioned. 561 ==> 415941 - Face identification in wrong place. 562 ==> 415550 - Faces setup by Picasa are not displayed correctly on rotated/portrait pictures. 563 ==> 413926 - Incompatibility between software, for face regions on auto-rotated portrait position photos. 564 ==> 406971 - Face frames are misaligned on Digikam when face framing was done on Picasa. 565 ==> 395243 - Incorrect face regions on vertical images. 566 ==> 378456 - When previewing faces the thumbnail preview is sometime sideways or not aligned to the face in question. 567 ==> 377628 - CR2 file face detection misplaced in portrait. 568 ==> 412920 - Image Editor displays incorrect coordinates for selections on scaled HiDPI screens. 569 ==> 407914 - Crash when tagging, finding duplicates, moving between albums. 570 ==> 392607 - Crash sometimes when applying Tags to images. 571 ==> 406612 - Pictures are not placed on map when the've got GPS metadata. 572 ==> 406611 - There is no GPS icon over the thumbnail. 573 ==> 406941 - Geo-filter on the right pane does not work. 574 ==> 413081 - German user interface? 575 ==> 398869 - Tabs text gone when digiKam window active. 576 ==> 204479 - Unable to use digiKam on Windows. 577 ==> 414176 - Recognition of people. 578 ==> 415521 - digiKam is crashing very oftenly while loading preview of an image on Windows 10. 579 ==> 412453 - Crash after adding a new album-network drive. 580 ==> 412950 - While processing new collection, any (mouse) action will result in crash of digiKam. 581 ==> 398674 - digiKam duplicates an album when the folder name has been renamed to lowercase or uppercase. 582 ==> 392109 - Renamed tags are not written to metadata. 583 ==> 391839 - Grouped pictures no longer appear in albums, tags, searches or timeline. 584 ==> 391544 - Metadata not written to image after renaming Tag. 585 ==> 326870 - Pop up window for file attributes with bad colors. 586 ==> 376640 - Changing tag name does not update sidecar metadata. 587 ==> 240224 - Foreground and background of the Settings menu item have the same color when the Dark Theme is selected. 588 ==> 290072 - XMP sidecars available for all file types user wants to. 589 ==> 403349 - digiKam window offset on high resolution display. 590 ==> 415353 - FEATURE REQUEST: hotkey-mode to assign photos to album categories, quickly. 591 ==> 414212 - Slow response after tagging. 592 ==> 386098 - Crash when adding pictures to a running digiKam. 593 ==> 416526 - Exporting no longer works at all on the 20/01 version. 594 ==> 416551 - Create an utility to allow to create external soft links for tagged files from database. 595 ==> 372230 - Searches tool : "Current Searches" virtual album appears more than one. 596 ==> 416492 - Panorama tool fails to make panoramas. 597 ==> 416756 - When searching for duplicates, only one photo is shown if the other one is in a group (and not the first of the group). 598 ==> 416759 - In duplicate tab, it should be possible to have reference image always at first/last. 599 ==> 416802 - Add confirmation dialog for "Delete all" action. 600 ==> 416755 - Tag with "." not processed correctly, likely to result in data loss. 601 ==> 416984 - Build failure with opencv4-4.2.0. 602 ==> 406066 - Cannot parse date string YYYY-MM-DDTHH:MM:SS.ssss and YYYY:MM:DD HH:MM:SS in EXIF and XMP. 603 ==> 417008 - Flickr export ERR_CERT_AUTHORITY_INVALID. 604 ==> 417100 - kbuildsycoca5 cannot be started under MacOS 10.11.6 when digiKam PKG is installed. 605 ==> 417136 - Export pictures by creating symlinks (e.g. for a best-of-selection on filesystem). 606 ==> 417178 - Export pictures by creating "relative" symlinks. 607 ==> 417221 - "Tags Filter" not honouring "AND" modifier. 608 ==> 417255 - People > Search In > Albums/Tags requires scrollbar. 609 ==> 417257 - When navigating various TreeViews with keyboard, selected item is not always in focus. 610 ==> 412539 - digiKam crash when starting. 611 ==> 417317 - digikam git master crash. 612 ==> 417322 - Unable to move album because tree view does not scroll. 613 ==> 417333 - Advanced slideshow is blocking the desktop. 614 ==> 417633 - The Google Photos transfer no longer works. 615 ==> 409324 - digiKam freezes when exiting image editor from edit on image from filtered view. 616 ==> 417696 - Using the button "Determine difference from clock photo" without any result. 617 ==> 386141 - Export to Google Photos not responding under Windows with QtWebKit. -618 ==> +618 ==> 417786 - Renaming files in batch processor fails. +619 ==> diff --git a/core/utilities/advancedrename/advancedrenamemanager.cpp b/core/utilities/advancedrename/advancedrenamemanager.cpp index 4bdf3bacef..f60bed1980 100644 --- a/core/utilities/advancedrename/advancedrenamemanager.cpp +++ b/core/utilities/advancedrename/advancedrenamemanager.cpp @@ -1,520 +1,532 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2010-08-08 * Description : a class that manages the files to be renamed * * Copyright (C) 2009-2012 by Andi Clemens * * 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 "advancedrenamemanager.h" // C++ includes #include // Qt includes #include #include #include #include // Local includes #include "digikam_debug.h" #include "advancedrenamewidget.h" #include "parsesettings.h" #include "parser.h" #include "defaultrenameparser.h" #include "importrenameparser.h" #include "iteminfo.h" namespace Digikam { struct SortByNameCaseInsensitive { bool operator() (const QString& s1, const QString& s2) const { return (s1.toLower() < s2.toLower()); } }; struct SortByDate { bool operator() (const QString& s1, const QString& s2) const { QFileInfo fi1(s1); QFileInfo fi2(s2); #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) return (fi1.birthTime() < fi2.birthTime()); #else return (fi1.created() < fi2.created()); #endif } }; struct SortBySize { bool operator() (const QString& s1, const QString& s2) const { QFileInfo fi1(s1); QFileInfo fi2(s2); return (fi1.size() < fi2.size()); } }; class Q_DECL_HIDDEN AdvancedRenameManager::Private { public: explicit Private() : parser(nullptr), widget(nullptr), parserType(AdvancedRenameManager::DefaultParser), sortAction(AdvancedRenameManager::SortCustom), sortDirection(AdvancedRenameManager::SortAscending), startIndex(1) { } QStringList files; QMap fileIndexMap; QMap folderIndexMap; QMap fileGroupIndexMap; QMap fileDatesMap; QMap renamedFiles; Parser* parser; AdvancedRenameWidget* widget; AdvancedRenameManager::ParserType parserType; AdvancedRenameManager::SortAction sortAction; AdvancedRenameManager::SortDirection sortDirection; int startIndex; }; AdvancedRenameManager::AdvancedRenameManager() : d(new Private) { setParserType(DefaultParser); } AdvancedRenameManager::AdvancedRenameManager(const QList& files) : d(new Private) { setParserType(DefaultParser); addFiles(files); } AdvancedRenameManager::~AdvancedRenameManager() { clearAll(); delete d->parser; delete d; } void AdvancedRenameManager::setSortAction(SortAction action) { d->sortAction = action; initialize(); QList list; foreach (const QString& file, d->files) { list << QUrl::fromLocalFile(file); } emit signalSortingChanged(list); } AdvancedRenameManager::SortAction AdvancedRenameManager::sortAction() const { return d->sortAction; } void AdvancedRenameManager::setSortDirection(SortDirection direction) { d->sortDirection = direction; initialize(); QList list; foreach (const QString& file, d->files) { list << QUrl::fromLocalFile(file); } emit signalSortingChanged(list); } AdvancedRenameManager::SortDirection AdvancedRenameManager::sortDirection() const { return d->sortDirection; } void AdvancedRenameManager::setStartIndex(int index) { d->startIndex = index < 1 ? 1 : index; initialize(); } void AdvancedRenameManager::setWidget(AdvancedRenameWidget* widget) { if (!widget) { d->widget = nullptr; return; } d->widget = widget; setParserType(d->parserType); } void AdvancedRenameManager::setParserType(ParserType type) { delete d->parser; if (type == ImportParser) { d->parser = new ImportRenameParser(); } else { d->parser = new DefaultRenameParser(); } d->parserType = type; if (d->widget) { d->widget->setParser(d->parser); if (type == ImportParser) { d->widget->setLayoutStyle(AdvancedRenameWidget::LayoutCompact); } else { d->widget->setLayoutStyle(AdvancedRenameWidget::LayoutNormal); } } } Parser* AdvancedRenameManager::getParser() const { return d->parser; } void AdvancedRenameManager::parseFiles() { if (!d->widget) { return; } parseFiles(d->widget->parseString()); } void AdvancedRenameManager::parseFiles(const ParseSettings& _settings) { if (!d->widget) { if (!(_settings.parseString.isEmpty())) { parseFiles(_settings.parseString, _settings); } } else { parseFiles(d->widget->parseString(), _settings); } } void AdvancedRenameManager::parseFiles(const QString& parseString) { if (!d->parser) { return; } d->parser->reset(); foreach (const QString& file, d->files) { QUrl url = QUrl::fromLocalFile(file); ParseSettings settings; settings.fileUrl = url; settings.parseString = parseString; settings.startIndex = d->startIndex; settings.creationTime = d->fileDatesMap[file]; settings.manager = this; d->renamedFiles[file] = d->parser->parse(settings); } } void AdvancedRenameManager::parseFiles(const QString& parseString, const ParseSettings& _settings) { if (!d->parser) { return; } d->parser->reset(); foreach (const QString& file, d->files) { QUrl url = QUrl::fromLocalFile(file); ParseSettings settings = _settings; settings.fileUrl = url; settings.parseString = parseString; settings.startIndex = d->startIndex; settings.manager = this; d->renamedFiles[file] = d->parser->parse(settings); } } void AdvancedRenameManager::addFiles(const QList& files) { foreach (const ParseSettings& ps, files) { addFile(ps.fileUrl.toLocalFile(), ps.creationTime); } initialize(); } void AdvancedRenameManager::clearMappings() { d->fileIndexMap.clear(); d->folderIndexMap.clear(); d->fileGroupIndexMap.clear(); d->renamedFiles.clear(); } void AdvancedRenameManager::clearAll() { d->files.clear(); clearMappings(); } void AdvancedRenameManager::reset() { clearAll(); resetState(); } void AdvancedRenameManager::resetState() { d->parser->reset(); d->startIndex = 1; } void AdvancedRenameManager::initializeFileList() { QStringList tmpFiles = d->files; switch (d->sortAction) { case SortName: { std::sort(tmpFiles.begin(), tmpFiles.end(), SortByNameCaseInsensitive()); break; } case SortDate: { std::sort(tmpFiles.begin(), tmpFiles.end(), SortByDate()); break; } case SortSize: { std::sort(tmpFiles.begin(), tmpFiles.end(), SortBySize()); break; } case SortCustom: default: break; } if (d->sortAction != SortCustom && d->sortDirection == SortDescending) { std::reverse(tmpFiles.begin(), tmpFiles.end()); } d->files = tmpFiles; } QStringList AdvancedRenameManager::fileList() const { return d->files; } -QMap AdvancedRenameManager::newFileList() const +QMap AdvancedRenameManager::newFileList(bool checkFileSystem) const { + if (checkFileSystem) + { + QMap renamedFiles; + + foreach (const QString& fileName, d->renamedFiles.keys()) + { + renamedFiles[fileName] = newName(fileName); + } + + return renamedFiles; + } + return d->renamedFiles; } bool AdvancedRenameManager::initialize() { if (d->files.isEmpty()) { return false; } // clear mappings clearMappings(); // initialize the file list according to the sort action and direction initializeFileList(); // fill normal index map { int counter = 1; foreach (const QString& file, d->files) { d->fileIndexMap[file] = counter++; } } // fill file group index map { int counter = 1; foreach (const QString& file, d->files) { if (!d->fileGroupIndexMap.contains(fileGroupKey(file))) { d->fileGroupIndexMap[fileGroupKey(file)] = counter++; } } } // fill folder group index map { QMap > dirMap; foreach (const QString& file, d->files) { QFileInfo fi(file); QString path = fi.absolutePath(); if (!path.isEmpty()) { if (!dirMap.contains(path)) { dirMap[path] = QList(); } dirMap[path].append(file); } } foreach (const QString& dir, dirMap.keys()) { int index = 0; foreach (const QString& f, dirMap[dir]) { if (!d->folderIndexMap.contains(f)) { d->folderIndexMap[f] = ++index; } } } } return true; } QString AdvancedRenameManager::fileGroupKey(const QString& filename) const { QFileInfo fi(filename); QString tmp = fi.absoluteFilePath().left(fi.absoluteFilePath().lastIndexOf(fi.suffix())); return tmp; } int AdvancedRenameManager::indexOfFile(const QString& filename) { return d->fileIndexMap.value(filename, -1); } int AdvancedRenameManager::indexOfFolder(const QString& filename) { return d->folderIndexMap.value(filename, -1); } int AdvancedRenameManager::indexOfFileGroup(const QString& filename) { return d->fileGroupIndexMap.value(fileGroupKey(filename), -1); } QString AdvancedRenameManager::newName(const QString& filename) const { // For the Linux or Windows file system, // we need to replace unsupported characters. QStorageInfo info(QFileInfo(filename).path()); QString regExpStr = QLatin1String("[?*"); QString newName = d->renamedFiles.value(filename, filename); QString sysType = QString::fromLatin1(info.fileSystemType()).toUpper(); if (sysType.contains(QLatin1String("FAT")) || sysType.contains(QLatin1String("NTFS")) || sysType.contains(QLatin1String("FUSEBLK"))) { regExpStr.append(QLatin1String("<>,:=\";|\\\\/")); if (sysType.contains(QLatin1String("FAT"))) { regExpStr.append(QLatin1Char('+')); } } QRegExp regExp(regExpStr + QLatin1Char(']')); newName.replace(regExp, QLatin1String("_")); return newName; } void AdvancedRenameManager::addFile(const QString& filename) const { d->files << filename; } void AdvancedRenameManager::addFile(const QString& filename, const QDateTime& datetime) const { d->files << filename; d->fileDatesMap[filename] = datetime; } } // namespace Digikam diff --git a/core/utilities/advancedrename/advancedrenamemanager.h b/core/utilities/advancedrename/advancedrenamemanager.h index fc20e158a4..7b59544546 100644 --- a/core/utilities/advancedrename/advancedrenamemanager.h +++ b/core/utilities/advancedrename/advancedrenamemanager.h @@ -1,134 +1,134 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2010-08-08 * Description : a class that manages the files to be renamed * * Copyright (C) 2009-2012 by Andi Clemens * * 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. * * ============================================================ */ #ifndef DIGIKAM_ADVANCED_RENAME_MANAGER_H #define DIGIKAM_ADVANCED_RENAME_MANAGER_H // Qt includes #include #include #include #include // Local includes #include "digikam_export.h" namespace Digikam { class AdvancedRenameWidget; class Parser; class ParseSettings; class DIGIKAM_GUI_EXPORT AdvancedRenameManager : public QObject { Q_OBJECT public: enum ParserType { DefaultParser = 0, ImportParser }; enum SortAction { SortName = 0, SortDate, SortSize, SortCustom }; enum SortDirection { SortAscending = 0, SortDescending }; public: AdvancedRenameManager(); explicit AdvancedRenameManager(const QList& files); virtual ~AdvancedRenameManager(); void addFiles(const QList& files); void reset(); void parseFiles(); void parseFiles(const ParseSettings& settings); void parseFiles(const QString& parseString); void parseFiles(const QString& parseString, const ParseSettings& settings); void setParserType(ParserType type); Parser* getParser() const; void setSortAction(SortAction action); SortAction sortAction() const; void setSortDirection(SortDirection direction); SortDirection sortDirection() const; void setStartIndex(int index); void setWidget(AdvancedRenameWidget* widget); int indexOfFile(const QString& filename); int indexOfFolder(const QString& filename); int indexOfFileGroup(const QString& filename); QString newName(const QString& filename) const; QStringList fileList() const; - QMap newFileList() const; + QMap newFileList(bool checkFileSystem = false) const; Q_SIGNALS: void signalSortingChanged(QList); private: AdvancedRenameManager(const AdvancedRenameManager&); AdvancedRenameManager& operator=(const AdvancedRenameManager&); void addFile(const QString& filename) const; void addFile(const QString& filename, const QDateTime& datetime) const; bool initialize(); void initializeFileList(); void resetState(); QString fileGroupKey(const QString& filename) const; void clearMappings(); void clearAll(); private: class Private; Private* const d; }; } // namespace Digikam #endif // DIGIKAM_ADVANCED_RENAME_MANAGER_H diff --git a/core/utilities/queuemanager/views/queuelist.cpp b/core/utilities/queuemanager/views/queuelist.cpp index 83138f4577..33045ecc5f 100644 --- a/core/utilities/queuemanager/views/queuelist.cpp +++ b/core/utilities/queuemanager/views/queuelist.cpp @@ -1,1215 +1,1215 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2008-11-21 * Description : Batch Queue Manager items list. * * Copyright (C) 2008-2020 by Gilles Caulier * Copyright (C) 2014 by Mohamed_Anwer * * 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 "queuelist.h" // Qt includes #include #include #include #include #include #include #include #include #include #include // KDE includes #include #include // Local includes #include "digikam_debug.h" #include "coredb.h" #include "coredbchangesets.h" #include "coredbwatch.h" #include "ddragobjects.h" #include "defaultrenameparser.h" #include "queuemgrwindow.h" #include "queuesettings.h" #include "queuetooltip.h" #include "thumbnailloadthread.h" #include "thumbnailsize.h" #include "workflowmanager.h" #include "dlayoutbox.h" #include "dworkingpixmap.h" namespace Digikam { class Q_DECL_HIDDEN QueueListViewItem::Private { public: explicit Private() : isBusy(false), done(false), hasThumb(false), progressIndex(0), view(nullptr) { } bool isBusy; bool done; bool hasThumb; int progressIndex; QString destFileName; QPixmap preview; QueueListView* view; ItemInfo info; }; QueueListViewItem::QueueListViewItem(QueueListView* const view, const ItemInfo& info) : QTreeWidgetItem(view), d(new Private) { d->view = view; setThumb(QIcon::fromTheme(QLatin1String("view-preview")).pixmap(48, QIcon::Disabled), false); setInfo(info); } QueueListViewItem::~QueueListViewItem() { delete d; } bool QueueListViewItem::hasValidThumbnail() const { return d->hasThumb; } void QueueListViewItem::setInfo(const ItemInfo& info) { d->info = info; setText(1, d->info.name()); } ItemInfo QueueListViewItem::info() const { return d->info; } void QueueListViewItem::setPixmap(const QPixmap& pix) { QIcon icon = QIcon(pix); // We make sure the preview icon stays the same regardless of the role icon.addPixmap(pix, QIcon::Selected, QIcon::On); icon.addPixmap(pix, QIcon::Selected, QIcon::Off); icon.addPixmap(pix, QIcon::Active, QIcon::On); icon.addPixmap(pix, QIcon::Active, QIcon::Off); icon.addPixmap(pix, QIcon::Normal, QIcon::On); icon.addPixmap(pix, QIcon::Normal, QIcon::Off); setIcon(0, icon); } void QueueListViewItem::setThumb(const QPixmap& pix, bool hasThumb) { QSize iSize = treeWidget()->iconSize(); QPixmap pixmap(iSize.width() + 2, iSize.height() + 2); pixmap.fill(Qt::transparent); QPainter p(&pixmap); p.drawPixmap((pixmap.width() / 2) - (pix.width() / 2), (pixmap.height() / 2) - (pix.height() / 2), pix); d->preview = pixmap; setPixmap(d->preview); d->hasThumb = hasThumb; } void QueueListViewItem::animProgress() { QPixmap icon(d->view->progressPixmapForIndex(d->progressIndex)); d->progressIndex++; if (d->view->progressPixmapForIndex(d->progressIndex).isNull()) { d->progressIndex = 0; } QPixmap preview = d->preview; QPixmap mask(preview.size()); mask.fill(QColor(128, 128, 128, 192)); QPainter p(&preview); p.drawPixmap(0, 0, mask); p.drawPixmap((preview.width() / 2) - (icon.width() / 2), (preview.height() / 2) - (icon.height() / 2), icon); setPixmap(preview); } void QueueListViewItem::setCanceled() { setPixmap(d->preview); setIcon(1, QIcon::fromTheme(QLatin1String("dialog-cancel"))); d->done = false; d->isBusy = false; d->progressIndex = 0; } void QueueListViewItem::setFailed() { setPixmap(d->preview); setIcon(1, QIcon::fromTheme(QLatin1String("dialog-error"))); d->done = false; d->isBusy = false; d->progressIndex = 0; } void QueueListViewItem::setDone() { setPixmap(d->preview); setIcon(1, QIcon::fromTheme(QLatin1String("dialog-ok-apply"))); d->done = true; d->isBusy = false; d->progressIndex = 0; } bool QueueListViewItem::isDone() const { return d->done; } void QueueListViewItem::reset() { setPixmap(d->preview); setIcon(1, QIcon()); d->done = false; d->isBusy = false; d->progressIndex = 0; } void QueueListViewItem::setBusy() { d->isBusy = true; } bool QueueListViewItem::isBusy() const { return d->isBusy; } void QueueListViewItem::setDestFileName(const QString& str) { d->destFileName = str; setText(2, d->destFileName); } QString QueueListViewItem::destFileName() const { return d->destFileName; } QString QueueListViewItem::destBaseName() const { QFileInfo fi(d->destFileName); return fi.completeBaseName(); } QString QueueListViewItem::destSuffix() const { QFileInfo fi(d->destFileName); return fi.suffix(); } // --------------------------------------------------------------------------- class Q_DECL_HIDDEN QueueListView::Private { public: enum RemoveItemsType { ItemsSelected = 0, ItemsDone, ItemsAll }; public: explicit Private() : showTips(false), iconSize(64), toolTipTimer(nullptr), progressTimer(nullptr), thumbLoadThread(ThumbnailLoadThread::defaultThread()), toolTip(nullptr), toolTipItem(nullptr), progressPix(DWorkingPixmap()) { } bool showTips; const int iconSize; QTimer* toolTipTimer; QTimer* progressTimer; ThumbnailLoadThread* thumbLoadThread; QueueSettings settings; AssignedBatchTools toolsList; QueueToolTip* toolTip; QueueListViewItem* toolTipItem; DWorkingPixmap progressPix; }; QueueListView::QueueListView(QWidget* const parent) : QTreeWidget(parent), d(new Private) { setIconSize(QSize(d->iconSize, d->iconSize)); setSelectionMode(QAbstractItemView::ExtendedSelection); setWhatsThis(i18n("This is the list of images to batch process.")); setAcceptDrops(true); viewport()->setAcceptDrops(true); setDropIndicatorShown(true); setDragEnabled(true); viewport()->setMouseTracking(true); setSortingEnabled(true); sortByColumn(1,Qt::AscendingOrder); setAllColumnsShowFocus(true); setRootIsDecorated(false); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); setColumnCount(3); setContextMenuPolicy(Qt::CustomContextMenu); QStringList titles; titles.append(i18n("Thumbnail")); titles.append(i18n("Original")); titles.append(i18n("Target")); setHeaderLabels(titles); header()->setSectionResizeMode(0, QHeaderView::ResizeToContents); header()->setSectionResizeMode(1, QHeaderView::Stretch); header()->setSectionResizeMode(2, QHeaderView::Stretch); d->toolTip = new QueueToolTip(this); d->toolTipTimer = new QTimer(this); d->progressTimer = new QTimer(this); // ----------------------------------------------------------- connect(CoreDbAccess::databaseWatch(), SIGNAL(collectionImageChange(CollectionImageChangeset)), this, SLOT(slotCollectionImageChange(CollectionImageChangeset)), Qt::QueuedConnection); connect(d->thumbLoadThread, SIGNAL(signalThumbnailLoaded(LoadingDescription,QPixmap)), this, SLOT(slotThumbnailLoaded(LoadingDescription,QPixmap))); connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(slotContextMenu())); connect(d->toolTipTimer, SIGNAL(timeout()), this, SLOT(slotToolTip())); connect(d->progressTimer, SIGNAL(timeout()), this, SLOT(slotProgressTimerDone())); } QueueListView::~QueueListView() { delete d->toolTip; delete d; } QPixmap QueueListView::progressPixmapForIndex(int index) const { if ((index >= 0) && (index < d->progressPix.frameCount())) { return (d->progressPix.frameAt(index)); } return QPixmap(); } Qt::DropActions QueueListView::supportedDropActions() const { return (Qt::CopyAction | Qt::MoveAction); } QMimeData* QueueListView::mimeData(const QList items) const { QList urls; QList albumIDs; QList imageIDs; foreach (QTreeWidgetItem* const itm, items) { QueueListViewItem* const vitem = dynamic_cast(itm); if (vitem) { urls.append(vitem->info().fileUrl()); albumIDs.append(vitem->info().albumId()); imageIDs.append(vitem->info().id()); } } DItemDrag* const mimeData = new DItemDrag(urls, albumIDs, imageIDs); return mimeData; } void QueueListView::startDrag(Qt::DropActions /*supportedActions*/) { QList items = selectedItems(); if (items.isEmpty()) { return; } QPixmap icon(QIcon::fromTheme(QLatin1String("image-jpeg")).pixmap(48)); int w = icon.width(); int h = icon.height(); QPixmap pix(w + 4, h + 4); QString text(QString::number(items.count())); QPainter p(&pix); p.fillRect(0, 0, pix.width() - 1, pix.height() - 1, QColor(Qt::white)); p.setPen(QPen(Qt::black, 1)); p.drawRect(0, 0, pix.width() - 1, pix.height() - 1); p.drawPixmap(2, 2, icon); QRect r = p.boundingRect(2, 2, w, h, Qt::AlignLeft | Qt::AlignTop, text); r.setWidth(qMax(r.width(), r.height())); r.setHeight(qMax(r.width(), r.height())); p.fillRect(r, QColor(0, 80, 0)); p.setPen(Qt::white); QFont f(font()); f.setBold(true); p.setFont(f); p.drawText(r, Qt::AlignCenter, text); p.end(); QDrag* const drag = new QDrag(this); drag->setMimeData(mimeData(items)); drag->setPixmap(pix); drag->exec(); } void QueueListView::dragEnterEvent(QDragEnterEvent* e) { QTreeWidget::dragEnterEvent(e); e->accept(); } void QueueListView::dragMoveEvent(QDragMoveEvent* e) { int albumID; QList albumIDs; QList imageIDs; QList urls; if (DItemDrag::decode(e->mimeData(), urls, albumIDs, imageIDs) || DAlbumDrag::decode(e->mimeData(), urls, albumID) || DTagListDrag::canDecode(e->mimeData())) { if (DItemDrag::decode(e->mimeData(), urls, albumIDs, imageIDs)) { ItemInfoList imageInfoList; for (QList::const_iterator it = imageIDs.constBegin() ; it != imageIDs.constEnd() ; ++it) { ItemInfo info(*it); if (!findItemByInfo(info)) { imageInfoList.append(info); } } if (!imageInfoList.isEmpty()) { QTreeWidget::dragMoveEvent(e); e->accept(); return; } } } else if (e->mimeData()->formats().contains(QLatin1String("digikam/workflow"))) { QTreeWidget::dragMoveEvent(e); e->accept(); return; } e->ignore(); } void QueueListView::dropEvent(QDropEvent* e) { int albumID; QList albumIDs; QList imageIDs; QList urls; if (DItemDrag::decode(e->mimeData(), urls, albumIDs, imageIDs)) { ItemInfoList imageInfoList; for (QList::const_iterator it = imageIDs.constBegin() ; it != imageIDs.constEnd() ; ++it) { ItemInfo info(*it); if (!findItemByInfo(info)) { imageInfoList.append(info); } } if (!imageInfoList.isEmpty()) { slotAddItems(imageInfoList); e->acceptProposedAction(); QueueListView* const vitem = dynamic_cast(e->source()); if (vitem && vitem != this) { foreach (const ItemInfo& info, imageInfoList) { vitem->removeItemByInfo(info); } } } } else if (DAlbumDrag::decode(e->mimeData(), urls, albumID)) { QList itemIDs = CoreDbAccess().db()->getItemIDsInAlbum(albumID); ItemInfoList imageInfoList; for (QList::const_iterator it = itemIDs.constBegin() ; it != itemIDs.constEnd() ; ++it) { ItemInfo info(*it); if (!findItemByInfo(info)) { imageInfoList.append(info); } } if (!imageInfoList.isEmpty()) { slotAddItems(imageInfoList); e->acceptProposedAction(); } } else if (DTagListDrag::canDecode(e->mimeData())) { QList tagIDs; if (!DTagListDrag::decode(e->mimeData(), tagIDs)) { return; } QList itemIDs = CoreDbAccess().db()->getItemIDsInTag(tagIDs.first(), true); ItemInfoList imageInfoList; for (QList::const_iterator it = itemIDs.constBegin() ; it != itemIDs.constEnd() ; ++it) { ItemInfo info(*it); if (!findItemByInfo(info)) { imageInfoList.append(info); } } if (!imageInfoList.isEmpty()) { slotAddItems(imageInfoList); e->acceptProposedAction(); } } else if (e->mimeData()->formats().contains(QLatin1String("digikam/workflow"))) { QByteArray ba = e->mimeData()->data(QLatin1String("digikam/workflow")); if (ba.size()) { QDataStream ds(ba); QString title; ds >> title; QueueMgrWindow::queueManagerWindow()->slotAssignQueueSettings(title); e->acceptProposedAction(); } } else { e->ignore(); } emit signalQueueContentsChanged(); } void QueueListView::setEnableToolTips(bool val) { d->showTips = val; if (!val) { hideToolTip(); } } void QueueListView::hideToolTip() { d->toolTipItem = nullptr; d->toolTipTimer->stop(); slotToolTip(); } bool QueueListView::acceptToolTip(const QPoint& pos) const { if (columnAt(pos.x()) == 0) { return true; } return false; } void QueueListView::slotToolTip() { d->toolTip->setQueueItem(d->toolTipItem); } void QueueListView::mouseMoveEvent(QMouseEvent* e) { if (e->buttons() == Qt::NoButton) { QueueListViewItem* item = dynamic_cast(itemAt(e->pos())); if (d->showTips) { if (!isActiveWindow()) { hideToolTip(); return; } if (item != d->toolTipItem) { hideToolTip(); if (acceptToolTip(e->pos())) { d->toolTipItem = item; d->toolTipTimer->setSingleShot(true); d->toolTipTimer->start(500); } } if (item == d->toolTipItem && !acceptToolTip(e->pos())) { hideToolTip(); } } return; } hideToolTip(); QTreeWidget::mouseMoveEvent(e); } void QueueListView::wheelEvent(QWheelEvent* e) { hideToolTip(); QTreeWidget::wheelEvent(e); } void QueueListView::keyPressEvent(QKeyEvent* e) { hideToolTip(); QTreeWidget::keyPressEvent(e); } void QueueListView::focusOutEvent(QFocusEvent* e) { hideToolTip(); QTreeWidget::focusOutEvent(e); } void QueueListView::leaveEvent(QEvent* e) { hideToolTip(); QTreeWidget::leaveEvent(e); } void QueueListView::slotAddItems(const ItemInfoList& list) { if (list.count() == 0) { return; } for (ItemInfoList::ConstIterator it = list.begin() ; it != list.end() ; ++it) { ItemInfo info = *it; // Check if the new item already exist in the list. bool find = false; QueueListViewItem* item = nullptr; QTreeWidgetItemIterator iter(this); while (*iter) { item = dynamic_cast(*iter); if (item && (item->info() == info)) { find = true; } ++iter; } if (!find) { new QueueListViewItem(this, info); } } updateDestFileNames(); emit signalQueueContentsChanged(); } void QueueListView::drawRow(QPainter* p, const QStyleOptionViewItem& opt, const QModelIndex& index) const { QueueListViewItem* const item = dynamic_cast(itemFromIndex(index)); if (item && !item->hasValidThumbnail()) { ItemInfo info = item->info(); d->thumbLoadThread->find(ThumbnailIdentifier(info.fileUrl().toLocalFile())); } QTreeWidget::drawRow(p, opt, index); } void QueueListView::slotThumbnailLoaded(const LoadingDescription& desc, const QPixmap& pix) { QTreeWidgetItemIterator it(this); while (*it) { QueueListViewItem* const item = dynamic_cast(*it); if (item && (item->info().fileUrl() == QUrl::fromLocalFile(desc.filePath))) { if (pix.isNull()) { item->setThumb(QIcon::fromTheme(QLatin1String("view-preview")).pixmap(d->iconSize, QIcon::Disabled)); } else { item->setThumb(pix.scaled(d->iconSize, d->iconSize, Qt::KeepAspectRatio)); } return; } ++it; } } void QueueListView::slotClearList() { removeItems(Private::ItemsAll); emit signalQueueContentsChanged(); } void QueueListView::slotRemoveSelectedItems() { removeItems(Private::ItemsSelected); emit signalQueueContentsChanged(); } void QueueListView::slotRemoveItemsDone() { removeItems(Private::ItemsDone); emit signalQueueContentsChanged(); } void QueueListView::removeItems(int removeType) { hideToolTip(); bool find; do { find = false; QTreeWidgetItemIterator it(this); while (*it) { QueueListViewItem* const item = dynamic_cast(*it); if (item) { switch (removeType) { case Private::ItemsSelected: { if (item->isSelected()) { delete item; find = true; } break; } case Private::ItemsDone: { if (item->isDone()) { delete item; find = true; } break; } default: // ItemsAll { delete item; find = true; break; } } } ++it; } } while (find); emit signalQueueContentsChanged(); } void QueueListView::removeItemByInfo(const ItemInfo& info) { removeItemById(info.id()); } void QueueListView::removeItemById(qlonglong id) { hideToolTip(); bool find; do { find = false; QTreeWidgetItemIterator it(this); while (*it) { QueueListViewItem* const item = dynamic_cast(*it); if (item && (item->info().id() == id)) { delete item; find = true; break; } ++it; } } while (find); emit signalQueueContentsChanged(); } bool QueueListView::findItemByInfo(const ItemInfo& info) { return (findItemById(info.id()) ? true : false); } QueueListViewItem* QueueListView::findItemById(qlonglong id) { QTreeWidgetItemIterator it(this); while (*it) { QueueListViewItem* const item = dynamic_cast(*it); if (item && (item->info().id() == id)) { return item; } ++it; } return nullptr; } QueueListViewItem* QueueListView::findItemByUrl(const QUrl& url) { QTreeWidgetItemIterator it(this); while (*it) { QueueListViewItem* const item = dynamic_cast(*it); if (item && (item->info().fileUrl() == url)) { return item; } ++it; } return nullptr; } int QueueListView::itemsCount() { int count = 0; QTreeWidgetItemIterator it(this); while (*it) { QueueListViewItem* const item = dynamic_cast(*it); if (item) { ++count; } ++it; } return count; } void QueueListView::cancelItems() { QTreeWidgetItemIterator it(this); while (*it) { QueueListViewItem* const item = dynamic_cast(*it); if (item && item->isBusy()) { item->setCanceled(); } ++it; } } ItemInfoList QueueListView::pendingItemsList() { ItemInfoList list; QTreeWidgetItemIterator it(this); while (*it) { QueueListViewItem* const item = dynamic_cast(*it); if (item && !item->isDone()) { list.append(item->info()); } ++it; } return list; } int QueueListView::pendingItemsCount() { return pendingItemsList().count(); } int QueueListView::pendingTasksCount() { int count = 0; QTreeWidgetItemIterator it(this); while (*it) { QueueListViewItem* const item = dynamic_cast(*it); if (item && !item->isDone()) { count += assignedTools().m_toolsList.count(); } ++it; } return count; } void QueueListView::setSettings(const QueueSettings& settings) { d->settings = settings; resetQueue(); updateDestFileNames(); } QueueSettings QueueListView::settings() const { return d->settings; } void QueueListView::setAssignedTools(const AssignedBatchTools& tools) { d->toolsList = tools; resetQueue(); updateDestFileNames(); } AssignedBatchTools QueueListView::assignedTools() const { return d->toolsList; } void QueueListView::slotAssignedToolsChanged(const AssignedBatchTools& tools) { setAssignedTools(tools); } void QueueListView::resetQueue() { //reset all items QTreeWidgetItemIterator it(this); while (*it) { QueueListViewItem* const item = dynamic_cast(*it); if (item) { item->reset(); } ++it; } } void QueueListView::updateDestFileNames() { QMap renamingResults; if (settings().renamingRule == QueueSettings::CUSTOMIZE) { AdvancedRenameManager manager; ParseSettings psettings; psettings.parseString = settings().renamingParser; QList files; QTreeWidgetItemIterator it(this); while (*it) { QueueListViewItem* const item = dynamic_cast(*it); if (item) { // Update base name using queue renaming rules. ItemInfo info = item->info(); QFileInfo fi(info.filePath()); ParseSettings ps; ps.fileUrl = QUrl::fromLocalFile(fi.absoluteFilePath()); files << ps; } ++it; } manager.addFiles(files); manager.parseFiles(psettings); - renamingResults = manager.newFileList(); + renamingResults = manager.newFileList(true); } AssignedBatchTools tools = assignedTools(); QTreeWidgetItemIterator it(this); while (*it) { QueueListViewItem* const item = dynamic_cast(*it); if (item) { // Update base name using queue renaming rules. ItemInfo info = item->info(); QFileInfo fi(info.filePath()); // Update suffix using assigned batch tool rules. bool extensionSet = false; tools.m_itemUrl = item->info().fileUrl(); QString newSuffix = tools.targetSuffix(&extensionSet); QString newName = QString::fromUtf8("%1.%2").arg(fi.completeBaseName()).arg(newSuffix); if ((settings().renamingRule == QueueSettings::CUSTOMIZE) && !renamingResults.isEmpty()) { QFileInfo fi2(renamingResults[fi.absoluteFilePath()]); if (extensionSet) { newName = QString::fromUtf8("%1.%2").arg(fi2.completeBaseName()) .arg(newSuffix); } else { newName = fi2.fileName(); } } item->setDestFileName(newName); } ++it; } } void QueueListView::slotContextMenu() { if (!viewport()->isEnabled()) { return; } KActionCollection* const acol = QueueMgrWindow::queueManagerWindow()->actionCollection(); QMenu popmenu(this); popmenu.addAction(acol->action(QLatin1String("queuemgr_removeitemssel"))); popmenu.addSeparator(); popmenu.addAction(acol->action(QLatin1String("queuemgr_clearlist"))); popmenu.exec(QCursor::pos()); } void QueueListView::slotCollectionImageChange(const CollectionImageChangeset& changeset) { if (QueueMgrWindow::queueManagerWindow()->isBusy()) { return; } switch (changeset.operation()) { case CollectionImageChangeset::Deleted: case CollectionImageChangeset::Removed: case CollectionImageChangeset::RemovedAll: { foreach (const qlonglong& id, changeset.ids()) { removeItemById(id); } break; } default: { break; } } } void QueueListView::reloadThumbs(const QUrl& url) { d->thumbLoadThread->find(ThumbnailIdentifier(url.toLocalFile())); } void QueueListView::setItemBusy(qlonglong id) { QueueListViewItem* const item = findItemById(id); if (item) { item->setBusy(); d->progressTimer->start(300); } } void QueueListView::slotProgressTimerDone() { QTreeWidgetItemIterator it(this); int active = 0; while (*it) { QueueListViewItem* const item = dynamic_cast(*it); if (item && item->isBusy()) { item->animProgress(); active++; } ++it; } if (!active) { d->progressTimer->stop(); } } } // namespace Digikam