[app] Made colors configurable

This commit is contained in:
Slava Monich 2022-10-10 03:45:18 +03:00
parent 4286bb0145
commit 2a64b91cde
47 changed files with 3506 additions and 937 deletions

View file

@ -55,13 +55,16 @@ OTHER_FILES += \
qml/*.qml \
qml/*.js \
qml/images/* \
settings/*.qml \
settings/*.json \
settings/Books*.qml \
settings/images/* \
data/default/* \
data/zlibrary/core/encodings/* \
data/zlibrary/core/resources/*
app_settings {
OTHER_FILES += settings/SystemSettings.qml
}
TARGET_DATA_DIR = /usr/share/$$TARGET
TARGET_DEFAULT_DATA_DIR = $$TARGET_DATA_DIR/data
TARGET_ZLIBRARY_DATA_DIR = $$TARGET_DEFAULT_DATA_DIR
@ -107,6 +110,8 @@ INCLUDEPATH += \
SOURCES += \
src/BooksBook.cpp \
src/BooksBookModel.cpp \
src/BooksColorScheme.cpp \
src/BooksColorSchemeModel.cpp \
src/BooksConfig.cpp \
src/BooksCoverModel.cpp \
src/BooksCoverWidget.cpp \
@ -123,6 +128,7 @@ SOURCES += \
src/BooksPos.cpp \
src/BooksSaveTimer.cpp \
src/BooksSettings.cpp \
src/BooksSettingsBase.cpp \
src/BooksShelf.cpp \
src/BooksStorage.cpp \
src/BooksStorageModel.cpp \
@ -137,6 +143,8 @@ SOURCES += \
HEADERS += \
src/BooksBook.h \
src/BooksBookModel.h \
src/BooksColorScheme.h \
src/BooksColorSchemeModel.h \
src/BooksConfig.h \
src/BooksCoverModel.h \
src/BooksCoverWidget.h \
@ -155,6 +163,7 @@ HEADERS += \
src/BooksPos.h \
src/BooksSaveTimer.h \
src/BooksSettings.h \
src/BooksSettingsBase.h \
src/BooksShelf.h \
src/BooksStorage.h \
src/BooksStorageModel.h \
@ -184,6 +193,7 @@ openrepos {
# harbour-lib
HEADERS += \
$$HARBOUR_INCLUDE_DIR/HarbourColorEditorModel.h \
$$HARBOUR_INCLUDE_DIR/HarbourDisplayBlanking.h \
$$HARBOUR_INCLUDE_DIR/HarbourJson.h \
$$HARBOUR_INCLUDE_DIR/HarbourMediaPlugin.h \
@ -191,12 +201,13 @@ HEADERS += \
$$HARBOUR_INCLUDE_DIR/HarbourPolicyPlugin.h \
$$HARBOUR_INCLUDE_DIR/HarbourSystem.h \
$$HARBOUR_INCLUDE_DIR/HarbourTask.h \
$$HARBOUR_INCLUDE_DIR/HarbourTheme.h
$$HARBOUR_INCLUDE_DIR/HarbourUtil.h
HEADERS += \
$$HARBOUR_SRC_DIR/HarbourMce.h
SOURCES += \
$$HARBOUR_SRC_DIR/HarbourColorEditorModel.cpp \
$$HARBOUR_SRC_DIR/HarbourDisplayBlanking.cpp \
$$HARBOUR_SRC_DIR/HarbourJson.cpp \
$$HARBOUR_SRC_DIR/HarbourMce.cpp \
@ -205,13 +216,16 @@ SOURCES += \
$$HARBOUR_SRC_DIR/HarbourPolicyPlugin.cpp \
$$HARBOUR_SRC_DIR/HarbourSystem.cpp \
$$HARBOUR_SRC_DIR/HarbourTask.cpp \
$$HARBOUR_SRC_DIR/HarbourTheme.cpp
$$HARBOUR_SRC_DIR/HarbourUtil.cpp
HARBOUR_QML_COMPONENTS = \
$$HARBOUR_LIB_QML/HarbourFitLabel.qml \
$$HARBOUR_LIB_QML/HarbourHighlightIcon.qml \
$$HARBOUR_LIB_QML/HarbourHorizontalSwipeHint.qml \
$$HARBOUR_LIB_QML/HarbourPressEffect.qml
$$HARBOUR_LIB_QML/HarbourColorEditorDialog.qml \
$$HARBOUR_LIB_QML/HarbourColorHueItem.qml \
$$HARBOUR_LIB_QML/HarbourColorPickerDialog.qml \
$$HARBOUR_LIB_QML/HarbourFitLabel.qml \
$$HARBOUR_LIB_QML/HarbourHighlightIcon.qml \
$$HARBOUR_LIB_QML/HarbourHorizontalSwipeHint.qml \
$$HARBOUR_LIB_QML/HarbourPressEffect.qml
OTHER_FILES += $${HARBOUR_QML_COMPONENTS}
@ -233,17 +247,6 @@ for(s, ICON_SIZES) {
INSTALLS += $${icon_target}
}
# Settings
app_settings {
settings_json.files = settings/$${TARGET}.json
settings_json.path = /usr/share/jolla-settings/entries/
equals(PREFIX, "openrepos") {
settings_json.extra = sed s/harbour/openrepos/g settings/harbour-$${NAME}.json > $$eval(settings_json.files)
settings_json.CONFIG += no_check_exist
}
INSTALLS += settings_json
}
settings_qml.files = settings/*.qml
settings_qml.path = /usr/share/$${TARGET}/settings/
INSTALLS += settings_qml
@ -262,6 +265,7 @@ openrepos {
# Translations
TRANSLATION_IDBASED=-idbased
TRANSLATION_SOURCES = \
$${_PRO_FILE_PWD_}/src \
$${_PRO_FILE_PWD_}/qml \
$${_PRO_FILE_PWD_}/settings

View file

@ -1,6 +1,6 @@
/*
Copyright (C) 2015-2021 Jolla Ltd.
Copyright (C) 2015-2021 Slava Monich <slava.monich@jolla.com>
Copyright (C) 2015-2022 Jolla Ltd.
Copyright (C) 2015-2022 Slava Monich <slava.monich@jolla.com>
You may use this file under the terms of BSD license as follows:
@ -218,7 +218,7 @@ Item {
Rectangle {
id: loadingBackground
anchors.fill: parent
color: HarbourTheme.invertedPrimaryColor
color: HarbourUtil.invertedColor(Theme.primaryColor)
visible: loading && opacity > 0
}

View file

@ -1,6 +1,6 @@
/*
Copyright (C) 2015-2020 Jolla Ltd.
Copyright (C) 2015-2020 Slava Monich <slava.monich@jolla.com>
Copyright (C) 2015-2021 Jolla Ltd.
Copyright (C) 2015-2021 Slava Monich <slava.monich@jolla.com>
You may use this file under the terms of BSD license as follows:
@ -72,7 +72,7 @@ Rectangle {
Connections {
target: Settings
onInvertColorsChanged: cancel()
onNightModeChanged: cancel()
}
MouseArea {

View file

@ -1,6 +1,6 @@
/*
Copyright (C) 2015-2020 Jolla Ltd.
Copyright (C) 2015-2020 Slava Monich <slava.monich@jolla.com>
Copyright (C) 2015-2021 Jolla Ltd.
Copyright (C) 2015-2021 Slava Monich <slava.monich@jolla.com>
You may use this file under the terms of BSD license as follows:
@ -58,6 +58,12 @@ ApplicationWindow {
Settings.keepDisplayOn
}
Binding {
target: Settings
property: "theme"
value: Theme
}
initialPage: BooksMainPage { id: mainPage }
cover: Component {

View file

@ -1,6 +1,6 @@
/*
Copyright (C) 2015-2021 Jolla Ltd.
Copyright (C) 2015-2021 Slava Monich <slava.monich@jolla.com>
Copyright (C) 2015-2022 Jolla Ltd.
Copyright (C) 2015-2022 Slava Monich <slava.monich@jolla.com>
You may use this file under the terms of BSD license as follows:
@ -124,7 +124,7 @@ Page {
isCurrentView: currentView === bookView
pageActive: page.pageActive
book: Settings.currentBook ? Settings.currentBook : null
loadingBackgroundOpacity: HarbourTheme.opacityOverlay * storageView.opacity
loadingBackgroundOpacity: 0.8 /* opacityOverlay */ * storageView.opacity
onCloseBook: Settings.currentBook = null
onVisibleChanged: if (visible) opacity = 1

View file

