7676 readonly property real mediaListViewportHeight: mediaList .height
7777 readonly property real mediaDetailViewportWidth: mediaDetailFocus .width
7878 readonly property real mediaDetailViewportHeight: mediaDetailFocus .height
79+ readonly property bool mediaGridFocusRequested: mediaGrid .focus
80+ readonly property bool mediaListFocusRequested: mediaList .focus
81+ readonly property bool clearSelectionFocusRequested: clearSelectionButton .focus
7982 readonly property real responsiveLayoutWidth: testLayoutWidth > 0 ? testLayoutWidth : window .width
8083 readonly property real responsiveLayoutHeight: testLayoutHeight > 0 ? testLayoutHeight : window .height
8184 readonly property bool compactLayout: responsiveLayoutWidth < 900
9699 readonly property real primaryImportActionHeight: primaryImportActionBar .height
97100 readonly property bool primaryImportActionVisible: primaryImportActionBar .visible
98101 readonly property bool emptySourceStateVisible: photoDockEmptyStateCard .visible
102+ readonly property bool clearSelectionInKeyboardChain:
103+ individualFilesCheck .KeyNavigation .tab === clearSelectionButton
104+ && clearSelectionButton .KeyNavigation .backtab === individualFilesCheck
99105
100106 function mediaGridDelegateAt (index ) {
101107 return mediaGrid .itemAtIndex (index)
@@ -494,6 +500,19 @@ Item {
494500 })
495501 }
496502
503+ function showMediaBrowseMode (mode ) {
504+ if (mode !== " grid" && mode !== " list" ) return
505+ mediaBrowseMode = mode
506+ Qt .callLater (function () {
507+ if (mode === " grid" ) mediaGrid .forceActiveFocus (Qt .TabFocusReason )
508+ else mediaList .forceActiveFocus (Qt .TabFocusReason )
509+ })
510+ }
511+
512+ function focusClearSelectionForTesting () {
513+ if (clearSelectionButton .visible ) clearSelectionButton .forceActiveFocus (Qt .TabFocusReason )
514+ }
515+
497516 function metadataRows () {
498517 if (! inspectedMedia || ! inspectedMedia .metadata ) return []
499518 var values = inspectedMedia .metadata
@@ -703,7 +722,7 @@ Item {
703722 anchors .fill : parent
704723 anchors .margins : 10
705724 text: root .effectiveService && root .effectiveService .snapshot ? root .effectiveService .snapshot .safetyStatement
706- : " Your source stays untouched. PhotoDock never deletes, renames, edits, or formats files on camera media ."
725+ : " Your source stays untouched. PhotoDock never deletes, renames, edits, or formats source files ."
707726 color: Color .foreground
708727 wrapMode: Text .WordWrap
709728 }
@@ -717,6 +736,10 @@ Item {
717736 color: Qt .rgba (Color .urgent .r , Color .urgent .g , Color .urgent .b , 0.10 )
718737 border .width : 1
719738 border .color : Qt .rgba (Color .urgent .r , Color .urgent .g , Color .urgent .b , 0.25 )
739+ Accessible .role : Accessible .AlertMessage
740+ Accessible .name : root .errorText || (root .effectiveService && root .effectiveService .lastError
741+ ? (root .effectiveService .lastError .message || root .effectiveService .lastError .code )
742+ : " " )
720743 RowLayout {
721744 id: errorRow
722745 anchors .fill : parent
@@ -748,6 +771,8 @@ Item {
748771 color: Color .muted
749772 font .pixelSize : 11
750773 wrapMode: Text .WordWrap
774+ Accessible .role : Accessible .AlertMessage
775+ Accessible .name : root .notice
751776 }
752777
753778 Controls .ScrollView {
@@ -788,7 +813,7 @@ Item {
788813 }
789814 Text {
790815 Layout .fillWidth : true
791- text: " Choose a photo folder, or insert an SD card, CFexpress card, supported USB mass-storage camera, or card reader. Browse photos before deciding what to import ."
816+ text: " Choose a mounted photo folder or removable camera source that Omarchy has already mounted. PhotoDock does not mount or eject media in this alpha ."
792817 color: Color .muted
793818 wrapMode: Text .WordWrap
794819 }
@@ -937,7 +962,7 @@ Item {
937962 checked: root .mediaBrowseMode === " grid"
938963 KeyNavigation .tab : listModeButton
939964 KeyNavigation .backtab : forgetFolderButton .visible ? forgetFolderButton : addFolderButton
940- onClicked: root .mediaBrowseMode = " grid"
965+ onClicked: root .showMediaBrowseMode ( " grid" )
941966 Accessible .name : " Show media as a thumbnail grid"
942967 }
943968 Controls .Button {
@@ -947,15 +972,16 @@ Item {
947972 checked: root .mediaBrowseMode === " list"
948973 KeyNavigation .tab : individualFilesCheck
949974 KeyNavigation .backtab : gridModeButton
950- onClicked: root .mediaBrowseMode = " list"
975+ onClicked: root .showMediaBrowseMode ( " list" )
951976 Accessible .name : " Show media as a compact list"
952977 }
953978 Controls .CheckBox {
954979 id: individualFilesCheck
955980 text: " Choose individual files"
956981 checked: root .limitToSelectedFiles
957982 enabled: root .inventoryTotal > 0 && ! root .activeJob
958- KeyNavigation .tab : previousPageButton .enabled ? previousPageButton
983+ KeyNavigation .tab : clearSelectionButton .visible ? clearSelectionButton
984+ : previousPageButton .enabled ? previousPageButton
959985 : nextPageButton .enabled ? nextPageButton : continueImportButton
960986 KeyNavigation .backtab : listModeButton
961987 onToggled: {
@@ -976,9 +1002,13 @@ Item {
9761002 font .pixelSize : 11
9771003 }
9781004 Controls .Button {
1005+ id: clearSelectionButton
9791006 text: " Clear"
9801007 visible: root .selectedFileIds .length > 0
9811008 enabled: ! root .activeJob
1009+ KeyNavigation .tab : previousPageButton .enabled ? previousPageButton
1010+ : nextPageButton .enabled ? nextPageButton : continueImportButton
1011+ KeyNavigation .backtab : individualFilesCheck
9821012 onClicked: root .clearFileSelection ()
9831013 Accessible .name : " Clear selected files"
9841014 }
@@ -992,7 +1022,8 @@ Item {
9921022 text: " ‹ Previous"
9931023 enabled: root .inventoryOffset > 0 && ! root .inventoryBusy
9941024 KeyNavigation .tab : nextPageButton .enabled ? nextPageButton : continueImportButton
995- KeyNavigation .backtab : individualFilesCheck
1025+ KeyNavigation .backtab : clearSelectionButton .visible
1026+ ? clearSelectionButton : individualFilesCheck
9961027 onClicked: root .loadInventory (Math .max (0 , root .inventoryOffset - root .inventoryPageSize ))
9971028 Accessible .name : " Previous media page"
9981029 }
@@ -1001,7 +1032,8 @@ Item {
10011032 text: " Next ›"
10021033 enabled: root .inventoryHasMore && ! root .inventoryBusy
10031034 KeyNavigation .tab : continueImportButton
1004- KeyNavigation .backtab : previousPageButton .enabled ? previousPageButton : individualFilesCheck
1035+ KeyNavigation .backtab : previousPageButton .enabled ? previousPageButton
1036+ : clearSelectionButton .visible ? clearSelectionButton : individualFilesCheck
10051037 onClicked: root .loadInventory (root .inventoryOffset + root .inventoryPageSize )
10061038 Accessible .name : " Next media page"
10071039 }
@@ -1012,7 +1044,8 @@ Item {
10121044 enabled: root .inventoryTotal > 0
10131045 KeyNavigation .tab : root .mediaBrowseMode === " grid" ? mediaGrid : mediaList
10141046 KeyNavigation .backtab : nextPageButton .enabled ? nextPageButton
1015- : previousPageButton .enabled ? previousPageButton : individualFilesCheck
1047+ : previousPageButton .enabled ? previousPageButton
1048+ : clearSelectionButton .visible ? clearSelectionButton : individualFilesCheck
10161049 onClicked: {
10171050 root .revealWorkflowItem (importDetailsHeader)
10181051 shootNameField .forceActiveFocus ()
@@ -1104,7 +1137,7 @@ Item {
11041137 keyNavigationWraps: false
11051138 activeFocusOnTab: true
11061139 Accessible .role : Accessible .List
1107- Accessible .name : " Media thumbnail grid; arrow keys move, Shift plus arrow selects a range, Enter opens, Space toggles selection, Control- click toggles, and Shift- click selects a range"
1140+ Accessible .name : " Media thumbnail grid; arrow keys move, Shift plus arrow selects a range, Enter opens, Space toggles selection, Control or Command click toggles, Shift click selects a range, and Control or Command plus Shift click adds a range"
11081141 KeyNavigation .tab : shootNameField
11091142 KeyNavigation .backtab : continueImportButton
11101143 Keys .priority : Keys .BeforeItem
@@ -1162,7 +1195,7 @@ Item {
11621195 highlighted: root .isFileSelected (mediaTile .modelData .fileId )
11631196 onClicked: root .activateMediaItem (mediaTile .index , Qt .NoModifier )
11641197 Accessible .name : " Open " + mediaTile .modelData .fileName
1165- Accessible .description : " Control- click toggles this file; Shift- click selects a range"
1198+ Accessible .description : " Control or Command click toggles this file; Shift click selects a range; Control or Command plus Shift click adds a range"
11661199 contentItem: ColumnLayout {
11671200 spacing: 4
11681201 Rectangle {
@@ -1282,6 +1315,8 @@ Item {
12821315 spacing: 2
12831316 model: root .inventoryItems
12841317 activeFocusOnTab: true
1318+ Accessible .role : Accessible .List
1319+ Accessible .name : " Media list; Up and Down arrows move, Shift plus arrow selects a range, Enter opens, Space toggles selection, Control or Command click toggles, Shift click selects a range, and Control or Command plus Shift click adds a range"
12851320 KeyNavigation .tab : shootNameField
12861321 KeyNavigation .backtab : continueImportButton
12871322 Keys .priority : Keys .BeforeItem
@@ -1370,7 +1405,7 @@ Item {
13701405 event .accepted = true
13711406 }
13721407 Accessible .name : " Open " + mediaRow .modelData .fileName + " ; press Space to select it"
1373- Accessible .description : " Control- click toggles this file; Shift- click selects a range"
1408+ Accessible .description : " Control or Command click toggles this file; Shift click selects a range; Control or Command plus Shift click adds a range"
13741409 contentItem: Column {
13751410 spacing: 2
13761411 Text { width: parent .width ; text: mediaRow .modelData .fileName ; color: Color .foreground ; elide: Text .ElideMiddle }
@@ -1633,7 +1668,7 @@ Item {
16331668 visible: root .lastOutcome !== null && root .activeJob === null
16341669 Text { text: " LAST OUTCOME" ; color: Color .muted ; font .pixelSize : 11 ; font .weight : Font .DemiBold }
16351670 Text { Layout .fillWidth : true ; text: root .lastOutcome ? root .lastOutcome .summary : " " ; color: Color .foreground ; wrapMode: Text .WordWrap }
1636- Text { Layout .fillWidth : true ; text: root .lastOutcome ? " Primary: " + root .lastOutcome .primary + " · Verification: " + root .lastOutcome .verification + " · Backup: " + root .lastOutcome .backup + " · Eject: " + root . lastOutcome . eject : " " ; color: Color .muted ; wrapMode: Text .WordWrap }
1671+ Text { Layout .fillWidth : true ; text: root .lastOutcome ? " Primary: " + root .lastOutcome .primary + " · Verification: " + root .lastOutcome .verification + " · Backup: " + root .lastOutcome .backup : " " ; color: Color .muted ; wrapMode: Text .WordWrap }
16371672 }
16381673 }
16391674 }
@@ -1684,8 +1719,10 @@ Item {
16841719 highlighted: true
16851720 enabled: root .effectiveService && ! root .activeJob && ! root .planBusy
16861721 onClicked: root .primaryImportAction ()
1687- Accessible .name : root .reviewedPlanReady
1688- ? " Start the reviewed import plan" : " Review settings and prepare to start import"
1722+ Accessible .name : root .activeJob ? " Import in progress"
1723+ : root .planBusy ? " Checking import settings"
1724+ : root .reviewedPlanReady ? " Start the reviewed import plan"
1725+ : " Review settings and prepare to start import"
16891726 Accessible .description : root .primaryImportActionHint
16901727 }
16911728 }
0 commit comments