diff --git a/App/App_macOS.swift b/App/App_macOS.swift index 531286e4..5fea89cc 100644 --- a/App/App_macOS.swift +++ b/App/App_macOS.swift @@ -37,6 +37,7 @@ struct Kiwix: App { @State private var selectedAmount: SelectedAmount? @StateObject var formReset = FormReset() @FocusState private var isSearchFocused: Bool + @FocusedValue(\.browserURL) var browserURL init() { UNUserNotificationCenter.current().delegate = notificationCenterDelegate @@ -78,6 +79,16 @@ struct Kiwix: App { SidebarNavigationCommands() Divider() } + CommandGroup(after: .pasteboard) { + Button(LocalString.library_zim_file_context_copy_url) { + if let browserURL { + CopyPasteMenu.copyToPasteBoard(url: browserURL) + } + } + .disabled(browserURL == nil) + .keyboardShortcut("c", modifiers: [.command, .shift]) + + } CommandGroup(after: .textEditing) { Button(LocalString.common_search) { isSearchFocused = true diff --git a/Support/en.lproj/Localizable.strings b/Support/en.lproj/Localizable.strings index a4c3f5c2..6f47b159 100644 --- a/Support/en.lproj/Localizable.strings +++ b/Support/en.lproj/Localizable.strings @@ -39,6 +39,7 @@ "common.button.no" = "no"; "common.button.print" = "Print"; "common.button.share" = "Share"; +"common.button.share_as_pdf" = "Share as PDF"; "common.search" = "Search"; "common.tab.manager.title" = "Tabs Manager"; diff --git a/Support/qqq.lproj/Localizable.strings b/Support/qqq.lproj/Localizable.strings index 9cc6b82d..75e0091c 100644 --- a/Support/qqq.lproj/Localizable.strings +++ b/Support/qqq.lproj/Localizable.strings @@ -23,6 +23,7 @@ "common.button.no" = "It is a title in the summary table on macOS: we list the attributes of a ZIM file: does it contain pictures yes/no, does it contain Videos yes/no, Details? yes/no"; "common.button.print" = "Accessibility label for button to print the currently loaded article"; "common.button.share" = "Accessibility label for share button, to share the currently loaded article with an external app."; +"common.button.share_as_pdf" = "Accesibility label for share button. to share the curretly loadded article with an external application in a PDF file format."; "common.search" = "The default placeholder text for searchbars, when the search input field is empty"; "common.tab.manager.title" = "Accessibility label for button tab bar button that opens an overlay menu."; "common.tab.navigation.title" = "On iPad it is a title in the sidemenu grouping tabs related buttons"; diff --git a/Views/BrowserTab.swift b/Views/BrowserTab.swift index b6fbf29e..960bf45e 100644 --- a/Views/BrowserTab.swift +++ b/Views/BrowserTab.swift @@ -44,11 +44,6 @@ struct BrowserTab: View { goForward: { [weak browser] in browser?.webView.goForward() }) - if let url = browser.url { - CopyPasteMenu(url: url) - .keyboardShortcut("c", modifiers: [.command, .shift]) - - } } #elseif os(iOS) ToolbarItemGroup(placement: .navigationBarLeading) { @@ -82,12 +77,21 @@ struct BrowserTab: View { } #else if !Brand.hideShareButton { - ExportButton( - relativeToView: browser.webView, - webViewURL: browser.webView.url, - pageDataWithExtension: { [weak browser] in await browser?.pageDataWithExtension() }, - isButtonDisabled: browser.zimFileName.isEmpty - ) + Menu { + if let url = browser.webView.url { + CopyPasteMenu(url: url) + .keyboardShortcut("c", modifiers: [.command, .shift]) + } + ExportButton( + relativeToView: browser.webView, + webViewURL: browser.webView.url, + pageDataWithExtension: { [weak browser] in await browser?.pageDataWithExtension() }, + isButtonDisabled: browser.zimFileName.isEmpty, + buttonLabel: LocalString.common_button_share_as_pdf + ) + } label: { + Label(LocalString.common_button_share, systemImage: "square.and.arrow.up") + }.disabled(browser.webView.url == nil) } if !Brand.hidePrintButton { PrintButton(browserURLName: { [weak browser] in @@ -117,6 +121,9 @@ struct BrowserTab: View { } .environmentObject(search) .focusedSceneValue(\.isBrowserURLSet, browser.url != nil) + #if os(macOS) + .focusedSceneValue(\.browserURL, browser.url) + #endif .focusedSceneValue(\.canGoBack, browser.canGoBack) .focusedSceneValue(\.canGoForward, browser.canGoForward) .modifier(ExternalLinkHandler(externalURL: $browser.externalURL)) diff --git a/Views/BuildingBlocks/CopyPasteMenu.swift b/Views/BuildingBlocks/CopyPasteMenu.swift index 57185294..5a27f65a 100644 --- a/Views/BuildingBlocks/CopyPasteMenu.swift +++ b/Views/BuildingBlocks/CopyPasteMenu.swift @@ -23,8 +23,7 @@ struct CopyPasteMenu: View { var body: some View { Button { #if os(macOS) - NSPasteboard.general.clearContents() - NSPasteboard.general.setString(url.absoluteString, forType: .string) + Self.copyToPasteBoard(url: url) #elseif os(iOS) UIPasteboard.general.setValue(url.absoluteString, forPasteboardType: UTType.url.identifier) #endif @@ -32,4 +31,11 @@ struct CopyPasteMenu: View { Label(LocalString.library_zim_file_context_copy_url, systemImage: "doc.on.doc") } } + + #if os(macOS) + public static func copyToPasteBoard(url: URL) { + NSPasteboard.general.clearContents() + NSPasteboard.general.setString(url.absoluteString, forType: .string) + } + #endif } diff --git a/Views/Buttons/ExportButton.swift b/Views/Buttons/ExportButton.swift index 91d4821a..b383dfc2 100644 --- a/Views/Buttons/ExportButton.swift +++ b/Views/Buttons/ExportButton.swift @@ -23,6 +23,8 @@ struct ExportButton: View { let webViewURL: URL? let pageDataWithExtension: () async -> (Data, String?)? let isButtonDisabled: Bool + + var buttonLabel: String = LocalString.common_button_share /// - Returns: Returns the browser data, fileName and extension private func dataNameAndExtension() async -> FileExportData? { @@ -48,12 +50,22 @@ struct ExportButton: View { NotificationCenter.exportFileData(exportData) #else guard let url = await tempFileURL() else { return } - NSSharingServicePicker(items: [url]).show(relativeTo: .null, of: relativeToView, preferredEdge: .minY) + NSSharingServicePicker(items: [url]).show( + relativeTo: NSRect( + origin: .zero, + size: CGSize( + width: 640, + height: 54 + ) + ), + of: relativeToView, + preferredEdge: .minY + ) #endif } } label: { Label { - Text(LocalString.common_button_share) + Text(buttonLabel) } icon: { Image(systemName: "square.and.arrow.up") } diff --git a/Views/Commands.swift b/Views/Commands.swift index 262bbaee..8ddbd1f1 100644 --- a/Views/Commands.swift +++ b/Views/Commands.swift @@ -25,6 +25,10 @@ struct IsBrowserURLSet: FocusedValueKey { typealias Value = Bool } +struct BrowserURL: FocusedValueKey { + typealias Value = URL +} + struct CanGoBackKey: FocusedValueKey { typealias Value = Bool } @@ -38,6 +42,12 @@ struct NavigationItemKey: FocusedValueKey { } extension FocusedValues { + #if os(macOS) + var browserURL: BrowserURL.Value? { + get { self[BrowserURL.self] } + set { self[BrowserURL.self] = newValue} + } + #endif var isBrowserURLSet: IsBrowserURLSet.Value? { get { self[IsBrowserURLSet.self] } set { self[IsBrowserURLSet.self] = newValue }