@ -1,6 +1,6 @@
/*
Copyright (C) 2015-2019 Jolla Ltd.
Copyright (C) 2015-2019 Slava Monich <slava.monich@jolla.com>
Copyright (C) 2015-2021 Jolla Ltd.
Copyright (C) 2015-2021 Slava Monich <slava.monich@jolla.com>
You may use this file under the terms of BSD license as follows:
@ -57,7 +57,7 @@ Item {
left: parent.left
verticalCenter: parent.verticalCenter
}
onClicked: Settings.invertColors = !Settings.invertColors
onClicked: Settings.nightMode = !Settings.nightMode
Image {
id: dayModeImage
@ -68,7 +68,7 @@ Item {
verticalCenter: parent.verticalCenter
}
sourceSize.height: Theme.iconSizeSmall
opacity: Settings.invertColors ? 0.5 : 0
opacity: Settings.nightMode ? 0.5 : 0
visible: opacity > 0
Behavior on opacity { FadeAnimation {} }
}
@ -77,7 +77,7 @@ Item {
source: "images/night-mode.svg"
anchors.centerIn: dayModeImage
sourceSize.height: Theme.iconSizeSmall
opacity: Settings.invertColors ? 0 : 0.25
opacity: Settings.nightMode ? 0 : 0.25
visible: opacity > 0
Behavior on opacity { FadeAnimation {} }
}
@ -101,7 +101,7 @@ Item {
verticalCenter: parent.verticalCenter
}
sourceSize.height: Theme.iconSizeSmall
opacity: Settings.invertColors ? 1 : 0.5
opacity: Settings.nightMode ? 1 : 0.5
Behavior on opacity { FadeAnimation {} }
}
onClicked: pageTools.increaseFontSize()
@ -123,7 +123,7 @@ Item {
verticalCenter: parent.verticalCenter
}
sourceSize.height: increaseFontSizeButtonImage.height
opacity: Settings.invertColors ? 1 : 0.5
opacity: Settings.nightMode ? 1 : 0.5
Behavior on opacity { FadeAnimation {} }
}
onClicked: pageTools.decreaseFontSize()

View file

@ -1,6 +1,6 @@
/*
Copyright (C) 2015-2020 Jolla Ltd.
Copyright (C) 2015-2020 Slava Monich <slava.monich@jolla.com>
Copyright (C) 2015-2021 Jolla Ltd.
Copyright (C) 2015-2021 Slava Monich <slava.monich@jolla.com>
You may use this file under the terms of BSD license as follows:
@ -109,7 +109,7 @@ Rectangle {
Image {
id: pressImage
source: Settings.invertColors ? "images/press-invert.svg" : "images/press.svg"
source: Settings.nightMode ? "images/press-invert.svg" : "images/press.svg"
visible: opacity > 0
opacity: 0
readonly property int maxsize: Math.max(view.width, view.height)

View file

@ -1,6 +1,6 @@
/*
Copyright (C) 2015-2021 Jolla Ltd.
Copyright (C) 2015-2021 Slava Monich <slava.monich@jolla.com>
Copyright (C) 2015-2022 Jolla Ltd.
Copyright (C) 2015-2022 Slava Monich <slava.monich@jolla.com>
You may use this file under the terms of BSD license as follows:
@ -113,7 +113,7 @@ Item {
pageStack.push(_settingsComponent, {
"title" : text,
"allowedOrientations": window.allowedOrientations,
"inApp": true
"inApp": true,
})
}
}

View file

@ -1,6 +1,6 @@
/*
Copyright (C) 2015-2021 Jolla Ltd.
Copyright (C) 2015-2021 Slava Monich <slava.monich@jolla.com>
Copyright (C) 2015-2022 Jolla Ltd.
Copyright (C) 2015-2022 Slava Monich <slava.monich@jolla.com>
You may use this file under the terms of BSD license as follows:
@ -32,530 +32,18 @@
*/
import QtQuick 2.0
import Sailfish.Silica 1.0
import org.nemomobile.configuration 1.0
import harbour.books 1.0
import "../qml/Books.js" as Books
import "../qml/harbour"
Page {
id: page
property bool inApp
property alias title: pageHeader.title
readonly property string rootPath: "/apps/" + appName() + "/"
readonly property bool darkOnLight: ('colorScheme' in Theme) && Theme.colorScheme === 1
readonly property int screenWidth: isPortrait ? Screen.width : Screen.height
readonly property int screenHeight: isPortrait ? Screen.height : Screen.width
readonly property bool landscapeLayout: (screenWidth > screenHeight && Screen.sizeCategory > Screen.Small) || Screen.sizeCategory > Screen.Medium
// jolla-settings expects these properties:
property var applicationName
property var applicationIcon
// Deduce package name from the path
function appName() {
var parts = Qt.resolvedUrl("dummy").split('/')
if (parts.length > 2) {
var name = parts[parts.length-3]
if (name.indexOf("-books") >= 0) {
return name
}
}
return "harbour-books"
// In-app settings
BooksSettingsBase {
inApp: true
colorSchemeModel: BooksColorSchemeModel {
Component.onCompleted: colorScheme = Settings.customColorScheme
onColorSchemeChanged: Settings.customColorScheme = colorScheme
}
Loader {
active: inApp // Follow orientation changes
Connections {
target: orientation
onValueChanged: allowedOrientations =
(orientation.value === 1) ? Orientation.Portrait :
(orientation.value === 2) ? Orientation.Landscape :
Orientation.All
}
}
SilicaFlickable {
anchors.fill: parent
contentHeight: content.height
// Night mode example (positioned right above the slider)
Rectangle {
opacity: nightModeBrightnessSlider.pressed ? 1.0 : 0
visible: opacity > 0
radius: Theme.paddingSmall
width: nightModeExampleLabel.width + 2 * Theme.paddingLarge
height: nightModeExampleLabel.height + 2 * Theme.paddingMedium
readonly property int xMin: nightModeBrightnessSlider.leftMargin
readonly property int xMax: content.width - nightModeBrightnessSlider.rightMargin - width
readonly property int yOffset: landscapeLayout ? (Theme.itemSizeExtraLarge - Theme.itemSizeMedium) : 0
x: content.x + displayGrid.x + Math.max(Math.min(nightModeBrightnessSlider.sliderLeft + Math.round(nightModeBrightnessSlider.sliderThumbX - width/2.0), xMax), xMin)
y: content.y + displayGrid.y + nightModeBrightnessSlider.y + yOffset - height
z: nightModeBrightnessSlider.z + 1
color: "black"
border {
color: Theme.highlightColor
width: Math.ceil(radius/5)
}
Label {
id: nightModeExampleLabel
anchors.centerIn: parent
color: "white"
opacity: Books.contentOpacity(nightModeBrightness.value)
//: Night mode example label
//% "Night mode"
text: qsTrId("harbour-books-settings-page-night_mode_example")
font {
bold: true
pixelSize: Theme.fontSizeLarge
family: "Times"
}
}
Behavior on x { SmoothedAnimation { duration: 125 } }
Behavior on opacity { FadeAnimation { duration: 500 } }
}
Column {
id: content
width: parent.width
PageHeader {
id: pageHeader
rightMargin: Theme.horizontalPageMargin + (appIcon.visible ? (height - appIcon.padding) : 0)
title: applicationName ? applicationName :
//: Settings page header (app name)
//% "Books"
qsTrId("harbour-books-settings-page-header")
description: inApp ? "" :
//: Settings page header description (app version)
//% "Version %1"
qsTrId("harbour-books-settings-version").arg(Books.version)
Image {
id: appIcon
readonly property int padding: Theme.paddingLarge
readonly property int size: pageHeader.height - 2 * padding
x: pageHeader.width - width - Theme.horizontalPageMargin
y: padding
width: size
height: size
sourceSize: Qt.size(size,size)
source: applicationIcon ? applicationIcon : ""
visible: appIcon.status === Image.Ready
}
}
// =============== Display ===============
SectionHeader {
//: Section header for display settings
//% "Display"
text: qsTrId("harbour-books-settings-page-display-section_header")
}
Grid {
id: displayGrid
width: parent.width
columns: landscapeLayout ? 2 : 1
readonly property real columnWidth: width/columns
Slider {
id: fontSizeSlider
minimumValue: -5
maximumValue: 15
stepSize: 1
width: parent.columnWidth
leftMargin: landscapeLayout ? Theme.horizontalPageMargin : nightModeBrightnessSlider.leftMargin
rightMargin: leftMargin
//: Slider value label for the standard font size
//% "Default"
readonly property string normal: qsTrId("harbour-books-settings-page-font_size_label-default")
//: Slider label
//% "Font size"
label: qsTrId("harbour-books-settings-page-font_size_label")
valueText: (value === 0) ? normal : ((value > 0) ? ("+" + value) : value)
onSliderValueChanged: fontSize.value = value
Component.onCompleted: value = fontSize.value
ConfigurationValue {
id: fontSize
key: rootPath + "fontSize"
defaultValue: 0
onValueChanged: fontSizeSlider.value = value
}
}
Slider {
id: nightModeBrightnessSlider
width: parent.columnWidth
leftMargin: keepDisplayOnSwitch.leftMargin - Theme.paddingLarge + Theme.itemSizeExtraSmall
rightMargin: leftMargin
//: Slider label
//% "Brightness in night mode"
label: qsTrId("harbour-books-settings-page-night_mode_brightness_label")
stepSize: (maximumValue - minimumValue) / 100.0
onSliderValueChanged: nightModeBrightness.value = value
value: nightModeBrightness.value
valueText: landscapeLayout ? " " : ""
readonly property real sliderLeft: x + leftMargin
readonly property real sliderRight: x + width - rightMargin
readonly property real sliderWidth: width - leftMargin - rightMargin
readonly property real sliderThumbX: sliderLeft + (maximumValue > minimumValue) ? (sliderWidth * sliderValue / (maximumValue - minimumValue)) : 0
readonly property real sliderBarVerticalCenter: Math.round(height - Theme.fontSizeSmall - Theme.paddingSmall - Theme.itemSizeExtraSmall*3/8)
readonly property color highlightColor: highlighted ? Theme.secondaryHighlightColor : Theme.secondaryColor
ConfigurationValue {
id: nightModeBrightness
key: rootPath + "nightModeBrightness"
defaultValue: 1
}
HarbourHighlightIcon {
source: "images/brightness.svg"
y: nightModeBrightnessSlider.sliderBarVerticalCenter - Math.round(height/2)
anchors {
left: parent.left
leftMargin: nightModeBrightnessSlider.leftMargin - Theme.paddingSmall - width
}
sourceSize.height: Math.round(Theme.iconSizeSmall * 0.8)
highlightColor: nightModeBrightnessSlider.highlightColor
opacity: (darkOnLight && !nightModeBrightnessSlider.highlighted) ? 0.6 : 1.0
}
HarbourHighlightIcon {
source: "images/brightness.svg"
y: nightModeBrightnessSlider.sliderBarVerticalCenter - Math.round(height/2)
anchors {
right: parent.right
rightMargin: nightModeBrightnessSlider.rightMargin - Theme.paddingSmall - width
}
sourceSize.height: Math.round(Theme.iconSizeSmall * 1.2)
highlightColor: nightModeBrightnessSlider.highlightColor
opacity: (darkOnLight && !nightModeBrightnessSlider.highlighted) ? 0.6 : 1.0
}
}
}
Grid {
width: parent.width
columns: landscapeLayout ? 2 : 1
flow: Grid.TopToBottom
readonly property real columnWidth: width/columns
Column {
width: parent.columnWidth
ComboBox {
id: orientationComboBox
//: Combo box label
//% "Orientation"
label: qsTrId("harbour-books-settings-page-orientation_label")
value: currentItem ? currentItem.text : ""
menu: ContextMenu {
id: orientationMenu
x: 0
width: orientationComboBox.width
readonly property int defaultIndex: 0
MenuItem {
readonly property int value: 0
//: Combo box value for dynamic orientation
//% "Dynamic"
text: qsTrId("harbour-books-settings-page-orientation-dynamic")
onClicked: orientation.value = value
}
MenuItem {
readonly property int value: 1
//: Combo box value for portrait orientation
//% "Portrait"
text: qsTrId("harbour-books-settings-page-orientation-portrait")
onClicked: orientation.value = value
}
MenuItem {
readonly property int value: 2
//: Combo box value for landscape orientation
//% "Landscape"
text: qsTrId("harbour-books-settings-page-orientation-landscape")
onClicked: orientation.value = value
}
}
Component.onCompleted: orientation.updateControls()
ConfigurationValue {
id: orientation
key: rootPath + "orientation"
defaultValue: 0
onValueChanged: updateControls()
function updateControls() {
var n = orientationMenu.children.length
var index = orientationMenu.defaultIndex
for (var i=0; i<n; i++) {
if (orientationMenu.children[i].value === value) {
index = i
break
}
}
orientationComboBox.currentIndex = index
}
}
}
ComboBox {
id: layoutComboBox
//: Combo box label
//% "Page layout"
label: qsTrId("harbour-books-settings-page-page_layout")
value: currentItem ? currentItem.valueText : ""
readonly property int yBottom: y + Theme.itemSizeSmall
menu: ContextMenu {
x: 0
width: layoutComboBox.width
readonly property int defaultIndex: 0
BooksDetailMenuItem {
//: Combo box value for dynamic page layout
//% "Dynamic"
valueText: qsTrId("harbour-books-settings-page-layout-dynamic")
//: Combo box detail for dynamic page layout
//% "(toggle on tap)"
detailText: qsTrId("harbour-books-settings-page-layout-dynamic-detail")
onClicked: pageDetailsFixed.value = false
}
BooksDetailMenuItem {
//: Combo box value for clean page layout (just the content)
//% "Clean"
valueText: qsTrId("harbour-books-settings-page-layout-clean")
//: Combo box detail for clean page layout (just the content)
//% "(just the content)"
detailText: qsTrId("harbour-books-settings-page-layout-clean-detail")
onClicked: {
pageDetailsFixed.value = true
pageDetails.value = 0
}
}
BooksDetailMenuItem {
//: Combo box value for minimal page layout (title + page)
//% "Minimal"
valueText: qsTrId("harbour-books-settings-page-layout-minimal")
//: Combo box detail for minimal page layout (title + page)
//% "(title, page)"
detailText: qsTrId("harbour-books-settings-page-layout-minimal-detail")
onClicked: {
pageDetailsFixed.value = true
pageDetails.value = 1
}
}
BooksDetailMenuItem {
//: Combo box value for normal page layout (title + page + slider)
//% "Regular"
valueText: qsTrId("harbour-books-settings-page-layout-normal")
//: Combo box detail for normal page layout (title + page + slider)
//% "(title, page, slider)"
detailText: qsTrId("harbour-books-settings-page-layout-normal-detail")
onClicked: {
pageDetailsFixed.value = true
pageDetails.value = 2
}
}
BooksDetailMenuItem {
//: Combo box value for full page layout (title + page + slider)
//% "Full"
valueText: qsTrId("harbour-books-settings-page-layout-full")
//: Combo box detail for full page layout (title + page + slider)
//% "(everything)"
detailText: qsTrId("harbour-books-settings-page-layout-full-detail")
onClicked: {
pageDetailsFixed.value = true
pageDetails.value = 3
}
}
}
Component.onCompleted: updateSelectedItem()
function updateSelectedItem() {
currentIndex = pageDetailsFixed.value ? (pageDetails.value + 1) : 0
}
ConfigurationValue {
id: pageDetails
key: rootPath + "pageDetails"
defaultValue: 0
onValueChanged: layoutComboBox.updateSelectedItem()
}
ConfigurationValue {
id: pageDetailsFixed
key: rootPath + "pageDetailsFixed"
defaultValue: false
onValueChanged: layoutComboBox.updateSelectedItem()
}
}
}
TextSwitch {
id: keepDisplayOnSwitch
width: parent.columnWidth
automaticCheck: false
checked: keepDisplayOn.value
//: Text switch label
//% "Keep display on while reading"
text: qsTrId("harbour-books-settings-page-keep_display_on")
//: Text switch description
//% "Prevent the display from blanking while reading the book."
description: qsTrId("harbour-books-settings-page-keep_display_on_description")
onClicked: keepDisplayOn.value = !keepDisplayOn.value
ConfigurationValue {
id: keepDisplayOn
key: rootPath + "keepDisplayOn"
defaultValue: false
}
}
}
// =============== Navigation ===============
SectionHeader {
//: Section header for media keys
//% "Navigation"
text: qsTrId("harbour-books-settings-page-navigation-section_header")
}
Grid {
width: parent.width
columns: landscapeLayout ? 2 : 1
flow: Grid.TopToBottom
readonly property real columnWidth: width/columns
Column {
width: parent.columnWidth
BooksActionSelector {
//: Combo box label
//% "Volume up"
label: qsTrId("harbour-books-settings-page-volume_up-label")
key: rootPath + "volumeUpAction"
defaultValue: 2 // BooksSettings.ActionNextPage
}
BooksActionSelector {
//: Combo box label
//% "Volume down"
label: qsTrId("harbour-books-settings-page-volume_down-label")
key: rootPath + "volumeDownAction"
defaultValue: 1 // BooksSettings.ActionPreviousPage
readonly property int yBottom: y + Theme.itemSizeSmall
}
}
Item {
width: 1
height: 1
visible: landscapeLayout // To occupy the grid slot
}
TextSwitch {
width: parent.columnWidth
automaticCheck: false
checked: turnPageByTap.value
//: Text switch label
//% "Turn pages by tapping the screen"
text: qsTrId("harbour-books-settings-page-turn_pages_by_tap")
//: Text switch description
//% "Tapping near the left edge of the screen returns to the previous page, tapping near the right edge gets you to the next page."
description: qsTrId("harbour-books-settings-page-turn_pages_by_tap-description")
onClicked: turnPageByTap.value = !turnPageByTap.value
ConfigurationValue {
id: turnPageByTap
key: rootPath + "turnPageByTap"
defaultValue: false
}
}
TextSwitch {
width: parent.columnWidth
automaticCheck: false
checked: bookPullDownMenu.value
//: Text switch label
//% "Show pulley menu when the book is open"
text: qsTrId("harbour-books-settings-page-book_pulldown_menu")
//: Text switch description
//% "Without the pulley menu, the book has to be closed by swiping it up."
description: qsTrId("harbour-books-settings-page-book_pulldown_menu-description")
onClicked: bookPullDownMenu.value = !bookPullDownMenu.value
ConfigurationValue {
id: bookPullDownMenu
key: rootPath + "bookPullDownMenu"
defaultValue: true
}
}
}
// =============== Memory card ===============
SectionHeader {
//: Section header for memory card settings
//% "Memory card"
text: qsTrId("harbour-books-settings-page-removable-section_header")
}
TextField {
id: removableRootField
width: parent.width
labelVisible: false
Component.onCompleted: text = removableRoot.value
onActiveFocusChanged: removableRoot.value = text
EnterKey.onClicked: page.focus = true
EnterKey.iconSource: "image://theme/icon-m-enter-close"
ConfigurationValue {
id: removableRoot
key: rootPath + "removableRoot"
defaultValue: "Books"
onValueChanged: removableRootField.text = value
}
}
Label {
id: removableRootLabel
//: Settings field label
//% "Books folder"
text: qsTrId("harbour-books-settings-page-removable_root-label")
x: removableRootField.textLeftMargin
width: removableRootField.width - removableRootField.textLeftMargin - removableRootField.textRightMargin
height: text.length ? (implicitHeight + Theme.paddingMedium) : 0
anchors {
topMargin: -Theme.paddingSmall
bottomMargin: Theme.paddingMedium
}
color: removableRootField.activeFocus ? Theme.highlightColor : Theme.primaryColor
opacity: removableRootField.activeFocus ? 1.0 : 0.6
elide: Text.ElideRight
font.pixelSize: Theme.fontSizeSmall
}
Label {
//: Settings field description
//% "Leave the folder name empty to scan the entire memory card for books."
text: qsTrId("harbour-books-settings-page-removable_root-description")
height: text.length ? (implicitHeight + Theme.paddingMedium) : 0
width: removableRootLabel.width
x: removableRootLabel.x
font.pixelSize: Theme.fontSizeExtraSmall
color: Theme.secondaryColor
wrapMode: Text.Wrap
}
}
VerticalScrollDecorator { }
colorEditorModel: HarbourColorEditorModel {
Component.onCompleted: colors = Settings.availableColors
onColorsChanged: Settings.availableColors = colors
}
onResetColors: colorEditorModel.colors = Settings.defaultColors
}

View file

@ -0,0 +1,698 @@
/*
Copyright (C) 2015-2022 Jolla Ltd.
Copyright (C) 2015-2022 Slava Monich <slava.monich@jolla.com>
You may use this file under the terms of BSD license as follows:
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
3. Neither the names of the copyright holders nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
*/
import QtQuick 2.0
import Sailfish.Silica 1.0
import org.nemomobile.configuration 1.0
import "../qml/Books.js" as Books
import "../qml/harbour"
Page {
id: thisPage
property bool inApp
property var colorSchemeModel
property var colorEditorModel
property alias title: pageHeader.title
signal resetColors()
// jolla-settings expects these properties:
property var applicationName
property var applicationIcon
// Internal properties
readonly property string _rootPath: "/apps/" + appName() + "/"
readonly property bool _darkOnLight: ('colorScheme' in Theme) && Theme.colorScheme === 1
readonly property int _screenWidth: isPortrait ? Screen.width : Screen.height
readonly property int _screenHeight: isPortrait ? Screen.height : Screen.width
readonly property bool _landscapeLayout: (_screenWidth > _screenHeight && Screen.sizeCategory > Screen.Small) || Screen.sizeCategory > Screen.Medium
// Deduce package name from the path
function appName() {
var parts = Qt.resolvedUrl("dummy").split('/')
if (parts.length > 2) {
var name = parts[parts.length-3]
if (name.indexOf("-books") >= 0) {
return name
}
}
return "harbour-books"
}
Loader {
active: inApp // Follow orientation changes
Connections {
target: orientation
onValueChanged: allowedOrientations =
(orientation.value === 1) ? Orientation.Portrait :
(orientation.value === 2) ? Orientation.Landscape :
Orientation.All
}
}
SilicaFlickable {
anchors.fill: parent
contentHeight: content.height
// Night mode example (positioned right above the slider)
Rectangle {
opacity: nightModeBrightnessSlider.pressed ? 1.0 : 0
visible: opacity > 0
radius: Theme.paddingSmall
width: nightModeExampleLabel.width + 2 * Theme.paddingLarge
height: nightModeExampleLabel.height + 2 * Theme.paddingMedium
readonly property int xMin: nightModeBrightnessSlider.leftMargin
readonly property int xMax: content.width - nightModeBrightnessSlider.rightMargin - width
readonly property int yOffset: _landscapeLayout ? (Theme.itemSizeExtraLarge - Theme.itemSizeMedium) : 0
x: content.x + displayGrid.x + Math.max(Math.min(nightModeBrightnessSlider.sliderLeft + Math.round(nightModeBrightnessSlider.sliderThumbX - width/2.0), xMax), xMin)
y: content.y + displayGrid.y + nightModeBrightnessSlider.y + yOffset - height
z: nightModeBrightnessSlider.z + 1
color: "black"
border {
color: Theme.highlightColor
width: Math.ceil(radius/5)
}
Label {
id: nightModeExampleLabel
anchors.centerIn: parent
color: "white"
opacity: Books.contentOpacity(nightModeBrightness.value)
//: Night mode example label
//% "Night mode"
text: qsTrId("harbour-books-settings-page-night_mode_example")
font {
bold: true
pixelSize: Theme.fontSizeLarge
family: "Times"
}
}
Behavior on x { SmoothedAnimation { duration: 125 } }
Behavior on opacity { FadeAnimation { duration: 500 } }
}
Column {
id: content
width: parent.width
PageHeader {
id: pageHeader
rightMargin: Theme.horizontalPageMargin + (appIcon.visible ? (height - appIcon.padding) : 0)
title: applicationName ? applicationName :
//: Settings page header (app name)
//% "Books"
qsTrId("harbour-books-settings-page-header")
description: inApp ? "" :
//: Settings page header description (app version)
//% "Version %1"
qsTrId("harbour-books-settings-version").arg(Books.version)
Image {
id: appIcon
readonly property int padding: Theme.paddingLarge
readonly property int size: pageHeader.height - 2 * padding
x: pageHeader.width - width - Theme.horizontalPageMargin
y: padding
width: size
height: size
sourceSize: Qt.size(size,size)
source: applicationIcon ? applicationIcon : ""
visible: appIcon.status === Image.Ready
}
}
// =============== Display ===============
SectionHeader {
//: Section header for display settings
//% "Display"
text: qsTrId("harbour-books-settings-page-display-section_header")
}
Grid {
id: displayGrid
width: parent.width
columns: _landscapeLayout ? 2 : 1
readonly property real columnWidth: width/columns
Slider {
id: fontSizeSlider
minimumValue: -5
maximumValue: 15
stepSize: 1
width: parent.columnWidth
leftMargin: _landscapeLayout ? Theme.horizontalPageMargin : nightModeBrightnessSlider.leftMargin
rightMargin: leftMargin
//: Slider value label for the standard font size
//% "Default"
readonly property string normal: qsTrId("harbour-books-settings-page-font_size_label-default")
//: Slider label
//% "Font size"
label: qsTrId("harbour-books-settings-page-font_size_label")
valueText: (value === 0) ? normal : ((value > 0) ? ("+" + value) : value)
onSliderValueChanged: fontSize.value = value
Component.onCompleted: value = fontSize.value
ConfigurationValue {
id: fontSize
key: _rootPath + "fontSize"
defaultValue: 0
onValueChanged: fontSizeSlider.value = value
}
}
Slider {
id: nightModeBrightnessSlider
width: parent.columnWidth
leftMargin: keepDisplayOnSwitch.leftMargin - Theme.paddingLarge + Theme.itemSizeExtraSmall
rightMargin: leftMargin
//: Slider label
//% "Brightness in night mode"
label: qsTrId("harbour-books-settings-page-night_mode_brightness_label")
stepSize: (maximumValue - minimumValue) / 100.0
onSliderValueChanged: nightModeBrightness.value = value
value: nightModeBrightness.value
valueText: _landscapeLayout ? " " : ""
readonly property real sliderLeft: x + leftMargin
readonly property real sliderRight: x + width - rightMargin
readonly property real sliderWidth: width - leftMargin - rightMargin
readonly property real sliderThumbX: sliderLeft + (maximumValue > minimumValue) ? (sliderWidth * sliderValue / (maximumValue - minimumValue)) : 0
readonly property real sliderBarVerticalCenter: Math.round(height - Theme.fontSizeSmall - Theme.paddingSmall - Theme.itemSizeExtraSmall*3/8)
readonly property color highlightColor: highlighted ? Theme.secondaryHighlightColor : Theme.secondaryColor
ConfigurationValue {
id: nightModeBrightness
key: _rootPath + "nightModeBrightness"
defaultValue: 1
}
HarbourHighlightIcon {
source: "images/brightness.svg"
y: nightModeBrightnessSlider.sliderBarVerticalCenter - Math.round(height/2)
anchors {
left: parent.left
leftMargin: nightModeBrightnessSlider.leftMargin - Theme.paddingSmall - width
}
sourceSize.height: Math.round(Theme.iconSizeSmall * 0.8)
highlightColor: nightModeBrightnessSlider.highlightColor
opacity: (_darkOnLight && !nightModeBrightnessSlider.highlighted) ? 0.6 : 1.0
}
HarbourHighlightIcon {
source: "images/brightness.svg"
y: nightModeBrightnessSlider.sliderBarVerticalCenter - Math.round(height/2)
anchors {
right: parent.right
rightMargin: nightModeBrightnessSlider.rightMargin - Theme.paddingSmall - width
}
sourceSize.height: Math.round(Theme.iconSizeSmall * 1.2)
highlightColor: nightModeBrightnessSlider.highlightColor
opacity: (_darkOnLight && !nightModeBrightnessSlider.highlighted) ? 0.6 : 1.0
}
}
}
Grid {
width: parent.width
columns: _landscapeLayout ? 2 : 1
flow: Grid.TopToBottom
readonly property real columnWidth: width/columns
Column {
width: parent.columnWidth
ComboBox {
id: orientationComboBox
//: Combo box label
//% "Orientation"
label: qsTrId("harbour-books-settings-page-orientation_label")
value: currentItem ? currentItem.text : ""
menu: ContextMenu {
id: orientationMenu
x: 0
width: orientationComboBox.width
readonly property int defaultIndex: 0
MenuItem {
readonly property int value: 0
//: Combo box value for dynamic orientation
//% "Dynamic"
text: qsTrId("harbour-books-settings-page-orientation-dynamic")
onClicked: orientation.value = value
}
MenuItem {
readonly property int value: 1
//: Combo box value for portrait orientation
//% "Portrait"
text: qsTrId("harbour-books-settings-page-orientation-portrait")
onClicked: orientation.value = value
}
MenuItem {
readonly property int value: 2
//: Combo box value for landscape orientation
//% "Landscape"
text: qsTrId("harbour-books-settings-page-orientation-landscape")
onClicked: orientation.value = value
}
}
Component.onCompleted: orientation.updateControls()
ConfigurationValue {
id: orientation
key: _rootPath + "orientation"
defaultValue: 0
onValueChanged: updateControls()
function updateControls() {
var n = orientationMenu.children.length
var index = orientationMenu.defaultIndex
for (var i=0; i<n; i++) {
if (orientationMenu.children[i].value === value) {
index = i
break
}
}
orientationComboBox.currentIndex = index
}
}
}
ComboBox {
id: layoutComboBox
//: Combo box label
//% "Page layout"
label: qsTrId("harbour-books-settings-page-page_layout")
value: currentItem ? currentItem.valueText : ""
readonly property int yBottom: y + Theme.itemSizeSmall
menu: ContextMenu {
x: 0
width: layoutComboBox.width
readonly property int defaultIndex: 0
BooksDetailMenuItem {
//: Combo box value for dynamic page layout
//% "Dynamic"
valueText: qsTrId("harbour-books-settings-page-layout-dynamic")
//: Combo box detail for dynamic page layout
//% "(toggle on tap)"
detailText: qsTrId("harbour-books-settings-page-layout-dynamic-detail")
onClicked: pageDetailsFixed.value = false
}
BooksDetailMenuItem {
//: Combo box value for clean page layout (just the content)
//% "Clean"
valueText: qsTrId("harbour-books-settings-page-layout-clean")
//: Combo box detail for clean page layout (just the content)
//% "(just the content)"
detailText: qsTrId("harbour-books-settings-page-layout-clean-detail")
onClicked: {
pageDetailsFixed.value = true
pageDetails.value = 0
}
}
BooksDetailMenuItem {
//: Combo box value for minimal page layout (title + page)
//% "Minimal"
valueText: qsTrId("harbour-books-settings-page-layout-minimal")
//: Combo box detail for minimal page layout (title + page)
//% "(title, page)"
detailText: qsTrId("harbour-books-settings-page-layout-minimal-detail")
onClicked: {
pageDetailsFixed.value = true
pageDetails.value = 1
}
}
BooksDetailMenuItem {
//: Combo box value for normal page layout (title + page + slider)
//% "Regular"
valueText: qsTrId("harbour-books-settings-page-layout-normal")
//: Combo box detail for normal page layout (title + page + slider)
//% "(title, page, slider)"
detailText: qsTrId("harbour-books-settings-page-layout-normal-detail")
onClicked: {
pageDetailsFixed.value = true
pageDetails.value = 2
}
}
BooksDetailMenuItem {
//: Combo box value for full page layout (title + page + slider)
//% "Full"
valueText: qsTrId("harbour-books-settings-page-layout-full")
//: Combo box detail for full page layout (title + page + slider)
//% "(everything)"
detailText: qsTrId("harbour-books-settings-page-layout-full-detail")
onClicked: {
pageDetailsFixed.value = true
pageDetails.value = 3
}
}
}
Component.onCompleted: updateSelectedItem()
function updateSelectedItem() {
currentIndex = pageDetailsFixed.value ? (pageDetails.value + 1) : 0
}
ConfigurationValue {
id: pageDetails
key: _rootPath + "pageDetails"
defaultValue: 0
onValueChanged: layoutComboBox.updateSelectedItem()
}
ConfigurationValue {
id: pageDetailsFixed
key: _rootPath + "pageDetailsFixed"
defaultValue: false
onValueChanged: layoutComboBox.updateSelectedItem()
}
}
}
TextSwitch {
id: keepDisplayOnSwitch
width: parent.columnWidth
automaticCheck: false
checked: keepDisplayOn.value
//: Text switch label
//% "Keep display on while reading"
text: qsTrId("harbour-books-settings-page-keep_display_on")
//: Text switch description
//% "Prevent the display from blanking while reading the book."
description: qsTrId("harbour-books-settings-page-keep_display_on_description")
onClicked: keepDisplayOn.value = !keepDisplayOn.value
ConfigurationValue {
id: keepDisplayOn
key: _rootPath + "keepDisplayOn"
defaultValue: false
}
}
}
// =============== Navigation ===============
SectionHeader {
//: Section header for media keys
//% "Navigation"
text: qsTrId("harbour-books-settings-page-navigation-section_header")
}
Grid {
width: parent.width
columns: _landscapeLayout ? 2 : 1
flow: Grid.TopToBottom
readonly property real columnWidth: width/columns
Column {
width: parent.columnWidth
BooksActionSelector {
//: Combo box label
//% "Volume up"
label: qsTrId("harbour-books-settings-page-volume_up-label")
key: _rootPath + "volumeUpAction"
defaultValue: 2 // BooksSettings.ActionNextPage
}
BooksActionSelector {
//: Combo box label
//% "Volume down"
label: qsTrId("harbour-books-settings-page-volume_down-label")
key: _rootPath + "volumeDownAction"
defaultValue: 1 // BooksSettings.ActionPreviousPage
readonly property int yBottom: y + Theme.itemSizeSmall
}
}
Item {
width: 1
height: 1
visible: _landscapeLayout // To occupy the grid slot
}
TextSwitch {
width: parent.columnWidth
automaticCheck: false
checked: turnPageByTap.value
//: Text switch label
//% "Turn pages by tapping the screen"
text: qsTrId("harbour-books-settings-page-turn_pages_by_tap")
//: Text switch description
//% "Tapping near the left edge of the screen returns to the previous page, tapping near the right edge gets you to the next page."
description: qsTrId("harbour-books-settings-page-turn_pages_by_tap-description")
onClicked: turnPageByTap.value = !turnPageByTap.value
ConfigurationValue {
id: turnPageByTap
key: _rootPath + "turnPageByTap"
defaultValue: false
}
}
TextSwitch {
width: parent.columnWidth
automaticCheck: false
checked: bookPullDownMenu.value
//: Text switch label
//% "Show pulley menu when the book is open"
text: qsTrId("harbour-books-settings-page-book_pulldown_menu")
//: Text switch description
//% "Without the pulley menu, the book has to be closed by swiping it up."
description: qsTrId("harbour-books-settings-page-book_pulldown_menu-description")
onClicked: bookPullDownMenu.value = !bookPullDownMenu.value
ConfigurationValue {
id: bookPullDownMenu
key: _rootPath + "bookPullDownMenu"
defaultValue: true
}
}
}
// =============== Colors ===============
SectionHeader {
//: Section header for colors
//% "Colors"
text: qsTrId("harbour-books-settings-page-colors-section_header")
}
TextSwitch {
id: useCustomColorSchemeSwitch
width: parent.width
automaticCheck: false
checked: !useCustomColorScheme.value
//: Text switch label
//% "Use standard colors"
text: qsTrId("harbour-books-settings-page-standard_colors")
//: Text switch description
//% "Note that colors hardcoded in the book override the color scheme."
description: qsTrId("harbour-books-settings-page-standard_colors-description")
onClicked: {
customColorsGridHeightBehavior.enabled = true
useCustomColorScheme.value = !useCustomColorScheme.value
customColorsGridHeightBehavior.enabled = false
}
ConfigurationValue {
id: useCustomColorScheme
key: _rootPath + "useCustomColorScheme"
defaultValue: false
}
}
Grid {
id: customColorsGrid
x: useCustomColorSchemeSwitch.leftMargin - Theme.paddingLarge - Theme.paddingMedium +
Theme.itemSizeExtraSmall + (_darkOnLight ? Theme.paddingMedium : 0)
width: parent.width - x
columns: _landscapeLayout ? 2 : 1
flow: Grid.TopToBottom
height: useCustomColorScheme.value ? implicitHeight : 0
visible: height > 0
clip: true
readonly property real columnWidth: width/columns
Repeater {
model: colorSchemeModel
delegate: BackgroundItem {
id: delegate
width: customColorsGrid.columnWidth
Rectangle {
id: colorButton
width: height
height: Theme.itemSizeSmall - 2 * Theme.paddingMedium
color: model.color
border {
width: 1
color: Theme.primaryColor
}
anchors {
verticalCenter: parent.verticalCenter
left: parent.left
leftMargin: Theme.paddingMedium
}
layer.enabled: delegate.highlighted
layer.effect: HarbourPressEffect {
source: colorButton
}
}
Label{
anchors {
verticalCenter: parent.verticalCenter
left: colorButton.right
leftMargin: Theme.paddingMedium
right: parent.right
}
truncationMode: TruncationMode.Fade
text: model.label
}
onClicked: {
var dialog = pageStack.push(Qt.resolvedUrl("../qml/harbour/HarbourColorPickerDialog.qml"), {
allowedOrientations: thisPage.allowedOrientations,
acceptDestinationAction: PageStackAction.Replace,
colorModel: colorEditorModel,
color: model.color,
//: Pulley menu item
//% "Reset colors"
resetColorsMenuText: qsTrId("harbour-books-color_picker-menu-reset_colors"),
//: Dialog title label
//% "Select color"
acceptText: qsTrId("harbour-books-color_picker-action-select_color"),
//: Dialog title label
//% "Add color"
addColorAcceptText: qsTrId("harbour-books-color_picker-action-add_color"),
//: Hue slider label
//% "Color"
addColorHueSliderText: qsTrId("harbour-books-color_picker-slider-hue"),
//: Brightness slider label
//% "Brightness"
addColorBrightnessSliderText: qsTrId("harbour-books-color_picker-slider-brightness"),
//: Text field description
//% "Hex notation"
addColorHexNotationText: qsTrId("harbour-books-color_picker-text-hex_notation")
})
dialog.resetColors.connect(thisPage.resetColors)
dialog.accepted.connect(function() {
delegate.setColor(dialog.color)
})
}
function setColor(c) {
model.color = c
}
}
}
Behavior on height {
id: customColorsGridHeightBehavior
enabled: false
NumberAnimation { duration: 200 }
}
}
// =============== Memory card ===============
SectionHeader {
//: Section header for memory card settings
//% "Memory card"
text: qsTrId("harbour-books-settings-page-removable-section_header")
}
TextField {
id: removableRootField
width: parent.width
labelVisible: false
Component.onCompleted: text = removableRoot.value
onActiveFocusChanged: removableRoot.value = text
EnterKey.onClicked: thisPage.focus = true
EnterKey.iconSource: "image://theme/icon-m-enter-close"
ConfigurationValue {
id: removableRoot
key: _rootPath + "removableRoot"
defaultValue: "Books"
onValueChanged: removableRootField.text = value
}
}
Label {
id: removableRootLabel
//: Settings field label
//% "Books folder"
text: qsTrId("harbour-books-settings-page-removable_root-label")
x: removableRootField.textLeftMargin
width: removableRootField.width - removableRootField.textLeftMargin - removableRootField.textRightMargin
height: text.length ? (implicitHeight + Theme.paddingMedium) : 0
anchors {
topMargin: -Theme.paddingSmall
bottomMargin: Theme.paddingMedium
}
color: removableRootField.activeFocus ? Theme.highlightColor : Theme.primaryColor
opacity: removableRootField.activeFocus ? 1.0 : 0.6
elide: Text.ElideRight
font.pixelSize: Theme.fontSizeSmall
}
Label {
//: Settings field description
//% "Leave the folder name empty to scan the entire memory card for books."
text: qsTrId("harbour-books-settings-page-removable_root-description")
height: text.length ? (implicitHeight + Theme.paddingMedium) : 0
width: removableRootLabel.width
x: removableRootLabel.x
font.pixelSize: Theme.fontSizeExtraSmall
color: Theme.secondaryColor
wrapMode: Text.Wrap
}
}
VerticalScrollDecorator { }
}
}

View file

@ -0,0 +1,78 @@
/*
* Copyright (C) 2022 Jolla Ltd.
* Copyright (C) 2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "BooksColorSchemeModel.h"
#include "BooksSettingsBase.h"
#include "HarbourColorEditorModel.h"
#include "HarbourDebug.h"
#include <QtQml>
#define SETTINGS_QML_PLUGIN "openrepos.books.settings"
#define SETTINGS_QML_REGISTER_(klass,name) \
qmlRegisterType<klass>(SETTINGS_QML_PLUGIN, 1, 0, name)
#define SETTINGS_QML_REGISTER(klass) \
SETTINGS_QML_REGISTER_(klass,#klass)
class BooksSettingsPlugin : public QQmlExtensionPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID SETTINGS_QML_PLUGIN)
public:
void initializeEngine(QQmlEngine*, const char*) Q_DECL_OVERRIDE;
void registerTypes(const char*) Q_DECL_OVERRIDE;
};
void
BooksSettingsPlugin::initializeEngine(
QQmlEngine*,
const char* aUri)
{
HDEBUG(aUri);
}
void
BooksSettingsPlugin::registerTypes(
const char* aUri)
{
HDEBUG(aUri);
HASSERT(QLatin1String(aUri) == QLatin1String(SETTINGS_QML_PLUGIN));
SETTINGS_QML_REGISTER_(BooksSettingsBase, "BooksSettings");
SETTINGS_QML_REGISTER(BooksColorSchemeModel);
SETTINGS_QML_REGISTER(HarbourColorEditorModel);
}
#include "BooksSettingsPlugin.moc"

View file

@ -0,0 +1,49 @@
/*
Copyright (C) 2022 Jolla Ltd.
Copyright (C) 2022 Slava Monich <slava.monich@jolla.com>
You may use this file under the terms of BSD license as follows:
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
3. Neither the names of the copyright holders nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
*/
import QtQuick 2.0
import openrepos.books.settings 1.0
// In-app settings
BooksSettingsBase {
BooksSettings { id: settings }
colorSchemeModel: BooksColorSchemeModel {
Component.onCompleted: colorScheme = settings.customColorScheme
onColorSchemeChanged: settings.customColorScheme = colorScheme
}
colorEditorModel: HarbourColorEditorModel {
Component.onCompleted: colors = settings.availableColors
onColorsChanged: settings.availableColors = colors
}
onResetColors: colorEditorModel.colors = settings.defaultColors
}

View file

@ -1,14 +0,0 @@
{
"translation_catalog" : "harbour-books",
"entries": [
{
"path": "applications/harbour-books.desktop",
"title": "Books",
"type": "page",
"icon": "harbour-books",
"params": {
"source": "/usr/share/harbour-books/settings/BooksSettings.qml"
}
}
]
}

View file

@ -0,0 +1,14 @@
{
"translation_catalog" : "openrepos-books",
"entries": [
{
"path": "applications/openrepos-books.desktop",
"title": "Books",
"type": "page",
"icon": "openrepos-books",
"params": {
"source": "/usr/share/openrepos-books/settings/SystemSettings.qml"
}
}
]
}

2
app/settings/qmldir Normal file
View file

@ -0,0 +1,2 @@
module openrepos.books.settings
plugin bookssettings

57
app/settings/settings.pro Normal file
View file

@ -0,0 +1,57 @@
TEMPLATE = lib
TARGET = bookssettings
# Directories
TARGETPATH = $$[QT_INSTALL_QML]/openrepos/books/settings
APP_SRC_DIR = ../src
HARBOUR_LIB_DIR = ../../harbour-lib
HARBOUR_LIB_INCLUDE_DIR = $$HARBOUR_LIB_DIR/include
HARBOUR_LIB_SRC_DIR = $$HARBOUR_LIB_DIR/src
QT += qml
CONFIG += qt plugin link_pkgconfig hide_symbols
PKGCONFIG += mlite5
DEFINES += OPENREPOS # It's for openrepos build only
QMAKE_CXXFLAGS += -Wno-unused-parameter
INCLUDEPATH += $${APP_SRC_DIR} $${HARBOUR_LIB_INCLUDE_DIR}
CONFIG(debug, debug|release) {
DEFINES += HARBOUR_DEBUG=1
}
target.path = $$TARGETPATH
INSTALLS += target
import.files = qmldir
import.path = $$TARGETPATH
INSTALLS += import
settings_json.files = openrepos-books.json
settings_json.path = /usr/share/jolla-settings/entries/
INSTALLS += settings_json
SOURCES += \
BooksSettingsPlugin.cpp \
$${APP_SRC_DIR}/BooksColorScheme.cpp \
$${APP_SRC_DIR}/BooksColorSchemeModel.cpp \
$${APP_SRC_DIR}/BooksSettingsBase.cpp
HEADERS += \
$${APP_SRC_DIR}/BooksColorScheme.h \
$${APP_SRC_DIR}/BooksColorSchemeModel.h \
$${APP_SRC_DIR}/BooksSettingsBase.h
OTHER_FILES += \
settings/*.json
# harbour-lib
HEADERS += \
$${HARBOUR_LIB_INCLUDE_DIR}/HarbourColorEditorModel.h \
$${HARBOUR_LIB_INCLUDE_DIR}/HarbourDebug.h \
$${HARBOUR_LIB_INCLUDE_DIR}/HarbourUtil.h
SOURCES += \
$${HARBOUR_LIB_SRC_DIR}/HarbourColorEditorModel.cpp \
$${HARBOUR_LIB_SRC_DIR}/HarbourUtil.cpp

View file

@ -98,8 +98,8 @@ BooksBook::CoverPaintContext::CoverPaintContext()
}
}
setWidth(gMaxScreenSize.width());
setHeight(gMaxScreenSize.height());
iWidth = gMaxScreenSize.width();
iHeight = gMaxScreenSize.height();
}
void BooksBook::CoverPaintContext::drawImage(int x, int y, const ZLImageData& image)

View file

@ -112,7 +112,7 @@ BooksBookModel::PagingTask::PagingTask(QThreadPool* aPool,
HarbourTask(aPool),
iBook(aBook),
iTextStyle(aModel->textStyle()),
iPaint(aModel->width(), aModel->height()),
iPaint(aModel->width(), aModel->height(), BooksColorScheme()),
iMargins(aModel->margins()),
iPageMarksFile(pageMarksFile(aModel)),
iHash(aModel->book()->hash()),

View file

@ -0,0 +1,345 @@
/*
* Copyright (C) 2022 Jolla Ltd.
* Copyright (C) 2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "BooksColorScheme.h"
#include "HarbourDebug.h"
#include "HarbourUtil.h"
#include <QHash>
#include <QAtomicInt>
#include <QCryptographicHash>
#define MEMBER_VAR(Name) i##Name
// ==========================================================================
// BooksColorScheme::Private
// ==========================================================================
class BooksColorScheme::Private
{
public:
struct Colors {
#define MEMBER_DECL(colorName,ColorName,key,default) \
QRgb MEMBER_VAR(ColorName);
BOOKS_COLORS(MEMBER_DECL)
#undef MEMBER_DECL
bool isDefault() const;
void invert();
};
static const Colors DEFAULT_COLORS;
static const QString DEFAULT_SCHEME_ID;
Private(const Colors*);
~Private();
void updateSchemeId();
static QString generateSchemeId(const Colors*);
static QString defaultSchemeId() { return generateSchemeId(&DEFAULT_COLORS); }
static void parseRgb(QRgb*, const QString&);
static uint rgb(QRgb);
public:
QAtomicInt iRef;
Colors iColors;
QString iSchemeId;
};
const BooksColorScheme::Private::Colors BooksColorScheme::Private::DEFAULT_COLORS = {
#define DEFAULT_INIT(colorName,ColorName,key,default) default,
BOOKS_COLORS(DEFAULT_INIT)
#undef DEFAULT_INIT
};
const QString BooksColorScheme::Private::DEFAULT_SCHEME_ID
(BooksColorScheme::Private::defaultSchemeId());
BooksColorScheme::Private::Private(
const Colors* aColors) :
iRef(1),
iColors(*aColors)
{
// Note: leaving iSchemeId empty. Caller must do updateSchemeId()
}
BooksColorScheme::Private::~Private()
{
}
QString
BooksColorScheme::Private::generateSchemeId(
const Colors* aColors)
{
QCryptographicHash md5(QCryptographicHash::Md5);
#define HASH_COLOR(colorName,ColorName,key,default) \
md5.addData((const char*)&aColors->MEMBER_VAR(ColorName), sizeof(aColors->MEMBER_VAR(ColorName)));
BOOKS_COLORS(HASH_COLOR)
#undef HASH_COLOR
return QString(QLatin1String(md5.result().toHex()));
}
inline bool
BooksColorScheme::Private::Colors::isDefault() const
{
return !memcmp(this, &DEFAULT_COLORS, sizeof(Colors));
}
void
BooksColorScheme::Private::Colors::invert()
{
#define INVERT_COLOR(colorName,ColorName,key,default) \
MEMBER_VAR(ColorName) = HarbourUtil::invertedRgb(MEMBER_VAR(ColorName));
BOOKS_COLORS(INVERT_COLOR)
#undef INVERT_COLOR
}
inline
void
BooksColorScheme::Private::updateSchemeId()
{
iSchemeId = generateSchemeId(&iColors);
}
void
BooksColorScheme::Private::parseRgb(
QRgb* aRgb,
const QString& aValue)
{
const int len = aValue.length();
if (len > 0 && len <= 8) {
uint rgb = 0;
for (int i = 0; i < len; i++) {
const int c = aValue.at(i).unicode();
if (isxdigit(c)) {
static const uchar hex[] = {
0, 1, 2, 3, 4, 5, 6, 7, /* 0x30..0x37 */
8, 9, 0, 0, 0, 0, 0, 0, /* 0x3a..0x3f */
0,10,11,12,13,14,15, 0, /* 0x40..0x47 */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x4a..0x4f */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x40..0x47 */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x5a..0x5f */
0,10,11,12,13,14,15, 0, /* 0x60..0x66 */
0, 0, 0, 0, 0, 0, 0, 0 /* Make it 64 bytes */
};
Q_STATIC_ASSERT(sizeof(hex) == 0x40);
rgb = (rgb << 4) | hex[(c - 0x30) & 0x3f];
} else {
HDEBUG("Not a valid hex string" << aValue);
return;
}
}
*aRgb = rgb;
}
}
uint
BooksColorScheme::Private::rgb(
QRgb aRgb)
{
// Strip off opaque alpha
return (qAlpha(aRgb) == 0xff) ? (aRgb & RGB_MASK) : aRgb;
}
// ==========================================================================
// BooksColorScheme
// ==========================================================================
BooksColorScheme::BooksColorScheme() :
iPrivate(Q_NULLPTR)
{
}
BooksColorScheme::BooksColorScheme(
const QString& aSpec) :
iPrivate(Q_NULLPTR)
{
QHash<QString,QString> map;
const QStringList parts(aSpec.split(QChar(':'), QString::SkipEmptyParts));
const int n = parts.count();
for (int i = 0; i < n; i++) {
const QStringList pair(parts.at(i).split(QChar('='), QString::SkipEmptyParts));
if (pair.count() == 2) {
map.insert(pair.at(0), pair.at(1));
}
}
Private::Colors colors = Private::DEFAULT_COLORS;
#define PARSE_KEY(colorName,ColorName,key,default) \
Private::parseRgb(&colors.MEMBER_VAR(ColorName), map.value(QStringLiteral(#key)));
BOOKS_COLORS(PARSE_KEY)
#undef PARSE_KEY
if (!colors.isDefault()) {
(iPrivate = new Private(&colors))->updateSchemeId();
}
}
BooksColorScheme::BooksColorScheme(
const BooksColorScheme& aScheme) :
iPrivate(aScheme.iPrivate)
{
if (iPrivate) {
iPrivate->iRef.ref();
}
}
BooksColorScheme::~BooksColorScheme()
{
if (iPrivate && !iPrivate->iRef.deref()) {
delete iPrivate;
}
}
const QString
BooksColorScheme::schemeId() const
{
return iPrivate ? iPrivate->iSchemeId : Private::DEFAULT_SCHEME_ID;
}
BooksColorScheme&
BooksColorScheme::operator=(
const BooksColorScheme& aScheme)
{
if (iPrivate != aScheme.iPrivate) {
if (iPrivate && !iPrivate->iRef.deref()) {
delete iPrivate;
}
iPrivate = aScheme.iPrivate;
if (iPrivate) {
iPrivate->iRef.ref();
}
}
return *this;
}
bool
BooksColorScheme::equals(
const BooksColorScheme& aScheme) const
{
if (iPrivate == aScheme.iPrivate) {
return true;
} else if (iPrivate && aScheme.iPrivate) {
#define MEMBER_EQUAL(colorName,ColorName,key,default) \
iPrivate->iColors.MEMBER_VAR(ColorName) == \
aScheme.iPrivate->iColors.MEMBER_VAR(ColorName) &&
return BOOKS_COLORS(MEMBER_EQUAL) true;
#undef MEMBER_EQUAL
} else {
#define METHOD_EQUAL(colorName,ColorName,key,default) \
colorName() == aScheme.colorName() &&
return BOOKS_COLORS(METHOD_EQUAL) true;
#undef METHOD_EQUAL
}
}
const QString
BooksColorScheme::toString() const
{
Private::Colors colors = iPrivate ? iPrivate->iColors : Private::DEFAULT_COLORS;
// QString::asprintf requires Qt 5.5
return QString().sprintf(
#define COLOR_FORMAT(colorName,ColorName,key,def) #key "=%06x:"
BOOKS_COLORS(COLOR_FORMAT)
#undef COLOR_FORMAT
"%s",
#define COLOR_VALUE(colorName,ColorName,key,def) \
Private::rgb(colors.MEMBER_VAR(ColorName)),
BOOKS_COLORS(COLOR_VALUE)
#undef COLOR_VALUE
"");
}
#define GETTER_IMPL(colorName,ColorName,key,default) \
QRgb BooksColorScheme::colorName() const { \
return iPrivate ? iPrivate->iColors.MEMBER_VAR(ColorName) : \
Private::DEFAULT_COLORS.MEMBER_VAR(ColorName); \
}
BOOKS_COLORS(GETTER_IMPL)
#undef GETTER_IMPL
#define SETTER_IMPL(colorName,ColorName,key,default) \
BooksColorScheme BooksColorScheme::with##ColorName(QRgb aColor) const { \
if (colorName() == aColor) { return *this; } else { \
BooksColorScheme scheme; \
if (iPrivate) { \
Private::Colors colors(iPrivate->iColors); \
colors.MEMBER_VAR(ColorName) = aColor; \
if (!colors.isDefault()) { \
(scheme.iPrivate = new Private(&colors))->updateSchemeId(); \
} \
} else { \
scheme.iPrivate = new Private(&Private::DEFAULT_COLORS); \
scheme.iPrivate->iColors.MEMBER_VAR(ColorName) = aColor; \
scheme.iPrivate->updateSchemeId(); \
} \
return scheme; \
} \
}
BOOKS_COLORS(SETTER_IMPL)
#undef SETTER_IMPL
BooksColorScheme
BooksColorScheme::inverted() const
{
BooksColorScheme scheme;
Private::Colors colors = iPrivate ? iPrivate->iColors : Private::DEFAULT_COLORS;
colors.invert();
if (!colors.isDefault()) {
(scheme.iPrivate = new Private(&colors))->updateSchemeId();
}
return scheme;
}
BooksColorScheme
BooksColorScheme::invertedWithSelectionBackground(
QRgb aColor) const
{
BooksColorScheme scheme;
Private::Colors colors = iPrivate ? iPrivate->iColors : Private::DEFAULT_COLORS;
colors.invert();
colors.iSelectionBackground = aColor;
if (!colors.isDefault()) {
(scheme.iPrivate = new Private(&colors))->updateSchemeId();
}
return scheme;
}
QString
BooksColorScheme::rgbToString(
QRgb aRgb)
{
// QString::asprintf requires Qt 5.5
return QString().sprintf("#%02x%02x%02x",
qRed(aRgb), qGreen(aRgb), qBlue(aRgb));
}

View file

@ -0,0 +1,97 @@
/*
* Copyright (C) 2022 Jolla Ltd.
* Copyright (C) 2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BOOKS_COLOR_SCHEME_H
#define BOOKS_COLOR_SCHEME_H
#include <QMetaType>
#include <QString>
#include <QRgb>
// Let preprocessor magic begin!
// color(colorName,ColorName,key,default)
#define BOOKS_COLORS(color) \
color(background,Background,bg,0xffffff) \
color(foreground,Foreground,fg,0x000000) \
color(selectionBackground,SelectionBackground,sb,0x3c8bff) \
color(highlightedText,HighlightedText,ht,0x3c8bff) \
color(internalHyperlink,InternalHyperlink,ih,0x2160b4) \
color(externalHyperlink,ExternalHyperlink,eh,0x2160b4)
// Container for colors (thread-safe)
class BooksColorScheme
{
public:
BooksColorScheme();
BooksColorScheme(const QString&);
BooksColorScheme(const BooksColorScheme&);
~BooksColorScheme();
BooksColorScheme& operator = (const BooksColorScheme&);
bool operator == (const BooksColorScheme&) const;
bool operator != (const BooksColorScheme&) const;
bool equals(const BooksColorScheme&) const;
const QString schemeId() const;
const QString toString() const;
// This generates pairs of method declarations, e.g.
// QRgb background() const;
// BooksColorScheme withBackground(QRgb aColor) const;
#define BOOKS_COLORS_DECL(colorName,ColorName,key,default) \
QRgb colorName() const; \
inline QString colorName##Color() const { return rgbToString(colorName()); } \
BooksColorScheme with##ColorName(QRgb) const Q_REQUIRED_RESULT;
BOOKS_COLORS(BOOKS_COLORS_DECL)
#undef BOOKS_COLORS_DECL
BooksColorScheme inverted() const Q_REQUIRED_RESULT;
BooksColorScheme invertedWithSelectionBackground(QRgb) const Q_REQUIRED_RESULT;
private:
static QString rgbToString(QRgb);
private:
class Private;
Private* iPrivate;
};
// Inline methods
inline bool BooksColorScheme::operator == (const BooksColorScheme& aScheme) const
{ return equals(aScheme); }
inline bool BooksColorScheme::operator != (const BooksColorScheme& aScheme) const
{ return !equals(aScheme); }
Q_DECLARE_METATYPE(BooksColorScheme)
#endif // BOOKS_COLOR_SCHEME_H

View file

@ -0,0 +1,286 @@
/*
* Copyright (C) 2022 Jolla Ltd.
* Copyright (C) 2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "BooksColorSchemeModel.h"
#include "HarbourDebug.h"
#include <QColor>
// Model roles
#define MODEL_ROLES_(first,role,last) \
first(Key,key) \
role(Label,label) \
last(Color,color)
#define MODEL_ROLES(role) \
MODEL_ROLES_(role,role,role)
// ==========================================================================
// BooksColorSchemeModel::Private
// ==========================================================================
class BooksColorSchemeModel::Private
{
public:
struct ColorDescriptor {
const QString iName;
QString (*iLabel)();
QRgb (BooksColorScheme::*iGetter)() const;
BooksColorScheme (BooksColorScheme::*iSetter)(QRgb) const;
};
enum Role {
#define FIRST(X,x) X##Role = Qt::UserRole,
#define ROLE(X,x) X##Role,
#define LAST(X,x) X##Role
MODEL_ROLES_(FIRST,ROLE,LAST)
#undef FIRST
#undef ROLE
#undef LAST
};
static const ColorDescriptor COLORS[];
#define COLOR_LABEL(colorName,ColorName,key,default) \
static QString ColorName##Label();
BOOKS_COLORS(COLOR_LABEL)
#undef COLOR_LABEL
public:
BooksColorScheme iColorScheme;
};
const BooksColorSchemeModel::Private::ColorDescriptor
BooksColorSchemeModel::Private::COLORS[] = {
#define COLOR_DESCRIPTOR(colorName,ColorName,key,default) \
{ QString(#colorName), &BooksColorSchemeModel::Private::ColorName##Label, \
&BooksColorScheme::colorName, &BooksColorScheme::with##ColorName },
BOOKS_COLORS(COLOR_DESCRIPTOR)
#undef COLOR_DESCRIPTOR
};
#define COLOR_COUNT ((int)\
(sizeof(BooksColorSchemeModel::Private::COLORS)/ \
sizeof(BooksColorSchemeModel::Private::COLORS[0])))
// Localized labels
QString
BooksColorSchemeModel::Private::BackgroundLabel()
{
//: List item label (description of a color scheme element)
//% "Page background"
return qtTrId("harbour-books-color-page_background");
}
QString
BooksColorSchemeModel::Private::ForegroundLabel()
{
//: List item label (description of a color scheme element)
//% "Regular text"
return qtTrId("harbour-books-color-text");
}
QString
BooksColorSchemeModel::Private::SelectionBackgroundLabel()
{
//: List item label (description of a color scheme element)
//% "Selection background"
return qtTrId("harbour-books-color-selection_background");
}
QString
BooksColorSchemeModel::Private::HighlightedTextLabel()
{
//: List item label (description of a color scheme element)
//% "Highlighted text"
return qtTrId("harbour-books-color-highlighted_text");
}
QString
BooksColorSchemeModel::Private::InternalHyperlinkLabel()
{
//: List item label (description of a color scheme element)
//% "Internal hyperlink"
return qtTrId("harbour-books-color-internal_hyperlink");
}
QString
BooksColorSchemeModel::Private::ExternalHyperlinkLabel()
{
//: List item label (description of a color scheme element)
//% "External hyperlink"
return qtTrId("harbour-books-color-external_hyperlink");
}
// ==========================================================================
// BooksColorSchemeModel
// ==========================================================================
BooksColorSchemeModel::BooksColorSchemeModel(
QObject* aParent) :
QAbstractListModel(aParent),
iPrivate(new Private)
{
}
BooksColorSchemeModel::~BooksColorSchemeModel()
{
delete iPrivate;
}
BooksColorScheme
BooksColorSchemeModel::colorScheme() const
{
return iPrivate->iColorScheme;
}
void
BooksColorSchemeModel::setColorScheme(
BooksColorScheme aScheme)
{
int i, nchanged = 0;
bool changed[COLOR_COUNT];
const BooksColorScheme* s1 = &iPrivate->iColorScheme;
const BooksColorScheme* s2 = &aScheme;
for (i = 0; i < COLOR_COUNT; i++) {
const Private::ColorDescriptor* colorDesc = Private::COLORS + i;
if ((s1->*(colorDesc->iGetter))() != (s2->*(colorDesc->iGetter))()) {
changed[i] = true;
nchanged++;
} else {
changed[i] = false;
}
}
if (nchanged) {
HDEBUG(aScheme.toString());
iPrivate->iColorScheme = aScheme;
const QVector<int> roles(1, Private::ColorRole);
for (i = 0; i < COLOR_COUNT && nchanged > 0; i++) {
if (changed[i]) {
const QModelIndex idx(index(i));
Q_EMIT dataChanged(idx, idx, roles);
nchanged--;
}
}
Q_EMIT colorSchemeChanged();
}
}
Qt::ItemFlags
BooksColorSchemeModel::flags(
const QModelIndex& aIndex) const
{
return QAbstractListModel::flags(aIndex) | Qt::ItemIsEditable;
}
QHash<int,QByteArray>
BooksColorSchemeModel::roleNames() const
{
QHash<int,QByteArray> roles;
#define ROLE(X,x) roles.insert(Private::X##Role, #x);
MODEL_ROLES(ROLE)
#undef ROLE
return roles;
}
int
BooksColorSchemeModel::rowCount(
const QModelIndex& aParent) const
{
return COLOR_COUNT;
}
QVariant
BooksColorSchemeModel::data(
const QModelIndex& aIndex,
int aRole) const
{
const int row = aIndex.row();
if (row >= 0 && row < COLOR_COUNT) {
const Private::ColorDescriptor* colorDesc = Private::COLORS + row;
switch ((Private::Role)aRole) {
case Private::KeyRole:
return colorDesc->iName;
case Private::LabelRole:
return colorDesc->iLabel();
case Private::ColorRole:
return QColor(((&iPrivate->iColorScheme)->*(colorDesc->iGetter))());
}
}
return QVariant();
}
bool
BooksColorSchemeModel::setData(
const QModelIndex& aIndex,
const QVariant& aValue,
int aRole)
{
const int row = aIndex.row();
if (row >= 0 && row < COLOR_COUNT) {
QColor newColor;
switch ((Private::Role)aRole) {
case Private::KeyRole:
case Private::LabelRole:
break;
case Private::ColorRole:
newColor = aValue.value<QColor>();
if (newColor.isValid()) {
const QRgb rgb = newColor.rgb();
const Private::ColorDescriptor* colorDesc = Private::COLORS + row;
const BooksColorScheme* scheme = &iPrivate->iColorScheme;
if ((scheme->*(colorDesc->iGetter))() != rgb) {
const QVector<int> roles(1, Private::ColorRole);
HDEBUG(colorDesc->iName << newColor);
iPrivate->iColorScheme = (scheme->*(colorDesc->iSetter))(rgb);
Q_EMIT dataChanged(aIndex, aIndex, roles);
Q_EMIT colorSchemeChanged();
}
return true;
}
break;
}
}
return false;
}

View file

@ -0,0 +1,69 @@
/*
* Copyright (C) 2022 Jolla Ltd.
* Copyright (C) 2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BOOKS_COLOR_SCHEME_MODEL_H
#define BOOKS_COLOR_SCHEME_MODEL_H
#include "BooksColorScheme.h"
#include <QAbstractListModel>
// Represents BooksColorScheme as a list model
class BooksColorSchemeModel: public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(BooksColorScheme colorScheme READ colorScheme WRITE setColorScheme NOTIFY colorSchemeChanged)
public:
explicit BooksColorSchemeModel(QObject* aParent = Q_NULLPTR);
~BooksColorSchemeModel();
BooksColorScheme colorScheme() const;
void setColorScheme(BooksColorScheme);
// QAbstractItemModel
Qt::ItemFlags flags(const QModelIndex&) const Q_DECL_OVERRIDE;
QHash<int,QByteArray> roleNames() const Q_DECL_OVERRIDE;
int rowCount(const QModelIndex& aParent) const Q_DECL_OVERRIDE;
QVariant data(const QModelIndex&, int) const Q_DECL_OVERRIDE;
bool setData(const QModelIndex&, const QVariant&, int) Q_DECL_OVERRIDE;
Q_SIGNALS:
void colorSchemeChanged();
private:
class Private;
Private* iPrivate;
};
#endif // BOOKS_COLOR_SCHEME_MODEL_H

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 2015-2021 Jolla Ltd.
* Copyright (C) 2015-2021 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2015-2022 Jolla Ltd.
* Copyright (C) 2015-2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
@ -58,13 +58,24 @@
#define BOOKS_QML_PLUGIN "harbour.books"
#define BOOKS_QML_PLUGIN_V1 1
#define BOOKS_QML_PLUGIN_V2 0
#define BOOKS_QML_REGISTER(klass,name) \
#define BOOKS_QML_REGISTER_(klass,name) \
qmlRegisterType<klass>(BOOKS_QML_PLUGIN, BOOKS_QML_PLUGIN_V1, \
BOOKS_QML_PLUGIN_V2, name)
#define BOOKS_QML_REGISTER_SINGLETON(klass,name) \
#define BOOKS_QML_REGISTER_UNCREATABLE_(klass,name) \
qmlRegisterUncreatableType<klass>(BOOKS_QML_PLUGIN, BOOKS_QML_PLUGIN_V1, \
BOOKS_QML_PLUGIN_V2, name, QString())
#define BOOKS_QML_REGISTER_SINGLETON_(klass,name) \
qmlRegisterSingletonType<klass>(BOOKS_QML_PLUGIN, BOOKS_QML_PLUGIN_V1, \
BOOKS_QML_PLUGIN_V2, name, klass::createSingleton)
#define BOOKS_QML_REGISTER(klass) \
BOOKS_QML_REGISTER_(klass,#klass)
#define BOOKS_QML_REGISTER_UNCREATABLE(klass) \
BOOKS_QML_REGISTER_UNCREATABLE_(klass,#klass)
#define BOOKS_QML_REGISTER_SINGLETON(klass) \
BOOKS_QML_REGISTER_SINGLETON_(klass,#klass)
#define BOOKS_STATE_FILE_SUFFIX ".state"
#define BOOKS_MARKS_FILE_SUFFIX ".marks"

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 2015-2020 Jolla Ltd.
* Copyright (C) 2015-2020 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2015-2021 Jolla Ltd.
* Copyright (C) 2015-2021 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
@ -60,7 +60,9 @@ public:
Data(shared_ptr<ZLTextModel> aModel, int aWidth, int aHeight) :
iModel(aModel), iPaintContext(aWidth, aHeight) {}
bool paint(QPainter* aPainter);
bool paint(QPainter* aPainter, BooksColorScheme aColors);
inline int width() const { return iPaintContext.width(); }
inline int height() const { return iPaintContext.height(); }
public:
shared_ptr<BooksTextView> iView;
@ -68,9 +70,10 @@ public:
BooksPaintContext iPaintContext;
};
bool BooksPageWidget::Data::paint(QPainter* aPainter)
bool BooksPageWidget::Data::paint(QPainter* aPainter, BooksColorScheme aColors)
{
if (!iView.isNull()) {
iPaintContext.iColors = aColors;
iPaintContext.beginPaint(aPainter);
iView->paint();
iPaintContext.endPaint();
@ -141,26 +144,28 @@ void BooksPageWidget::ResetTask::performTask()
class BooksPageWidget::RenderTask : public HarbourTask {
public:
RenderTask(QThreadPool* aPool, QThread* aTargetThread, Data::Ptr aData,
int aWidth, int aHeight) : HarbourTask(aPool, aTargetThread),
iData(aData), iWidth(aWidth), iHeight(aHeight) {}
BooksColorScheme aColors) : HarbourTask(aPool, aTargetThread),
iData(aData), iColors(aColors) {}
void performTask();
public:
Data::Ptr iData;
int iWidth;
int iHeight;
BooksColorScheme iColors;
QImage iImage;
};
void BooksPageWidget::RenderTask::performTask()
{
if (!isCanceled() && !iData.isNull() && !iData->iView.isNull() &&
iWidth > 0 && iHeight > 0) {
iImage = QImage(iWidth, iHeight, QImage::Format_ARGB32_Premultiplied);
if (!isCanceled()) {
QPainter painter(&iImage);
iData->paint(&painter);
if (!iData.isNull() && !iData->iView.isNull()) {
const int width = iData->width();
const int height = iData->height();
if (width > 0 && height > 0) {
iImage = QImage(width, height, QImage::Format_ARGB32_Premultiplied);
if (!isCanceled()) {
QPainter painter(&iImage);
iData->paint(&painter, iColors);
}
}
}
}
@ -171,32 +176,34 @@ void BooksPageWidget::RenderTask::performTask()
class BooksPageWidget::ClearSelectionTask : public HarbourTask {
public:
ClearSelectionTask(QThreadPool* aPool, Data::Ptr aData, int aWidth,
int aHeight) : HarbourTask(aPool),
iData(aData), iWidth(aWidth), iHeight(aHeight), iImageUpdated(false) {}
ClearSelectionTask(QThreadPool* aPool, Data::Ptr aData, BooksColorScheme aColors) :
HarbourTask(aPool), iData(aData), iColors(aColors), iImageUpdated(false) {}
void performTask();
public:
Data::Ptr iData;
int iWidth;
int iHeight;
BooksColorScheme iColors;
QImage iImage;
bool iImageUpdated;
};
void BooksPageWidget::ClearSelectionTask::performTask()
{
iData->iView->endSelection();
if (!isCanceled() && iWidth > 0 && iHeight > 0) {
const ZLTextArea& area = iData->iView->textArea();
if (!area.selectionIsEmpty()) {
area.clearSelection();
iImage = QImage(iWidth, iHeight, QImage::Format_ARGB32_Premultiplied);
if (!isCanceled()) {
QPainter painter(&iImage);
iData->paint(&painter);
iImageUpdated = true;
if (!iData.isNull() && !iData->iView.isNull()) {
iData->iView->endSelection();
const int width = iData->width();
const int height = iData->height();
if (!isCanceled() && width > 0 && height > 0) {
const ZLTextArea& area = iData->iView->textArea();
if (!area.selectionIsEmpty()) {
area.clearSelection();
iImage = QImage(width, height, QImage::Format_ARGB32_Premultiplied);
if (!isCanceled()) {
QPainter painter(&iImage);
iData->paint(&painter, iColors);
iImageUpdated = true;
}
}
}
}
@ -209,8 +216,8 @@ void BooksPageWidget::ClearSelectionTask::performTask()
class BooksPageWidget::StartSelectionTask : public HarbourTask {
public:
StartSelectionTask(QThreadPool* aPool, Data::Ptr aData, int aX, int aY,
int aWidth, int aHeight) : HarbourTask(aPool),
iData(aData), iX(aX), iY(aY), iWidth(aWidth), iHeight(aHeight),
BooksColorScheme aColors) : HarbourTask(aPool),
iData(aData), iX(aX), iY(aY), iColors(aColors),
iSelectionEmpty(true) {}
void performTask();
@ -219,22 +226,25 @@ public:
Data::Ptr iData;
int iX;
int iY;
int iWidth;
int iHeight;
BooksColorScheme iColors;
QImage iImage;
bool iSelectionEmpty;
};
void BooksPageWidget::StartSelectionTask::performTask()
{
if (!isCanceled() && iWidth > 0 && iHeight > 0) {
iData->iView->startSelection(iX, iY);
iSelectionEmpty = iData->iView->textArea().selectionIsEmpty();
if (!isCanceled()) {
iImage = QImage(iWidth, iHeight, QImage::Format_RGB32);
if (!iData.isNull() && !iData->iView.isNull()) {
const int width = iData->width();
const int height = iData->height();
if (width > 0 && height > 0) {
iData->iView->startSelection(iX, iY);
iSelectionEmpty = iData->iView->textArea().selectionIsEmpty();
if (!isCanceled()) {
QPainter painter(&iImage);
iData->paint(&painter);
iImage = QImage(width, height, QImage::Format_ARGB32_Premultiplied);
if (!isCanceled()) {
QPainter painter(&iImage);
iData->paint(&painter, iColors);
}
}
}
}
@ -247,8 +257,8 @@ void BooksPageWidget::StartSelectionTask::performTask()
class BooksPageWidget::ExtendSelectionTask : public HarbourTask {
public:
ExtendSelectionTask(QThreadPool* aPool, Data::Ptr aData, int aX, int aY,
int aWidth, int aHeight) : HarbourTask(aPool),
iData(aData), iX(aX), iY(aY), iWidth(aWidth), iHeight(aHeight),
BooksColorScheme aColors) : HarbourTask(aPool),
iData(aData), iX(aX), iY(aY), iColors(aColors),
iSelectionChanged(false), iSelectionEmpty(true) {}
void performTask();
@ -257,8 +267,7 @@ public:
Data::Ptr iData;
int iX;
int iY;
int iWidth;
int iHeight;
BooksColorScheme iColors;
QImage iImage;
bool iSelectionChanged;
bool iSelectionEmpty;
@ -266,14 +275,18 @@ public:
void BooksPageWidget::ExtendSelectionTask::performTask()
{
if (!isCanceled() && iWidth > 0 && iHeight > 0) {
iSelectionChanged = iData->iView->extendSelection(iX, iY);
iSelectionEmpty = iData->iView->textArea().selectionIsEmpty();
if (iSelectionChanged && !isCanceled()) {
iImage = QImage(iWidth, iHeight, QImage::Format_RGB32);
if (!isCanceled()) {
QPainter painter(&iImage);
iData->paint(&painter);
if (!iData.isNull() && !iData->iView.isNull()) {
const int width = iData->width();
const int height = iData->height();
if (width > 0 && height > 0) {
iSelectionChanged = iData->iView->extendSelection(iX, iY);
iSelectionEmpty = iData->iView->textArea().selectionIsEmpty();
if (iSelectionChanged && !isCanceled()) {
iImage = QImage(width, height, QImage::Format_ARGB32_Premultiplied);
if (!isCanceled()) {
QPainter painter(&iImage);
iData->paint(&painter, iColors);
}
}
}
}
@ -290,7 +303,7 @@ public:
shared_ptr<ZLTextModel> aTextModel, shared_ptr<ZLTextStyle> aTextStyle,
const BooksSettings* aSettings) : HarbourTask(aPool),
iTextModel(aTextModel), iTextStyle(aTextStyle),
iInvertColors(aSettings->invertColors()),
iColors(aSettings->colorScheme()),
iX(aX), iY(aY), iMaxWidth(aMaxWidth), iMaxHeight(aMaxHeight),
iRef(aRef), iLinkText(aLinkText), iPath(aPath) {}
~FootnoteTask();
@ -305,7 +318,7 @@ public:
public:
shared_ptr<ZLTextModel> iTextModel;
shared_ptr<ZLTextStyle> iTextStyle;
bool iInvertColors;
BooksColorScheme iColors;
int iX;
int iY;
int iMaxWidth;
@ -327,7 +340,7 @@ shared_ptr<ZLTextStyle> BooksPageWidget::FootnoteTask::baseStyle() const
ZLColor BooksPageWidget::FootnoteTask::color(const std::string& aStyle) const
{
return BooksPaintContext::realColor(aStyle, iInvertColors);
return BooksPaintContext::realColor(aStyle, iColors);
}
bool BooksPageWidget::FootnoteTask::isSelectionEnabled() const
@ -340,7 +353,7 @@ void BooksPageWidget::FootnoteTask::performTask()
if (!isCanceled()) {
// Determine the size of the footnote canvas
ZLTextParagraphCursorCache cache;
BooksPaintContext sizeContext(iMaxWidth, iMaxHeight);
BooksPaintContext sizeContext(iMaxWidth, iMaxHeight, iColors);
ZLTextAreaController sizeController(sizeContext, *this, &cache);
ZLSize size;
sizeController.setModel(iTextModel);
@ -351,8 +364,7 @@ void BooksPageWidget::FootnoteTask::performTask()
size.myWidth = (size.myWidth + 3) & -4;
HDEBUG("footnote size:" << size.myWidth << "x" << size.myHeight);
cache.clear();
BooksPaintContext paintContext(size.myWidth, size.myHeight);
paintContext.setInvertColors(iInvertColors);
BooksPaintContext paintContext(size.myWidth, size.myHeight, iColors);
ZLTextAreaController paintController(paintContext, *this, &cache);
iImage = QImage(size.myWidth, size.myHeight, QImage::Format_ARGB32_Premultiplied);
QPainter painter(&iImage);
@ -510,7 +522,7 @@ BooksPageWidget::BooksPageWidget(QQuickItem* aParent) :
iCurrentPage(false),
iPage(-1)
{
connect(iSettings.data(), SIGNAL(invertColorsChanged()), SLOT(onColorsChanged()));
connect(iSettings.data(), SIGNAL(colorSchemeChanged()), SLOT(onColorsChanged()));
setFlag(ItemHasContents, true);
iResizeTimer->setSingleShot(true);
iResizeTimer->setInterval(0);
@ -753,9 +765,9 @@ void BooksPageWidget::scheduleRepaint()
const int h = height();
if (w > 0 && h > 0 && !iData.isNull() && !iData->iView.isNull()) {
const shared_ptr<BooksTextView> view(iData->iView);
view->setInvertColors(iSettings->invertColors());
(iRenderTask = new RenderTask(iTaskQueue->pool(), thread(),
iData, w, h))->submit(this, SLOT(onRenderTaskDone()));
iData, iSettings->colorScheme()))->
submit(this, SLOT(onRenderTaskDone()));
} else {
update();
}
@ -876,11 +888,9 @@ void BooksPageWidget::onFootnoteTaskDone()
// Footnotes with normal and inverted background need to
// have different ids so that the cached image with the wrong
// background doesn't show up after we invert the colors
static const QString NORMAL("n");
static const QString INVERTED("i");
static const QString FOOTNOTE_ID("footnote/%1#%2?p=%3&t=%4&s=%5x%6");
static const QString FOOTNOTE_ID("footnote/%1#%2?p=%3&c=%4&s=%5x%6");
QString id = FOOTNOTE_ID.arg(task->iPath, task->iRef).
arg(iPage).arg(task->iInvertColors ? INVERTED : NORMAL).
arg(iPage).arg(task->iColors.schemeId()).
arg(task->iImage.width()).arg(task->iImage.height());
QString url = IMAGE_URL.arg(BooksImageProvider::PROVIDER_ID, id);
HDEBUG(url);
@ -958,8 +968,8 @@ void BooksPageWidget::onLongPressTaskDone()
} else if (!iData.isNull()) {
if (iStartSelectionTask) iStartSelectionTask->release(this);
(iStartSelectionTask = new StartSelectionTask(iTaskQueue->pool(), iData,
task->iX, task->iY, width(), height()))->
submit(this, SLOT(onStartSelectionTaskDone()));
task->iX, task->iY, iSettings->colorScheme()))->
submit(this, SLOT(onStartSelectionTaskDone()));
}
task->release(this);
@ -1040,8 +1050,8 @@ void BooksPageWidget::handlePositionChanged(int aX, int aY)
}
}
(task = new ExtendSelectionTask(iTaskQueue->pool(), iData,
aX, aY, width(), height()))->
submit(this, SLOT(onExtendSelectionTaskDone()));
aX, aY, iSettings->colorScheme()))->
submit(this, SLOT(onExtendSelectionTaskDone()));
iExtendSelectionTasks.append(task);
} else {
// Finger was moved before we entered selection mode
@ -1058,8 +1068,8 @@ void BooksPageWidget::clearSelection()
if (!iData.isNull()) {
if (iClearSelectionTask) iClearSelectionTask->release(this);
(iClearSelectionTask =new ClearSelectionTask(iTaskQueue->pool(),
iData, width(), height()))->
submit(this, SLOT(onClearSelectionTaskDone()));
iData, iSettings->colorScheme()))->
submit(this, SLOT(onClearSelectionTaskDone()));
}
if (iSelecting) {
iSelecting = false;

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 2015-2020 Jolla Ltd.
* Copyright (C) 2015-2020 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2015-2022 Jolla Ltd.
* Copyright (C) 2015-2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
@ -48,14 +48,13 @@
static const std::string HELVETICA = "Helvetica";
BooksPaintContext::BooksPaintContext() :
iPainter(NULL), iWidth(0), iHeight(0),
iSpaceWidth(0), iDescent(0), iInvertColors(false)
iPainter(Q_NULLPTR), iSpaceWidth(0), iDescent(0), iWidth(0), iHeight(0)
{
}
BooksPaintContext::BooksPaintContext(int aWidth, int aHeight) :
iPainter(NULL), iWidth(aWidth), iHeight(aHeight),
iSpaceWidth(0), iDescent(0), iInvertColors(false)
BooksPaintContext::BooksPaintContext(int aWidth, int aHeight, BooksColorScheme aColors) :
iPainter(Q_NULLPTR), iSpaceWidth(0), iDescent(0),
iWidth(aWidth), iHeight(aHeight), iColors(aColors)
{
}
@ -71,7 +70,7 @@ void BooksPaintContext::beginPaint(QPainter *aPainter)
void BooksPaintContext::endPaint()
{
iPainter = NULL;
iPainter = Q_NULLPTR;
}
void BooksPaintContext::fillFamiliesList(std::vector<std::string> &families) const
@ -259,23 +258,12 @@ int BooksPaintContext::height() const
return iHeight;
}
ZLColor BooksPaintContext::realColor(uchar aRed, uchar aGreen, uchar aBlue, uchar aAlpha,
bool aInvertColors)
{
if (aInvertColors) {
aRed = 255 - aRed;
aGreen = 255 - aGreen;
aBlue = 255 - aBlue;
}
return ZLColor(aRed, aGreen, aBlue, aAlpha);
}
ZLColor BooksPaintContext::realColor(const std::string& aStyle, bool aInvert)
ZLColor BooksPaintContext::realColor(const std::string& aStyle, BooksColorScheme aColors)
{
static const std::string INTERNAL_HYPERLINK("internal");
static const std::string EXTERNAL_HYPERLINK("external");
static const std::string BOOK_HYPERLINK("book");
unsigned long argb = ZLColor::rgbValue(0);
unsigned long argb = ZLColor::rgbValue(aColors.foreground());
if (ZLStringUtil::startsWith(aStyle, '#')) {
const size_t len = aStyle.length();
@ -306,15 +294,13 @@ ZLColor BooksPaintContext::realColor(const std::string& aStyle, bool aInvert)
}
}
} else if (aStyle == INTERNAL_HYPERLINK) {
argb = ZLColor::rgbValue(0x2160b4);
} else if (aStyle == EXTERNAL_HYPERLINK) {
argb = ZLColor::rgbValue(0x2160b4);
} else if (aStyle == BOOK_HYPERLINK) {
argb = ZLColor::rgbValue(0x174480);
argb = ZLColor::rgbValue(aColors.internalHyperlink());
} else if (aStyle == EXTERNAL_HYPERLINK || aStyle == BOOK_HYPERLINK) {
argb = ZLColor::rgbValue(aColors.externalHyperlink());
} else if (aStyle == ZLTextStyle::SELECTION_BACKGROUND) {
argb = ZLColor::rgbValue(0x3c8bff);
argb = ZLColor::rgbValue(aColors.selectionBackground());
} else if (aStyle == ZLTextStyle::HIGHLIGHTED_TEXT) {
argb = ZLColor::rgbValue(0x3c8bff);
argb = ZLColor::rgbValue(aColors.highlightedText());
}
return realColor(ZLColor(argb), aInvert);
return ZLColor(argb);
}

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 2015-2020 Jolla Ltd.
* Copyright (C) 2015-2020 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2015-2021 Jolla Ltd.
* Copyright (C) 2015-2021 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
@ -35,6 +35,7 @@
#define BOOKS_PAINT_CONTEXT_H
#include "BooksTypes.h"
#include "BooksColorScheme.h"
#include "ZLColor.h"
#include "ZLPaintContext.h"
@ -46,73 +47,63 @@
class QPainter;
class BooksPaintContext : public ZLPaintContext {
public:
BooksPaintContext(int aWidth, int aHeight);
protected:
BooksPaintContext();
public:
BooksPaintContext(int aWidth, int aHeight, BooksColorScheme aColors = BooksColorScheme());
~BooksPaintContext();
void setWidth(int aWidth);
void setHeight(int aHeight);
void setSize(int aWidth, int aHeight);
bool isEmpty() const;
QSize size() const;
// ZLPaintContext
void beginPaint(QPainter* painter);
void endPaint();
int width() const;
int height() const;
// ZLPaintContext
int width() const Q_DECL_OVERRIDE;
int height() const Q_DECL_OVERRIDE;
void clear(ZLColor color);
void clear(ZLColor color) Q_DECL_OVERRIDE;
void fillFamiliesList(std::vector<std::string>& families) const;
const std::string realFontFamilyName(std::string& fontFamily) const;
void fillFamiliesList(std::vector<std::string>& families) const Q_DECL_OVERRIDE;
const std::string realFontFamilyName(std::string& fontFamily) const Q_DECL_OVERRIDE;
void setFont(const std::string& family, int size, bool bold, bool italic);
void setColor(ZLColor color, LineStyle style);
void setFillColor(ZLColor color, FillStyle style);
void setFont(const std::string& family, int size, bool bold, bool italic) Q_DECL_OVERRIDE;
void setColor(ZLColor color, LineStyle style) Q_DECL_OVERRIDE;
void setFillColor(ZLColor color, FillStyle style) Q_DECL_OVERRIDE;
int stringWidth(const char* str, int len, bool rtl) const;
int spaceWidth() const;
int stringHeight() const;
int descent() const;
void drawString(int x, int y, const char* str, int len, bool rtl);
int stringWidth(const char* str, int len, bool rtl) const Q_DECL_OVERRIDE;
int spaceWidth() const Q_DECL_OVERRIDE;
int stringHeight() const Q_DECL_OVERRIDE;
int descent() const Q_DECL_OVERRIDE;
void drawString(int x, int y, const char* str, int len, bool rtl) Q_DECL_OVERRIDE;
void drawImage(int x, int y, const ZLImageData& image);
void drawImage(int x, int y, const ZLImageData& image, int width, int height, ScalingType type);
void drawImage(int x, int y, const ZLImageData& image) Q_DECL_OVERRIDE;
void drawImage(int x, int y, const ZLImageData& image, int width, int height, ScalingType type) Q_DECL_OVERRIDE;
void drawLine(int x0, int y0, int x1, int y1);
void fillRectangle(int x0, int y0, int x1, int y1);
void drawFilledCircle(int x, int y, int r);
void setInvertColors(bool aInvertColors);
void drawLine(int x0, int y0, int x1, int y1) Q_DECL_OVERRIDE;
void fillRectangle(int x0, int y0, int x1, int y1) Q_DECL_OVERRIDE;
void drawFilledCircle(int x, int y, int r) Q_DECL_OVERRIDE;
ZLColor realColor(const ZLColor aColor) const;
ZLColor realColor(const std::string& aStyle) const;
static ZLColor realColor(const std::string& aStyle, bool aInvert);
private:
ZLColor realColor(uchar aRed, uchar aGreen, uchar aBlue, uchar aAlpha) const;
static ZLColor realColor(uchar aRed, uchar aGreen, uchar aBlue, uchar aAlpha, bool aInvert);
static ZLColor realColor(const ZLColor aColor, bool aInvert);
static ZLColor realColor(const std::string& aStyle, BooksColorScheme aColors);
private:
QPainter* iPainter;
int iWidth;
int iHeight;
mutable int iSpaceWidth;
int iDescent;
bool iInvertColors;
QFont iFont;
protected:
int iWidth;
int iHeight;
public:
BooksColorScheme iColors;
};
inline void BooksPaintContext::setWidth(int aWidth)
{ iWidth = aWidth; }
inline void BooksPaintContext::setHeight(int aHeight)
{ iHeight = aHeight; }
inline void BooksPaintContext::setSize(int aWidth, int aHeight)
{ iWidth = aWidth; iHeight = aHeight; }
inline bool BooksPaintContext::isEmpty() const
{ return (iWidth <= 0 || iHeight <= 0); }
inline QSize BooksPaintContext::size() const
@ -120,15 +111,7 @@ inline QSize BooksPaintContext::size() const
inline QColor qtColor(const ZLColor& aColor)
{ return QColor(aColor.Red, aColor.Green, aColor.Blue, aColor.Alpha); }
inline ZLColor BooksPaintContext::realColor(const ZLColor aColor) const
{ return realColor(aColor.Red, aColor.Green, aColor.Blue, aColor.Alpha); }
inline ZLColor BooksPaintContext::realColor(uchar aRed, uchar aGreen, uchar aBlue, uchar aAlpha) const
{ return realColor(aRed, aGreen, aBlue, aAlpha, iInvertColors); }
inline ZLColor BooksPaintContext::realColor(const ZLColor aColor, bool aInvert)
{ return realColor(aColor.Red, aColor.Green, aColor.Blue, aColor.Alpha, aInvert); }
inline ZLColor BooksPaintContext::realColor(const std::string& aStyle) const
{ return realColor(aStyle, iInvertColors); }
inline void BooksPaintContext::setInvertColors(bool aInvertColors)
{ iInvertColors = aInvertColors; }
{ return realColor(aStyle, iColors); }
#endif /* BOOKS_PAINT_CONTEXT_H */

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 2015-2021 Jolla Ltd.
* Copyright (C) 2015-2021 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2015-2022 Jolla Ltd.
* Copyright (C) 2015-2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
@ -44,21 +44,21 @@
#include <MGConfItem>
#define DCONF_PATH BOOKS_DCONF_ROOT
#define KEY_FONT_SIZE "fontSize"
#define KEY_PAGE_DETAILS "pageDetails"
#define KEY_NIGHT_MODE_BRIGHTNESS "nightModeBrightness"
#define KEY_PAGE_DETAILS_FIXED "pageDetailsFixed"
#define KEY_TURN_PAGE_BY_TAP "turnPageByTap"
#define KEY_SAMPLE_BOOK_COPIED "sampleBookCopied"
#define KEY_CURRENT_BOOK "currentBook"
#define KEY_CURRENT_FOLDER "currentFolder"
#define KEY_REMOVABLE_ROOT "removableRoot"
#define KEY_INVERT_COLORS "invertColors"
#define KEY_KEEP_DISPLAY_ON "keepDisplayOn"
#define KEY_BOOK_PULL_DOWN_MENU "bookPullDownMenu"
#define KEY_VOLUME_UP_ACTION "volumeUpAction"
#define KEY_VOLUME_DOWN_ACTION "volumeDownAction"
#define KEY_ORIENTATION "orientation"
#define DCONF_PATH_(x) BOOKS_DCONF_ROOT x
#define KEY_FONT_SIZE DCONF_PATH_("fontSize")
#define KEY_PAGE_DETAILS DCONF_PATH_("pageDetails")
#define KEY_NIGHT_MODE_BRIGHTNESS DCONF_PATH_("nightModeBrightness")
#define KEY_PAGE_DETAILS_FIXED DCONF_PATH_("pageDetailsFixed")
#define KEY_TURN_PAGE_BY_TAP DCONF_PATH_("turnPageByTap")
#define KEY_SAMPLE_BOOK_COPIED DCONF_PATH_("sampleBookCopied")
#define KEY_CURRENT_BOOK DCONF_PATH_("currentBook")
#define KEY_CURRENT_FOLDER DCONF_PATH_("currentFolder")
#define KEY_REMOVABLE_ROOT DCONF_PATH_("removableRoot")
#define KEY_KEEP_DISPLAY_ON DCONF_PATH_("keepDisplayOn")
#define KEY_BOOK_PULL_DOWN_MENU DCONF_PATH_("bookPullDownMenu")
#define KEY_VOLUME_UP_ACTION DCONF_PATH_("volumeUpAction")
#define KEY_VOLUME_DOWN_ACTION DCONF_PATH_("volumeDownAction")
#define KEY_ORIENTATION DCONF_PATH_("orientation")
#define DEFAULT_FONT_SIZE 0
#define DEFAULT_NIGHT_BRIGHTNESS 1.0
@ -69,15 +69,12 @@
#define DEFAULT_CURRENT_BOOK QString()
#define DEFAULT_CURRENT_FOLDER QString()
#define DEFAULT_REMOVABLE_ROOT "Books"
#define DEFAULT_INVERT_COLORS false
#define DEFAULT_KEEP_DISPLAY_ON false
#define DEFAULT_BOOK_PULL_DOWN_MENU true
#define DEFAULT_VOLUME_UP_ACTION (BooksSettings::ActionNextPage)
#define DEFAULT_VOLUME_DOWN_ACTION (BooksSettings::ActionPreviousPage)
#define DEFAULT_ORIENTATION (BooksSettings::OrientationAny)
#define DEFAULT_BACKGROUND QColor(Qt::white)
#define INVERTED_BACKGROUND QColor(Qt::black)
#define PAGETOOL_COLOR QColor(128,128,128) // any bg
#define NORMAL_PAGETOOL_HIGHLIGHT_COLOR QColor(64,64,64) // on white
#define INVERTED_PAGETOOL_HIGHLIGHT_COLOR QColor(192,192,192) // on black
@ -94,27 +91,27 @@ public:
iFontSize(iDefaultStyle->fontSize() + 2*aFontSizeModifier)
{ HDEBUG(iFontSize); }
bool isDecorated() const;
bool isDecorated() const Q_DECL_OVERRIDE;
const std::vector<std::string> &fontFamilies() const;
const std::vector<std::string> &fontFamilies() const Q_DECL_OVERRIDE;
int fontSize() const;
bool bold() const;
bool italic() const;
int fontSize() const Q_DECL_OVERRIDE;
bool bold() const Q_DECL_OVERRIDE;
bool italic() const Q_DECL_OVERRIDE;
const std::string &colorStyle() const;
const std::string &colorStyle() const Q_DECL_OVERRIDE;
short spaceBefore(const ZLTextStyleEntry::Metrics& aMetrics) const;
short spaceAfter(const ZLTextStyleEntry::Metrics& aMetrics) const;
short lineStartIndent(const ZLTextStyleEntry::Metrics& aMetrics, bool aRtl) const;
short lineEndIndent(const ZLTextStyleEntry::Metrics& aMetrics, bool aRtl) const;
short firstLineIndentDelta(const ZLTextStyleEntry::Metrics& aMetrics) const;
int verticalShift() const;
short spaceBefore(const ZLTextStyleEntry::Metrics&) const Q_DECL_OVERRIDE;
short spaceAfter(const ZLTextStyleEntry::Metrics&) const Q_DECL_OVERRIDE;
short lineStartIndent(const ZLTextStyleEntry::Metrics&, bool) const Q_DECL_OVERRIDE;
short lineEndIndent(const ZLTextStyleEntry::Metrics&, bool) const Q_DECL_OVERRIDE;
short firstLineIndentDelta(const ZLTextStyleEntry::Metrics&) const Q_DECL_OVERRIDE;
int verticalShift() const Q_DECL_OVERRIDE;
ZLTextAlignmentType alignment() const;
ZLTextAlignmentType alignment() const Q_DECL_OVERRIDE;
double lineSpace() const;
bool allowHyphenations() const;
double lineSpace() const Q_DECL_OVERRIDE;
bool allowHyphenations() const Q_DECL_OVERRIDE;
private:
shared_ptr<ZLTextStyle> iDefaultStyle;
@ -222,28 +219,35 @@ BooksSettings::TextStyle::allowHyphenations() const
// BooksSettings::Private
// ==========================================================================
class BooksSettings::Private : public QObject {
class BooksSettings::Private : public QObject
{
Q_OBJECT
public:
Private(BooksSettings* aParent);
// Matches Silica::Theme::ColorScheme
enum ColorScheme {
LightOnDark,
DarkOnLight
};
BooksSettings* parentSettings() const;
Private(BooksSettings* aParent);
~Private();
BooksSettings* parentObject() const;
bool updateCurrentBook();
bool updateCurrentStorage();
bool updateBrightness();
bool invertColors() const;
int fontSizeValue() const;
int fontSize(int aFontSizeAdjust) const;
qreal brightnessValue() const;
qreal nightModeBrightness() const;
QString currentFolder() const;
shared_ptr<ZLTextStyle> textStyle(int aFontSizeAdjust) const;
void setCurrentBook(QObject* aBook);
static Action getAction(MGConfItem* aItem, Action aDefault);
static qreal normalizeBrightness(qreal aBrightness);
void setCurrentBook(QObject*);
static Action getAction(MGConfItem*, Action);
static qreal normalizeBrightness(qreal);
private Q_SLOTS:
void onInvertColorsChanged();
public Q_SLOTS:
void onNightModeChanged();
void onNightModeBrightnessChanged();
void onFontSizeValueChanged();
void onCurrentBookPathChanged();
@ -256,7 +260,6 @@ public:
MGConfItem* iPageDetailsConf;
MGConfItem* iPageDetailsFixedConf;
MGConfItem* iTurnPageByTapConf;
MGConfItem* iInvertColorsConf;
MGConfItem* iSampleBookCopiedConf;
MGConfItem* iKeepDisplayOnConf;
MGConfItem* iBookPullDownMenuConf;
@ -277,29 +280,28 @@ QWeakPointer<BooksSettings> BooksSettings::Private::sSharedInstance;
BooksSettings::Private::Private(BooksSettings* aParent) :
QObject(aParent),
iFontSizeConf(new MGConfItem(DCONF_PATH KEY_FONT_SIZE, this)),
iNightModeBrightnessConf(new MGConfItem(DCONF_PATH KEY_NIGHT_MODE_BRIGHTNESS, this)),
iPageDetailsConf(new MGConfItem(DCONF_PATH KEY_PAGE_DETAILS, this)),
iPageDetailsFixedConf(new MGConfItem(DCONF_PATH KEY_PAGE_DETAILS_FIXED, this)),
iTurnPageByTapConf(new MGConfItem(DCONF_PATH KEY_TURN_PAGE_BY_TAP, this)),
iInvertColorsConf(new MGConfItem(DCONF_PATH KEY_INVERT_COLORS, this)),
iSampleBookCopiedConf(new MGConfItem(DCONF_PATH KEY_SAMPLE_BOOK_COPIED, this)),
iKeepDisplayOnConf(new MGConfItem(DCONF_PATH KEY_KEEP_DISPLAY_ON, this)),
iBookPullDownMenuConf(new MGConfItem(DCONF_PATH KEY_BOOK_PULL_DOWN_MENU, this)),
iVolumeUpActionConf(new MGConfItem(DCONF_PATH KEY_VOLUME_UP_ACTION, this)),
iVolumeDownActionConf(new MGConfItem(DCONF_PATH KEY_VOLUME_DOWN_ACTION, this)),
iCurrentFolderConf(new MGConfItem(DCONF_PATH KEY_CURRENT_FOLDER, this)),
iCurrentBookPathConf(new MGConfItem(DCONF_PATH KEY_CURRENT_BOOK, this)),
iOrientationConf(new MGConfItem(DCONF_PATH KEY_ORIENTATION, this)),
iRemovableRootConf(new MGConfItem(DCONF_PATH KEY_REMOVABLE_ROOT, this)),
iCurrentBook(NULL)
iFontSizeConf(new MGConfItem(KEY_FONT_SIZE, this)),
iNightModeBrightnessConf(new MGConfItem(KEY_NIGHT_MODE_BRIGHTNESS, this)),
iPageDetailsConf(new MGConfItem(KEY_PAGE_DETAILS, this)),
iPageDetailsFixedConf(new MGConfItem(KEY_PAGE_DETAILS_FIXED, this)),
iTurnPageByTapConf(new MGConfItem(KEY_TURN_PAGE_BY_TAP, this)),
iSampleBookCopiedConf(new MGConfItem(KEY_SAMPLE_BOOK_COPIED, this)),
iKeepDisplayOnConf(new MGConfItem(KEY_KEEP_DISPLAY_ON, this)),
iBookPullDownMenuConf(new MGConfItem(KEY_BOOK_PULL_DOWN_MENU, this)),
iVolumeUpActionConf(new MGConfItem(KEY_VOLUME_UP_ACTION, this)),
iVolumeDownActionConf(new MGConfItem(KEY_VOLUME_DOWN_ACTION, this)),
iCurrentFolderConf(new MGConfItem(KEY_CURRENT_FOLDER, this)),
iCurrentBookPathConf(new MGConfItem(KEY_CURRENT_BOOK, this)),
iOrientationConf(new MGConfItem(KEY_ORIENTATION, this)),
iRemovableRootConf(new MGConfItem(KEY_REMOVABLE_ROOT, this)),
iCurrentBook(Q_NULLPTR)
{
iFontSize = fontSizeValue();
iBrightness = brightnessValue();
connect(aParent, SIGNAL(nightModeChanged()), SLOT(onNightModeChanged()));
connect(iFontSizeConf, SIGNAL(valueChanged()), SLOT(onFontSizeValueChanged()));
connect(iCurrentFolderConf, SIGNAL(valueChanged()), SLOT(onCurrentFolderChanged()));
connect(iCurrentBookPathConf, SIGNAL(valueChanged()), SLOT(onCurrentBookPathChanged()));
connect(iInvertColorsConf, SIGNAL(valueChanged()), SLOT(onInvertColorsChanged()));
connect(iNightModeBrightnessConf, SIGNAL(valueChanged()), SLOT(onNightModeBrightnessChanged()));
connect(iPageDetailsConf, SIGNAL(valueChanged()), aParent, SIGNAL(pageDetailsChanged()));
connect(iPageDetailsFixedConf, SIGNAL(valueChanged()), aParent, SIGNAL(pageDetailsFixedChanged()));
@ -313,16 +315,14 @@ BooksSettings::Private::Private(BooksSettings* aParent) :
connect(iRemovableRootConf, SIGNAL(valueChanged()), aParent, SIGNAL(removableRootChanged()));
}
inline BooksSettings*
BooksSettings::Private::parentSettings() const
BooksSettings::Private::~Private()
{
return qobject_cast<BooksSettings*>(parent());
}
inline bool
BooksSettings::Private::invertColors() const
inline BooksSettings*
BooksSettings::Private::parentObject() const
{
return iInvertColorsConf->value(DEFAULT_INVERT_COLORS).toBool();
return qobject_cast<BooksSettings*>(parent());
}
inline qreal
@ -344,7 +344,7 @@ BooksSettings::Private::nightModeBrightness() const
inline qreal
BooksSettings::Private::brightnessValue() const
{
return invertColors() ? nightModeBrightness() : 1.0;
return parentObject()->nightMode() ? nightModeBrightness() : 1.0;
}
bool
@ -360,20 +360,19 @@ BooksSettings::Private::updateBrightness()
}
void
BooksSettings::Private::onInvertColorsChanged()
BooksSettings::Private::onNightModeChanged()
{
BooksSettings* settings = parentSettings();
BooksSettings* settings = parentObject();
if (updateBrightness()) {
Q_EMIT settings->brightnessChanged();
}
Q_EMIT settings->invertColorsChanged();
Q_EMIT settings->pageBackgroundColorChanged();
Q_EMIT settings->highlightPageToolColorChanged();
}
void
BooksSettings::Private::onNightModeBrightnessChanged()
{
BooksSettings* settings = parentSettings();
BooksSettings* settings = parentObject();
if (updateBrightness()) {
Q_EMIT settings->brightnessChanged();
}
@ -444,10 +443,10 @@ BooksSettings::Private::setCurrentBook(
(iCurrentBook = book)->retain();
iCurrentBookPathConf->set(book->path());
} else {
iCurrentBook = NULL;
iCurrentBook = Q_NULLPTR;
iCurrentBookPathConf->set(QString());
}
Q_EMIT parentSettings()->currentBookChanged();
Q_EMIT parentObject()->currentBookChanged();
}
}
@ -507,7 +506,7 @@ BooksSettings::Private::onFontSizeValueChanged()
for (int i=0; i<=FontSizeSteps; i++) {
iTextStyle[i].reset();
}
BooksSettings* settings = parentSettings();
BooksSettings* settings = parentObject();
Q_EMIT settings->fontSizeChanged();
Q_EMIT settings->textStyleChanged();
}
@ -516,7 +515,7 @@ BooksSettings::Private::onFontSizeValueChanged()
void
BooksSettings::Private::onCurrentFolderChanged()
{
BooksSettings* settings = parentSettings();
BooksSettings* settings = parentObject();
if (updateCurrentStorage()) {
Q_EMIT settings->currentStorageChanged();
}
@ -528,7 +527,7 @@ void
BooksSettings::Private::onCurrentBookPathChanged()
{
if (updateCurrentBook()) {
Q_EMIT parentSettings()->currentBookChanged();
Q_EMIT parentObject()->currentBookChanged();
}
}
@ -554,7 +553,7 @@ BooksSettings::Private::getAction(
// ==========================================================================
BooksSettings::BooksSettings(QObject* aParent) :
QObject(aParent),
BooksSettingsBase(aParent),
iPrivate(new Private(this))
{
}
@ -692,20 +691,6 @@ BooksSettings::setTurnPageByTap(
iPrivate->iTurnPageByTapConf->set(aValue);
}
bool
BooksSettings::invertColors() const
{
return iPrivate->invertColors();
}
void
BooksSettings::setInvertColors(
bool aValue)
{
HDEBUG(aValue);
iPrivate->iInvertColorsConf->set(aValue);
}
bool
BooksSettings::keepDisplayOn() const
{
@ -800,7 +785,7 @@ BooksSettings::currentFolder() const
void
BooksSettings::setCurrentFolder(
QString aValue)
const QString aValue)
{
HDEBUG(aValue);
iPrivate->iCurrentFolderConf->set(aValue);
@ -819,28 +804,6 @@ BooksSettings::setCurrentBook(
iPrivate->setCurrentBook(aBook);
}
QColor
BooksSettings::primaryPageToolColor() const
{
return PAGETOOL_COLOR;
}
QColor
BooksSettings::highlightPageToolColor() const
{
return iPrivate->invertColors() ?
INVERTED_PAGETOOL_HIGHLIGHT_COLOR :
NORMAL_PAGETOOL_HIGHLIGHT_COLOR;
}
QColor
BooksSettings::pageBackgroundColor() const
{
return iPrivate->invertColors() ?
INVERTED_BACKGROUND :
DEFAULT_BACKGROUND;
}
BooksSettings::Orientation
BooksSettings::orientation() const
{
@ -857,8 +820,23 @@ BooksSettings::orientation() const
return DEFAULT_ORIENTATION;
}
QColor
BooksSettings::primaryPageToolColor() const
{
return PAGETOOL_COLOR;
}
QColor
BooksSettings::highlightPageToolColor() const
{
return nightMode() ?
INVERTED_PAGETOOL_HIGHLIGHT_COLOR :
NORMAL_PAGETOOL_HIGHLIGHT_COLOR;
}
void
BooksSettings::setCurrentBookPath(QString aPath)
BooksSettings::setCurrentBookPath(
QString aPath)
{
HDEBUG(aPath);
iPrivate->iCurrentBookPathConf->set(aPath);

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 2015-2021 Jolla Ltd.
* Copyright (C) 2015-2021 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2015-2022 Jolla Ltd.
* Copyright (C) 2015-2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
@ -34,13 +34,14 @@
#ifndef BOOKS_SETTINGS_H
#define BOOKS_SETTINGS_H
#include "BooksTypes.h"
#include "shared_ptr.h"
#include "ZLTextStyle.h"
#include <QObject>
#include <QColor>
#include "BooksSettingsBase.h"
#include <QSharedPointer>
class BooksSettings : public QObject
class BooksSettings : public BooksSettingsBase
{
Q_OBJECT
Q_ENUMS(FontSize)
@ -52,7 +53,6 @@ class BooksSettings : public QObject
Q_PROPERTY(int pageDetails READ pageDetails WRITE setPageDetails NOTIFY pageDetailsChanged)
Q_PROPERTY(bool pageDetailsFixed READ pageDetailsFixed WRITE setPageDetailsFixed NOTIFY pageDetailsFixedChanged)
Q_PROPERTY(bool turnPageByTap READ turnPageByTap WRITE setTurnPageByTap NOTIFY turnPageByTapChanged)
Q_PROPERTY(bool invertColors READ invertColors WRITE setInvertColors NOTIFY invertColorsChanged)
Q_PROPERTY(bool sampleBookCopied READ sampleBookCopied NOTIFY sampleBookCopiedChanged)
Q_PROPERTY(bool keepDisplayOn READ keepDisplayOn WRITE setKeepDisplayOn NOTIFY keepDisplayOnChanged)
Q_PROPERTY(bool bookPullDownMenu READ bookPullDownMenu WRITE setBookPullDownMenu NOTIFY bookPullDownMenuChanged)
@ -63,11 +63,9 @@ class BooksSettings : public QObject
Q_PROPERTY(QString currentStorage READ currentStorage NOTIFY currentStorageChanged)
Q_PROPERTY(QString relativePath READ relativePath NOTIFY relativePathChanged)
Q_PROPERTY(QString removableRoot READ removableRoot NOTIFY removableRootChanged)
Q_PROPERTY(QColor primaryPageToolColor READ primaryPageToolColor CONSTANT)
Q_PROPERTY(QColor highlightPageToolColor READ highlightPageToolColor NOTIFY invertColorsChanged)
Q_PROPERTY(QColor invertedPageBackgroundColor READ highlightPageToolColor NOTIFY invertColorsChanged)
Q_PROPERTY(QColor pageBackgroundColor READ pageBackgroundColor NOTIFY pageBackgroundColorChanged)
Q_PROPERTY(int orientation READ orientation NOTIFY orientationChanged)
Q_PROPERTY(QColor primaryPageToolColor READ primaryPageToolColor CONSTANT)
Q_PROPERTY(QColor highlightPageToolColor READ highlightPageToolColor NOTIFY highlightPageToolColorChanged)
class TextStyle;
public:
@ -115,9 +113,6 @@ public:
bool turnPageByTap() const;
void setTurnPageByTap(bool aValue);
bool invertColors() const; // Night mode
void setInvertColors(bool aValue);
bool keepDisplayOn() const;
void setKeepDisplayOn(bool aValue);
@ -139,12 +134,11 @@ public:
QString relativePath() const;
QString removableRoot() const;
QString currentFolder() const;
void setCurrentFolder(QString aValue);
void setCurrentFolder(const QString aValue);
QString currentStorage() const;
QColor primaryPageToolColor() const;
QColor highlightPageToolColor() const;
QColor pageBackgroundColor() const;
Orientation orientation() const;
@ -154,12 +148,12 @@ public Q_SLOTS:
Q_SIGNALS:
void fontSizeChanged();
void nightModeBrightnessChanged();
void highlightPageToolColorChanged();
void brightnessChanged();
void textStyleChanged();
void pageDetailsChanged();
void pageDetailsFixedChanged();
void turnPageByTapChanged();
void invertColorsChanged();
void sampleBookCopiedChanged();
void keepDisplayOnChanged();
void bookPullDownMenuChanged();
@ -170,7 +164,6 @@ Q_SIGNALS:
void currentStorageChanged();
void relativePathChanged();
void removableRootChanged();
void pageBackgroundColorChanged();
void orientationChanged();
private:

View file

@ -0,0 +1,496 @@
/*
* Copyright (C) 2015-2022 Jolla Ltd.
* Copyright (C) 2015-2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "BooksSettingsBase.h"
#include "BooksDefs.h"
#include "HarbourDebug.h"
#include "HarbourUtil.h"
#include <MGConfItem>
#define DCONF_PATH BOOKS_DCONF_ROOT
#define DCONF_PATH_(x) BOOKS_DCONF_ROOT x
#define KEY_NIGHT_MODE DCONF_PATH_("invertColors")
#define KEY_CUSTOM_COLOR_SCHEME DCONF_PATH_("customColorScheme")
#define KEY_USE_CUSTOM_COLOR_SCHEME DCONF_PATH_("useCustomColorScheme")
#define KEY_AVAILABLE_COLORS DCONF_PATH_("availableColors")
#define DEFAULT_NIGHT_MODE false
#define DEFAULT_USE_CUSTOM_COLOR_SCHEME false
// ==========================================================================
// BooksSettingsBase::Private
// ==========================================================================
class BooksSettingsBase::Private : public QObject
{
Q_OBJECT
public:
// Matches Silica::Theme::ColorScheme
enum ColorScheme {
LightOnDark,
DarkOnLight
};
static const char* gDefaultColors[];
Private(BooksSettingsBase* aParent);
~Private();
BooksSettingsBase* parentObject() const;
static QStringList defaultColors();
QStringList availableColors() const;
ColorScheme silicaColorScheme() const;
bool darkOnLight() const;
BooksColorScheme nightModeScheme(const BooksColorScheme);
QString customColorSchemeSpec() const;
bool useCustomColorScheme() const;
void setTheme(QObject*);
void updateColorScheme();
void updateDarkOnLight();
void updateDefaultHighlightBackgroundColor();
bool setCustomColorScheme(const BooksColorScheme);
void emitPendingSignals();
bool nightMode() const;
public Q_SLOTS:
void onUseCustomColorSchemeChanged();
void onThemeHighlightBackgroundColorChanged();
void onThemeColorSchemeChanged();
void onNightModeChanged();
void onCustomColorSchemeChanged();
void onAvailableColorsChanged();
public:
MGConfItem* iNightModeConf;
MGConfItem* iCustomColorSchemeConf;
MGConfItem* iUseCustomColorSchemeConf;
MGConfItem* iAvailableColorsConf;
const QStringList iDefaultColors;
QStringList iAvailableColors;
BooksColorScheme iDefaultColorScheme;
BooksColorScheme iDefaultNightModeColorScheme;
BooksColorScheme iCustomColorScheme;
BooksColorScheme iCustomNightModeColorScheme;
BooksColorScheme iColorScheme;
QObject* iTheme;
bool iHaveSilicaColorScheme;
bool iDarkOnLight;
bool iColorSchemeChangePending;
bool iDarkOnLightChangePending;
};
const char* BooksSettingsBase::Private::gDefaultColors[] = {
"#000000", "#2160b4", "#3c8bff",
"#007f7f", "#01823f", "#4fb548",
"#c82246", "#f13c27", "#fedc00",
"#f78628", "#7d499b", "#937782",
"#545454", "#a8a8a8", "#ffffff"
};
BooksSettingsBase::Private::Private(
BooksSettingsBase* aParent) :
QObject(aParent),
iNightModeConf(new MGConfItem(KEY_NIGHT_MODE, this)),
iCustomColorSchemeConf(new MGConfItem(KEY_CUSTOM_COLOR_SCHEME, this)),
iUseCustomColorSchemeConf(new MGConfItem(KEY_USE_CUSTOM_COLOR_SCHEME, this)),
iAvailableColorsConf(new MGConfItem(KEY_AVAILABLE_COLORS, this)),
iDefaultColors(defaultColors()),
iTheme(Q_NULLPTR),
iHaveSilicaColorScheme(false),
iDarkOnLight(false),
iColorSchemeChangePending(false),
iDarkOnLightChangePending(false)
{
iDefaultNightModeColorScheme = nightModeScheme(iDefaultColorScheme);
iCustomColorScheme = BooksColorScheme(customColorSchemeSpec());
iCustomNightModeColorScheme = nightModeScheme(iCustomColorScheme);
connect(iNightModeConf, SIGNAL(valueChanged()), SLOT(onNightModeChanged()));
connect(iCustomColorSchemeConf, SIGNAL(valueChanged()), SLOT(onCustomColorSchemeChanged()));
connect(iUseCustomColorSchemeConf, SIGNAL(valueChanged()), SLOT(onUseCustomColorSchemeChanged()));
connect(iUseCustomColorSchemeConf, SIGNAL(valueChanged()), SLOT(onUseCustomColorSchemeChanged()));
connect(iAvailableColorsConf, SIGNAL(valueChanged()), SLOT(onAvailableColorsChanged()));
iAvailableColors = availableColors();
HDEBUG("Custom color scheme" << customColorSchemeSpec() << "=>" << iCustomColorScheme.toString());
}
BooksSettingsBase::Private::~Private()
{
if (iTheme) disconnect(iTheme);
}
BooksSettingsBase*
BooksSettingsBase::Private::parentObject() const
{
return qobject_cast<BooksSettingsBase*>(parent());
}
QStringList
BooksSettingsBase::Private::defaultColors()
{
QStringList colors;
const uint n = sizeof(gDefaultColors)/sizeof(gDefaultColors[0]);
colors.reserve(n);
for (uint i = 0; i < n; i++) {
colors.append(QLatin1String(gDefaultColors[i]));
}
return colors;
}
bool
BooksSettingsBase::Private::nightMode() const
{
return iNightModeConf->value(DEFAULT_NIGHT_MODE).toBool();
}
QString
BooksSettingsBase::Private::customColorSchemeSpec() const
{
return iCustomColorSchemeConf->value().toString();
}
bool
BooksSettingsBase::Private::useCustomColorScheme() const
{
return iUseCustomColorSchemeConf->value(DEFAULT_USE_CUSTOM_COLOR_SCHEME).toBool();
}
void
BooksSettingsBase::Private::setTheme(
QObject* aTheme)
{
if (iTheme != aTheme) {
if (iTheme) disconnect(iTheme);
iTheme = aTheme;
if (iTheme) {
connect(iTheme,
SIGNAL(highlightBackgroundColorChanged()),
SLOT(onThemeHighlightBackgroundColorChanged()));
iHaveSilicaColorScheme = connect(iTheme,
SIGNAL(colorSchemeChanged()),
SLOT(onThemeColorSchemeChanged()));
} else {
iHaveSilicaColorScheme = false;
}
onThemeColorSchemeChanged();
Q_EMIT parentObject()->themeChanged();
}
}
BooksSettingsBase::Private::ColorScheme
BooksSettingsBase::Private::silicaColorScheme() const
{
if (iHaveSilicaColorScheme) {
bool ok = false;
int value = iTheme->property("colorScheme").toInt(&ok);
if (ok) {
return (ColorScheme)value;
}
}
return LightOnDark;
}
bool
BooksSettingsBase::Private::darkOnLight() const
{
return silicaColorScheme() == DarkOnLight;
}
void
BooksSettingsBase::Private::updateColorScheme()
{
BooksColorScheme scheme(useCustomColorScheme() ?
(nightMode() ? iCustomNightModeColorScheme : iCustomColorScheme) :
(nightMode() ? iDefaultNightModeColorScheme : iDefaultColorScheme));
if (iColorScheme != scheme) {
iColorScheme = scheme;
iColorSchemeChangePending = true;
}
}
void
BooksSettingsBase::Private::updateDarkOnLight()
{
const bool currentValue = darkOnLight();
if (iDarkOnLight != currentValue) {
iDarkOnLight = currentValue;
iDarkOnLightChangePending = true;
HDEBUG("darkOnLight" << (iDarkOnLight ? "yes" : "no"));
}
}
void
BooksSettingsBase::Private::updateDefaultHighlightBackgroundColor()
{
if (iTheme) {
const QColor highlightBackgroundColor(iTheme->
property("highlightBackgroundColor").value<QColor>());
HDEBUG(highlightBackgroundColor << silicaColorScheme());
iDefaultColorScheme = iDefaultColorScheme.
withSelectionBackground(((silicaColorScheme() == LightOnDark) ?
highlightBackgroundColor.lighter() : highlightBackgroundColor).rgb());
} else {
iDefaultColorScheme = BooksColorScheme();
}
iDefaultNightModeColorScheme = nightModeScheme(iDefaultColorScheme);
updateColorScheme();
}
BooksColorScheme
BooksSettingsBase::Private::nightModeScheme(
const BooksColorScheme aColors)
{
return aColors.invertedWithSelectionBackground(QColor(aColors.
selectionBackground()).darker().rgb());
}
void
BooksSettingsBase::Private::onThemeColorSchemeChanged()
{
updateDefaultHighlightBackgroundColor();
updateDarkOnLight();
emitPendingSignals();
}
void
BooksSettingsBase::Private::onThemeHighlightBackgroundColorChanged()
{
updateDefaultHighlightBackgroundColor();
emitPendingSignals();
}
void
BooksSettingsBase::Private::onUseCustomColorSchemeChanged()
{
updateColorScheme();
Q_EMIT parentObject()->useCustomColorSchemeChanged();
emitPendingSignals();
}
void
BooksSettingsBase::Private::onCustomColorSchemeChanged()
{
const BooksColorScheme scheme(customColorSchemeSpec());
if (iCustomColorScheme != scheme) {
iCustomColorScheme = scheme;
iCustomNightModeColorScheme = nightModeScheme(iCustomColorScheme);
updateColorScheme();
emitPendingSignals();
}
}
void
BooksSettingsBase::Private::emitPendingSignals()
{
if (iColorSchemeChangePending || iDarkOnLightChangePending) {
const bool colorSchemeChanged = iColorSchemeChangePending;
const bool darkOnLightChanged = iDarkOnLightChangePending;
BooksSettingsBase* settings = parentObject();
iColorSchemeChangePending = false;
iDarkOnLightChangePending = false;
if (colorSchemeChanged) {
Q_EMIT settings->colorSchemeChanged();
}
if (darkOnLightChanged) {
Q_EMIT settings->darkOnLightChanged();
}
}
}
bool
BooksSettingsBase::Private::setCustomColorScheme(
const BooksColorScheme aColors)
{
if (iCustomColorScheme != aColors) {
iCustomColorScheme = aColors;
iCustomNightModeColorScheme = nightModeScheme(aColors);
iCustomColorSchemeConf->set(aColors.toString());
updateColorScheme();
emitPendingSignals();
return true;
}
return false;
}
void
BooksSettingsBase::Private::onNightModeChanged()
{
BooksSettingsBase* settings = parentObject();
updateColorScheme();
emitPendingSignals();
Q_EMIT settings->nightModeChanged();
}
QStringList
BooksSettingsBase::Private::availableColors() const
{
return iAvailableColorsConf->value(iDefaultColors).toStringList();
}
void
BooksSettingsBase::Private::onAvailableColorsChanged()
{
const QStringList newColors(availableColors());
if (iAvailableColors != newColors) {
iAvailableColors = newColors;
Q_EMIT parentObject()->availableColorsChanged();
}
}
// ==========================================================================
// BooksSettingsBase
// ==========================================================================
BooksSettingsBase::BooksSettingsBase(
QObject* aParent) :
QObject(aParent),
iPrivate(new Private(this))
{
}
BooksSettingsBase::~BooksSettingsBase()
{
delete iPrivate;
}
QObject*
BooksSettingsBase::theme() const
{
return iPrivate->iTheme;
}
void
BooksSettingsBase::setTheme(
QObject* aTheme)
{
iPrivate->setTheme(aTheme);
}
bool
BooksSettingsBase::darkOnLight() const
{
return iPrivate->iDarkOnLight;
}
bool
BooksSettingsBase::nightMode() const
{
return iPrivate->nightMode();
}
void
BooksSettingsBase::setNightMode(
bool aValue)
{
HDEBUG(aValue);
iPrivate->iNightModeConf->set(aValue);
}
QColor
BooksSettingsBase::pageBackgroundColor() const
{
return QColor(iPrivate->iColorScheme.background());
}
QColor
BooksSettingsBase::invertedPageBackgroundColor() const
{
return QColor(HarbourUtil::invertedRgb(iPrivate->iColorScheme.background()));
}
BooksColorScheme
BooksSettingsBase::colorScheme() const
{
return iPrivate->iColorScheme;
}
BooksColorScheme
BooksSettingsBase::customColorScheme() const
{
return iPrivate->iCustomColorScheme;
}
BooksColorScheme
BooksSettingsBase::customNightModeColorScheme() const
{
return iPrivate->iCustomNightModeColorScheme;
}
void
BooksSettingsBase::setCustomColorScheme(
const BooksColorScheme aColors)
{
if (iPrivate->setCustomColorScheme(aColors)) {
Q_EMIT customColorSchemeChanged();
}
}
bool
BooksSettingsBase::useCustomColorScheme() const
{
return iPrivate->useCustomColorScheme();
}
void
BooksSettingsBase::setUseCustomColorScheme(
bool aValue)
{
HDEBUG(aValue);
iPrivate->iUseCustomColorSchemeConf->set(aValue);
}
const QStringList
BooksSettingsBase::defaultColors() const
{
return iPrivate->iDefaultColors;
}
QStringList
BooksSettingsBase::availableColors() const
{
return iPrivate->iAvailableColors;
}
void
BooksSettingsBase::setAvailableColors(
const QStringList aColors)
{
iPrivate->iAvailableColorsConf->set(aColors);
if (iPrivate->iAvailableColors != aColors) {
Q_EMIT availableColorsChanged();
}
}
#include "BooksSettingsBase.moc"

View file

@ -0,0 +1,99 @@
/*
* Copyright (C) 2022 Jolla Ltd.
* Copyright (C) 2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BOOKS_SETTINGS_BASE_H
#define BOOKS_SETTINGS_BASE_H
#include "BooksTypes.h"
#include "BooksColorScheme.h"
#include <QObject>
#include <QColor>
#include <QStringList>
class BooksSettingsBase : public QObject
{
Q_OBJECT
Q_PROPERTY(QObject* theme READ theme WRITE setTheme NOTIFY themeChanged)
Q_PROPERTY(bool darkOnLight READ darkOnLight NOTIFY darkOnLightChanged)
Q_PROPERTY(bool nightMode READ nightMode WRITE setNightMode NOTIFY nightModeChanged)
Q_PROPERTY(QColor pageBackgroundColor READ pageBackgroundColor NOTIFY colorSchemeChanged)
Q_PROPERTY(QColor invertedPageBackgroundColor READ invertedPageBackgroundColor NOTIFY colorSchemeChanged)
Q_PROPERTY(BooksColorScheme colorScheme READ colorScheme NOTIFY colorSchemeChanged)
Q_PROPERTY(BooksColorScheme customColorScheme READ customColorScheme WRITE setCustomColorScheme NOTIFY customColorSchemeChanged)
Q_PROPERTY(BooksColorScheme customNightModeColorScheme READ customNightModeColorScheme NOTIFY customColorSchemeChanged)
Q_PROPERTY(bool useCustomColorScheme READ useCustomColorScheme WRITE setUseCustomColorScheme NOTIFY useCustomColorSchemeChanged)
Q_PROPERTY(QStringList defaultColors READ defaultColors CONSTANT)
Q_PROPERTY(QStringList availableColors READ availableColors WRITE setAvailableColors NOTIFY availableColorsChanged)
public:
explicit BooksSettingsBase(QObject* aParent = Q_NULLPTR);
~BooksSettingsBase();
QObject* theme() const;
void setTheme(QObject*);
bool darkOnLight() const;
bool nightMode() const;
void setNightMode(bool);
QColor pageBackgroundColor() const;
QColor invertedPageBackgroundColor() const;
BooksColorScheme colorScheme() const;
BooksColorScheme customColorScheme() const;
BooksColorScheme customNightModeColorScheme() const;
void setCustomColorScheme(const BooksColorScheme);
bool useCustomColorScheme() const;
void setUseCustomColorScheme(bool aValue);
const QStringList defaultColors() const;
QStringList availableColors() const;
void setAvailableColors(const QStringList);
Q_SIGNALS:
void themeChanged();
void darkOnLightChanged();
void nightModeChanged();
void colorSchemeChanged();
void customColorSchemeChanged();
void useCustomColorSchemeChanged();
void availableColorsChanged();
private:
class Private;
Private* iPrivate;
};
#endif // BOOKS_SETTINGS_BASE_H

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 2015-2020 Jolla Ltd.
* Copyright (C) 2015-2020 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2015-2021 Jolla Ltd.
* Copyright (C) 2015-2021 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
@ -57,7 +57,6 @@ public:
void startSelection(int aX, int aY);
bool extendSelection(int aX, int aY);
void endSelection();
void setInvertColors(bool aInvertColors);
void gotoPosition(const BooksPos& aPos);
bool nextPage();
void paint();
@ -88,7 +87,5 @@ private:
inline BooksPos BooksTextView::position() const
{ return BooksPos(textArea().startCursor()); }
inline void BooksTextView::setInvertColors(bool aInvertColors)
{ iPaintContext.setInvertColors(aInvertColors); }
#endif // BOOKS_TEXT_VIEW_H

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 2015 Jolla Ltd.
* Contact: Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2015-2022 Jolla Ltd.
* Copyright (C) 2015-2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
@ -8,15 +8,15 @@
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Nemo Mobile nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@ -34,7 +34,6 @@
#ifndef BOOKS_TYPES_H
#define BOOKS_TYPES_H
#include "shared_ptr.h"
#include <QFile>
class BooksBook;

View file

@ -98,12 +98,6 @@ void ZLibrary::initLocale()
}
}
ZLPaintContext* ZLibrary::createContext()
{
HDEBUG("creating context");
return new BooksPaintContext();
}
bool ZLibrary::init(int& aArgc, char** &aArgv)
{
HDEBUG("initializing");

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 2015-2021 Jolla Ltd.
* Copyright (C) 2015-2021 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2015-2022 Jolla Ltd.
* Copyright (C) 2015-2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
@ -36,6 +36,8 @@
#include "BooksShelf.h"
#include "BooksBook.h"
#include "BooksBookModel.h"
#include "BooksColorScheme.h"
#include "BooksColorSchemeModel.h"
#include "BooksCoverModel.h"
#include "BooksConfig.h"
#include "BooksImageProvider.h"
@ -49,11 +51,12 @@
#include "BooksTaskQueue.h"
#include "BooksHints.h"
#include "HarbourColorEditorModel.h"
#include "HarbourDisplayBlanking.h"
#include "HarbourDebug.h"
#include "HarbourMediaPlugin.h"
#include "HarbourPolicyPlugin.h"
#include "HarbourTheme.h"
#include "HarbourUtil.h"
#include "ZLibrary.h"
#include "ZLLanguageUtil.h"
@ -81,22 +84,30 @@
Q_DECL_EXPORT int main(int argc, char **argv)
{
QGuiApplication* app = SailfishApp::application(argc, argv);
qRegisterMetaType<BooksPos>();
BOOKS_QML_REGISTER(BooksShelf, "Shelf");
BOOKS_QML_REGISTER(BooksBook, "Book");
BOOKS_QML_REGISTER(BooksBookModel, "BookModel");
BOOKS_QML_REGISTER(BooksCoverModel, "CoverModel");
BOOKS_QML_REGISTER(BooksImportModel, "BooksImportModel");
BOOKS_QML_REGISTER(BooksPathModel, "BooksPathModel");
BOOKS_QML_REGISTER(BooksPageStack, "BooksPageStack");
BOOKS_QML_REGISTER(BooksStorageModel, "BookStorage");
BOOKS_QML_REGISTER(BooksPageWidget, "PageWidget");
BOOKS_QML_REGISTER(BooksListWatcher, "ListWatcher");
BOOKS_QML_REGISTER(BooksCoverWidget, "BookCover");
BOOKS_QML_REGISTER(BooksSettings, "BooksSettings");
BOOKS_QML_REGISTER(HarbourDisplayBlanking, "DisplayBlanking");
BOOKS_QML_REGISTER_SINGLETON(HarbourTheme, "HarbourTheme");
BOOKS_QML_REGISTER_SINGLETON(BooksHints, "BooksHints");
qRegisterMetaType<BooksColorScheme>();
// For historical reasons these QML and C++ names don't match:
BOOKS_QML_REGISTER_(BooksShelf, "Shelf");
BOOKS_QML_REGISTER_(BooksBook, "Book");
BOOKS_QML_REGISTER_(BooksBookModel, "BookModel");
BOOKS_QML_REGISTER_(BooksCoverModel, "CoverModel");
BOOKS_QML_REGISTER_(BooksStorageModel, "BookStorage");
BOOKS_QML_REGISTER_(BooksPageWidget, "PageWidget");
BOOKS_QML_REGISTER_(BooksListWatcher, "ListWatcher");
BOOKS_QML_REGISTER_(BooksCoverWidget, "BookCover");
BOOKS_QML_REGISTER_(HarbourDisplayBlanking, "DisplayBlanking");
// But these do (and I think it's a good idea)
BOOKS_QML_REGISTER(HarbourColorEditorModel);
BOOKS_QML_REGISTER(BooksColorSchemeModel);
BOOKS_QML_REGISTER(BooksImportModel);
BOOKS_QML_REGISTER(BooksPathModel);
BOOKS_QML_REGISTER(BooksPageStack);
BOOKS_QML_REGISTER_SINGLETON(HarbourUtil);
BOOKS_QML_REGISTER_SINGLETON(BooksHints);
BOOKS_QML_REGISTER_UNCREATABLE(BooksSettings);
QLocale locale;
QTranslator* translator = new QTranslator(app);

View file

@ -294,6 +294,21 @@
<extracomment>Text switch description</extracomment>
<translation type="unfinished">Ohne Schiebemenü muss das Buch durch Hochstreichen geschlossen werden.</translation>
</message>
<message id="harbour-books-settings-page-colors-section_header">
<source>Colors</source>
<extracomment>Section header for colors</extracomment>
<translation type="unfinished">Farben</translation>
</message>
<message id="harbour-books-settings-page-standard_colors">
<source>Use standard colors</source>
<extracomment>Text switch label</extracomment>
<translation type="unfinished">Verwende Standardfarben</translation>
</message>
<message id="harbour-books-settings-page-standard_colors-description">
<source>Note that colors hardcoded in the book override the color scheme.</source>
<extracomment>Text switch description</extracomment>
<translation type="unfinished">Beachte, dass die vom Buch definierten Farben die Standardfarben überschreiben.</translation>
</message>
<message id="harbour-books-settings-page-removable-section_header">
<source>Memory card</source>
<extracomment>Section header for memory card settings</extracomment>
@ -307,7 +322,67 @@
<message id="harbour-books-settings-page-removable_root-description">
<source>Leave the folder name empty to scan the entire memory card for books.</source>
<extracomment>Settings field description</extracomment>
<translation type="unfinished">Lassen Sie den Verzeichnisnamen leer, um die gesamte Speicherkarte für Bücher zu scannen.</translation>
<translation type="unfinished">Lasse das Feld Verzeichnisname leer, um die gesamte Speicherkarte für Bücher zu scannen.</translation>
</message>
<message id="harbour-books-color-page_background">
<source>Page background</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Seitenhintergrund</translation>
</message>
<message id="harbour-books-color-text">
<source>Regular text</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Normaler Text</translation>
</message>
<message id="harbour-books-color-selection_background">
<source>Selection background</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Auswahlhintergrund</translation>
</message>
<message id="harbour-books-color-highlighted_text">
<source>Highlighted text</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Hervorgehobener Text</translation>
</message>
<message id="harbour-books-color-internal_hyperlink">
<source>Internal hyperlink</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Interner Link</translation>
</message>
<message id="harbour-books-color-external_hyperlink">
<source>External hyperlink</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Externer Link</translation>
</message>
<message id="harbour-books-color_picker-menu-reset_colors">
<source>Reset colors</source>
<extracomment>Pulley menu item</extracomment>
<translation type="unfinished">Farben zurücksetzen</translation>
</message>
<message id="harbour-books-color_picker-action-select_color">
<source>Select color</source>
<extracomment>Dialog title label</extracomment>
<translation type="unfinished">Wähle Farbe</translation>
</message>
<message id="harbour-books-color_picker-action-add_color">
<source>Add color</source>
<extracomment>Dialog title label</extracomment>
<translation type="unfinished">Füge Farbe</translation>
</message>
<message id="harbour-books-color_picker-slider-hue">
<source>Color</source>
<extracomment>Hue slider label</extracomment>
<translation type="unfinished">Farbe</translation>
</message>
<message id="harbour-books-color_picker-slider-brightness">
<source>Brightness</source>
<extracomment>Brightness slider label</extracomment>
<translation type="unfinished">Helligkeit</translation>
</message>
<message id="harbour-books-color_picker-text-hex_notation">
<source>Hex notation</source>
<extracomment>Text field description</extracomment>
<translation type="unfinished">Hex-Notation</translation>
</message>
</context>
</TS>

View file

@ -294,6 +294,21 @@
<extracomment>Text switch description</extracomment>
<translation type="unfinished">Sin menú actualizable, el libro debe cerrarse deslizándose hacia arriba.</translation>
</message>
<message id="harbour-books-settings-page-colors-section_header">
<source>Colors</source>
<extracomment>Section header for colors</extracomment>
<translation type="unfinished">Colores</translation>
</message>
<message id="harbour-books-settings-page-standard_colors">
<source>Use standard colors</source>
<extracomment>Text switch label</extracomment>
<translation type="unfinished">Usa colores estándar</translation>
</message>
<message id="harbour-books-settings-page-standard_colors-description">
<source>Note that colors hardcoded in the book override the color scheme.</source>
<extracomment>Text switch description</extracomment>
<translation type="unfinished">Tenga en cuenta que los colores definidos por el libro prevalecen sobre los colores estándar.</translation>
</message>
<message id="harbour-books-settings-page-removable-section_header">
<source>Memory card</source>
<extracomment>Section header for memory card settings</extracomment>
@ -309,5 +324,65 @@
<extracomment>Settings field description</extracomment>
<translation>Salir del nombre de la carpeta vacía para escanear la tarjeta de memoria entera en busca de libros.</translation>
</message>
<message id="harbour-books-color-page_background">
<source>Page background</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Fondo de la página</translation>
</message>
<message id="harbour-books-color-text">
<source>Regular text</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Texto normal</translation>
</message>
<message id="harbour-books-color-selection_background">
<source>Selection background</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Fondo de selección</translation>
</message>
<message id="harbour-books-color-highlighted_text">
<source>Highlighted text</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Texto resaltado</translation>
</message>
<message id="harbour-books-color-internal_hyperlink">
<source>Internal hyperlink</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Enlace interno</translation>
</message>
<message id="harbour-books-color-external_hyperlink">
<source>External hyperlink</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Enlace externo</translation>
</message>
<message id="harbour-books-color_picker-menu-reset_colors">
<source>Reset colors</source>
<extracomment>Pulley menu item</extracomment>
<translation type="unfinished">Restaurar colores</translation>
</message>
<message id="harbour-books-color_picker-action-select_color">
<source>Select color</source>
<extracomment>Dialog title label</extracomment>
<translation type="unfinished">Seleccionar el color</translation>
</message>
<message id="harbour-books-color_picker-action-add_color">
<source>Add color</source>
<extracomment>Dialog title label</extracomment>
<translation type="unfinished">Añadir color</translation>
</message>
<message id="harbour-books-color_picker-slider-hue">
<source>Color</source>
<extracomment>Hue slider label</extracomment>
<translation type="unfinished">Color</translation>
</message>
<message id="harbour-books-color_picker-slider-brightness">
<source>Brightness</source>
<extracomment>Brightness slider label</extracomment>
<translation type="unfinished">Luminosidad</translation>
</message>
<message id="harbour-books-color_picker-text-hex_notation">
<source>Hex notation</source>
<extracomment>Text field description</extracomment>
<translation type="unfinished">Hexadecimal</translation>
</message>
</context>
</TS>

View file

@ -282,7 +282,7 @@
<message id="harbour-books-settings-page-turn_pages_by_tap-description">
<source>Tapping near the left edge of the screen returns to the previous page, tapping near the right edge gets you to the next page.</source>
<extracomment>Text switch description</extracomment>
<translation type="unfinished"></translation>
<translation type="unfinished">Napauttamalla lähellä näytön vasenta reunaa palaat edelliselle sivulle, napauttamalla lähellä oikeaa reunaa siirryt seuraavalle sivulle.</translation>
</message>
<message id="harbour-books-settings-page-book_pulldown_menu">
<source>Show pulley menu when the book is open</source>
@ -294,6 +294,21 @@
<extracomment>Text switch description</extracomment>
<translation type="unfinished">Ilman vetovalikkoa kirja on suljettava pyyhkäisemällä sitä ylös.</translation>
</message>
<message id="harbour-books-settings-page-colors-section_header">
<source>Colors</source>
<extracomment>Section header for colors</extracomment>
<translation type="unfinished">Värit</translation>
</message>
<message id="harbour-books-settings-page-standard_colors">
<source>Use standard colors</source>
<extracomment>Text switch label</extracomment>
<translation type="unfinished">Käytä vakiovärejä</translation>
</message>
<message id="harbour-books-settings-page-standard_colors-description">
<source>Note that colors hardcoded in the book override the color scheme.</source>
<extracomment>Text switch description</extracomment>
<translation type="unfinished">Pitää mielessä, että kirjassa määritellyt värit syrjäyttävät vakiovärit.</translation>
</message>
<message id="harbour-books-settings-page-removable-section_header">
<source>Memory card</source>
<extracomment>Section header for memory card settings</extracomment>
@ -309,5 +324,65 @@
<extracomment>Settings field description</extracomment>
<translation type="unfinished">Jätä kenttä tyhjäksi käyttää kokonaista muistikorttia.</translation>
</message>
<message id="harbour-books-color-page_background">
<source>Page background</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Sivun tausta</translation>
</message>
<message id="harbour-books-color-text">
<source>Regular text</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Tavallinen teksti</translation>
</message>
<message id="harbour-books-color-selection_background">
<source>Selection background</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Valinta tausta</translation>
</message>
<message id="harbour-books-color-highlighted_text">
<source>Highlighted text</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Korostettu teksti</translation>
</message>
<message id="harbour-books-color-internal_hyperlink">
<source>Internal hyperlink</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Sisäinen linkki</translation>
</message>
<message id="harbour-books-color-external_hyperlink">
<source>External hyperlink</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Ulkoinen linkki</translation>
</message>
<message id="harbour-books-color_picker-menu-reset_colors">
<source>Reset colors</source>
<extracomment>Pulley menu item</extracomment>
<translation type="unfinished">Palauttaa värit alkutilaan</translation>
</message>
<message id="harbour-books-color_picker-action-select_color">
<source>Select color</source>
<extracomment>Dialog title label</extracomment>
<translation type="unfinished">Valitse väri</translation>
</message>
<message id="harbour-books-color_picker-action-add_color">
<source>Add color</source>
<extracomment>Dialog title label</extracomment>
<translation type="unfinished">Lisää väri</translation>
</message>
<message id="harbour-books-color_picker-slider-hue">
<source>Color</source>
<extracomment>Hue slider label</extracomment>
<translation type="unfinished">Väri</translation>
</message>
<message id="harbour-books-color_picker-slider-brightness">
<source>Brightness</source>
<extracomment>Brightness slider label</extracomment>
<translation type="unfinished">Kirkkaus</translation>
</message>
<message id="harbour-books-color_picker-text-hex_notation">
<source>Hex notation</source>
<extracomment>Text field description</extracomment>
<translation type="unfinished">Hex-merkintä</translation>
</message>
</context>
</TS>

View file

@ -292,6 +292,21 @@
<extracomment>Text switch description</extracomment>
<translation type="unfinished">Lehúzható menü nélkül a könyvet felfelé húzással kell bezárni.</translation>
</message>
<message id="harbour-books-settings-page-colors-section_header">
<source>Colors</source>
<extracomment>Section header for colors</extracomment>
<translation type="unfinished">Színek</translation>
</message>
<message id="harbour-books-settings-page-standard_colors">
<source>Use standard colors</source>
<extracomment>Text switch label</extracomment>
<translation type="unfinished">Használjon szabványos színeket</translation>
</message>
<message id="harbour-books-settings-page-standard_colors-description">
<source>Note that colors hardcoded in the book override the color scheme.</source>
<extracomment>Text switch description</extracomment>
<translation type="unfinished">Vegye figyelembe, hogy a könyv által meghatározott színek felülírják a szabványos színeket.</translation>
</message>
<message id="harbour-books-settings-page-removable-section_header">
<source>Memory card</source>
<extracomment>Section header for memory card settings</extracomment>
@ -307,5 +322,65 @@
<extracomment>Settings field description</extracomment>
<translation>Hagyd üresen a mappanevet a teljes memóriakártya könyvek utáni pásztázásához.</translation>
</message>
<message id="harbour-books-color-page_background">
<source>Page background</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Oldal háttere</translation>
</message>
<message id="harbour-books-color-text">
<source>Regular text</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Normál szöveg</translation>
</message>
<message id="harbour-books-color-selection_background">
<source>Selection background</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Kiválasztás háttér</translation>
</message>
<message id="harbour-books-color-highlighted_text">
<source>Highlighted text</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Kiemelt szöveg</translation>
</message>
<message id="harbour-books-color-internal_hyperlink">
<source>Internal hyperlink</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Belső hivatkozás</translation>
</message>
<message id="harbour-books-color-external_hyperlink">
<source>External hyperlink</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Külső hivatkozás</translation>
</message>
<message id="harbour-books-color_picker-menu-reset_colors">
<source>Reset colors</source>
<extracomment>Pulley menu item</extracomment>
<translation type="unfinished">Állítsa vissza a színeket</translation>
</message>
<message id="harbour-books-color_picker-action-select_color">
<source>Select color</source>
<extracomment>Dialog title label</extracomment>
<translation type="unfinished">Válasszon színt</translation>
</message>
<message id="harbour-books-color_picker-action-add_color">
<source>Add color</source>
<extracomment>Dialog title label</extracomment>
<translation type="unfinished">Add színt</translation>
</message>
<message id="harbour-books-color_picker-slider-hue">
<source>Color</source>
<extracomment>Hue slider label</extracomment>
<translation type="unfinished">Szín</translation>
</message>
<message id="harbour-books-color_picker-slider-brightness">
<source>Brightness</source>
<extracomment>Brightness slider label</extracomment>
<translation type="unfinished">Fényerősség</translation>
</message>
<message id="harbour-books-color_picker-text-hex_notation">
<source>Hex notation</source>
<extracomment>Text field description</extracomment>
<translation type="unfinished">Hex jelölés</translation>
</message>
</context>
</TS>

View file

@ -294,6 +294,21 @@
<extracomment>Text switch description</extracomment>
<translation type="unfinished">Zonder uittrekmenu moet het boek worden gesloten door het omhoog te vegen.</translation>
</message>
<message id="harbour-books-settings-page-colors-section_header">
<source>Colors</source>
<extracomment>Section header for colors</extracomment>
<translation type="unfinished">Kleuren</translation>
</message>
<message id="harbour-books-settings-page-standard_colors">
<source>Use standard colors</source>
<extracomment>Text switch label</extracomment>
<translation type="unfinished">Gebruik standaard kleuren</translation>
</message>
<message id="harbour-books-settings-page-standard_colors-description">
<source>Note that colors hardcoded in the book override the color scheme.</source>
<extracomment>Text switch description</extracomment>
<translation type="unfinished">Houd er rekening mee dat kleuren die door het boek worden gedefinieerd, de standaardkleuren overschrijven.</translation>
</message>
<message id="harbour-books-settings-page-removable-section_header">
<source>Memory card</source>
<extracomment>Section header for memory card settings</extracomment>
@ -309,5 +324,65 @@
<extracomment>Settings field description</extracomment>
<translation>Laat de mapnaam leeg om op de volledige geheugenkaart te zoeken naar boeken.</translation>
</message>
<message id="harbour-books-color-page_background">
<source>Page background</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Pagina achtergrond</translation>
</message>
<message id="harbour-books-color-text">
<source>Regular text</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Gewone tekst</translation>
</message>
<message id="harbour-books-color-selection_background">
<source>Selection background</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Selectie achtergrond</translation>
</message>
<message id="harbour-books-color-highlighted_text">
<source>Highlighted text</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Gemarkeerde tekst</translation>
</message>
<message id="harbour-books-color-internal_hyperlink">
<source>Internal hyperlink</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Interne link</translation>
</message>
<message id="harbour-books-color-external_hyperlink">
<source>External hyperlink</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Externe link</translation>
</message>
<message id="harbour-books-color_picker-menu-reset_colors">
<source>Reset colors</source>
<extracomment>Pulley menu item</extracomment>
<translation type="unfinished">Kleuren resetten</translation>
</message>
<message id="harbour-books-color_picker-action-select_color">
<source>Select color</source>
<extracomment>Dialog title label</extracomment>
<translation type="unfinished">Selecteer kleur</translation>
</message>
<message id="harbour-books-color_picker-action-add_color">
<source>Add color</source>
<extracomment>Dialog title label</extracomment>
<translation type="unfinished">Kleur toevoegen</translation>
</message>
<message id="harbour-books-color_picker-slider-hue">
<source>Color</source>
<extracomment>Hue slider label</extracomment>
<translation type="unfinished">Kleur</translation>
</message>
<message id="harbour-books-color_picker-slider-brightness">
<source>Brightness</source>
<extracomment>Brightness slider label</extracomment>
<translation type="unfinished">Lichtsterkte</translation>
</message>
<message id="harbour-books-color_picker-text-hex_notation">
<source>Hex notation</source>
<extracomment>Text field description</extracomment>
<translation type="unfinished">Hex notatie</translation>
</message>
</context>
</TS>

View file

@ -296,6 +296,21 @@
<extracomment>Text switch description</extracomment>
<translation>Aby zamknąć książkę w przypadku braku menu wysuwanego, należy przesunąć w górę o ponad pół ekranu.</translation>
</message>
<message id="harbour-books-settings-page-colors-section_header">
<source>Colors</source>
<extracomment>Section header for colors</extracomment>
<translation type="unfinished">Kolory</translation>
</message>
<message id="harbour-books-settings-page-standard_colors">
<source>Use standard colors</source>
<extracomment>Text switch label</extracomment>
<translation type="unfinished">Użyj standardowych kolorów</translation>
</message>
<message id="harbour-books-settings-page-standard_colors-description">
<source>Note that colors hardcoded in the book override the color scheme.</source>
<extracomment>Text switch description</extracomment>
<translation type="unfinished">Należy pamiętać, że niektóre lub nawet wszystkie kolory mogą być określone w samej książce, w którym to przypadku schemat kolorów jest ignorowany.</translation>
</message>
<message id="harbour-books-settings-page-removable-section_header">
<source>Memory card</source>
<extracomment>Section header for memory card settings</extracomment>
@ -311,5 +326,65 @@
<extracomment>Settings field description</extracomment>
<translation>Pozostaw nazwę katalogu pustą, aby skanować całą kartę pamięci w poszukiwaniu książek.</translation>
</message>
<message id="harbour-books-color-page_background">
<source>Page background</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Tło strony</translation>
</message>
<message id="harbour-books-color-text">
<source>Regular text</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Zwykły tekst</translation>
</message>
<message id="harbour-books-color-selection_background">
<source>Selection background</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Dedykowane tło</translation>
</message>
<message id="harbour-books-color-highlighted_text">
<source>Highlighted text</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Wyróżniony tekst</translation>
</message>
<message id="harbour-books-color-internal_hyperlink">
<source>Internal hyperlink</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Link wewnętrzny</translation>
</message>
<message id="harbour-books-color-external_hyperlink">
<source>External hyperlink</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Link zewnętrzny</translation>
</message>
<message id="harbour-books-color_picker-menu-reset_colors">
<source>Reset colors</source>
<extracomment>Pulley menu item</extracomment>
<translation>Zresetuj kolory</translation>
</message>
<message id="harbour-books-color_picker-action-select_color">
<source>Select color</source>
<extracomment>Dialog title label</extracomment>
<translation>Wybierz kolor</translation>
</message>
<message id="harbour-books-color_picker-action-add_color">
<source>Add color</source>
<extracomment>Dialog title label</extracomment>
<translation>Dodaj kolor</translation>
</message>
<message id="harbour-books-color_picker-slider-hue">
<source>Color</source>
<extracomment>Hue slider label</extracomment>
<translation>Kolor</translation>
</message>
<message id="harbour-books-color_picker-slider-brightness">
<source>Brightness</source>
<extracomment>Brightness slider label</extracomment>
<translation>Jasność</translation>
</message>
<message id="harbour-books-color_picker-text-hex_notation">
<source>Hex notation</source>
<extracomment>Text field description</extracomment>
<translation>Format szesnastkowy</translation>
</message>
</context>
</TS>

View file

@ -294,6 +294,21 @@
<extracomment>Text switch description</extracomment>
<translation type="unfinished">Sem o menu deslizante, o livro deve ser fechado deslizando-o para cima.</translation>
</message>
<message id="harbour-books-settings-page-colors-section_header">
<source>Colors</source>
<extracomment>Section header for colors</extracomment>
<translation type="unfinished">Cores</translation>
</message>
<message id="harbour-books-settings-page-standard_colors">
<source>Use standard colors</source>
<extracomment>Text switch label</extracomment>
<translation type="unfinished">Use cores padrão</translation>
</message>
<message id="harbour-books-settings-page-standard_colors-description">
<source>Note that colors hardcoded in the book override the color scheme.</source>
<extracomment>Text switch description</extracomment>
<translation type="unfinished">Observe que as cores definidas pelo livro substituem as cores padrão.</translation>
</message>
<message id="harbour-books-settings-page-removable-section_header">
<source>Memory card</source>
<extracomment>Section header for memory card settings</extracomment>
@ -309,5 +324,65 @@
<extracomment>Settings field description</extracomment>
<translation>Deixe este campo vazio para escanear todo o cartão de memória.</translation>
</message>
<message id="harbour-books-color-page_background">
<source>Page background</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Plano de fundo da página</translation>
</message>
<message id="harbour-books-color-text">
<source>Regular text</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Texto normal</translation>
</message>
<message id="harbour-books-color-selection_background">
<source>Selection background</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Plano de fundo da seleção</translation>
</message>
<message id="harbour-books-color-highlighted_text">
<source>Highlighted text</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Texto destacado</translation>
</message>
<message id="harbour-books-color-internal_hyperlink">
<source>Internal hyperlink</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Link interno</translation>
</message>
<message id="harbour-books-color-external_hyperlink">
<source>External hyperlink</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Link externo</translation>
</message>
<message id="harbour-books-color_picker-menu-reset_colors">
<source>Reset colors</source>
<extracomment>Pulley menu item</extracomment>
<translation type="unfinished">Repor cores</translation>
</message>
<message id="harbour-books-color_picker-action-select_color">
<source>Select color</source>
<extracomment>Dialog title label</extracomment>
<translation type="unfinished">Selecione a cor</translation>
</message>
<message id="harbour-books-color_picker-action-add_color">
<source>Add color</source>
<extracomment>Dialog title label</extracomment>
<translation type="unfinished">Adicione cor</translation>
</message>
<message id="harbour-books-color_picker-slider-hue">
<source>Color</source>
<extracomment>Hue slider label</extracomment>
<translation type="unfinished">Cor</translation>
</message>
<message id="harbour-books-color_picker-slider-brightness">
<source>Brightness</source>
<extracomment>Brightness slider label</extracomment>
<translation type="unfinished">Luminocidade</translation>
</message>
<message id="harbour-books-color_picker-text-hex_notation">
<source>Hex notation</source>
<extracomment>Text field description</extracomment>
<translation type="unfinished">Notação hexadecimal</translation>
</message>
</context>
</TS>

View file

@ -244,23 +244,13 @@
<message id="harbour-books-settings-page-keep_display_on_description">
<source>Prevent the display from blanking while reading the book.</source>
<extracomment>Text switch description</extracomment>
<translation>Не гасить экран, пока открыта книга. Это не очень хорошо для батареи, зато удобно для чтения. Главное - не уснуть.</translation>
<translation>То есть не гасить экран, пока открыта книга. Это не очень хорошо для батареи, зато удобно для чтения. Главное - не уснуть.</translation>
</message>
<message id="harbour-books-settings-page-navigation-section_header">
<source>Navigation</source>
<extracomment>Section header for media keys</extracomment>
<translation>Навигация</translation>
</message>
<message id="harbour-books-settings-page-turn_pages_by_tap">
<source>Turn pages by tapping the screen</source>
<extracomment>Text switch label</extracomment>
<translation>Листать страницы касанием экрана</translation>
</message>
<message id="harbour-books-settings-page-turn_pages_by_tap-description">
<source>Tapping near the left edge of the screen returns to the previous page, tapping near the right edge gets you to the next page.</source>
<extracomment>Text switch description</extracomment>
<translation>Касание ближе к левому краю экрана вызывает переход на предыдущую страницу, ближе к правому краю - на следующую.</translation>
</message>
<message id="harbour-books-settings-page-action-none">
<source>No action</source>
<extracomment>Combo box value for no action</extracomment>
@ -286,10 +276,15 @@
<extracomment>Combo box label</extracomment>
<translation>Громкость вниз</translation>
</message>
<message id="harbour-books-settings-page-removable-section_header">
<source>Memory card</source>
<extracomment>Section header for memory card settings</extracomment>
<translation>Карта памяти</translation>
<message id="harbour-books-settings-page-turn_pages_by_tap">
<source>Turn pages by tapping the screen</source>
<extracomment>Text switch label</extracomment>
<translation>Листать страницы касанием экрана</translation>
</message>
<message id="harbour-books-settings-page-turn_pages_by_tap-description">
<source>Tapping near the left edge of the screen returns to the previous page, tapping near the right edge gets you to the next page.</source>
<extracomment>Text switch description</extracomment>
<translation>Касание ближе к левому краю экрана вызывает переход на предыдущую страницу, ближе к правому краю - на следующую.</translation>
</message>
<message id="harbour-books-settings-page-book_pulldown_menu">
<source>Show pulley menu when the book is open</source>
@ -301,6 +296,26 @@
<extracomment>Text switch description</extracomment>
<translation>Чтобы закрыть книгу в отсутствие вытягиваемого меню, её надо будет сдвинуть вверх больше, чем на пол-экрана.</translation>
</message>
<message id="harbour-books-settings-page-colors-section_header">
<source>Colors</source>
<extracomment>Section header for colors</extracomment>
<translation>Цвета</translation>
</message>
<message id="harbour-books-settings-page-standard_colors">
<source>Use standard colors</source>
<extracomment>Text switch label</extracomment>
<translation>Использовать стандартные цвета</translation>
</message>
<message id="harbour-books-settings-page-standard_colors-description">
<source>Note that colors hardcoded in the book override the color scheme.</source>
<extracomment>Text switch description</extracomment>
<translation>Имейте в виду, что некоторые или даже все цвета могут быть прописаны в самой книге и в этом случае цветовая схема игнорируется.</translation>
</message>
<message id="harbour-books-settings-page-removable-section_header">
<source>Memory card</source>
<extracomment>Section header for memory card settings</extracomment>
<translation>Карта памяти</translation>
</message>
<message id="harbour-books-settings-page-removable_root-label">
<source>Books folder</source>
<extracomment>Settings field label</extracomment>
@ -311,5 +326,65 @@
<extracomment>Settings field description</extracomment>
<translation>Если оставить имя папки пустым, то можно будет найти книгу в любой папке на карте памяти. Особого смысла в этой настройке нет, просто так исторически сложилось, что по умолчанию книги искались только в папке Books, а теперь можно вообще где угодно.</translation>
</message>
<message id="harbour-books-color-page_background">
<source>Page background</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation>Фон страницы</translation>
</message>
<message id="harbour-books-color-text">
<source>Regular text</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation>Обычный текст</translation>
</message>
<message id="harbour-books-color-selection_background">
<source>Selection background</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation>Выделенный фон</translation>
</message>
<message id="harbour-books-color-highlighted_text">
<source>Highlighted text</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation>Выделенный текст</translation>
</message>
<message id="harbour-books-color-internal_hyperlink">
<source>Internal hyperlink</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation>Внутренняя ссылка</translation>
</message>
<message id="harbour-books-color-external_hyperlink">
<source>External hyperlink</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation>Внешняя ссылка</translation>
</message>
<message id="harbour-books-color_picker-menu-reset_colors">
<source>Reset colors</source>
<extracomment>Pulley menu item</extracomment>
<translation>Сбросить цвета</translation>
</message>
<message id="harbour-books-color_picker-action-select_color">
<source>Select color</source>
<extracomment>Dialog title label</extracomment>
<translation>Выбрать цвет</translation>
</message>
<message id="harbour-books-color_picker-action-add_color">
<source>Add color</source>
<extracomment>Dialog title label</extracomment>
<translation>Добавить цвет</translation>
</message>
<message id="harbour-books-color_picker-slider-hue">
<source>Color</source>
<extracomment>Hue slider label</extracomment>
<translation>Цвет</translation>
</message>
<message id="harbour-books-color_picker-slider-brightness">
<source>Brightness</source>
<extracomment>Brightness slider label</extracomment>
<translation>Яркость</translation>
</message>
<message id="harbour-books-color_picker-text-hex_notation">
<source>Hex notation</source>
<extracomment>Text field description</extracomment>
<translation>Текстовый формат</translation>
</message>
</context>
</TS>

View file

@ -294,6 +294,21 @@
<extracomment>Text switch description</extracomment>
<translation>Utan toppmeny måste boken stängas genom att svepa uppåt.</translation>
</message>
<message id="harbour-books-settings-page-colors-section_header">
<source>Colors</source>
<extracomment>Section header for colors</extracomment>
<translation type="unfinished">Färger</translation>
</message>
<message id="harbour-books-settings-page-standard_colors">
<source>Use standard colors</source>
<extracomment>Text switch label</extracomment>
<translation type="unfinished">Använd standardfärger</translation>
</message>
<message id="harbour-books-settings-page-standard_colors-description">
<source>Note that colors hardcoded in the book override the color scheme.</source>
<extracomment>Text switch description</extracomment>
<translation type="unfinished">Notera att färger som definieras av boken åsidosätter standardfärgerna.</translation>
</message>
<message id="harbour-books-settings-page-removable-section_header">
<source>Memory card</source>
<extracomment>Section header for memory card settings</extracomment>
@ -309,5 +324,65 @@
<extracomment>Settings field description</extracomment>
<translation>Lämna mappnamnet tomt för att söka igenom hela minneskortet efter böcker.</translation>
</message>
<message id="harbour-books-color-page_background">
<source>Page background</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Sidans bakgrund</translation>
</message>
<message id="harbour-books-color-text">
<source>Regular text</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Vanlig text</translation>
</message>
<message id="harbour-books-color-selection_background">
<source>Selection background</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Urval bakgrund</translation>
</message>
<message id="harbour-books-color-highlighted_text">
<source>Highlighted text</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Markerad text</translation>
</message>
<message id="harbour-books-color-internal_hyperlink">
<source>Internal hyperlink</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Intern länk</translation>
</message>
<message id="harbour-books-color-external_hyperlink">
<source>External hyperlink</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished">Extern länk</translation>
</message>
<message id="harbour-books-color_picker-menu-reset_colors">
<source>Reset colors</source>
<extracomment>Pulley menu item</extracomment>
<translation type="unfinished">Återställ färger</translation>
</message>
<message id="harbour-books-color_picker-action-select_color">
<source>Select color</source>
<extracomment>Dialog title label</extracomment>
<translation type="unfinished">Välj färg</translation>
</message>
<message id="harbour-books-color_picker-action-add_color">
<source>Add color</source>
<extracomment>Dialog title label</extracomment>
<translation type="unfinished">Lägg till färg</translation>
</message>
<message id="harbour-books-color_picker-slider-hue">
<source>Color</source>
<extracomment>Hue slider label</extracomment>
<translation type="unfinished">Färg</translation>
</message>
<message id="harbour-books-color_picker-slider-brightness">
<source>Brightness</source>
<extracomment>Brightness slider label</extracomment>
<translation type="unfinished">Ljusstyrka</translation>
</message>
<message id="harbour-books-color_picker-text-hex_notation">
<source>Hex notation</source>
<extracomment>Text field description</extracomment>
<translation type="unfinished">Hex notation</translation>
</message>
</context>
</TS>

View file

@ -293,6 +293,21 @@
<extracomment>Text switch description</extracomment>
<translation type="unfinished"></translation>
</message>
<message id="harbour-books-settings-page-colors-section_header">
<source>Colors</source>
<extracomment>Section header for colors</extracomment>
<translation type="unfinished"></translation>
</message>
<message id="harbour-books-settings-page-standard_colors">
<source>Use standard colors</source>
<extracomment>Text switch label</extracomment>
<translation type="unfinished">使</translation>
</message>
<message id="harbour-books-settings-page-standard_colors-description">
<source>Note that colors hardcoded in the book override the color scheme.</source>
<extracomment>Text switch description</extracomment>
<translation type="unfinished"></translation>
</message>
<message id="harbour-books-settings-page-removable-section_header">
<source>Memory card</source>
<extracomment>Section header for memory card settings</extracomment>
@ -308,5 +323,65 @@
<extracomment>Settings field description</extracomment>
<translation>SD卡中的全部书籍</translation>
</message>
<message id="harbour-books-color-page_background">
<source>Page background</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished"></translation>
</message>
<message id="harbour-books-color-text">
<source>Regular text</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished"></translation>
</message>
<message id="harbour-books-color-selection_background">
<source>Selection background</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished"></translation>
</message>
<message id="harbour-books-color-highlighted_text">
<source>Highlighted text</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished"></translation>
</message>
<message id="harbour-books-color-internal_hyperlink">
<source>Internal hyperlink</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished"></translation>
</message>
<message id="harbour-books-color-external_hyperlink">
<source>External hyperlink</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation type="unfinished"></translation>
</message>
<message id="harbour-books-color_picker-menu-reset_colors">
<source>Reset colors</source>
<extracomment>Pulley menu item</extracomment>
<translation type="unfinished"></translation>
</message>
<message id="harbour-books-color_picker-action-select_color">
<source>Select color</source>
<extracomment>Dialog title label</extracomment>
<translation type="unfinished"></translation>
</message>
<message id="harbour-books-color_picker-action-add_color">
<source>Add color</source>
<extracomment>Dialog title label</extracomment>
<translation type="unfinished"></translation>
</message>
<message id="harbour-books-color_picker-slider-hue">
<source>Color</source>
<extracomment>Hue slider label</extracomment>
<translation type="unfinished"></translation>
</message>
<message id="harbour-books-color_picker-slider-brightness">
<source>Brightness</source>
<extracomment>Brightness slider label</extracomment>
<translation type="unfinished"></translation>
</message>
<message id="harbour-books-color_picker-text-hex_notation">
<source>Hex notation</source>
<extracomment>Text field description</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

View file

@ -294,6 +294,21 @@
<extracomment>Text switch description</extracomment>
<translation>Without the pulley menu, the book has to be closed by swiping it up.</translation>
</message>
<message id="harbour-books-settings-page-colors-section_header">
<source>Colors</source>
<extracomment>Section header for colors</extracomment>
<translation>Colors</translation>
</message>
<message id="harbour-books-settings-page-standard_colors">
<source>Use standard colors</source>
<extracomment>Text switch label</extracomment>
<translation>Use standard colors</translation>
</message>
<message id="harbour-books-settings-page-standard_colors-description">
<source>Note that colors hardcoded in the book override the color scheme.</source>
<extracomment>Text switch description</extracomment>
<translation>Note that colors hardcoded in the book override the color scheme.</translation>
</message>
<message id="harbour-books-settings-page-removable-section_header">
<source>Memory card</source>
<extracomment>Section header for memory card settings</extracomment>
@ -309,5 +324,65 @@
<extracomment>Settings field description</extracomment>
<translation>Leave the folder name empty to scan the entire memory card for books.</translation>
</message>
<message id="harbour-books-color-page_background">
<source>Page background</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation>Page background</translation>
</message>
<message id="harbour-books-color-text">
<source>Regular text</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation>Regular text</translation>
</message>
<message id="harbour-books-color-selection_background">
<source>Selection background</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation>Selection background</translation>
</message>
<message id="harbour-books-color-highlighted_text">
<source>Highlighted text</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation>Highlighted text</translation>
</message>
<message id="harbour-books-color-internal_hyperlink">
<source>Internal hyperlink</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation>Internal hyperlink</translation>
</message>
<message id="harbour-books-color-external_hyperlink">
<source>External hyperlink</source>
<extracomment>List item label (description of a color scheme element)</extracomment>
<translation>External hyperlink</translation>
</message>
<message id="harbour-books-color_picker-menu-reset_colors">
<source>Reset colors</source>
<extracomment>Pulley menu item</extracomment>
<translation>Reset colors</translation>
</message>
<message id="harbour-books-color_picker-action-select_color">
<source>Select color</source>
<extracomment>Dialog title label</extracomment>
<translation>Select color</translation>
</message>
<message id="harbour-books-color_picker-action-add_color">
<source>Add color</source>
<extracomment>Dialog title label</extracomment>
<translation>Add color</translation>
</message>
<message id="harbour-books-color_picker-slider-hue">
<source>Color</source>
<extracomment>Hue slider label</extracomment>
<translation>Color</translation>
</message>
<message id="harbour-books-color_picker-slider-brightness">
<source>Brightness</source>
<extracomment>Brightness slider label</extracomment>
<translation>Brightness</translation>
</message>
<message id="harbour-books-color_picker-text-hex_notation">
<source>Hex notation</source>
<extracomment>Text field description</extracomment>
<translation>Hex notation</translation>
</message>
</context>
</TS>

View file

@ -1,7 +1,12 @@
TEMPLATE = subdirs
CONFIG += ordered
CONFIG += ordered app_settings
SUBDIRS = fribidi linebreak fbreader app
app_settings {
SUBDIRS += settings
settings.file = app/settings/settings.pro
}
OTHER_FILES += \
README.md \
rpm/*.spec

View file

@ -42,6 +42,8 @@ FBReader-based e-book reader.
rm -rf %{buildroot}
cd app
%qmake5_install
cd settings
%qmake5_install
desktop-file-install --delete-original \
--dir %{buildroot}%{_datadir}/applications \
@ -60,8 +62,9 @@ if [ "$1" == 0 ] ; then \
%{_datadir}/applications/%{name}.desktop
%{_datadir}/icons/hicolor/*/apps/%{name}.png
%{_datadir}/translations/%{name}*.qm
%{_datadir}/dbus-1/services/%{name}.service
%{_datadir}/jolla-settings/entries/%{name}.json
%{_datadir}/dbus-1/services/%{name}.service
%{_libdir}/qt5/qml/openrepos/books/settings
%check
make -C test test