diff --git a/NEWS b/NEWS index b9298a9598..43a57717db 100644 --- a/NEWS +++ b/NEWS @@ -1,641 +1,642 @@ 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 digiKam 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 ==> 417786 - Renaming files in batch processor fails. 619 ==> 318516 - SCAN : Improve digiKam loading time [patch]. 620 ==> 417708 - Video export => geolocation is not exported. 621 ==> 397819 - digiKam not showing date taken. 622 ==> 327466 - digiKam crashes after launching alternate image processing software. -623 ==> +623 ==> 332903 - Altering Geo-Data. +624 ==> diff --git a/core/app/views/tableview/tableview.cpp b/core/app/views/tableview/tableview.cpp index 00a5b1f56c..160bb5f523 100644 --- a/core/app/views/tableview/tableview.cpp +++ b/core/app/views/tableview/tableview.cpp @@ -1,670 +1,671 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2013-02-11 * Description : Table view * - * Copyright (C) 2013 by Michael G. Hansen - * Copyright (C) 2017 by Simon Frei + * Copyright (C) 2013 by Michael G. Hansen + * Copyright (C) 2017 by Simon Frei + * Copyright (C) 2017-2020 by Gilles Caulier * * 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 "tableview.h" // Qt includes #include #include #include #include #include #include #include #include #include // KDE includes #include #include // Local includes #include "advancedrenamedialog.h" #include "advancedrenameprocessdialog.h" #include "applicationsettings.h" #include "contextmenuhelper.h" #include "digikam_debug.h" #include "fileactionmngr.h" #include "album.h" #include "itemviewutilities.h" #include "tableview_columnfactory.h" #include "tableview_model.h" #include "tableview_selection_model_syncer.h" #include "tableview_shared.h" #include "tableview_treeview.h" namespace Digikam { class ItemAlbumModel; class ItemFilterModel; class Q_DECL_HIDDEN TableView::Private { public: explicit Private() : columnProfiles(), thumbnailSize(), imageViewUtilities(nullptr) { } QList columnProfiles; ThumbnailSize thumbnailSize; ItemViewUtilities* imageViewUtilities; }; TableView::TableView(QItemSelectionModel* const selectionModel, DCategorizedSortFilterProxyModel* const imageFilterModel, QWidget* const parent) : QWidget(parent), StateSavingObject(this), d(new Private()), s(new TableViewShared()) { s->isActive = false; s->tableView = this; s->thumbnailLoadThread = new ThumbnailLoadThread(this); s->imageFilterModel = dynamic_cast(imageFilterModel); s->imageModel = dynamic_cast(imageFilterModel->sourceModel()); s->imageFilterSelectionModel = selectionModel; s->columnFactory = new TableViewColumnFactory(s.data(), this); QVBoxLayout* const vbox1 = new QVBoxLayout(); s->tableViewModel = new TableViewModel(s.data(), this); s->tableViewSelectionModel = new QItemSelectionModel(s->tableViewModel); s->tableViewSelectionModelSyncer = new TableViewSelectionModelSyncer(s.data(), this); s->treeView = new TableViewTreeView(s.data(), this); s->treeView->installEventFilter(this); d->imageViewUtilities = new ItemViewUtilities(this); connect(s->treeView, SIGNAL(activated(QModelIndex)), this, SLOT(slotItemActivated(QModelIndex))); connect(s->treeView, SIGNAL(signalZoomInStep()), this, SIGNAL(signalZoomInStep())); connect(s->treeView, SIGNAL(signalZoomOutStep()), this, SIGNAL(signalZoomOutStep())); connect(s->tableViewSelectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SIGNAL(signalItemsChanged())); connect(s->treeView, SIGNAL(collapsed(QModelIndex)), this, SIGNAL(signalItemsChanged())); connect(s->treeView, SIGNAL(expanded(QModelIndex)), this, SIGNAL(signalItemsChanged())); connect(s->tableViewModel, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SIGNAL(signalItemsChanged())); connect(s->tableViewModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SIGNAL(signalItemsChanged())); connect(s->tableViewModel, SIGNAL(layoutChanged()), this, SIGNAL(signalItemsChanged())); connect(s->tableViewModel, SIGNAL(modelReset()), this, SIGNAL(signalItemsChanged())); vbox1->addWidget(s->treeView); vbox1->setContentsMargins(QMargins()); setLayout(vbox1); } TableView::~TableView() { } void TableView::doLoadState() { const KConfigGroup group = getConfigGroup(); TableViewColumnProfile profile; const KConfigGroup groupCurrentProfile = group.group("Current Profile"); profile.loadSettings(groupCurrentProfile); s->tableViewModel->loadColumnProfile(profile); const TableViewModel::GroupingMode groupingMode = TableViewModel::GroupingMode(group.readEntry("Grouping mode", int(TableViewModel::GroupingShowSubItems))); s->tableViewModel->setGroupingMode(groupingMode); if (!profile.headerState.isEmpty()) { s->treeView->header()->restoreState(profile.headerState); } } void TableView::doSaveState() { KConfigGroup group = getConfigGroup(); TableViewColumnProfile profile = s->tableViewModel->getColumnProfile(); profile.headerState = s->treeView->header()->saveState(); KConfigGroup groupCurrentProfile = group.group("Current Profile"); profile.saveSettings(groupCurrentProfile); group.writeEntry("Grouping mode", int(s->tableViewModel->groupingMode())); } void TableView::slotItemActivated(const QModelIndex& tableViewIndex) { const ItemInfo info = s->tableViewModel->imageInfo(tableViewIndex); if (info.isNull()) { return; } if (qApp->queryKeyboardModifiers() != Qt::MetaModifier) { if (ApplicationSettings::instance()->getItemLeftClickAction() == ApplicationSettings::ShowPreview) { emit signalPreviewRequested(info); } else { d->imageViewUtilities->openInfos(info, allItemInfos(), currentAlbum()); } } else { d->imageViewUtilities->openInfosWithDefaultApplication(QList() << info); } } bool TableView::eventFilter(QObject* watched, QEvent* event) { // we are looking for context menu events for the table view if ((watched == s->treeView) && (event->type() == QEvent::ContextMenu)) { QContextMenuEvent* const e = static_cast(event); e->accept(); const QModelIndex contextMenuIndex = s->treeView->indexAt(e->pos()); if (contextMenuIndex.isValid()) { emit signalShowContextMenuOnInfo(e, s->tableViewModel->imageInfo(contextMenuIndex), getExtraGroupingActions()); } else { emit signalShowContextMenu(e, getExtraGroupingActions()); } // event has been filtered by us return true; } return QObject::eventFilter(watched, event); } void TableView::setThumbnailSize(const ThumbnailSize& size) { d->thumbnailSize = size; const QList columnObjects = s->tableViewModel->getColumnObjects(); foreach (TableViewColumn* const iColumn, columnObjects) { iColumn->updateThumbnailSize(); } } ThumbnailSize TableView::getThumbnailSize() const { return d->thumbnailSize; } Album* TableView::currentAlbum() const { ItemAlbumModel* const albumModel = qobject_cast(s->imageModel); if (!albumModel) { return nullptr; } if (albumModel->currentAlbums().isEmpty()) { return nullptr; } return albumModel->currentAlbums().first(); } void TableView::slotPaste() { DragDropViewImplementation* const dragDropViewImplementation = s->treeView; dragDropViewImplementation->paste(); } ItemInfo TableView::currentInfo() const { return s->tableViewModel->imageInfo(s->tableViewSelectionModel->currentIndex()); } ItemInfoList TableView::allItemInfos(bool grouping) const { if (grouping) { return s->treeView->resolveGrouping(ItemInfoList(s->tableViewModel->allItemInfo())); } return ItemInfoList(s->tableViewModel->allItemInfo()); } bool TableView::allNeedGroupResolving(const ApplicationSettings::OperationType type) const { return s->treeView->needGroupResolving(type, allItemInfos()); } bool TableView::selectedNeedGroupResolving(const ApplicationSettings::OperationType type) const { return s->treeView->needGroupResolving(type, selectedItemInfos()); } void TableView::slotDeleteSelected(const ItemViewUtilities::DeleteMode deleteMode) { const ItemInfoList infoList = selectedItemInfos(true); /// @todo Update parameter naming for deleteImages if (d->imageViewUtilities->deleteImages(infoList, deleteMode)) { slotAwayFromSelection(); } } void TableView::slotDeleteSelectedWithoutConfirmation(const ItemViewUtilities::DeleteMode deleteMode) { const ItemInfoList infoList = selectedItemInfos(true); d->imageViewUtilities->deleteImagesDirectly(infoList, deleteMode); slotAwayFromSelection(); } QList TableView::getExtraGroupingActions() { QList actionList; const TableViewModel::GroupingMode currentGroupingMode = s->tableViewModel->groupingMode(); QAction* const actionHideGrouped = new QAction(i18n("Hide grouped items"), this); actionHideGrouped->setCheckable(true); actionHideGrouped->setChecked(currentGroupingMode == TableViewModel::GroupingHideGrouped); actionHideGrouped->setData(QVariant::fromValue(TableViewModel::GroupingHideGrouped)); connect(actionHideGrouped, SIGNAL(triggered(bool)), this, SLOT(slotGroupingModeActionTriggered())); actionList << actionHideGrouped; QAction* const actionIgnoreGrouping = new QAction(i18n("Ignore grouping"), this); actionIgnoreGrouping->setCheckable(true); actionIgnoreGrouping->setChecked(currentGroupingMode == TableViewModel::GroupingIgnoreGrouping); actionIgnoreGrouping->setData(QVariant::fromValue(TableViewModel::GroupingIgnoreGrouping)); connect(actionIgnoreGrouping, SIGNAL(triggered(bool)), this, SLOT(slotGroupingModeActionTriggered())); actionList << actionIgnoreGrouping; QAction* const actionShowSubItems = new QAction(i18n("Show grouping in tree"), this); actionShowSubItems->setCheckable(true); actionShowSubItems->setChecked(currentGroupingMode == TableViewModel::GroupingShowSubItems); actionShowSubItems->setData(QVariant::fromValue(TableViewModel::GroupingShowSubItems)); connect(actionShowSubItems, SIGNAL(triggered(bool)), this, SLOT(slotGroupingModeActionTriggered())); actionList << actionShowSubItems; return actionList; } void TableView::slotGroupingModeActionTriggered() { const QAction* const senderAction = qobject_cast(sender()); if (!senderAction) { return; } const TableViewModel::GroupingMode newGroupingMode = senderAction->data().value(); s->tableViewModel->setGroupingMode(newGroupingMode); } int TableView::numberOfSelectedItems() const { return s->tableViewSelectionModel->selectedRows().count(); } void TableView::slotGoToRow(const int rowNumber, const bool relativeMove) { int nextDeepRowNumber = rowNumber; if (relativeMove) { const QModelIndex currentTableViewIndex = s->tableViewSelectionModel->currentIndex(); const int currentDeepRowNumber = s->tableViewModel->indexToDeepRowNumber(currentTableViewIndex); nextDeepRowNumber += currentDeepRowNumber; } const QModelIndex nextIndex = s->tableViewModel->deepRowIndex(nextDeepRowNumber); if (nextIndex.isValid()) { const QItemSelection rowSelection = s->tableViewSelectionModelSyncer->targetIndexToRowItemSelection(nextIndex); s->tableViewSelectionModel->select(rowSelection, QItemSelectionModel::ClearAndSelect); s->tableViewSelectionModel->setCurrentIndex(nextIndex, QItemSelectionModel::Select); } } ItemInfo TableView::deepRowItemInfo(const int rowNumber, const bool relative) const { int targetRowNumber = rowNumber; if (relative) { const QModelIndex& currentTableViewIndex = s->tableViewSelectionModel->currentIndex(); if (!currentTableViewIndex.isValid()) { return ItemInfo(); } - const int currentDeepRowNumber = s->tableViewModel->indexToDeepRowNumber(currentTableViewIndex); - targetRowNumber += currentDeepRowNumber; + const int currentDeepRowNumber = s->tableViewModel->indexToDeepRowNumber(currentTableViewIndex); + targetRowNumber += currentDeepRowNumber; } const QModelIndex targetIndex = s->tableViewModel->deepRowIndex(targetRowNumber); return s->tableViewModel->imageInfo(targetIndex); } ItemInfo TableView::nextInfo() const { const QModelIndex cIndex = s->tableViewSelectionModel->currentIndex(); const int currentDeepRowNumber = s->tableViewModel->indexToDeepRowNumber(cIndex); const int nextDeepRowNumber = currentDeepRowNumber + 1; if (nextDeepRowNumber>=s->tableViewModel->deepRowCount()) { return ItemInfo(); } const QModelIndex nextDeepRowIndex = s->tableViewModel->deepRowIndex(nextDeepRowNumber); return s->tableViewModel->imageInfo(nextDeepRowIndex); } ItemInfo TableView::previousInfo() const { const QModelIndex cIndex = s->tableViewSelectionModel->currentIndex(); const int currentDeepRowNumber = s->tableViewModel->indexToDeepRowNumber(cIndex); const int previousDeepRowNumber = currentDeepRowNumber - 1; if (previousDeepRowNumber < 0) { return ItemInfo(); } const QModelIndex previousDeepRowIndex = s->tableViewModel->deepRowIndex(previousDeepRowNumber); return s->tableViewModel->imageInfo(previousDeepRowIndex); } void TableView::slotSetCurrentWhenAvailable(const qlonglong id) { const QModelIndex idx = s->tableViewModel->indexFromImageId(id, 0); if (!idx.isValid()) { /// @todo Actually buffer this request until the model is fully populated return; } s->tableViewSelectionModel->setCurrentIndex(idx, QItemSelectionModel::ClearAndSelect); } /** * @brief Unselects the current selection and changes the current item * * @todo This may not work correctly if grouped items are deleted, but are not selected */ void TableView::slotAwayFromSelection() { QModelIndexList selection = s->tableViewSelectionModel->selectedRows(0); if (selection.isEmpty()) { return; } const QModelIndex firstIndex = s->tableViewModel->deepRowIndex(0); const QModelIndex lastIndex = s->tableViewModel->deepRowIndex(-1); if (selection.contains(firstIndex) && selection.contains(lastIndex)) { // both the first and the last index are selected, we have to // select an index inbetween const int nextFreeDeepRow = s->tableViewModel->firstDeepRowNotInList(selection); if (nextFreeDeepRow < 0) { s->tableViewSelectionModel->clearSelection(); s->tableViewSelectionModel->setCurrentIndex(QModelIndex(), QItemSelectionModel::ClearAndSelect); } else { const QModelIndex nextFreeIndex = s->tableViewModel->deepRowIndex(nextFreeDeepRow); s->tableViewSelectionModel->setCurrentIndex(nextFreeIndex, QItemSelectionModel::ClearAndSelect); const QItemSelection nextFreeIndexAsRow = s->tableViewSelectionModelSyncer->targetIndexToRowItemSelection(nextFreeIndex); s->tableViewSelectionModel->select(nextFreeIndexAsRow, QItemSelectionModel::ClearAndSelect); } } else if (selection.contains(lastIndex)) { const int firstSelectedRowNumber = s->tableViewModel->indexToDeepRowNumber(selection.first()); const QModelIndex newIndex = s->tableViewModel->deepRowIndex(firstSelectedRowNumber-1); s->tableViewSelectionModel->setCurrentIndex(newIndex, QItemSelectionModel::ClearAndSelect); const QItemSelection newIndexAsRow = s->tableViewSelectionModelSyncer->targetIndexToRowItemSelection(newIndex); s->tableViewSelectionModel->select(newIndexAsRow, QItemSelectionModel::ClearAndSelect); } else { const int lastSelectedRowNumber = s->tableViewModel->indexToDeepRowNumber(selection.last()); const QModelIndex newIndex = s->tableViewModel->deepRowIndex(lastSelectedRowNumber+1); s->tableViewSelectionModel->setCurrentIndex(newIndex, QItemSelectionModel::ClearAndSelect); const QItemSelection newIndexAsRow = s->tableViewSelectionModelSyncer->targetIndexToRowItemSelection(newIndex); s->tableViewSelectionModel->select(newIndexAsRow, QItemSelectionModel::ClearAndSelect); } } void TableView::clearSelection() { s->tableViewSelectionModel->clearSelection(); } void TableView::invertSelection() { const int deepRowCount = s->tableViewModel->deepRowCount(); QList rowsToSelect; int lastSelectedRow = -1; /// @todo Create a DeepRowIterator because there is a lot of overhead here for (int i = 0 ; i < deepRowCount ; ++i) { const QModelIndex iIndex = s->tableViewModel->deepRowIndex(i); if (s->tableViewSelectionModel->isSelected(iIndex)) { if ((i - 1) > lastSelectedRow) { for (int j = lastSelectedRow + 1 ; j < i ; ++j) { rowsToSelect << j; } } lastSelectedRow = i; } } if (lastSelectedRow + 1 < deepRowCount) { for (int j = lastSelectedRow + 1 ; j < deepRowCount ; ++j) { rowsToSelect << j; } } s->tableViewSelectionModel->clearSelection(); foreach (const int i, rowsToSelect) { const QModelIndex iIndex = s->tableViewModel->deepRowIndex(i); const QItemSelection is = s->tableViewSelectionModelSyncer->targetIndexToRowItemSelection(iIndex); s->tableViewSelectionModel->select(is, QItemSelectionModel::Select); } } void TableView::selectAll() { /// @todo This only selects expanded items. s->treeView->selectAll(); } void TableView::slotSetActive(const bool isActive) { if (s->isActive != isActive) { s->isActive = isActive; s->tableViewModel->slotSetActive(isActive); s->tableViewSelectionModelSyncer->slotSetActive(isActive); } } ItemInfoList TableView::selectedItemInfos(bool grouping) const { ItemInfoList infos = ItemInfoList(s->tableViewModel->imageInfos(s->tableViewSelectionModel->selectedRows())); if (grouping) { return s->treeView->resolveGrouping(infos); } return infos; } ItemInfoList TableView::selectedItemInfosCurrentFirst(bool grouping) const { QModelIndexList indexes = s->tableViewSelectionModel->selectedRows(); const QModelIndex current = s->tableViewModel->toCol0(s->tableViewSelectionModel->currentIndex()); if (!indexes.isEmpty()) { if (indexes.first() != current) { if (indexes.removeOne(current)) { indexes.prepend(current); } } } if (grouping) { return s->treeView->resolveGrouping(ItemInfoList(s->tableViewModel->imageInfos(indexes))); } return ItemInfoList(s->tableViewModel->imageInfos(indexes)); } void TableView::rename() { ItemInfoList infos = selectedItemInfos(); if (s->treeView->needGroupResolving(ApplicationSettings::Rename, infos)) { infos = s->treeView->resolveGrouping(infos); } QList urls = infos.toImageUrlList(); bool loop = false; NewNamesList newNamesList; do { qCDebug(DIGIKAM_GENERAL_LOG) << "Selected URLs to rename: " << urls; QPointer dlg = new AdvancedRenameDialog(this); dlg->slotAddImages(urls); if (dlg->exec() != QDialog::Accepted) { delete dlg; break; } if (!loop) { slotAwayFromSelection(); loop = true; } newNamesList = dlg->newNames(); delete dlg; setFocus(); qApp->processEvents(); if (!newNamesList.isEmpty()) { QPointer dlg2 = new AdvancedRenameProcessDialog(newNamesList, this); dlg2->exec(); s->tableViewModel->scheduleResort(); urls = dlg2->failedUrls(); delete dlg2; } } while (!urls.isEmpty() && !newNamesList.isEmpty()); } } // namespace Digikam diff --git a/core/app/views/tableview/tableview.h b/core/app/views/tableview/tableview.h index 3984ea9a64..ccaf9ae6ae 100644 --- a/core/app/views/tableview/tableview.h +++ b/core/app/views/tableview/tableview.h @@ -1,132 +1,134 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2013-02-11 * Description : Table view * - * Copyright (C) 2013 by Michael G. Hansen - * Copyright (C) 2017 by Simon Frei + * Copyright (C) 2013 by Michael G. Hansen + * Copyright (C) 2017 by Simon Frei + * Copyright (C) 2017-2020 by Gilles Caulier * * 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_TABLE_VIEW_H #define DIGIKAM_TABLE_VIEW_H // Qt includes #include // Local includes #include "applicationsettings.h" #include "dcategorizedsortfilterproxymodel.h" #include "digikam_export.h" #include "itemviewutilities.h" #include "iteminfo.h" #include "statesavingobject.h" class QMenu; class QContextMenuEvent; class QItemDelegate; class QItemSelectionModel; class QTreeView; namespace Digikam { class Album; class ItemFilterModel; class ThumbnailSize; class TableViewShared; class TableView : public QWidget, public StateSavingObject { Q_OBJECT public: explicit TableView(QItemSelectionModel* const selectionModel, DCategorizedSortFilterProxyModel* const imageFilterModel, QWidget* const parent); virtual ~TableView(); void setThumbnailSize(const ThumbnailSize& size); ThumbnailSize getThumbnailSize() const; ItemInfo currentInfo() const; Album* currentAlbum() const; int numberOfSelectedItems() const; ItemInfo nextInfo() const; ItemInfo previousInfo() const; ItemInfo deepRowItemInfo(const int rowNumber, const bool relative) const; void selectAll(); void clearSelection(); void invertSelection(); ItemInfoList allItemInfos(bool grouping = false) const; ItemInfoList selectedItemInfos(bool grouping = false) const; ItemInfoList selectedItemInfosCurrentFirst(bool grouping = false) const; bool allNeedGroupResolving(const ApplicationSettings::OperationType type) const; bool selectedNeedGroupResolving(const ApplicationSettings::OperationType type) const; protected: void doLoadState(); void doSaveState(); virtual bool eventFilter(QObject* watched, QEvent* event); QList getExtraGroupingActions(); public Q_SLOTS: void slotGoToRow(const int rowNumber, const bool relativeMove); void slotSetCurrentWhenAvailable(const qlonglong id); void slotAwayFromSelection(); void slotDeleteSelected(const ItemViewUtilities::DeleteMode deleteMode = ItemViewUtilities::DeleteUseTrash); void slotDeleteSelectedWithoutConfirmation(const ItemViewUtilities::DeleteMode deleteMode = ItemViewUtilities::DeleteUseTrash); void slotSetActive(const bool isActive); void slotPaste(); void rename(); protected Q_SLOTS: void slotItemActivated(const QModelIndex& tableViewIndex); void slotGroupingModeActionTriggered(); Q_SIGNALS: void signalPreviewRequested(const ItemInfo& info); void signalZoomInStep(); void signalZoomOutStep(); void signalPopupTagsView(); void signalItemsChanged(); void signalInsertSelectedToExistingQueue(int queue); void signalShowContextMenu(QContextMenuEvent* event, const QList& actions); void signalShowContextMenuOnInfo(QContextMenuEvent* event, const ItemInfo& info, const QList& actions, ItemFilterModel* filterModel = nullptr); private: class Private; - const QScopedPointer d; + + const QScopedPointer d; const QScopedPointer s; }; } // namespace Digikam #endif // DIGIKAM_TABLE_VIEW_H diff --git a/core/app/views/tableview/tableview_treeview.cpp b/core/app/views/tableview/tableview_treeview.cpp index d977d42c51..fb1c8c6977 100644 --- a/core/app/views/tableview/tableview_treeview.cpp +++ b/core/app/views/tableview/tableview_treeview.cpp @@ -1,350 +1,373 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2013-03-02 * Description : Table view: Tree view subelement * - * Copyright (C) 2013 by Michael G. Hansen + * Copyright (C) 2017-2020 by Gilles Caulier + * Copyright (C) 2013 by Michael G. Hansen * * 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 "tableview_treeview.h" // Qt includes #include #include #include #include #include // KDE includes #include // Local includes #include "digikam_debug.h" #include "contextmenuhelper.h" #include "iteminfo.h" #include "itemmodel.h" #include "tableview_column_configuration_dialog.h" #include "tableview_columnfactory.h" #include "tableview_model.h" #include "tableview_selection_model_syncer.h" #include "tableview_treeview_delegate.h" #include "thumbnailsize.h" namespace Digikam { class Q_DECL_HIDDEN TableViewTreeView::Private { public: explicit Private() : headerContextMenuActiveColumn(-1), actionHeaderContextMenuRemoveColumn(nullptr), actionHeaderContextMenuConfigureColumn(nullptr), dragDropThumbnailSize() { } public: int headerContextMenuActiveColumn; QAction* actionHeaderContextMenuRemoveColumn; QAction* actionHeaderContextMenuConfigureColumn; ThumbnailSize dragDropThumbnailSize; }; TableViewTreeView::TableViewTreeView(TableViewShared* const tableViewShared, QWidget* const parent) : QTreeView(parent), d(new Private()), s(tableViewShared) { setModel(s->tableViewModel); setSelectionModel(s->tableViewSelectionModel); s->itemDelegate = new TableViewItemDelegate(s, this); setSelectionMode(QAbstractItemView::ExtendedSelection); setItemDelegate(s->itemDelegate); setAlternatingRowColors(true); setSortingEnabled(true); setAllColumnsShowFocus(true); setDragEnabled(true); setAcceptDrops(true); setWordWrap(true); -// viewport()->setAcceptDrops(true); - - d->actionHeaderContextMenuRemoveColumn = new QAction(QIcon::fromTheme(QLatin1String("edit-table-delete-column")), i18n("Remove this column"), this); +/* + viewport()->setAcceptDrops(true); +*/ + d->actionHeaderContextMenuRemoveColumn = new QAction(QIcon::fromTheme(QLatin1String("edit-table-delete-column")), i18n("Remove this column"), this); connect(d->actionHeaderContextMenuRemoveColumn, SIGNAL(triggered(bool)), this, SLOT(slotHeaderContextMenuActionRemoveColumnTriggered())); d->actionHeaderContextMenuConfigureColumn = new QAction(QIcon::fromTheme(QLatin1String("configure")), i18n("Configure this column"), this); connect(d->actionHeaderContextMenuConfigureColumn, SIGNAL(triggered(bool)), this, SLOT(slotHeaderContextMenuConfigureColumn())); header()->installEventFilter(this); slotModelGroupingModeChanged(); connect(s->tableViewModel, SIGNAL(signalGroupingModeChanged()), this, SLOT(slotModelGroupingModeChanged())); } TableViewTreeView::~TableViewTreeView() { } bool TableViewTreeView::eventFilter(QObject* watched, QEvent* event) { QHeaderView* const headerView = header(); if ((watched == headerView) && (event->type() == QEvent::ContextMenu)) { showHeaderContextMenu(event); return true; } return QObject::eventFilter(watched, event); } void TableViewTreeView::addColumnDescriptionsToMenu(const QList& columnDescriptions, QMenu* const menu) { - for (int i = 0; i < columnDescriptions.count(); ++i) + for (int i = 0 ; i < columnDescriptions.count() ; ++i) { const TableViewColumnDescription& desc = columnDescriptions.at(i); QAction* const action = new QAction(desc.columnTitle, menu); if (!desc.columnIcon.isEmpty()) { action->setIcon(QIcon::fromTheme(desc.columnIcon)); } if (desc.subColumns.isEmpty()) { connect(action, SIGNAL(triggered(bool)), this, SLOT(slotHeaderContextMenuAddColumn())); action->setData(QVariant::fromValue(desc)); } else { QMenu* const subMenu = new QMenu(menu); addColumnDescriptionsToMenu(desc.subColumns, subMenu); action->setMenu(subMenu); } menu->addAction(action); } } void TableViewTreeView::showHeaderContextMenu(QEvent* const event) { QContextMenuEvent* const e = static_cast(event); QHeaderView* const headerView = header(); d->headerContextMenuActiveColumn = headerView->logicalIndexAt(e->pos()); const TableViewColumn* const columnObject = s->tableViewModel->getColumnObject(d->headerContextMenuActiveColumn); QMenu* const menu = new QMenu(this); d->actionHeaderContextMenuRemoveColumn->setEnabled(s->tableViewModel->columnCount(QModelIndex())>1); menu->addAction(d->actionHeaderContextMenuRemoveColumn); const bool columnCanConfigure = columnObject->getColumnFlags().testFlag(TableViewColumn::ColumnHasConfigurationWidget); d->actionHeaderContextMenuConfigureColumn->setEnabled(columnCanConfigure); menu->addAction(d->actionHeaderContextMenuConfigureColumn); menu->addSeparator(); // add actions for all columns + QList columnDescriptions = s->columnFactory->getColumnDescriptionList(); addColumnDescriptionsToMenu(columnDescriptions, menu); menu->exec(e->globalPos()); } void TableViewTreeView::slotHeaderContextMenuAddColumn() { QAction* const triggeredAction = qobject_cast(sender()); const QVariant actionData = triggeredAction->data(); if (!actionData.canConvert()) { return; } const TableViewColumnDescription desc = actionData.value(); qCDebug(DIGIKAM_GENERAL_LOG) << "clicked: " << desc.columnTitle; const int newColumnLogicalIndex = d->headerContextMenuActiveColumn+1; s->tableViewModel->addColumnAt(desc, newColumnLogicalIndex); // since the header column order is not the same as the model's column order, we need // to make sure the new column is moved directly behind the current column in the header: + const int clickedVisualIndex = header()->visualIndex(d->headerContextMenuActiveColumn); const int newColumnVisualIndex = header()->visualIndex(newColumnLogicalIndex); int newColumnVisualTargetIndex = clickedVisualIndex + 1; // If the column is inserted before the clicked column, we have to // subtract one from the target index because it looks like QHeaderView first removes // the column and then inserts it. + if (newColumnVisualIndex < clickedVisualIndex) { newColumnVisualTargetIndex--; } if (newColumnVisualIndex!=newColumnVisualTargetIndex) { header()->moveSection(newColumnVisualIndex, newColumnVisualTargetIndex); } // Ensure that the newly created column is visible. // This is especially important if the new column is the last one, // because then it can be outside of the viewport. + const QModelIndex topIndex = indexAt(QPoint(0, 0)); const QModelIndex targetIndex = s->tableViewModel->index(topIndex.row(), newColumnLogicalIndex, topIndex.parent()); scrollTo(targetIndex, EnsureVisible); } void TableViewTreeView::slotHeaderContextMenuActionRemoveColumnTriggered() { qCDebug(DIGIKAM_GENERAL_LOG) << "remove column " << d->headerContextMenuActiveColumn; s->tableViewModel->removeColumnAt(d->headerContextMenuActiveColumn); } void TableViewTreeView::slotHeaderContextMenuConfigureColumn() { TableViewConfigurationDialog* const configurationDialog = new TableViewConfigurationDialog(s, d->headerContextMenuActiveColumn, this); const int result = configurationDialog->exec(); if (result!=QDialog::Accepted) { return; } - const TableViewColumnConfiguration newConfiguration = configurationDialog->getNewConfiguration(); + const TableViewColumnConfiguration newConfiguration = configurationDialog->getNewConfiguration(); s->tableViewModel->getColumnObject(d->headerContextMenuActiveColumn)->setConfiguration(newConfiguration); } AbstractItemDragDropHandler* TableViewTreeView::dragDropHandler() const { qCDebug(DIGIKAM_GENERAL_LOG)<imageModel->dragDropHandler(); + return s->imageModel->dragDropHandler(); } QModelIndex TableViewTreeView::mapIndexForDragDrop(const QModelIndex& index) const { // "index" is a TableViewModel index. // We are using the drag-drop-handler of ItemModel, thus // we have to convert it to an index of ItemModel. // map to ItemModel + const QModelIndex imageModelIndex = s->tableViewModel->toItemModelIndex(index); return imageModelIndex; } QPixmap TableViewTreeView::pixmapForDrag(const QList< QModelIndex >& indexes) const { const QModelIndex& firstIndex = indexes.at(0); - const ItemInfo info = s->tableViewModel->imageInfo(firstIndex); + const ItemInfo info = s->tableViewModel->imageInfo(firstIndex); const QString path = info.filePath(); QPixmap thumbnailPixmap; + /// @todo The first thumbnail load always fails. We have to add thumbnail pre-generation /// like in ItemModel. Getting thumbnails from ItemModel does not help, because it /// does not necessarily prepare them the same way. /// @todo Make a central drag-drop thumbnail generator? + if (!s->thumbnailLoadThread->find(info.thumbnailIdentifier(), thumbnailPixmap, d->dragDropThumbnailSize.size())) { /// @todo better default pixmap? + thumbnailPixmap.fill(); } /// @todo Decorate the pixmap like the other drag-drop implementations? /// @todo Write number of images onto the pixmap + return thumbnailPixmap; +/* + const QModelIndex& firstIndex = indexes.at(0); + const QModelIndex& imageModelIndex = s->sortModel->toItemModelIndex(firstIndex); + ItemModel* const imageModel = s->imageFilterModel->sourceItemModel(); -// const QModelIndex& firstIndex = indexes.at(0); -// const QModelIndex& imageModelIndex = s->sortModel->toItemModelIndex(firstIndex); -// ItemModel* const imageModel = s->imageFilterModel->sourceItemModel(); -// -// /// @todo Determine how other views choose the size -// const QSize thumbnailSize(60, 60); -// -// imageModel->setData(imageModelIndex, qMax(thumbnailSize.width(), thumbnailSize.height()), ItemModel::ThumbnailRole); -// QVariant thumbnailData = imageModel->data(imageModelIndex, ItemModel::ThumbnailRole); -// imageModel->setData(imageModelIndex, QVariant(), ItemModel::ThumbnailRole); -// -// QPixmap thumbnailPixmap = thumbnailData.value(); -// -// /// @todo Write number of images onto the pixmap -// return thumbnailPixmap; + /// @todo Determine how other views choose the size + + const QSize thumbnailSize(60, 60); + + imageModel->setData(imageModelIndex, qMax(thumbnailSize.width(), thumbnailSize.height()), ItemModel::ThumbnailRole); + QVariant thumbnailData = imageModel->data(imageModelIndex, ItemModel::ThumbnailRole); + imageModel->setData(imageModelIndex, QVariant(), ItemModel::ThumbnailRole); + + QPixmap thumbnailPixmap = thumbnailData.value(); + + /// @todo Write number of images onto the pixmap + + return thumbnailPixmap; +*/ } Album* TableViewTreeView::albumAt(const QPoint& pos) const { Q_UNUSED(pos) ItemAlbumModel* const albumModel = qobject_cast(s->imageModel); if (albumModel) { if (!(albumModel->currentAlbums().isEmpty())) + { return albumModel->currentAlbums().first(); + } } return nullptr; } void TableViewTreeView::wheelEvent(QWheelEvent* event) { if (event->modifiers() & Qt::ControlModifier) { const int delta = event->angleDelta().y(); if (delta > 0) { emit signalZoomInStep(); } else if (delta < 0) { emit signalZoomOutStep(); } event->accept(); + return; } QTreeView::wheelEvent(event); } bool TableViewTreeView::hasHiddenGroupedImages(const ItemInfo& info) const { - return (info.hasGroupedImages() - && (s->tableViewModel->groupingMode() == s->tableViewModel->GroupingMode::GroupingHideGrouped - || (s->tableViewModel->groupingMode() == s->tableViewModel->GroupingMode::GroupingShowSubItems - && !s->treeView->isExpanded(s->tableViewModel->indexFromImageId(info.id(), 0))))); + return ( + info.hasGroupedImages() && + ( + (s->tableViewModel->groupingMode() == s->tableViewModel->GroupingMode::GroupingHideGrouped) || + ((s->tableViewModel->groupingMode() == s->tableViewModel->GroupingMode::GroupingShowSubItems) && + (!s->treeView->isExpanded(s->tableViewModel->indexFromImageId(info.id(), 0))) + ) + ) + ); } void TableViewTreeView::slotModelGroupingModeChanged() { - setRootIsDecorated(s->tableViewModel->groupingMode()==TableViewModel::GroupingShowSubItems); + setRootIsDecorated(s->tableViewModel->groupingMode() == TableViewModel::GroupingShowSubItems); } } // namespace Digikam diff --git a/core/app/views/tableview/tableview_treeview.h b/core/app/views/tableview/tableview_treeview.h index 161761074b..89508979a8 100644 --- a/core/app/views/tableview/tableview_treeview.h +++ b/core/app/views/tableview/tableview_treeview.h @@ -1,104 +1,107 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2013-03-02 * Description : Table view: Tree view subelement * - * Copyright (C) 2013 by Michael G. Hansen + * Copyright (C) 2017-2020 by Gilles Caulier + * Copyright (C) 2013 by Michael G. Hansen * * 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_TABLE_VIEW_TREEVIEW_H #define DIGIKAM_TABLE_VIEW_TREEVIEW_H // Qt includes #include #include // Local includes #include "digikam_export.h" #include "dragdropimplementations.h" #include "itemalbummodel.h" #include "itemfiltermodel.h" #include "statesavingobject.h" #include "tableview_columnfactory.h" #include "tableview_shared.h" #include "thumbnailloadthread.h" #include "groupingviewimplementation.h" class QMenu; class QContextMenuEvent; namespace Digikam { -/// @todo For proper drag-and-drop support, we probably have to implement more -/// of DragDropModelImplementation's functions in the TableViewModel or -/// in the sort model. Subclassing DragDropModelImplementation would not -/// work there, because we want to re-use ItemDragDropHandler... +/** + * @todo For proper drag-and-drop support, we probably have to implement more + * of DragDropModelImplementation's functions in the TableViewModel or + * in the sort model. Subclassing DragDropModelImplementation would not + * work there, because we want to re-use ItemDragDropHandler. + */ class TableViewTreeView : public QTreeView, public DragDropViewImplementation, public GroupingViewImplementation { Q_OBJECT public: explicit TableViewTreeView(TableViewShared* const tableViewShared, QWidget* const parent = nullptr); virtual ~TableViewTreeView(); Album* albumAt(const QPoint& pos) const; protected: virtual bool eventFilter(QObject* watched, QEvent* event) override; DECLARE_VIEW_DRAG_DROP_METHODS(QTreeView) - virtual AbstractItemDragDropHandler* dragDropHandler() const override; - virtual QModelIndex mapIndexForDragDrop(const QModelIndex& index) const override; + virtual AbstractItemDragDropHandler* dragDropHandler() const override; + virtual QModelIndex mapIndexForDragDrop(const QModelIndex& index) const override; virtual QPixmap pixmapForDrag(const QList& indexes) const override; virtual void wheelEvent(QWheelEvent* event) override; - virtual bool hasHiddenGroupedImages(const ItemInfo& info) const override; + virtual bool hasHiddenGroupedImages(const ItemInfo& info) const override; private: void addColumnDescriptionsToMenu(const QList& columnDescriptions, QMenu* const menu); void showHeaderContextMenu(QEvent* const event); private Q_SLOTS: void slotHeaderContextMenuAddColumn(); void slotHeaderContextMenuConfigureColumn(); void slotHeaderContextMenuActionRemoveColumnTriggered(); void slotModelGroupingModeChanged(); Q_SIGNALS: void signalZoomInStep(); void signalZoomOutStep(); private: class Private; - const QScopedPointer d; - TableViewShared* const s; + const QScopedPointer d; + TableViewShared* const s; }; } // namespace Digikam #endif // DIGIKAM_TABLE_VIEW_TREEVIEW_H diff --git a/core/app/views/tableview/tableview_treeview_delegate.cpp b/core/app/views/tableview/tableview_treeview_delegate.cpp index 2ba462c8ef..e5e9e55112 100644 --- a/core/app/views/tableview/tableview_treeview_delegate.cpp +++ b/core/app/views/tableview/tableview_treeview_delegate.cpp @@ -1,134 +1,140 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2013-03-02 * Description : Table view: Tree view subelement * - * Copyright (C) 2013 by Michael G. Hansen + * Copyright (C) 2017-2020 by Gilles Caulier + * Copyright (C) 2013 by Michael G. Hansen * * 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 "tableview_treeview_delegate.h" // Qt includes #include // Local includes #include "digikam_debug.h" #include "contextmenuhelper.h" #include "coredbfields.h" #include "coredbwatch.h" #include "fileactionmngr.h" #include "iteminfo.h" #include "itemmodel.h" #include "itemposition.h" #include "importfiltermodel.h" #include "importimagemodel.h" #include "importui.h" #include "tableview_column_configuration_dialog.h" #include "tableview_columnfactory.h" #include "tableview_model.h" #include "tableview_selection_model_syncer.h" #include "thumbnailloadthread.h" namespace Digikam { TableViewItemDelegate::TableViewItemDelegate(TableViewShared* const tableViewShared, QObject* const parent) : QItemDelegate(parent), s(tableViewShared) { } TableViewItemDelegate::~TableViewItemDelegate() { } void TableViewItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& tableViewModelIndex) const { const int columnIndex = tableViewModelIndex.column(); const int columnCount = s->tableViewModel->columnCount(QModelIndex()); - if (columnIndex < 0 || columnIndex >= columnCount) + if ((columnIndex < 0) || (columnIndex >= columnCount)) { QItemDelegate::paint(painter, option, tableViewModelIndex); return; } TableViewColumn* const columnObject = s->tableViewModel->getColumnObject(columnIndex); bool useDefaultPainter = !columnObject->getColumnFlags().testFlag(TableViewColumn::ColumnCustomPainting); if (!useDefaultPainter) { TableViewModel::Item* const item = s->tableViewModel->itemFromIndex(tableViewModelIndex); useDefaultPainter = !columnObject->paint(painter, option, item); } if (useDefaultPainter) { QItemDelegate::paint(painter, option, tableViewModelIndex); } } QSize TableViewItemDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& tableViewModelIndex) const { const int columnIndex = tableViewModelIndex.column(); /// we have to take the maximum of all columns for the height /// @todo somehow cache this calculation /// @todo check column flags + const int columnCount = s->tableViewModel->columnCount(QModelIndex()); TableViewModel::Item* const item = s->tableViewModel->itemFromIndex(tableViewModelIndex); int maxHeight = 0; - if (columnIndex < 0 || columnIndex >= columnCount) + if ((columnIndex < 0) || (columnIndex >= columnCount)) { return QItemDelegate::sizeHint(option, tableViewModelIndex); } - for (int i = 0; i < columnCount ; ++i) + for (int i = 0 ; i < columnCount ; ++i) { TableViewColumn* const iColumnObject = s->tableViewModel->getColumnObject(i); if (iColumnObject && item) { const QSize iColumnSize = iColumnObject->sizeHint(option, item); if (iColumnSize.isValid()) { maxHeight = qMax(maxHeight, iColumnSize.height()); } } } QSize columnSize; TableViewColumn* const columnObject = s->tableViewModel->getColumnObject(columnIndex); if (columnObject && item) + { columnSize = columnObject->sizeHint(option, item); + } if (!columnSize.isValid()) { columnSize = QItemDelegate::sizeHint(option, tableViewModelIndex); + /// @todo we have to incorporate the height given by QItemDelegate for the other columns, too + maxHeight = qMax(maxHeight, columnSize.height()); } return QSize(columnSize.width(), maxHeight); } } // namespace Digikam diff --git a/core/app/views/tableview/tableview_treeview_delegate.h b/core/app/views/tableview/tableview_treeview_delegate.h index 3df2d28926..3da487a5fe 100644 --- a/core/app/views/tableview/tableview_treeview_delegate.h +++ b/core/app/views/tableview/tableview_treeview_delegate.h @@ -1,66 +1,67 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2013-03-02 * Description : Table view: Tree view subelement * - * Copyright (C) 2013 by Michael G. Hansen + * Copyright (C) 2017-2020 by Gilles Caulier + * Copyright (C) 2013 by Michael G. Hansen * * 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_TABLE_VIEW_TREEVIEW_DELEGATE_H #define DIGIKAM_TABLE_VIEW_TREEVIEW_DELEGATE_H // Qt includes #include #include // Local includes #include "digikam_export.h" #include "itemalbummodel.h" #include "itemfiltermodel.h" #include "statesavingobject.h" #include "tableview_columnfactory.h" #include "tableview_shared.h" #include "thumbnailloadthread.h" class QMenu; class QContextMenuEvent; namespace Digikam { class TableViewItemDelegate : public QItemDelegate { Q_OBJECT public: explicit TableViewItemDelegate(TableViewShared* const tableViewShared, QObject* const parent = nullptr); virtual ~TableViewItemDelegate(); virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& tableViewModelIndex) const; - virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& tableViewModelIndex) const; + virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& tableViewModelIndex) const; private: TableViewShared* const s; }; } // namespace Digikam #endif // DIGIKAM_TABLE_VIEW_TREEVIEW_DELEGATE_H