Compare commits

..

1 Commits

Author SHA1 Message Date
Philip Withnall 844507bf25 WIP
Signed-off-by: Philip Withnall <withnall@endlessm.com>
2020-02-04 11:58:20 +00:00
153 changed files with 3292 additions and 45084 deletions

View File

@ -1,3 +1,13 @@
image: fedora:30
before_script:
- dnf install -y meson pkgconf-pkg-config gtk-doc
libxml2-devel dbus-daemon
glib2-devel dbus-devel gobject-introspection-devel
gettext-devel polkit-devel polkit-gnome git
lcov pam-devel gtk3-devel accountsservice-devel flatpak-devel
- export LANG=C.UTF-8
stages:
- build
- deploy
@ -6,53 +16,23 @@ cache:
paths:
- _ccache/
variables:
DEBIAN_IMAGE: "registry.freedesktop.org/pwithnall/malcontent/debian-unstable:v4"
MESON_TEST_TIMEOUT_MULTIPLIER: 2
G_MESSAGES_DEBUG: all
MESON_COMMON_OPTIONS: "--buildtype debug --wrap-mode=nodownload"
.only-default:
only:
- branches
fedora:
stage: build
except:
- tags
.build:
extends: .only-default
before_script:
- cp -r $HOME/subprojects/* subprojects/
debian:
extends: .build
image: $DEBIAN_IMAGE
stage: build
variables:
CFLAGS: "-coverage -ftest-coverage -fprofile-arcs"
script:
- meson ${MESON_COMMON_OPTIONS}
--werror
-Db_coverage=true
-Dinstalled_tests=true
-Dprivileged_group=sudo
_build
- ninja -C _build
- mkdir -p _coverage
- lcov --config-file .gitlab-ci/lcovrc --directory _build --capture --initial --output-file "_coverage/${CI_JOB_NAME}-baseline.lcov"
- .gitlab-ci/run-tests.sh
- lcov --config-file .gitlab-ci/lcovrc --directory _build --capture --output-file "_coverage/${CI_JOB_NAME}.lcov"
- bash -x ./.gitlab-ci/coverage-docker.sh
- git submodule update --init
- meson --buildtype debug --werror -Db_coverage=true -Ddocumentation=true _build .
- meson test -C _build
# FIXME: lcov doesn't support gcc9 yet:
# https://github.com/linux-test-project/lcov/issues/58
- ninja -C _build coverage || true
coverage: '/^\s+lines\.+:\s+([\d.]+\%)\s+/'
artifacts:
reports:
junit: "_build/${CI_JOB_NAME}-report.xml"
name: "malcontent-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
when: always
name: "malcontent-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
paths:
- "_build/config.h"
- "_build/meson-logs"
- "_build/${CI_JOB_NAME}-report.xml"
- "_coverage"
# FIXME: Run gtkdoc-check when we can. See:
# https://github.com/mesonbuild/meson/issues/3580
@ -60,9 +40,10 @@ debian:
pages:
stage: deploy
only:
- main
- master
script:
- mv _coverage/ public/
- mkdir -p public/
- mv _build/meson-logs/coveragereport/ public/coverage/
artifacts:
paths:
- public

View File

@ -1,23 +0,0 @@
# CI support stuff
## Docker image
GitLab CI jobs run in a Docker image, defined here. To update that image
(perhaps to install some more packages):
1. Edit `.gitlab-ci/Dockerfile` with the changes you want
1. Run `.gitlab-ci/run-docker.sh build --base=debian-unstable --base-version=1` to
build the new image (bump the version from the latest listed for that `base`
on https://gitlab.freedesktop.org/pwithnall/malcontent/container_registry)
1. Run `.gitlab-ci/run-docker.sh push --base=debian-unstable --base-version=1` to
upload the new image to the GNOME GitLab Docker registry
* If this is the first time you're doing this, you'll need to log into the
registry
* If you use 2-factor authentication on your GNOME GitLab account, you'll
need to [create a personal access token][pat] and use that rather than
your normal password — the token should have `read_registry` and
`write_registry` permissions
1. Edit `.gitlab-ci.yml` (in the root of this repository) to use your new
image
[pat]: https://gitlab.freedesktop.org/profile/personal_access_tokens

View File

@ -1,9 +0,0 @@
#!/bin/bash
set -e
git clone --depth 1 --no-tags https://gitlab.freedesktop.org/pwithnall/malcontent.git
meson subprojects download --sourcedir malcontent
rm malcontent/subprojects/*.wrap
mv malcontent/subprojects/ .
rm -rf malcontent

View File

@ -1,29 +0,0 @@
#!/bin/bash
set -e
for path in _coverage/*.lcov; do
# Remove coverage from generated code in the build directory
lcov --config-file .gitlab-ci/lcovrc -r "${path}" '*/_build/*' -o "$(pwd)/${path}"
# Remove any coverage from system files
lcov --config-file .gitlab-ci/lcovrc -e "${path}" "$(pwd)/*" -o "$(pwd)/${path}"
done
genhtml \
--ignore-errors=source \
--config-file .gitlab-ci/lcovrc \
_coverage/*.lcov \
-o _coverage/coverage
cd _coverage
rm -f ./*.lcov
cat >index.html <<EOL
<html>
<body>
<ul>
<li><a href="coverage/index.html">Coverage</a></li>
</ul>
</body>
</html>
EOL

View File

@ -1,45 +0,0 @@
FROM debian:unstable
RUN apt-get update -qq && apt-get install --no-install-recommends -qq -y \
desktop-file-utils \
gettext \
git \
gtk-doc-tools \
lcov \
libadwaita-1-dev \
libaccountsservice-dev \
libappstream-dev \
libdbus-1-dev \
libflatpak-dev \
libgirepository1.0-dev \
libglib2.0-dev \
libglib-testing-0-dev \
libgtk-4-dev \
libpam0g-dev \
libpolkit-gobject-1-dev \
libxml2-utils \
locales \
meson \
pkg-config \
policykit-1 \
python3-pip \
&& rm -rf /usr/share/doc/* /usr/share/man/*
# Locale for our build
RUN locale-gen C.UTF-8 && /usr/sbin/update-locale LANG=C.UTF-8
ENV LANG=C.UTF-8 LANGUAGE=C.UTF-8 LC_ALL=C.UTF-8
RUN pip3 install meson==0.59.4
ARG HOST_USER_ID=5555
ENV HOST_USER_ID ${HOST_USER_ID}
RUN useradd -u $HOST_USER_ID -ms /bin/bash user
USER user
WORKDIR /home/user
COPY cache-subprojects.sh .
RUN ./cache-subprojects.sh
ENV LANG=C.UTF-8 LANGUAGE=C.UTF-8 LC_ALL=C.UTF-8

View File

@ -1,13 +0,0 @@
# lcov and genhtml configuration
# See http://ltp.sourceforge.net/coverage/lcov/lcovrc.5.php
# Always enable branch coverage
lcov_branch_coverage = 1
# Exclude precondition assertions, as we can never reasonably get full branch
# coverage of them, as they should never normally fail.
# See https://github.com/linux-test-project/lcov/issues/44
lcov_excl_br_line = LCOV_EXCL_BR_LINE|g_return_if_fail|g_return_val_if_fail|g_assert|g_assert_
# Similarly for unreachable assertions.
lcov_excl_line = LCOV_EXCL_LINE|g_return_if_reached|g_return_val_if_reached|g_assert_not_reached

View File

@ -1,115 +0,0 @@
#!/usr/bin/env python3
# Turns a Meson testlog.json file into a JUnit XML report
#
# Copyright 2019 GNOME Foundation
#
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# Original author: Emmanuele Bassi
import argparse
import datetime
import json
import os
import sys
import xml.etree.ElementTree as ET
aparser = argparse.ArgumentParser(description='Turns a Meson test log into a JUnit report')
aparser.add_argument('--project-name', metavar='NAME',
help='The project name',
default='unknown')
aparser.add_argument('--job-id', metavar='ID',
help='The job ID for the report',
default='Unknown')
aparser.add_argument('--branch', metavar='NAME',
help='Branch of the project being tested',
default='main')
aparser.add_argument('--output', metavar='FILE',
help='The output file, stdout by default',
type=argparse.FileType('w', encoding='UTF-8'),
default=sys.stdout)
aparser.add_argument('infile', metavar='FILE',
help='The input testlog.json, stdin by default',
type=argparse.FileType('r', encoding='UTF-8'),
default=sys.stdin)
args = aparser.parse_args()
outfile = args.output
testsuites = ET.Element('testsuites')
testsuites.set('id', '{}/{}'.format(args.job_id, args.branch))
testsuites.set('package', args.project_name)
testsuites.set('timestamp', datetime.datetime.utcnow().isoformat())
suites = {}
for line in args.infile:
data = json.loads(line)
(full_suite, unit_name) = data['name'].split(' / ')
try:
(project_name, suite_name) = full_suite.split(':')
except ValueError:
project_name = full_suite
suite_name = full_suite
duration = data['duration']
return_code = data['returncode']
log = data['stdout']
log_stderr = data.get('stderr', '')
unit = {
'suite': suite_name,
'name': unit_name,
'duration': duration,
'returncode': return_code,
'stdout': log,
'stderr': log_stderr,
}
units = suites.setdefault(suite_name, [])
units.append(unit)
for name, units in suites.items():
print('Processing suite {} (units: {})'.format(name, len(units)))
def if_failed(unit):
if unit['returncode'] != 0:
return True
return False
def if_succeded(unit):
if unit['returncode'] == 0:
return True
return False
successes = list(filter(if_succeded, units))
failures = list(filter(if_failed, units))
print(' - {}: {} pass, {} fail'.format(name, len(successes), len(failures)))
testsuite = ET.SubElement(testsuites, 'testsuite')
testsuite.set('name', '{}/{}'.format(args.project_name, name))
testsuite.set('tests', str(len(units)))
testsuite.set('errors', str(len(failures)))
testsuite.set('failures', str(len(failures)))
for unit in successes:
testcase = ET.SubElement(testsuite, 'testcase')
testcase.set('classname', '{}/{}'.format(args.project_name, unit['suite']))
testcase.set('name', unit['name'])
testcase.set('time', str(unit['duration']))
for unit in failures:
testcase = ET.SubElement(testsuite, 'testcase')
testcase.set('classname', '{}/{}'.format(args.project_name, unit['suite']))
testcase.set('name', unit['name'])
testcase.set('time', str(unit['duration']))
failure = ET.SubElement(testcase, 'failure')
failure.set('classname', '{}/{}'.format(args.project_name, unit['suite']))
failure.set('name', unit['name'])
failure.set('type', 'error')
failure.text = unit['stdout'] + '\n' + unit['stderr']
output = ET.tostring(testsuites, encoding='unicode')
outfile.write(output)

View File

@ -1,132 +0,0 @@
#!/bin/bash
read_arg() {
# $1 = arg name
# $2 = arg value
# $3 = arg parameter
local rematch='^[^=]*=(.*)$'
if [[ $2 =~ $rematch ]]; then
read -r "$1" <<< "${BASH_REMATCH[1]}"
else
read -r "$1" <<< "$3"
# There is no way to shift our callers args, so
# return 1 to indicate they should do it instead.
return 1
fi
}
SUDO_CMD="sudo"
if docker -v |& grep -q podman; then
# Using podman
SUDO_CMD=""
# Docker is actually implemented by podman, and its OCI output
# is incompatible with some of the dockerd instances on GitLab
# CI runners.
export BUILDAH_FORMAT=docker
fi
set -e
base=""
base_version=""
build=0
run=0
push=0
list=0
print_help=0
no_login=0
while (($# > 0)); do
case "${1%%=*}" in
build) build=1;;
run) run=1;;
push) push=1;;
list) list=1;;
help) print_help=1;;
--base|-b) read_arg base "$@" || shift;;
--base-version) read_arg base_version "$@" || shift;;
--no-login) no_login=1;;
*) echo -e "\e[1;31mERROR\e[0m: Unknown option '$1'"; exit 1;;
esac
shift
done
if [ $print_help == 1 ]; then
echo "$0 - Build and run Docker images"
echo ""
echo "Usage: $0 <command> [options] [basename]"
echo ""
echo "Available commands"
echo ""
echo " build --base=<BASENAME> - Build Docker image <BASENAME>.Dockerfile"
echo " run --base=<BASENAME> - Run Docker image <BASENAME>"
echo " push --base=<BASENAME> - Push Docker image <BASENAME> to the registry"
echo " list - List available images"
echo " help - This help message"
echo ""
exit 0
fi
cd "$(dirname "$0")"
if [ $list == 1 ]; then
echo "Available Docker images:"
for f in *.Dockerfile; do
filename=$( basename -- "$f" )
basename="${filename%.*}"
echo -e " \e[1;39m$basename\e[0m"
done
exit 0
fi
# All commands after this require --base to be set
if [ -z "${base}" ]; then
echo "Usage: $0 <command>"
exit 1
fi
if [ ! -f "$base.Dockerfile" ]; then
echo -e "\e[1;31mERROR\e[0m: Dockerfile for '$base' not found"
exit 1
fi
if [ -z "${base_version}" ]; then
base_version="latest"
else
base_version="v$base_version"
fi
TAG="registry.freedesktop.org/pwithnall/malcontent/${base}:${base_version}"
if [ $build == 1 ]; then
echo -e "\e[1;32mBUILDING\e[0m: ${base} as ${TAG}"
$SUDO_CMD docker build \
--build-arg HOST_USER_ID="$UID" \
--tag "${TAG}" \
--file "${base}.Dockerfile" .
exit $?
fi
if [ $push == 1 ]; then
echo -e "\e[1;32mPUSHING\e[0m: ${base} as ${TAG}"
if [ $no_login == 0 ]; then
$SUDO_CMD docker login registry.freedesktop.org
fi
$SUDO_CMD docker push $TAG
exit $?
fi
if [ $run == 1 ]; then
echo -e "\e[1;32mRUNNING\e[0m: ${base} as ${TAG}"
$SUDO_CMD docker run \
--rm \
--volume "$(pwd)/..:/home/user/app" \
--workdir "/home/user/app" \
--tty \
--interactive "${TAG}" \
bash
exit $?
fi

View File

@ -1,29 +0,0 @@
#!/bin/bash
set +e
case "$1" in
--log-file)
log_file="$2"
shift
shift
;;
*)
log_file="_build/meson-logs/testlog.json"
esac
meson test \
-C _build \
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
--no-suite flaky \
"$@"
exit_code=$?
python3 .gitlab-ci/meson-junit-report.py \
--project-name=malcontent \
--job-id "${CI_JOB_NAME}" \
--output "_build/${CI_JOB_NAME}-report.xml" \
"${log_file}"
exit $exit_code

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "subprojects/libglib-testing"]
path = subprojects/libglib-testing
url = https://gitlab.gnome.org/pwithnall/libglib-testing.git

View File

@ -1,61 +0,0 @@
Attribution-ShareAlike 3.0 Unported
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM ITS USE.
License
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.
1. Definitions
"Adaptation" means a work based upon the Work, or upon the Work and other pre-existing works, such as a translation, adaptation, derivative work, arrangement of music or other alterations of a literary or artistic work, or phonogram or performance and includes cinematographic adaptations or any other form in which the Work may be recast, transformed, or adapted including in any form recognizably derived from the original, except that a work that constitutes a Collection will not be considered an Adaptation for the purpose of this License. For the avoidance of doubt, where the Work is a musical work, performance or phonogram, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered an Adaptation for the purpose of this License.
"Collection" means a collection of literary or artistic works, such as encyclopedias and anthologies, or performances, phonograms or broadcasts, or other works or subject matter other than works listed in Section 1(f) below, which, by reason of the selection and arrangement of their contents, constitute intellectual creations, in which the Work is included in its entirety in unmodified form along with one or more other contributions, each constituting separate and independent works in themselves, which together are assembled into a collective whole. A work that constitutes a Collection will not be considered an Adaptation (as defined below) for the purposes of this License.
"Creative Commons Compatible License" means a license that is listed at http://creativecommons.org/compatiblelicenses that has been approved by Creative Commons as being essentially equivalent to this License, including, at a minimum, because that license: (i) contains terms that have the same purpose, meaning and effect as the License Elements of this License; and, (ii) explicitly permits the relicensing of adaptations of works made available under that license under this License or a Creative Commons jurisdiction license with the same License Elements as this License.
"Distribute" means to make available to the public the original and copies of the Work or Adaptation, as appropriate, through sale or other transfer of ownership.
"License Elements" means the following high-level license attributes as selected by Licensor and indicated in the title of this License: Attribution, ShareAlike.
"Licensor" means the individual, individuals, entity or entities that offer(s) the Work under the terms of this License.
"Original Author" means, in the case of a literary or artistic work, the individual, individuals, entity or entities who created the Work or if no individual or entity can be identified, the publisher; and in addition (i) in the case of a performance the actors, singers, musicians, dancers, and other persons who act, sing, deliver, declaim, play in, interpret or otherwise perform literary or artistic works or expressions of folklore; (ii) in the case of a phonogram the producer being the person or legal entity who first fixes the sounds of a performance or other sounds; and, (iii) in the case of broadcasts, the organization that transmits the broadcast.
"Work" means the literary and/or artistic work offered under the terms of this License including without limitation any production in the literary, scientific and artistic domain, whatever may be the mode or form of its expression including digital form, such as a book, pamphlet and other writing; a lecture, address, sermon or other work of the same nature; a dramatic or dramatico-musical work; a choreographic work or entertainment in dumb show; a musical composition with or without words; a cinematographic work to which are assimilated works expressed by a process analogous to cinematography; a work of drawing, painting, architecture, sculpture, engraving or lithography; a photographic work to which are assimilated works expressed by a process analogous to photography; a work of applied art; an illustration, map, plan, sketch or three-dimensional work relative to geography, topography, architecture or science; a performance; a broadcast; a phonogram; a compilation of data to the extent it is protected as a copyrightable work; or a work performed by a variety or circus performer to the extent it is not otherwise considered a literary or artistic work.
"You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation.
"Publicly Perform" means to perform public recitations of the Work and to communicate to the public those public recitations, by any means or process, including by wire or wireless means or public digital performances; to make available to the public Works in such a way that members of the public may access these Works from a place and at a place individually chosen by them; to perform the Work to the public by any means or process and the communication to the public of the performances of the Work, including by public digital performance; to broadcast and rebroadcast the Work by any means including signs, sounds or images.
"Reproduce" means to make copies of the Work by any means including without limitation by sound or visual recordings and the right of fixation and reproducing fixations of the Work, including storage of a protected performance or phonogram in digital form or other electronic medium.
2. Fair Dealing Rights. Nothing in this License is intended to reduce, limit, or restrict any uses free from copyright or rights arising from limitations or exceptions that are provided for in connection with the copyright protection under copyright law or other applicable laws.
3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below:
to Reproduce the Work, to incorporate the Work into one or more Collections, and to Reproduce the Work as incorporated in the Collections;
to create and Reproduce Adaptations provided that any such Adaptation, including any translation in any medium, takes reasonable steps to clearly label, demarcate or otherwise identify that changes were made to the original Work. For example, a translation could be marked "The original work was translated from English to Spanish," or a modification could indicate "The original work has been modified.";
to Distribute and Publicly Perform the Work including as incorporated in Collections; and,
to Distribute and Publicly Perform Adaptations.
For the avoidance of doubt:
Non-waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License;
Waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor waives the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; and,
Voluntary License Schemes. The Licensor waives the right to collect royalties, whether individually or, in the event that the Licensor is a member of a collecting society that administers voluntary licensing schemes, via that society, from any exercise by You of the rights granted under this License.
The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. Subject to Section 8(f), all rights not expressly granted by Licensor are hereby reserved.
4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions:
You may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from any Licensor You must, to the extent practicable, remove from the Collection any credit as required by Section 4(c), as requested. If You create an Adaptation, upon notice from any Licensor You must, to the extent practicable, remove from the Adaptation any credit as required by Section 4(c), as requested.
You may Distribute or Publicly Perform an Adaptation only under the terms of: (i) this License; (ii) a later version of this License with the same License Elements as this License; (iii) a Creative Commons jurisdiction license (either this or a later license version) that contains the same License Elements as this License (e.g., Attribution-ShareAlike 3.0 US)); (iv) a Creative Commons Compatible License. If you license the Adaptation under one of the licenses mentioned in (iv), you must comply with the terms of that license. If you license the Adaptation under the terms of any of the licenses mentioned in (i), (ii) or (iii) (the "Applicable License"), you must comply with the terms of the Applicable License generally and the following provisions: (I) You must include a copy of, or the URI for, the Applicable License with every copy of each Adaptation You Distribute or Publicly Perform; (II) You may not offer or impose any terms on the Adaptation that restrict the terms of the Applicable License or the ability of the recipient of the Adaptation to exercise the rights granted to that recipient under the terms of the Applicable License; (III) You must keep intact all notices that refer to the Applicable License and to the disclaimer of warranties with every copy of the Work as included in the Adaptation You Distribute or Publicly Perform; (IV) when You Distribute or Publicly Perform the Adaptation, You may not impose any effective technological measures on the Adaptation that restrict the ability of a recipient of the Adaptation from You to exercise the rights granted to that recipient under the terms of the Applicable License. This Section 4(b) applies to the Adaptation as incorporated in a Collection, but this does not require the Collection apart from the Adaptation itself to be made subject to the terms of the Applicable License.
If You Distribute, or Publicly Perform the Work or any Adaptations or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or if the Original Author and/or Licensor designate another party or parties (e.g., a sponsor institute, publishing entity, journal) for attribution ("Attribution Parties") in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and (iv) , consistent with Ssection 3(b), in the case of an Adaptation, a credit identifying the use of the Work in the Adaptation (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). The credit required by this Section 4(c) may be implemented in any reasonable manner; provided, however, that in the case of a Adaptation or Collection, at a minimum such credit will appear, if a credit for all contributing authors of the Adaptation or Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributing authors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Original Author, Licensor and/or Attribution Parties, as appropriate, of You or Your use of the Work, without the separate, express prior written permission of the Original Author, Licensor and/or Attribution Parties.
Except as otherwise agreed in writing by the Licensor or as may be otherwise permitted by applicable law, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Adaptations or Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the Original Author's honor or reputation. Licensor agrees that in those jurisdictions (e.g. Japan), in which any exercise of the right granted in Section 3(b) of this License (the right to make Adaptations) would be deemed to be a distortion, mutilation, modification or other derogatory action prejudicial to the Original Author's honor and reputation, the Licensor will waive or not assert, as appropriate, this Section, to the fullest extent permitted by the applicable national law, to enable You to reasonably exercise Your right under Section 3(b) of this License (right to make Adaptations) but not otherwise.
5. Representations, Warranties and Disclaimer
UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
7. Termination
This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Adaptations or Collections from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License.
Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above.
8. Miscellaneous
Each time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License.
Each time You Distribute or Publicly Perform an Adaptation, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License.
If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent.
This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You.
The rights granted under, and the subject matter referenced, in this License were drafted utilizing the terminology of the Berne Convention for the Protection of Literary and Artistic Works (as amended on September 28, 1979), the Rome Convention of 1961, the WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and the Universal Copyright Convention (as revised on July 24, 1971). These rights and subject matter take effect in the relevant jurisdiction in which the License terms are sought to be enforced according to the corresponding provisions of the implementation of those treaty provisions in the applicable national law. If the standard suite of rights granted under applicable copyright law includes additional rights not granted under this License, such additional rights are deemed to be included in the License; this License is not intended to restrict the license of any rights under applicable law.

View File

@ -1,22 +0,0 @@
Terminology
-----------
The main terminology used in malcontent is parental controls, which are
implemented by administrators and enforced on child users.
The feature applies to a range of other carer/caree relationships, though, where
the caree user might need to be protected from doing things on the computer
which arent suitable for them.
The terminology parental controls is used consistently, despite not all
situations actually involving a parent or child, because thats how most users
will find the functionality.
To remain as inclusive as possible, there are some rules about which terminology
to use:
- Use parental controls to refer to the overall feature
- Refer to administrators or administrator accounts rather than parents
- Refer to child users in general contexts, but refer to particular user
accounts using their full name — dont mention child in that case
Reference: https://gitlab.freedesktop.org/pwithnall/malcontent/-/issues/13

417
NEWS
View File

@ -1,420 +1,3 @@
Overview of changes in malcontent 0.11.1
========================================
* Bugs fixed:
- !147 0.11.0
- !148 build: Switch to Mesons gnome.post_install function
- !149 po: add Georgian translation
- !150 Update Hungarian translation
- !151 Update Hindi (hi) translation
- !152 doc: Add Turkish Translation
* Translation updates:
- Georgian (NorwayFun)
- Hindi (Hemish)
- Hungarian (Balázs Úr)
- Turkish (Sabri Unal)
Overview of changes in malcontent 0.11.0
========================================
* libmalcontent-ui, and the malcontent-control application, now use
libappstream rather than appstream-glib. (#51)
* libmalcontent-ui, and the malcontent-control application, now use GTK 4 and
libadwaita rather than GTK+ 3. (!141)
* As a result of these changes, the pkg-config name has been bumped to
libmalcontent-ui-1, and the gobject-introspection name to MalcontentUi-1.
* Improve keyboard navigation of the malcontent-control application. (#52)
* Translation updates:
- Italian
- Russian
Overview of changes in malcontent 0.10.5
========================================
* Bugs fixed:
- !134 Update it.po
- !135 Add German help translation
- !136 Update pt_BR.po
- !137 Update tr.po
- !138 Update Chinese (Taiwan) translation file.
* Translation updates:
- Chinese (Taiwan)
- Italian
- Portuguese (Brazil)
- Turkish
Overview of changes in malcontent 0.10.4
========================================
* Bugs fixed:
- !127 Update Catalan translation
- !128 Update German proof-read translation from https://l10n.gnome.org/vertimus/malcontent/main/po/de/
- !129 Update it.po
- !132 Remove superfluous arguments to i18n.merge_file
- !133 help: Add Italian help translation
* Translation updates:
- Catalan
- German
- Italian
Overview of changes in malcontent 0.10.3
========================================
* Bugs fixed:
- #44 Do not make malcontent-control user uninstallable using gui
- !123 Add Czech translation
- !124 Update Czech translation
- !125 malcontent-control: Fix an unterminated option entry array
- !126 malcontent-control: Focus controls rather than user selector
* Translation updates:
- Czech
Overview of changes in malcontent 0.10.2
========================================
* Hide the launcher for malcontent-control from gnome-shell if using the GNOME
desktop; find it via gnome-control-center instead (!119)
* Bugs fixed:
- !118 ci: Limit depth of clone of subprojects
- !119 malcontent-control: Hide application in GNOME
- !121 ci: Rename master to main branch
* Translation updates:
- Indonesian
- Italian
Overview of changes in malcontent 0.10.1
========================================
* Bugs fixed:
- #32 App sort key does not match displayed name
- !112 Update Swedish translation
- !113 Update Polish translation 201220
- !116 libmalcontent-ui: Drop handling of eos-link desktop files
* Translation updates:
- Polish
- Swedish
Overview of changes in malcontent 0.10.0
========================================
* Improve support for systems without accountsservice (#27)
* Fix some data loss-causing state synchronisation problems (#18, #28)
* Hide support for flatpak user repositories, as they are typically not
configured on systems (#30)
* Bugs fixed:
- #4 Add manpage docs for malcontent-client monitor, set and oars-section commands
- #13 Consider terminology of parental controls
- #15 Improving padding/spacing in malcontent-control UI
- #18 Reload Restrict Apps list when installed apps change on system
- #19 Add command line option to malcontent-control to pre-select a user
- #23 appdata not validating
- #25 Parental controls app empty state is misleading
- #27 Fails closed if accountsservice isn't available on the bus
- #28 Restrict Applications dialogue is empty if MctUserControls is created with empty app filter
- #30 Restrict App Installation tickboxes are confusing
- !85 Update Ukrainian translation
- !86 l10n: Update Italian translation
- !87 l10n-sv
- !88 Add Danish translation
- !91 libmalcontent: Rationalise a couple of translatable strings
- !92 Fix several issues with the app list in the restrict applications dialogue
- !93 Update Ukrainian translation
- !94 Update Polish translation 201018
- !96 Update Polish translation 201025
- !100 Bump appstream-glib dep and update content rating code
- !101 Fix partial loss of parental controls settings when partially updating them
- !102 user-controls: Only save the app filter if its changed
- !103 malcontent-control: Add link to guidance on how to set parental controls
- !104 docs: Add a development principles section to the README
- !106 Update Danish translation
- !107 Update Ukrainian translation
- !108 Update Ukrainian translation
- !109 Update Ukrainian translation
- !111 accounts-service: Allow installation to the system repo by default
* Translation updates:
- Danish
- Italian
- Polish
- Swedish
- Ukrainian
Overview of changes in malcontent 0.9.0
=======================================
* Use appstream-glib code for content rating systems if available — this
adds a dependency on appstream-glib, but no particular version (see #7)
* Rename three APIs in `app-filter.h` to avoid discriminatory language:
- `mct_app_filter_builder_blacklist_path` → `…_blocklist_path`
- `…_blacklist_flatpak_ref` → `…_blocklist_flatpak_ref`
- `…_blacklist_content_type` → `…_blocklist_content_type`
This is an API break. (See !72)
* Add a `privileged_group` configure option to set the name of the system
sudo group — it might be `sudo` or `wheel` (thanks to Sergey Shatunov; see #22)
* Bugs fixed:
- #7 Lift GNOME Software content rating implementation into appstream-glib, and fix it
- #21 No references to homosexuality
- #22 Polkit rules should use wheel group instead of sudo
- !69 Two small UI tweaks
- !72 tree-wide: Replace usages of whitelist/blacklist
- !73 po: Update translations from downstream in Endless
- !74 Update Ukrainian translation
- !75 Update Polish translation 200614
- !77 all: Fix various typos and incorrect terminology
- !78 build: Use meson.current_source_dir() instead of source_root()
- !79 build: Re-add libglib-testing subproject
- !80 Update Brazilian Portuguese translation
- !81 ci: Use pre-built Docker images for CI builds
- !82 subprojects: Limit depth when cloning
- !83 Update Spanish translation
* Translation updates:
- Afrikaans
- Arabic
- Bangla
- Basque
- Bokmål, Norwegian
- Bulgarian
- Catalan
- Catalan — valencia.UTF-8
- Chinese (Taiwan)
- Croatian
- Czech
- Danish
- Dutch
- Esperanto
- Finnish
- French
- Friulian
- Gaelic
- Galician
- German
- Greek, Modern (1453-)
- Hebrew
- Hindi
- Hungarian
- Indonesian
- Italian
- Kazakh
- Korean
- Latvian
- Lithuanian
- Malay
- Malayalam
- Occitan (post 1500)
- Panjabi
- Persian
- Polish
- Portuguese
- Portuguese (Brazil)
- Romanian
- Russian
- Serbian
- Serbian — latin.UTF-8
- Slovak
- Slovenian
- Spanish
- Swedish
- Thai
- Turkish
- Ukrainian
- Vietnamese
Overview of changes in malcontent 0.8.0
=======================================
* Add user manual (!51)
* Add a header bar and primary menu to the main UI (!58)
* Bump Meson dependency to 0.50.0 (!59)
* Fix translation of libmalcontent-ui widgets when used in other applications (!68)
* Bugs fixed:
- !3 Remove use of libglib-testing subproject
- !50 Various meson cleanups
- !51 Add user manual/documentation
- !52 Update Polish translation 200329
- !53 Added Indonesian translation
- !54 Update Ukrainian translation
- !55 libmalcontent: Add enum types to fix introspection of MctManagerError
- !56 Update Polish translation 200405
- !57 Update Ukrainian translation + docs translation
- !58 malcontent-control: Add a header bar and primary menu
- !59 meson: bump minimum version to 0.50.0
- !60 user-controls: Add a fallback bus connection
- !62 Added Indonesian help translation
- !63 Import translations from Endless
- !64 Import zh_TW translation from Endless
- !65 Add translator comments for about dialog strings
- !66 Update Brazilian Portuguese translation
- !67 Add Brazilian Portuguese translation
- !68 Fix translation of libmalcontent-ui
* Translation updates:
- Afrikaans
- Arabic
- Bangla
- Basque
- Bokmål, Norwegian
- Bulgarian
- Catalan
- Catalan — valencia.UTF-8
- Chinese (Taiwan)
- Croatian
- Czech
- Danish
- Dutch
- Esperanto
- Finnish
- French
- Friulian
- Gaelic
- Galician
- German
- Greek, Modern (1453-)
- Hebrew
- Hindi
- Hungarian
- Indonesian
- Italian
- Kazakh
- Korean
- Latvian
- Lithuanian
- Malay
- Malayalam
- Occitan (post 1500)
- Panjabi
- Persian
- Polish
- Portuguese
- Portuguese (Brazil)
- Romanian
- Russian
- Serbian
- Serbian — latin.UTF-8
- Slovak
- Slovenian
- Spanish
- Swedish
- Thai
- Turkish
- Ukrainian
- Vietnamese
Overview of changes in malcontent 0.7.0
=======================================
* Add `-Dui` configure option to help work around circular dependency with
flatpak (#16)
* Add data serialization and deserialization methods for app filters and
session limits (!45)
* Add mct_app_filter_is_enabled() and mct_session_limits_is_enabled() APIs
for determining whether filtering/limits are enabled at a high level (!47)
* Bugs fixed:
- #16 Circular dependency on flatpak
- !35 Update Ukrainian translation
- !37 Drop a few unnecessary dependencies
- !39 Add Polish translation
- !40 Use libglib-testing submodule only as fallback
- !41 Fix typo in malcontent-client.8
- !42 docs: Update license information in README and meson.build
- !43 user-controls: Make OARS drop down open to the right
- !44 Fix updating the UI when a users locale changes
- !45 Support data serialisation and deserialisation
- !46 Fix papercuts when editing parental controls of current user
- !47 app-filter: Add mct_app_filter_is_enabled() API
- !48 Update POTFILES.in 200320
- !49 malcontent-control: Refactor bus initialisation
* Translation updates:
- Polish
- Ukrainian
Overview of changes in malcontent 0.6.0
=======================================
* Add icon for `malcontent-control` (thanks Jakub Steiner) (#9)
* Redesign `malcontent-control` UI in response to design feedback (#11)
* Add `AccountInfo` interface for metadata on parent accounts (!26)
* Fix translation of the UI (!31)
* Bugs fixed:
- #9 Add icon for malcontent-control
- #11 User controls UI tweaks
- !26 accounts-service: Add AccountInfo interface
- !27 user-selector: Fix some const-to-non-const cast warnings
- !29 po: Add some missing files to POTFILES.in
- !30 Add Ukrainian translation
- !31 build: Fix definition of PACKAGE_LOCALE_DIR
- !32 Add Brazilian Portuguese translation
- !33 po: Order LINGUAS alphabetically
- !34 More small UI tweaks
* Translation updates:
- Portuguese (Brazil)
- Ukrainian
Overview of changes in malcontent 0.5.0
=======================================
* Add libmalcontent-ui library for parental controls widgets
* Add malcontent-control parental controls app
* Add initial support for session limits (but more needs to be done)
* Rename some of the commands for `malcontent-client` and rename some C APIs
(but with compatibility defines)
* Bugs fixed:
- #6 Align GLib dependency requirements
- !16 docs: Improve documentation of "app-filter-changed" signal
- !18 build: Port meson-make-symlink script to Python
- !19 Add session limits support and PAM module
- !20 Initial version of parental controls app
- !21 build: Fix default value of pamlibdir
- !22 Iterate on UI of parental controls app
- !23 Split widgets into separate library
- !24 Allow user controls to be used for not-yet-existing users
Overview of changes in malcontent 0.4.0
=======================================

View File

@ -52,32 +52,6 @@ AppArmor or SELinux. However, its correct use by applications should provide
enough of an obstacle to prevent users easily or accidentally having access to
content which they shouldnt.
Development principles
---
malcontent exists to make it easier for parents to responsibly set limits on
what their children can do on the computer (similarly, for other carer/caree
relationships). It should provide guidance on, and nudge parents towards,
following the best practice for discussing, choosing and setting restrictions on
their childs computer use.
Restrictions should be supported which allow giving children access to material
which is appropriate to their age/stage of development, but which can restrict
access to other material so they are not overwhelmed with too many, or too
complex, ideas for their stage of development. Similarly, restrictions should be
supported to control unsupervised communication with unknown people online, as
being coerced or bullied is one of the more common harms for children online.
Best practices should be research and evidence-based, and supported by large
international or national childrens organisations or charities. They may change
over time.
malcontent is a tool to help with a social problem. In the hands of a bad
parent, it can be used to do bad things. Features in malcontent should be
designed with that in mind, such that if they are used maliciously, they should
not give the parent radically more power over their child than they would have
had without malcontent.
Example usage
---
@ -87,7 +61,7 @@ set parental controls policies for users.
```
$ # This sets the parental controls policy for user philip to allow no \\
installation of apps with anything more than none for realistic violence, \\
and to blocklist running the org.freedesktop.Bustle flatpak:
and to blacklist running the org.freedesktop.Bustle flatpak:
$ malcontent-client set philip \\
violence-realistic=none \\
app/org.freedesktop.Bustle/x86_64/stable
@ -115,23 +89,19 @@ Dependencies
------------
* accounts-service
* appstream
* dbus-daemon
* flatpak
* gio-2.0 ≥ 2.60
* gio-unix-2.0 ≥ 2.60
* glib-2.0 ≥ 2.60
* gobject-2.0 ≥ 2.60
* gtk4
* libadwaita
* gtk+-3.0
* polkit-gobject-1
Licensing
---------
All code in the libraries in this project is licensed under LGPL-2.1+. Code in the
`malcontent-control` application is licensed under GPL-2.0+. See `COPYING` and the
copyright headers in individual files for more details.
All code in this project is licensed under LGPL-2.1+. See COPYING for more details.
Bugs
----

View File

@ -1,35 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="com.endlessm.ParentalControls.AccountInfo">
<annotation name="org.freedesktop.Accounts.VendorExtension" value="true"/>
<annotation name="org.freedesktop.Accounts.Authentication.ChangeOwn"
value="com.endlessm.ParentalControls.AccountInfo.ChangeOwn"/>
<annotation name="org.freedesktop.Accounts.Authentication.ReadOwn"
value="com.endlessm.ParentalControls.AccountInfo.ReadOwn"/>
<annotation name="org.freedesktop.Accounts.Authentication.ChangeAny"
value="com.endlessm.ParentalControls.AccountInfo.ChangeAny"/>
<annotation name="org.freedesktop.Accounts.Authentication.ReadAny"
value="com.endlessm.ParentalControls.AccountInfo.ReadAny"/>
<!--
IsParent:
Whether this user is a parent on the system. All parents must be
administrators, but not all administrators must be parents.
This is intended to allow parent accounts to be rendered differently in
the user interface. It must not be used to make authentication
decisions — use polkit for that.
The value of this property must be treated as `false` if the user is not
an administrator.
-->
<property name="IsParent" type="b" access="readwrite">
<annotation name="org.freedesktop.Accounts.DefaultValue" value="false"/>
</property>
</interface>
</node>

View File

@ -24,8 +24,8 @@
The string list contains flatpak application IDs (containing at least one
dot and no leading slash) and absolute binary paths (containing a leading
slash). The boolean value indicates whether this is an allowlist (true)
or blocklist (false).
slash). The boolean value indicates whether this is a whitelist (true) or
blacklist (false).
-->
<property name="AppFilter" type="(bas)" access="readwrite">
<annotation name="org.freedesktop.Accounts.DefaultValue"
@ -69,7 +69,7 @@
installation can proceed.
If this is false, the user is not allowed to install any apps or runtimes
to their flatpak user repository due to parental controls.
to their flatpak user repository.
-->
<property name="AllowUserInstallation" type="b" access="readwrite">
<annotation name="org.freedesktop.Accounts.DefaultValue" value="true"/>
@ -80,15 +80,14 @@
Whether this user is allowed to install to the flatpak system repository.
If this is true, and if the polkit check for allowing app installation
succeeds (i.e. the user is an administrator or an administrator has given
permission), and if the OarsFilter does not restrict this app, app
succeeds, and if the OarsFilter does not restrict this app, app
installation can proceed.
If this is false, the user is not allowed to install any apps or runtimes
to the flatpak system repository due to parental controls.
to the flatpak system repository.
-->
<property name="AllowSystemInstallation" type="b" access="readwrite">
<annotation name="org.freedesktop.Accounts.DefaultValue" value="true"/>
<annotation name="org.freedesktop.Accounts.DefaultValue" value="false"/>
</property>
</interface>
</node>

View File

@ -79,44 +79,4 @@
<allow_active>auth_admin_keep</allow_active>
</defaults>
</action>
<action id="com.endlessm.ParentalControls.AccountInfo.ChangeOwn">
<description>Change your own account info</description>
<message>Authentication is required to change your account info.</message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
</action>
<action id="com.endlessm.ParentalControls.AccountInfo.ReadOwn">
<description>Read your own account info</description>
<message>Authentication is required to read your account info.</message>
<defaults>
<allow_any>yes</allow_any>
<allow_inactive>yes</allow_inactive>
<allow_active>yes</allow_active>
</defaults>
</action>
<action id="com.endlessm.ParentalControls.AccountInfo.ChangeAny">
<description>Change another users account info</description>
<message>Authentication is required to change another users account info.</message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
</action>
<action id="com.endlessm.ParentalControls.AccountInfo.ReadAny">
<description>Read another users account info</description>
<message>Authentication is required to read another users account info.</message>
<defaults>
<allow_any>yes</allow_any>
<allow_inactive>yes</allow_inactive>
<allow_active>yes</allow_active>
</defaults>
</action>
</policyconfig>

View File

@ -27,7 +27,7 @@ polkit.addRule(function(action, subject) {
action.id == "com.endlessm.ParentalControls.SessionLimits.ReadOwn" ||
action.id == "com.endlessm.ParentalControls.SessionLimits.ReadAny") &&
subject.active && subject.local &&
subject.isInGroup("@PRIVILEGED_GROUP@")) {
subject.isInGroup("sudo")) {
return polkit.Result.YES;
}

View File

@ -1,4 +1,4 @@
i18n.merge_file(
i18n.merge_file('com.endlessm.ParentalControls.policy',
input: 'com.endlessm.ParentalControls.policy.in',
output: 'com.endlessm.ParentalControls.policy',
po_dir: po_dir,
@ -7,7 +7,6 @@ i18n.merge_file(
)
dbus_interfaces = [
'com.endlessm.ParentalControls.AccountInfo',
'com.endlessm.ParentalControls.AppFilter',
'com.endlessm.ParentalControls.SessionLimits',
]
@ -21,11 +20,5 @@ foreach dbus_interface: dbus_interfaces
join_paths(accountsserviceinterfacesdir, filename))
endforeach
polkit_conf = configuration_data()
polkit_conf.set('PRIVILEGED_GROUP', get_option('privileged_group'))
configure_file(
input: 'com.endlessm.ParentalControls.rules.in',
output: 'com.endlessm.ParentalControls.rules',
configuration: polkit_conf,
install_dir: join_paths(get_option('datadir'), 'polkit-1', 'rules.d')
)
install_data('com.endlessm.ParentalControls.rules',
install_dir: join_paths(get_option('datadir'), 'polkit-1', 'rules.d'))

View File

@ -1,21 +0,0 @@
<?xml version="1.0"?>
<page xmlns="http://projectmallard.org/1.0/" type="topic" id="creating-a-child-user">
<info>
<link type="guide" xref="index#setup"/>
<include href="legal.xml" xmlns="http://www.w3.org/2001/XInclude"/>
<desc>Creating a child user on the computer.</desc>
</info>
<title>Creating a Child User</title>
<p>Parental controls can only be applied to non-administrator accounts. Such
an account may have been created when the computer was initially set up.
If not, a new child user may be created from the <app>Parental
Controls</app> application if no child users already exist; and otherwise
may be created from the <app>Control Center</app>.</p>
<p>To create a new child user, see <link type="guide" xref="help:gnome-help/user-add">Add a new user account</link>.
As soon as the new user is created, it will appear in the <app>Parental
Controls</app> window so that its parental controls settings can be
configured.</p>
</page>

View File

@ -1,21 +0,0 @@
<?xml version="1.0"?>
<page xmlns="http://projectmallard.org/1.0/" type="guide" id="index">
<info>
<revision pkgversion="0.7.0" version="0.1" date="2020-03-27" status="final"/>
<credit type="author copyright">
<name>Philip Withnall</name>
<email>withnall@endlessm.com</email>
<years>2020</years>
</credit>
<include href="legal.xml" xmlns="http://www.w3.org/2001/XInclude"/>
</info>
<title>Parental Controls Help</title>
<section id="setup" style="2column">
<title>Introduction &amp; Setup</title>
</section>
<section id="controls" style="2column">
<title>Controls to Apply</title>
</section>
</page>

View File

@ -1,23 +0,0 @@
<?xml version="1.0"?>
<page xmlns="http://projectmallard.org/1.0/" type="topic" id="internet">
<info>
<link type="guide" xref="index#controls"/>
<include href="legal.xml" xmlns="http://www.w3.org/2001/XInclude"/>
<desc>Restricting a child users access to the internet.</desc>
</info>
<title>Restricting Access to the Internet</title>
<p>You can restrict a users access to the internet. This will prevent them
using a web browser, but it will not prevent them using the internet (in
potentially more limited forms) through other applications. For example,
it will not prevent access to e-mail accounts using <app>Evolution</app>,
and it will not prevent software updates being downloaded and applied.</p>
<p>To restrict a users access to the internet:</p>
<steps>
<item><p>Open the <app>Parental Controls</app> application.</p></item>
<item><p>Select the user in the tabs at the top.</p></item>
<item><p>Enable the <gui style="checkbox">Restrict Web Browsers</gui> checkbox.</p></item>
</steps>
</page>

View File

@ -1,30 +0,0 @@
<?xml version="1.0"?>
<page xmlns="http://projectmallard.org/1.0/" type="topic" id="introduction">
<info>
<link type="guide" xref="index#setup"/>
<include href="legal.xml" xmlns="http://www.w3.org/2001/XInclude"/>
<desc>Overview of parental controls, the <app>Parental Controls</app>
application and its use in other situations where access restrictions are
needed on a user.</desc>
<link type="seealso" xref="creating-a-child-user"/>
</info>
<title>Introduction to Parental Controls</title>
<p>Parental controls are a way to restrict what non-administrator accounts can
do on the computer, with the aim of allowing parents to restrict what their
children can do when using the computer unsupervised or under limited
supervision.</p>
<p>This functionality can be used in other situations ­ such as other
carer/caree relationships but is labelled as parental controls so that
its easy to find, as thats what most people will be looking for.</p>
<p>The parental controls for any user can be queried and set using the
<app>Parental Controls</app> application. This lists the non-administrator
accounts in tabs along its top bar, and shows their current parental
controls settings below. Changes to the parental controls apply immediately.</p>
<p>Restrictions on using the computer can only be applied to non-administrator
accounts. The parental controls settings for a user can only be changed by
an administrator, although the administrator can do so from the users
account by entering their password when prompted by the <app>Parental
Controls</app> application.</p>
</page>

View File

@ -1,6 +0,0 @@
<license xmlns="http://projectmallard.org/1.0/"
href="http://creativecommons.org/licenses/by-sa/3.0/">
<p>This work is licensed under a
<link href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons
Attribution-ShareAlike 3.0 Unported License</link>.</p>
</license>

View File

@ -1,30 +0,0 @@
<?xml version="1.0"?>
<page xmlns="http://projectmallard.org/1.0/" type="topic" id="restricting-applications">
<info>
<link type="guide" xref="index#controls"/>
<include href="legal.xml" xmlns="http://www.w3.org/2001/XInclude"/>
<desc>Restricting a child user from running already-installed applications.</desc>
</info>
<title>Restricting Access to Installed Applications</title>
<p>You can prevent a user from running specific applications which are already
installed on the computer. This could be useful if other users need those
applications but they are not appropriate for a child.</p>
<p>When installing additional software, you should consider whether that needs
to be restricted for some users — newly installed software is usable by all
users by default.</p>
<p>To restrict a users access to a specific application:</p>
<steps>
<item><p>Open the <app>Parental Controls</app> application.</p></item>
<item><p>Select the user in the tabs at the top.</p></item>
<item><p>Press the <gui style="button">Restrict Applications</gui> button.</p></item>
<item><p>Enable the switch in the row for each application you would like to restrict the user from accessing.</p></item>
<item><p>Close the <gui>Restrict Applications</gui> window.</p></item>
</steps>
<p>Restricting access to specific applications is often used in conjunction
with <link xref="software-installation"/> to prevent a user from installing
additional software which has not been vetted.</p>
</page>

View File

@ -1,66 +0,0 @@
<?xml version="1.0"?>
<page xmlns="http://projectmallard.org/1.0/" type="topic" id="software-installation">
<info>
<link type="guide" xref="index#controls"/>
<include href="legal.xml" xmlns="http://www.w3.org/2001/XInclude"/>
<desc>Restricting the software a child user can install, or preventing them installing additional software entirely.</desc>
</info>
<title>Restricting Software Installation</title>
<p>You can prevent a user from installing additional software on the system.
They will still be able to search for new software to install, but will need
an administrator to authorize the installation when they try to install an
application. This applies whether they are trying to install the application
system-wide (for all users) or just for themselves.</p>
<p>Additionally, you can restrict which software a user can browse or search
for in the <app>Software</app> catalog by age categories.</p>
<p>To prevent a user from running an application which has already been
installed, see <link xref="restricting-applications"/>.</p>
<section id="installation">
<title>Preventing Software Installation</title>
<p>To prevent a user from installing additional software:</p>
<steps>
<item><p>Open the <app>Parental Controls</app> application.</p></item>
<item><p>Select the user in the tabs at the top.</p></item>
<item><p>Enable the <gui style="checkbox">Restrict Application Installation</gui> checkbox.</p></item>
</steps>
</section>
<section id="oars">
<title>Restricting Software Installation by Age</title>
<p>Applications in the <app>Software</app> catalog have information about
content they contain which might be inappropriate for some ages — for
example, various forms of violence, unmoderated chat with other people on
the internet, or the possibility of spending money.</p>
<p>For each application, this information is summarized as the minimum age
child it is typically suitable to be used by — for example, “suitable for
ages 7+”. These age ratings are presented in region-specific schemes which
can be compared with the ratings schemes used for films and games.</p>
<p>The applications shown to a user in the <app>Software</app> catalog can
be filtered by their age suitability. Applications which are not suitable
for the user will be hidden, and will not be installable by that user.
They will be installable by other users (if their age suitability is set
high enough).</p>
<p>To filter the applications seen by a user in the <app>Software</app>
catalog to only those suitable for a certain age:</p>
<steps>
<item><p>Open the <app>Parental Controls</app> application.</p></item>
<item><p>Select the user in the tabs at the top.</p></item>
<item><p>In the <gui>Application Suitability</gui> list, select the age which applications should be suitable for.</p></item>
</steps>
<note style="important">
<p>The users actual age is not stored, so the <gui>Application Suitability</gui>
is not automatically updated over time as the child grows older. You
must periodically re-assess the appropriate <gui>Application Suitability</gui>
for each user.</p>
</note>
</section>
</page>

View File

@ -1,13 +0,0 @@
# please keep this list sorted alphabetically
da
de
es
hu
id
it
pl
pt_BR
ru
sv
tr
uk

View File

@ -1,457 +0,0 @@
# Danish translation for malcontent.
# Copyright (C) 2020 malcontent's COPYRIGHT HOLDER
# This file is distributed under the same license as the malcontent package.
# scootergrisen, 2020.
# scootergrisen: oversættelsen er ikke afprøvet
msgid ""
msgstr ""
"Project-Id-Version: malcontent master\n"
"POT-Creation-Date: 2020-10-11 03:28+0000\n"
"PO-Revision-Date: 2020-11-18 00:00+0200\n"
"Last-Translator: scootergrisen\n"
"Language-Team: Danish\n"
"Language: da\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. Put one translator per line, in the form NAME <EMAIL>, YEAR1, YEAR2
msgctxt "_"
msgid "translator-credits"
msgstr "scootergrisen <>, 2020"
#. (itstool) path: info/desc
#: C/creating-a-child-user.page:6
msgid "Creating a child user on the computer."
msgstr "Oprettelse af en barnebruger på computeren."
#. (itstool) path: page/title
#: C/creating-a-child-user.page:9
msgid "Creating a Child User"
msgstr "Oprettelse af en barnebruger"
#. (itstool) path: page/p
#: C/creating-a-child-user.page:11
msgid ""
"Parental controls can only be applied to non-administrator accounts. Such an "
"account may have been created when the computer was initially set up. If "
"not, a new child user may be created from the <app>Parental Controls</app> "
"application if no child users already exist; and otherwise may be created "
"from the <app>Control Center</app>."
msgstr ""
"Forældrestyring kan kun anvendes på konti som ikke er administrator. En "
"sådan konto kan være blevet oprettet, første gang computeren blev opsat. Er "
"det ikke tilfældet, så kan der oprettes en ny barnebruger i programmet "
"<app>Forældrestyring</app>, hvis der ikke allerede findes en barnebruger, "
"ellers kan den oprettes i <app>Kontrolpanel</app>."
#. (itstool) path: page/p
#: C/creating-a-child-user.page:17
msgid ""
"To create a new child user, see <link type=\"guide\" xref=\"help:gnome-help/"
"user-add\">Add a new user account</link>. As soon as the new user is "
"created, it will appear in the <app>Parental Controls</app> window so that "
"its parental controls settings can be configured."
msgstr ""
"Se <link type=\"guide\" xref=\"help:gnome-"
"help/user-add\">Tilføj en ny brugerkonto</link>, for at oprette en ny barnebruger. Den nye bruger vises i "
"vinduet <app>Forældrestyring</app>, så snart den er oprettet, så dens "
"forældrestyringsindstillinger kan konfigureres."
#. (itstool) path: credit/name
#: C/index.page:6
msgid "Philip Withnall"
msgstr "Philip Withnall"
#. (itstool) path: credit/years
#: C/index.page:8
msgid "2020"
msgstr "2020"
#. (itstool) path: page/title
#: C/index.page:12
msgid "Parental Controls Help"
msgstr "Hjælp til Forældrestyring"
#. (itstool) path: section/title
#: C/index.page:15
msgid "Introduction &amp; Setup"
msgstr "Introduktion og opsætning"
#. (itstool) path: section/title
#: C/index.page:19
msgid "Controls to Apply"
msgstr "Styring som kan anvendes"
#. (itstool) path: info/desc
#: C/internet.page:6
msgid "Restricting a child users access to the internet."
msgstr "Begrænsning af en barnebrugers adgang til internettet."
#. (itstool) path: page/title
#: C/internet.page:9
msgid "Restricting Access to the Internet"
msgstr "Begrænsning af adgang til internettet"
#. (itstool) path: page/p
#: C/internet.page:11
msgid ""
"You can restrict a users access to the internet. This will prevent them "
"using a web browser, but it will not prevent them using the internet (in "
"potentially more limited forms) through other applications. For example, it "
"will not prevent access to e-mail accounts using <app>Evolution</app>, and "
"it will not prevent software updates being downloaded and applied."
msgstr ""
"Du kan begrænse en brugers adgang til internettet. Det forhindrer dem i at "
"bruge en webbrowser, men det forhindrer dem ikke i at bruge internettet (i "
"potentielt mere begrænset form) gennem andre programmer. Det vil f.eks. "
"ikke forhindre adgang til e-mailkonti med <app>Evolution</app> og det "
"forhindrer ikke softwareopdateringer i at blive downloadet og installeret."
#. (itstool) path: page/p
#: C/internet.page:17
msgid "To restrict a users access to the internet:"
msgstr "Sådan begrænses en brugers adgang til internettet:"
#. (itstool) path: item/p
#: C/internet.page:19 C/restricting-applications.page:20
#: C/software-installation.page:27 C/software-installation.page:64
msgid "Open the <app>Parental Controls</app> application."
msgstr "Åbn programmet <app>Forældrestyring</app>."
#. (itstool) path: item/p
#: C/internet.page:20 C/restricting-applications.page:21
#: C/software-installation.page:28 C/software-installation.page:65
msgid "Select the user in the tabs at the top."
msgstr "Vælg brugeren i fanebladene øverst."
#. (itstool) path: item/p
#: C/internet.page:21
msgid ""
"Enable the <gui style=\"checkbox\">Restrict Web Browsers</gui> checkbox."
msgstr ""
"Aktivér afkrydsningsboksen <gui style=\"checkbox\">Begræns webbrowsere</gui>."
#. (itstool) path: info/desc
#: C/introduction.page:6
msgid ""
"Overview of parental controls and the <app>Parental Controls</app> "
"application."
msgstr "Overblik over forældrestyring og programmet <app>Forældrestyring</app>."
#. (itstool) path: page/title
#: C/introduction.page:10
msgid "Introduction to Parental Controls"
msgstr "Introduktion til Forældrestyring"
#. (itstool) path: page/p
#: C/introduction.page:12
msgid ""
"Parental controls are a way to restrict what non-administrator accounts can "
"do on the computer, with the aim of allowing parents to restrict what their "
"children can do when using the computer unsupervised or under limited "
"supervision."
msgstr ""
"Forældrestyring er et måde til at begrænse, hvad konti, som ikke er "
"administrator, kan gøre på computeren med det mål at give forældre mulighed "
"for at begrænse, hvad deres børn kan, når de bruger computeren uden opsyn "
"eller under begrænset opsyn."
# scootergrisen: fra gennemlæsning: det skal nok ikke forstås som en plejesituation som på et plejehjem, men som et forhold mellem dem, der bestemmer, og dem der bliver bestemt over
# scootergrisen: fra gennemlæsning: Prøv med: såsom andre forhold mellem myndige og umyndige
#. (itstool) path: page/p
#: C/introduction.page:16
msgid ""
"This functionality can be used in other situations ­ such as other carer/"
"caree relationships but is labelled as parental controls so that its "
"easy to find."
msgstr ""
"Funktionaliteten kan bruges i andre situationer ­ såsom et andet forhold mellem "
"plejer og plejede men kaldes forældrestyring for at det skal være let at finde."
#. (itstool) path: page/p
#: C/introduction.page:19
msgid ""
"The parental controls for any user can be queried and set using the "
"<app>Parental Controls</app> application. This lists the non-administrator "
"accounts in tabs along its top bar, and shows their current parental "
"controls settings below. Changes to the parental controls apply immediately."
msgstr ""
"Forældrestyringen kan for alle brugere forespørges og indstilles med "
"programmet <app>Forældrestyring</app>. Det viser de konti, som ikke er "
"administrator, i faneblade langs den øverste linje og viser deres nuværende "
"forældrestyringsindstillinger nedenfor. Ændringer til forældrestyringen "
"anvendes straks."
#. (itstool) path: page/p
#: C/introduction.page:23
msgid ""
"Restrictions on using the computer can only be applied to non-administrator "
"accounts. The parental controls settings for a user can only be changed by "
"an administrator, although the administrator can do so from the users "
"account by entering their password when prompted by the <app>Parental "
"Controls</app> application."
msgstr ""
"Begrænsninger i at bruge computeren kan kun anvendes på konti som ikke er "
"administrator. Forældrestyringsindstillingerne til en bruger kan kun ændres "
"af en administrator, dog kan administratoren gøre det fra brugerens konto "
"ved at indtaste deres adgangskode når de bliver spurgt om det i programmet "
"<app>Forældrestyring</app>."
#. (itstool) path: p/link
#: C/legal.xml:4
msgid "Creative Commons Attribution-ShareAlike 3.0 Unported License"
msgstr ""
"Creative Commons Kreditering-Deling på samme vilkår 3.0 Ikke porteret-licens"
#. (itstool) path: license/p
#: C/legal.xml:3
msgid "This work is licensed under a <_:link-1/>."
msgstr "Værket er licenseret under en <_:link-1/>."
#. (itstool) path: info/desc
#: C/restricting-applications.page:6
msgid "Restricting a child user from running already-installed applications."
msgstr ""
"Begrænsning af en barnebruger i at køre programmer som allerede er "
"installeret."
#. (itstool) path: page/title
#: C/restricting-applications.page:9
msgid "Restricting Access to Installed Applications"
msgstr "Begrænsning af adgang til installerede programmer"
#. (itstool) path: page/p
#: C/restricting-applications.page:11
msgid ""
"You can prevent a user from running specific applications which are already "
"installed on the computer. This could be useful if other users need those "
"applications but they are not appropriate for a child."
msgstr ""
"Du kan forhindre en bruger i at køre bestemte programmer som allerede er "
"installeret på computeren. Det kan være nyttigt hvis andre brugere har brug "
"for de programmet men de ikke er egnet til et barn."
#. (itstool) path: page/p
#: C/restricting-applications.page:14
msgid ""
"When installing additional software, you should consider whether that needs "
"to be restricted for some users — newly installed software is usable by all "
"users by default."
msgstr ""
"Når der installeres yderligere software bør du overveje om det skal "
"begrænses til nogle brugere — nyligt "
"installeret software kan bruges af alle brugere som standard."
#. (itstool) path: page/p
#: C/restricting-applications.page:18
msgid "To restrict a users access to a specific application:"
msgstr "Sådan begrænses en brugers adgang til et bestemt program:"
#. (itstool) path: item/p
#: C/restricting-applications.page:22
msgid "Press the <gui style=\"button\">Restrict Applications</gui> button."
msgstr "Tryk på knappen <gui style=\"button\">Begræns programmer</gui>."
#. (itstool) path: item/p
#: C/restricting-applications.page:23
msgid ""
"Enable the switch in the row for each application you would like to restrict "
"the user from accessing."
msgstr ""
"Aktivér kontakten i rækken ved de programmer du vil begrænse brugeren i at få "
"adgang til."
#. (itstool) path: item/p
#: C/restricting-applications.page:24
msgid "Close the <gui>Restrict Applications</gui> window."
msgstr "Luk vinduet <gui>Begræns programmer</gui>."
#. (itstool) path: page/p
#: C/restricting-applications.page:27
msgid ""
"Restricting access to specific applications is often used in conjunction "
"with <link xref=\"software-installation\"/> to prevent a user from "
"installing additional software which has not been vetted."
msgstr ""
"Begrænsning af adgang til bestemte programmer bruges ofte sammen med <link "
"xref=\"software-installation\"/> for at forhindre en bruger i at installere "
"yderligere software som ikke er blevet undersøgt."
# scootergrisen: her er både "Restricting" og "preventing" brugt
# scootergrisen: så måske de ikke begge skal være samme ord
#. (itstool) path: info/desc
#: C/software-installation.page:6
msgid ""
"Restricting the software a child user can install, or preventing them "
"installing additional software entirely."
msgstr ""
"Begrænsning af den software en barnebruger kan installere eller helt forhindre "
"dem i at installere yderligere software."
#. (itstool) path: page/title
#: C/software-installation.page:9
msgid "Restricting Software Installation"
msgstr "Begrænsning af softwareinstallation"
#. (itstool) path: page/p
#: C/software-installation.page:11
msgid ""
"You can prevent a user from installing additional software, either for the "
"entire system, or just for themselves. They will still be able to search for "
"new software to install, but will need an administrator to authorize the "
"installation when they try to install an application."
msgstr ""
"Du kan forhindre en bruger i at installere yderligere software, enten for "
"hele systemet eller blot sig selv. De vil stadigvæk være i stand til at søge "
"efter ny software der skal installeres, men en administrator skal godkende "
"installationen når de forsøger at installere et program."
#. (itstool) path: page/p
#: C/software-installation.page:16
msgid ""
"Additionally, you can restrict which software a user can browse or search "
"for in the <app>Software</app> catalog by age categories."
msgstr ""
"Derudover kan du begrænse, hvilken software en bruger kan gennemse eller søge "
"efter i <app>Software</app>-kataloget efter aldersgruppekategorier."
#. (itstool) path: page/p
#: C/software-installation.page:19
msgid ""
"To prevent a user from running an application which has already been "
"installed, see <link xref=\"restricting-applications\"/>."
msgstr ""
"For at forhindre en bruger i at køre et program som allerede er blevet "
"installeret, se <link xref=\"restricting-applications\"/>."
#. (itstool) path: section/title
#: C/software-installation.page:23
msgid "Preventing Software Installation"
msgstr "Forhindring af softwareinstallation"
#. (itstool) path: section/p
#: C/software-installation.page:25
msgid "To prevent a user from installing additional software:"
msgstr "Sådan forhindres en bruger i at installere yderligere software:"
#. (itstool) path: item/p
#: C/software-installation.page:29
msgid ""
"Enable the <gui style=\"checkbox\">Restrict Application Installation</gui> "
"checkbox."
msgstr ""
"Aktivér afkrydsningsboksen <gui style=\"checkbox\">Begræns "
"programinstallation</gui>."
#. (itstool) path: item/p
#: C/software-installation.page:30
msgid ""
"Or enable the <gui style=\"checkbox\">Restrict Application Installation for "
"Others</gui> checkbox."
msgstr ""
"Eller aktivér afkrydsningsboksen <gui style=\"checkbox\">Begræns "
"programinstallation for andre</gui>."
#. (itstool) path: section/p
#: C/software-installation.page:33
msgid ""
"The <gui style=\"checkbox\">Restrict Application Installation for Others</"
"gui> checkbox allows the user to install additional software for themselves, "
"but prevents that software from being made available to other users. It "
"could be used, for example, if there were two child users, one of whom is "
"mature enough to be allowed to install additional software, but the other "
"isnt — enabling <gui style=\"checkbox\">Restrict Application Installation "
"for Others</gui> would prevent the more mature child from installing "
"applications which are inappropriate for the other child and making them "
"available to the other child."
msgstr ""
"Afkrydsningsboksen <gui style=\"checkbox\">Begræns programinstallation for "
"andre</gui> giver brugeren mulighed for at installere yderligere software "
"til sig selv, men forhindrer softwaren i at blive gjort tilgængelig for andre "
"brugere. Det kan f.eks. bruges, hvis der er to barnebrugere, hvoraf en af dem "
"er moden nok til at få tilladelse til at installere yderligere software, men "
"den anden ikke er — hvis <gui style=\"checkbox\">Begræns programinstallation "
"for andre</gui> tillades vil det forhindre det modne barn i at installere "
"programmer, som kan være uegnet for det andet barn og gøre dem tilgængelige "
"for det andet barn."
#. (itstool) path: section/title
#: C/software-installation.page:45
msgid "Restricting Software Installation by Age"
msgstr "Begrænsning af softwareinstallation efter aldersgruppe"
# scootergrisen: find god oversættelse af "unmoderated"
#. (itstool) path: section/p
#: C/software-installation.page:47
msgid ""
"Applications in the <app>Software</app> catalog have information about "
"content they contain which might be inappropriate for some ages — for "
"example, various forms of violence, unmoderated chat with other people on "
"the internet, or the possibility of spending money."
msgstr ""
"Programmer i <app>Software</app>-kataloget har information om deres indhold "
"som kan være uegnet til nogle aldersgrupper — f.eks. diverse former for "
"vold, umodereret chat med andre personer på internettet eller muligheden for "
"at bruge penge."
# scootergrisen: find ud af hvordan "suitable for ages 7+" er oversat andet sted
#. (itstool) path: section/p
#: C/software-installation.page:51
msgid ""
"For each application, this information is summarized as the minimum age "
"child it is typically suitable to be used by — for example, “suitable for "
"ages 7+”. These age ratings are presented in region-specific schemes which "
"can be compared with the ratings schemes used for films and games."
msgstr ""
"Informationen er opsummeret i hvert program som den laveste alder for børn "
"det typisk er egnet for at blive brugt af — f.eks. “suitable for ages 7+”. "
"Disse aldersvurderinger præsenteres i områdespecifikke modeller som kan "
"sammenlignes med de vurderingsmodeller som bruges til film og spil."
# scootergrisen: tjek "age suitability". Findes to gange
#. (itstool) path: section/p
#: C/software-installation.page:55
msgid ""
"The applications shown to a user in the <app>Software</app> catalog can be "
"filtered by their age suitability. Applications which are not suitable for "
"the user will be hidden, and will not be installable by that user. They will "
"be installable by other users (if their age suitability is set high enough)."
msgstr ""
"De programmer, som vises til en bruger i <app>Software</app>-kataloget, kan "
"filtreres efter den aldersgruppe, de er egnet til. Programmer, som ikke er "
"egnet til brugeren, skjules og kan ikke installeres af den bruger. De kan "
"installeres af andre brugere (hvis aldersgruppen de er egnet til er "
"indstillet højt nok)."
#. (itstool) path: section/p
#: C/software-installation.page:61
msgid ""
"To filter the applications seen by a user in the <app>Software</app> catalog "
"to only those suitable for a certain age:"
msgstr ""
"Sådan filtreres de programmer en bruger kan se i "
"<app>Software</app>-kataloget til dem der kun er egnet til en bestemt "
"aldersgruppe:"
#. (itstool) path: item/p
#: C/software-installation.page:66
msgid ""
"In the <gui>Application Suitability</gui> list, select the age which "
"applications should be suitable for."
msgstr ""
"Vælg den aldersgruppe som programmerne "
"skal være egnet til i listen <gui>Programegnethed</gui>."
#. (itstool) path: note/p
#: C/software-installation.page:70
msgid ""
"The users actual age is not stored, so the <gui>Application Suitability</"
"gui> is not automatically updated over time as the child grows older. You "
"must periodically re-assess the appropriate <gui>Application Suitability</"
"gui> for each user."
msgstr ""
"Brugerens rigtige alder gemmes ikke, så <gui>Programegnethed</gui> opdateres "
"ikke automatisk efterhånden som barnet bliver ældre. Du skal periodisk "
"revurdere den passende <gui>Programegnethed</gui> til hver bruger."

View File

@ -1,362 +0,0 @@
# German translation for malcontent.
# Copyright (C) 2021 malcontent's COPYRIGHT HOLDER
# This file is distributed under the same license as the malcontent package.
# Christian Kirbach <Christian.Kirbach@gmail.com>, 2021.
#
msgid ""
msgstr ""
"Project-Id-Version: malcontent main\n"
"POT-Creation-Date: 2021-12-29 15:34+0000\n"
"PO-Revision-Date: 2021-12-31 13:36+0100\n"
"Last-Translator: Tim Sabsch <tim@sabsch.com>\n"
"Language-Team: German <gnome-de@gnome.org>\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 3.0\n"
#. Put one translator per line, in the form NAME <EMAIL>, YEAR1, YEAR2
msgctxt "_"
msgid "translator-credits"
msgstr "Christian Kirbach <christian.kirbach@gmail.com>, 2021."
#. (itstool) path: info/desc
#: C/creating-a-child-user.page:6
msgid "Creating a child user on the computer."
msgstr "So legen Sie ein Kinderkonto auf dem Rechner an."
#. (itstool) path: page/title
#: C/creating-a-child-user.page:9
msgid "Creating a Child User"
msgstr "Ein Kinderkonto anlegen"
#. (itstool) path: page/p
#: C/creating-a-child-user.page:11
msgid ""
"Parental controls can only be applied to non-administrator accounts. Such an "
"account may have been created when the computer was initially set up. If "
"not, a new child user may be created from the <app>Parental Controls</app> "
"application if no child users already exist; and otherwise may be created "
"from the <app>Control Center</app>."
msgstr ""
"Die Kindersicherung kann für alle Konten außer Administrator-Konten "
"eingerichtet werden. Ein solches Konto wurde vermutlich bei der "
"Ersteinrichtung des Rechners angelegt. Falls nicht, können Sie ein neues "
"Kinderkonto in der Anwendung <app>Kindersicherung</app> anlegen, und "
"alternativ in den <app>Einstellungen</app>."
#. (itstool) path: page/p
#: C/creating-a-child-user.page:17
msgid ""
"To create a new child user, see <link type=\"guide\" xref=\"help:gnome-help/"
"user-add\">Add a new user account</link>. As soon as the new user is "
"created, it will appear in the <app>Parental Controls</app> window so that "
"its parental controls settings can be configured."
msgstr ""
"Folgen Sie den Anweisungen <link type=\"guide\" xref=\"help:gnome-help/user-"
"add\">Ein neues Benutzerkonto anlegen</link>, um ein neues Kinderkonto "
"anzulegen. Sobald der neue Benutzer angelegt wurde, erscheint er im Fenster "
"von <app>Kindersicherung</app>. Die Einrichtung der Kindersicherung wird "
"dort durchgeführt."
#. (itstool) path: credit/name
#: C/index.page:6
msgid "Philip Withnall"
msgstr "Philip Withnall"
#. (itstool) path: credit/years
#: C/index.page:8
msgid "2020"
msgstr "2020"
#. (itstool) path: page/title
#: C/index.page:12
msgid "Parental Controls Help"
msgstr "Hilfe zur Kindersicherung"
#. (itstool) path: section/title
#: C/index.page:15
msgid "Introduction &amp; Setup"
msgstr "Einführung und Einrichtung"
#. (itstool) path: section/title
#: C/index.page:19
msgid "Controls to Apply"
msgstr ""
#. (itstool) path: info/desc
#: C/internet.page:6
msgid "Restricting a child users access to the internet."
msgstr "Den Internet-Zugang eines Kinderkontos einschränken."
#. (itstool) path: page/title
#: C/internet.page:9
msgid "Restricting Access to the Internet"
msgstr "Den Zugriff auf das Internet einschränken"
#. (itstool) path: page/p
#: C/internet.page:11
msgid ""
"You can restrict a users access to the internet. This will prevent them "
"using a web browser, but it will not prevent them using the internet (in "
"potentially more limited forms) through other applications. For example, it "
"will not prevent access to e-mail accounts using <app>Evolution</app>, and "
"it will not prevent software updates being downloaded and applied."
msgstr ""
#. (itstool) path: page/p
#: C/internet.page:17
msgid "To restrict a users access to the internet:"
msgstr "So schränken Sie den Internet-Zugang eines Kinderkontos ein:"
#. (itstool) path: item/p
#: C/internet.page:19 C/restricting-applications.page:20
#: C/software-installation.page:28 C/software-installation.page:54
msgid "Open the <app>Parental Controls</app> application."
msgstr "Öffnen Sie die Anwendung <app>Kindersicherung</app>."
#. (itstool) path: item/p
#: C/internet.page:20 C/restricting-applications.page:21
#: C/software-installation.page:29 C/software-installation.page:55
msgid "Select the user in the tabs at the top."
msgstr "Wählen Sie den Benutzer oben in den Reitern."
#. (itstool) path: item/p
#: C/internet.page:21
msgid ""
"Enable the <gui style=\"checkbox\">Restrict Web Browsers</gui> checkbox."
msgstr ""
"Aktivieren Sie das Ankreuzfeld <gui style=\"checkbox\">Web-Browser "
"einschränken</gui>."
#. (itstool) path: info/desc
#: C/introduction.page:6
msgid ""
"Overview of parental controls, the <app>Parental Controls</app> application "
"and its use in other situations where access restrictions are needed on a "
"user."
msgstr ""
#. (itstool) path: page/title
#: C/introduction.page:12
msgid "Introduction to Parental Controls"
msgstr "Einführung in die Kindersicherung"
#. (itstool) path: page/p
#: C/introduction.page:14
msgid ""
"Parental controls are a way to restrict what non-administrator accounts can "
"do on the computer, with the aim of allowing parents to restrict what their "
"children can do when using the computer unsupervised or under limited "
"supervision."
msgstr ""
#. (itstool) path: page/p
#: C/introduction.page:18
msgid ""
"This functionality can be used in other situations ­ such as other carer/"
"caree relationships but is labelled as parental controls so that its "
"easy to find, as thats what most people will be looking for."
msgstr ""
#. (itstool) path: page/p
#: C/introduction.page:21
msgid ""
"The parental controls for any user can be queried and set using the "
"<app>Parental Controls</app> application. This lists the non-administrator "
"accounts in tabs along its top bar, and shows their current parental "
"controls settings below. Changes to the parental controls apply immediately."
msgstr ""
#. (itstool) path: page/p
#: C/introduction.page:25
msgid ""
"Restrictions on using the computer can only be applied to non-administrator "
"accounts. The parental controls settings for a user can only be changed by "
"an administrator, although the administrator can do so from the users "
"account by entering their password when prompted by the <app>Parental "
"Controls</app> application."
msgstr ""
#. (itstool) path: p/link
#: C/legal.xml:4
msgid "Creative Commons Attribution-ShareAlike 3.0 Unported License"
msgstr "Creative Commons Attribution-ShareAlike 3.0 Unported License"
#. (itstool) path: license/p
#: C/legal.xml:3
msgid "This work is licensed under a <_:link-1/>."
msgstr "Dieses Werk wird unter einer <_:link-1/> verbreitet."
#. (itstool) path: info/desc
#: C/restricting-applications.page:6
msgid "Restricting a child user from running already-installed applications."
msgstr ""
#. (itstool) path: page/title
#: C/restricting-applications.page:9
msgid "Restricting Access to Installed Applications"
msgstr "Den Zugriff auf installierte Anwendungen einschränken"
#. (itstool) path: page/p
#: C/restricting-applications.page:11
msgid ""
"You can prevent a user from running specific applications which are already "
"installed on the computer. This could be useful if other users need those "
"applications but they are not appropriate for a child."
msgstr ""
"Sie können Benutzer daran hindern, bestimmte Anwendungen auszuführen, die "
"auf dem Rechner installiert sind. Dies ist nützlich, wenn andere Benutzer "
"die Anwendungen benötigen, diese aber nicht für Kinder geeignet sind."
#. (itstool) path: page/p
#: C/restricting-applications.page:14
msgid ""
"When installing additional software, you should consider whether that needs "
"to be restricted for some users — newly installed software is usable by all "
"users by default."
msgstr ""
"Wenn Sie weitere Software installieren, sollten Sie berücksichtigen, ob sie "
"für einige Benutzer eingeschränkt werden muss. Neu installierte Software ist "
"standardmäßig für alle Benutzer nutzbar."
#. (itstool) path: page/p
#: C/restricting-applications.page:18
msgid "To restrict a users access to a specific application:"
msgstr ""
"So schränken Sie den Zugriff eines Benutzers auf bestimmte Anwendungen ein:"
#. (itstool) path: item/p
#: C/restricting-applications.page:22
msgid "Press the <gui style=\"button\">Restrict Applications</gui> button."
msgstr ""
#. (itstool) path: item/p
#: C/restricting-applications.page:23
msgid ""
"Enable the switch in the row for each application you would like to restrict "
"the user from accessing."
msgstr ""
#. (itstool) path: item/p
#: C/restricting-applications.page:24
msgid "Close the <gui>Restrict Applications</gui> window."
msgstr ""
#. (itstool) path: page/p
#: C/restricting-applications.page:27
msgid ""
"Restricting access to specific applications is often used in conjunction "
"with <link xref=\"software-installation\"/> to prevent a user from "
"installing additional software which has not been vetted."
msgstr ""
#. (itstool) path: info/desc
#: C/software-installation.page:6
msgid ""
"Restricting the software a child user can install, or preventing them "
"installing additional software entirely."
msgstr ""
#. (itstool) path: page/title
#: C/software-installation.page:9
msgid "Restricting Software Installation"
msgstr "Software-Installation einschränken"
#. (itstool) path: page/p
#: C/software-installation.page:11
msgid ""
"You can prevent a user from installing additional software on the system. "
"They will still be able to search for new software to install, but will need "
"an administrator to authorize the installation when they try to install an "
"application. This applies whether they are trying to install the application "
"system-wide (for all users) or just for themselves."
msgstr ""
#. (itstool) path: page/p
#: C/software-installation.page:17
msgid ""
"Additionally, you can restrict which software a user can browse or search "
"for in the <app>Software</app> catalog by age categories."
msgstr ""
#. (itstool) path: page/p
#: C/software-installation.page:20
msgid ""
"To prevent a user from running an application which has already been "
"installed, see <link xref=\"restricting-applications\"/>."
msgstr ""
#. (itstool) path: section/title
#: C/software-installation.page:24
msgid "Preventing Software Installation"
msgstr ""
#. (itstool) path: section/p
#: C/software-installation.page:26
msgid "To prevent a user from installing additional software:"
msgstr ""
#. (itstool) path: item/p
#: C/software-installation.page:30
msgid ""
"Enable the <gui style=\"checkbox\">Restrict Application Installation</gui> "
"checkbox."
msgstr ""
#. (itstool) path: section/title
#: C/software-installation.page:35
msgid "Restricting Software Installation by Age"
msgstr ""
#. (itstool) path: section/p
#: C/software-installation.page:37
msgid ""
"Applications in the <app>Software</app> catalog have information about "
"content they contain which might be inappropriate for some ages — for "
"example, various forms of violence, unmoderated chat with other people on "
"the internet, or the possibility of spending money."
msgstr ""
#. (itstool) path: section/p
#: C/software-installation.page:41
msgid ""
"For each application, this information is summarized as the minimum age "
"child it is typically suitable to be used by — for example, “suitable for "
"ages 7+”. These age ratings are presented in region-specific schemes which "
"can be compared with the ratings schemes used for films and games."
msgstr ""
#. (itstool) path: section/p
#: C/software-installation.page:45
msgid ""
"The applications shown to a user in the <app>Software</app> catalog can be "
"filtered by their age suitability. Applications which are not suitable for "
"the user will be hidden, and will not be installable by that user. They will "
"be installable by other users (if their age suitability is set high enough)."
msgstr ""
#. (itstool) path: section/p
#: C/software-installation.page:51
msgid ""
"To filter the applications seen by a user in the <app>Software</app> catalog "
"to only those suitable for a certain age:"
msgstr ""
#. (itstool) path: item/p
#: C/software-installation.page:56
msgid ""
"In the <gui>Application Suitability</gui> list, select the age which "
"applications should be suitable for."
msgstr ""
#. (itstool) path: note/p
#: C/software-installation.page:60
msgid ""
"The users actual age is not stored, so the <gui>Application Suitability</"
"gui> is not automatically updated over time as the child grows older. You "
"must periodically re-assess the appropriate <gui>Application Suitability</"
"gui> for each user."
msgstr ""

View File

@ -1,455 +0,0 @@
# Spanish translations for malcontent.
# Copyright © 2020 the malcontent authors.
# This file is distributed under the same license as the malcontent package.
# Adolfo Jayme Barrientos <fitojb@ubuntu.com>, 2020.
#
msgid ""
msgstr ""
"Project-Id-Version: malcontent master\n"
"POT-Creation-Date: 2020-04-24 15:30+0000\n"
"PO-Revision-Date: 2020-08-22 09:41-0500\n"
"Last-Translator: Adolfo Jayme Barrientos <fitojb@ubuntu.com>\n"
"Language-Team: \n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 2.4.1\n"
#. Put one translator per line, in the form NAME <EMAIL>, YEAR1, YEAR2
msgctxt "_"
msgid "translator-credits"
msgstr "Adolfo Jayme Barrientos <fitojb@ubuntu.com>, 2020"
#. (itstool) path: info/desc
#: C/creating-a-child-user.page:6
msgid "Creating a child user on the computer."
msgstr "Crear una cuenta infantil en el equipo."
#. (itstool) path: page/title
#: C/creating-a-child-user.page:9
msgid "Creating a Child User"
msgstr "Crear una cuenta infantil"
#. (itstool) path: page/p
#: C/creating-a-child-user.page:11
msgid ""
"Parental controls can only be applied to non-administrator accounts. Such an "
"account may have been created when the computer was initially set up. If "
"not, a new child user may be created from the <app>Parental Controls</app> "
"application if no child users already exist; and otherwise may be created "
"from the <app>Control Center</app>."
msgstr ""
"Los controles parentales pueden aplicarse únicamente a las cuentas no "
"administrativas. Puede que se haya creado una cuenta de este tipo al momento "
"de la configuración inicial del equipo. Si no es así, es posible crear una "
"cuenta infantil nueva desde la aplicación <app>Controles parentales</app> o "
"mediante la <app>Configuración</app>."
#. (itstool) path: page/p
#: C/creating-a-child-user.page:17
msgid ""
"To create a new child user, see <link type=\"guide\" xref=\"help:gnome-help/"
"user-add\">Add a new user account</link>. As soon as the new user is "
"created, it will appear in the <app>Parental Controls</app> window so that "
"its parental controls settings can be configured."
msgstr ""
"Para crear una cuenta infantil, consulte <link type=\"guide\" xref=\"help:"
"gnome-help/user-add\">Añadir una cuenta de usuario nueva</link>. Tan pronto "
"como haya creado la cuenta nueva, esta figurará en la ventana de "
"<app>Controles parentales</app> para que puedan definirse sus "
"configuraciones de control parental."
#. (itstool) path: credit/name
#: C/index.page:6
msgid "Philip Withnall"
msgstr "Philip Withnall"
#. (itstool) path: credit/years
#: C/index.page:8
msgid "2020"
msgstr "2020"
#. (itstool) path: page/title
#: C/index.page:12
msgid "Parental Controls Help"
msgstr "Ayuda sobre los controles parentales"
#. (itstool) path: section/title
#: C/index.page:15
msgid "Introduction &amp; Setup"
msgstr "Introducción y configuración"
#. (itstool) path: section/title
#: C/index.page:19
msgid "Controls to Apply"
msgstr "Controles para aplicar"
#. (itstool) path: info/desc
#: C/internet.page:6
msgid "Restricting a child users access to the internet."
msgstr "Restringir el acceso a Internet por parte de un menor"
#. (itstool) path: page/title
#: C/internet.page:9
msgid "Restricting Access to the Internet"
msgstr "Restringir el acceso a Internet"
#. (itstool) path: page/p
#: C/internet.page:11
msgid ""
"You can restrict a users access to the internet. This will prevent them "
"using a web browser, but it will not prevent them using the internet (in "
"potentially more limited forms) through other applications. For example, it "
"will not prevent access to e-mail accounts using <app>Evolution</app>, and "
"it will not prevent software updates being downloaded and applied."
msgstr ""
"Es posible restringir el acceso de un usuario a Internet. Esto le impedirá "
"utilizar un navegador web, pero no restringirá la conexión a Internet de "
"otras aplicaciones. Por ejemplo, no impedirá el acceso a las cuentas de "
"correo electrónico mediante <app>Evolution</app>, ni impedirá la descarga y "
"aplicación de actualizaciones de software."
#. (itstool) path: page/p
#: C/internet.page:17
msgid "To restrict a users access to the internet:"
msgstr "Para restringir el acceso de un usuario a Internet:"
#. (itstool) path: item/p
#: C/internet.page:19 C/restricting-applications.page:20
#: C/software-installation.page:27 C/software-installation.page:64
msgid "Open the <app>Parental Controls</app> application."
msgstr "Abra la aplicación <app>Controles parentales</app>."
#. (itstool) path: item/p
#: C/internet.page:20 C/restricting-applications.page:21
#: C/software-installation.page:28 C/software-installation.page:65
msgid "Select the user in the tabs at the top."
msgstr "En las pestañas de la parte superior, seleccione la cuenta deseada."
#. (itstool) path: item/p
#: C/internet.page:21
msgid ""
"Enable the <gui style=\"checkbox\">Restrict Web Browsers</gui> checkbox."
msgstr ""
"Active la casilla <gui style=\"checkbox\">Restringir navegadores web</gui>."
#. (itstool) path: info/desc
#: C/introduction.page:6
msgid ""
"Overview of parental controls and the <app>Parental Controls</app> "
"application."
msgstr ""
"Visión de conjunto de los controles parentales y la aplicación "
"<app>Controles parentales</app>."
#. (itstool) path: page/title
#: C/introduction.page:10
msgid "Introduction to Parental Controls"
msgstr "Introducción al control parental"
#. (itstool) path: page/p
#: C/introduction.page:12
msgid ""
"Parental controls are a way to restrict what non-administrator accounts can "
"do on the computer, with the aim of allowing parents to restrict what their "
"children can do when using the computer unsupervised or under limited "
"supervision."
msgstr ""
"Los controles parentales representan una manera de restringir lo que las "
"cuentas no administrativas pueden efectuar en el equipo, con el objetivo de "
"permitir que los padres restrinjan las acciones de sus hijos al utilizar el "
"equipo sin supervisión o bajo supervisión limitada."
#. (itstool) path: page/p
#: C/introduction.page:16
msgid ""
"This functionality can be used in other situations ­ such as other carer/"
"caree relationships but is labelled as parental controls so that its "
"easy to find."
msgstr ""
"Esta funcionalidad puede ser de utilidad en otras situaciones —como las "
"relaciones entre cuidadores y tutelados—, pero se denomina «controles "
"parentales» para facilitar su localización."
#. (itstool) path: page/p
#: C/introduction.page:19
msgid ""
"The parental controls for any user can be queried and set using the "
"<app>Parental Controls</app> application. This lists the non-administrator "
"accounts in tabs along its top bar, and shows their current parental "
"controls settings below. Changes to the parental controls apply immediately."
msgstr ""
"La aplicación <app>Controles parentales</app> permite realizar consultas "
"sobre cualquier cuenta y definir controles por cada una. La aplicación "
"enumera todas las cuentas no administrativas en forma de pestañas en la "
"barra superior de la ventana, y por debajo muestra los controles definidos "
"actualmente. Las modificaciones a los controles parentales surten efecto de "
"inmediato."
#. (itstool) path: page/p
#: C/introduction.page:23
msgid ""
"Restrictions on using the computer can only be applied to non-administrator "
"accounts. The parental controls settings for a user can only be changed by "
"an administrator, although the administrator can do so from the users "
"account by entering their password when prompted by the <app>Parental "
"Controls</app> application."
msgstr ""
"Solo se puede aplicar restricciones de uso del equipo sobre cuentas no "
"administrativas. Únicamente los administradores pueden establecer las "
"configuraciones de controles parentales para una cuenta determinada. Es "
"posible hacer esto sin salir de la cuenta; basta con proporcionar la "
"contraseña administrativa cuando <app>Controles parentales</app> la solicite."
#. (itstool) path: p/link
#: C/legal.xml:4
msgid "Creative Commons Attribution-ShareAlike 3.0 Unported License"
msgstr ""
"Licencia genérica Creative Commons 3.0 de atribución e igual compartición"
#. (itstool) path: license/p
#: C/legal.xml:3
msgid "This work is licensed under a <_:link-1/>."
msgstr "Esta obra está disponible en virtud de la <_:link-1/>."
#. (itstool) path: info/desc
#: C/restricting-applications.page:6
msgid "Restricting a child user from running already-installed applications."
msgstr "Restringir a los menores el uso de aplicaciones ya instaladas."
#. (itstool) path: page/title
#: C/restricting-applications.page:9
msgid "Restricting Access to Installed Applications"
msgstr "Restringir el acceso a las aplicaciones instaladas"
#. (itstool) path: page/p
#: C/restricting-applications.page:11
msgid ""
"You can prevent a user from running specific applications which are already "
"installed on the computer. This could be useful if other users need those "
"applications but they are not appropriate for a child."
msgstr ""
"Puede impedir que una cuenta ejecute determinadas aplicaciones instaladas en "
"el equipo. Esto puede ser útil si hay otros usuarios que necesitan estas "
"aplicaciones, pese a ser inadecuadas para un menor."
#. (itstool) path: page/p
#: C/restricting-applications.page:14
msgid ""
"When installing additional software, you should consider whether that needs "
"to be restricted for some users — newly installed software is usable by all "
"users by default."
msgstr ""
"Tras instalar software adicional, es recomendable que considere si hace "
"falta restringírselo a determinados usuarios, dado que, de manera "
"predeterminada, todos los usuarios pueden utilizarlo."
#. (itstool) path: page/p
#: C/restricting-applications.page:18
msgid "To restrict a users access to a specific application:"
msgstr "Para restringir el acceso de una cuenta a una aplicación concreta:"
#. (itstool) path: item/p
#: C/restricting-applications.page:22
msgid "Press the <gui style=\"button\">Restrict Applications</gui> button."
msgstr "Pulse el botón <gui style=\"button\">Restringir aplicaciones</gui>."
#. (itstool) path: item/p
#: C/restricting-applications.page:23
msgid ""
"Enable the switch in the row for each application you would like to restrict "
"the user from accessing."
msgstr ""
"Active el interruptor en la fila de cada aplicación que quiera restringir."
#. (itstool) path: item/p
#: C/restricting-applications.page:24
msgid "Close the <gui>Restrict Applications</gui> window."
msgstr "Cierre la ventana <gui>Restringir aplicaciones</gui>."
#. (itstool) path: page/p
#: C/restricting-applications.page:27
msgid ""
"Restricting access to specific applications is often used in conjunction "
"with <link xref=\"software-installation\"/> to prevent a user from "
"installing additional software which has not been vetted."
msgstr ""
"La restricción de acceso a aplicaciones determinadas se emplea a menudo "
"junto con <link xref=\"software-installation\"/> para evitar que se instale "
"software sin que usted lo examine."
#. (itstool) path: info/desc
#: C/software-installation.page:6
msgid ""
"Restricting the software a child user can install, or preventing them "
"installing additional software entirely."
msgstr ""
"Restringir el software que un menor puede instalar, o bien evitar que "
"instalen software adicional por completo."
#. (itstool) path: page/title
#: C/software-installation.page:9
msgid "Restricting Software Installation"
msgstr "Restringir la instalación de software"
#. (itstool) path: page/p
#: C/software-installation.page:11
msgid ""
"You can prevent a user from installing additional software, either for the "
"entire system, or just for themselves. They will still be able to search for "
"new software to install, but will need an administrator to authorize the "
"installation when they try to install an application."
msgstr ""
"Puede impedir que un usuario instale software adicional, bien para todo el "
"sistema, bien para sí mismo. Todavía será capaz de buscar software nuevo "
"para instalar, pero si intenta instalarlo deberá contar con la ayuda de un "
"administrador para que este lo autorice."
#. (itstool) path: page/p
#: C/software-installation.page:16
msgid ""
"Additionally, you can restrict which software a user can browse or search "
"for in the <app>Software</app> catalog by age categories."
msgstr ""
"Además, si se sirve de las categorías por edades en <app>Software</app>, "
"puede restringir qué software se podrá explorar en su catálogo."
#. (itstool) path: page/p
#: C/software-installation.page:19
msgid ""
"To prevent a user from running an application which has already been "
"installed, see <link xref=\"restricting-applications\"/>."
msgstr ""
"Para evitar que un usuario ejecute una aplicación previamente instalada, "
"consulte <link xref=\"restricting-applications\"/>."
#. (itstool) path: section/title
#: C/software-installation.page:23
msgid "Preventing Software Installation"
msgstr "Evitar la instalación de software"
#. (itstool) path: section/p
#: C/software-installation.page:25
msgid "To prevent a user from installing additional software:"
msgstr ""
"Siga este procedimiento para impedir la instalación de software adicional:"
#. (itstool) path: item/p
#: C/software-installation.page:29
msgid ""
"Enable the <gui style=\"checkbox\">Restrict Application Installation</gui> "
"checkbox."
msgstr ""
"Active la casilla <gui style=\"checkbox\">Restringir instalación de "
"aplicaciones</gui>."
#. (itstool) path: item/p
#: C/software-installation.page:30
msgid ""
"Or enable the <gui style=\"checkbox\">Restrict Application Installation for "
"Others</gui> checkbox."
msgstr ""
"O bien, active la casilla <gui style=\"checkbox\">Restringir instalación de "
"aplicaciones para los otros</gui>."
#. (itstool) path: section/p
#: C/software-installation.page:33
msgid ""
"The <gui style=\"checkbox\">Restrict Application Installation for Others</"
"gui> checkbox allows the user to install additional software for themselves, "
"but prevents that software from being made available to other users. It "
"could be used, for example, if there were two child users, one of whom is "
"mature enough to be allowed to install additional software, but the other "
"isnt — enabling <gui style=\"checkbox\">Restrict Application Installation "
"for Others</gui> would prevent the more mature child from installing "
"applications which are inappropriate for the other child and making them "
"available to the other child."
msgstr ""
"La casilla <gui style=\"checkbox\">Restringir instalación de aplicaciones a "
"los otros</gui> permite la instalación de software adicional para uno mismo, "
"pero restringe su disponibilidad a las demás cuentas. Se puede sacar "
"provecho de esta función, por ejemplo, si tiene dos menores, de los cuales "
"solo uno es lo suficientemente maduro para permitírsele la instalación de "
"software; activar <gui style=\"checkbox\">Restringir instalación de "
"aplicaciones a los otros</gui> impedirá que el menor más maduro instale "
"aplicaciones inapropiadas para el otro niño."
#. (itstool) path: section/title
#: C/software-installation.page:45
msgid "Restricting Software Installation by Age"
msgstr "Restringir la instalación de software por edades"
#. (itstool) path: section/p
#: C/software-installation.page:47
msgid ""
"Applications in the <app>Software</app> catalog have information about "
"content they contain which might be inappropriate for some ages — for "
"example, various forms of violence, unmoderated chat with other people on "
"the internet, or the possibility of spending money."
msgstr ""
"Las aplicaciones que se incluyen en el catálogo de <app>Software</app> "
"incluyen información relativa al contenido que poseen y la aptitud de este "
"según la edad, notando detalles como: diversas formas de violencia, chat no "
"moderado con otras personas a través de internet, o la posibilidad de gastar "
"dinero."
#. (itstool) path: section/p
#: C/software-installation.page:51
msgid ""
"For each application, this information is summarized as the minimum age "
"child it is typically suitable to be used by — for example, “suitable for "
"ages 7+”. These age ratings are presented in region-specific schemes which "
"can be compared with the ratings schemes used for films and games."
msgstr ""
"En cada aplicación, esta información se condensa como la edad mínima en la "
"que se considera adecuado que un menor la utilice; por ejemplo, «de 7 años "
"en adelante». Estas clasificaciones se presentan de conformidad con ciertos "
"esquemas regionales, comparables con los que se utilizan para clasificar "
"películas y juegos."
#. (itstool) path: section/p
#: C/software-installation.page:55
msgid ""
"The applications shown to a user in the <app>Software</app> catalog can be "
"filtered by their age suitability. Applications which are not suitable for "
"the user will be hidden, and will not be installable by that user. They will "
"be installable by other users (if their age suitability is set high enough)."
msgstr ""
"Las aplicaciones que <app>Software</app> muestra a cada usuario se pueden "
"filtrar por adecuación a la edad. Aquellas aplicaciones que no sean "
"adecuadas para una cuenta se ocultarán del catálogo y no se podrán instalar. "
"Otros usuarios las podrán instalar (si es que su clasificación de edad lo "
"permite)."
#. (itstool) path: section/p
#: C/software-installation.page:61
msgid ""
"To filter the applications seen by a user in the <app>Software</app> catalog "
"to only those suitable for a certain age:"
msgstr ""
"Para filtrar las aplicaciones que un usuario ve en el catálogo de "
"<app>Software</app> y que se muestren solo las adecuadas para una "
"determinada edad:"
#. (itstool) path: item/p
#: C/software-installation.page:66
msgid ""
"In the <gui>Application Suitability</gui> list, select the age which "
"applications should be suitable for."
msgstr ""
"En la lista <gui>Idoneidad de aplicaciones</gui>, seleccione la edad deseada."
#. (itstool) path: note/p
#: C/software-installation.page:70
msgid ""
"The users actual age is not stored, so the <gui>Application Suitability</"
"gui> is not automatically updated over time as the child grows older. You "
"must periodically re-assess the appropriate <gui>Application Suitability</"
"gui> for each user."
msgstr ""
"Como no se almacena la edad del usuario, la <gui>idoneidad de aplicaciones</"
"gui> no se actualiza automáticamente a medida que crece el menor. Debe "
"revalorar periódicamente el nivel adecuado de <gui>Idoneidad de "
"aplicaciones</gui> para cada una de las cuentas."

View File

@ -1,441 +0,0 @@
# Hungarian translation for malcontent.
# Copyright (C) 2022 Free Software Foundation, Inc.
# This file is distributed under the same license as the malcontent package.
#
# Balázs Úr <ur.balazs at fsf dot hu>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: malcontent main\n"
"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pwithnall/malcontent/"
"issues\n"
"POT-Creation-Date: 2022-09-21 15:25+0000\n"
"PO-Revision-Date: 2022-09-22 23:43+0200\n"
"Last-Translator: Balázs Úr <ur.balazs at fsf dot hu>\n"
"Language-Team: Hungarian <gnome-hu-list at gnome dot org>\n"
"Language: hu\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Lokalize 19.12.3\n"
#. Put one translator per line, in the form NAME <EMAIL>, YEAR1, YEAR2
msgctxt "_"
msgid "translator-credits"
msgstr "Úr Balázs <ur dot balazs at fsf dot hu>, 2022."
#. (itstool) path: info/desc
#: C/creating-a-child-user.page:6
msgid "Creating a child user on the computer."
msgstr "Gyermekfelhasználó létrehozása a számítógépen."
#. (itstool) path: page/title
#: C/creating-a-child-user.page:9
msgid "Creating a Child User"
msgstr "Gyermekfelhasználó létrehozása"
#. (itstool) path: page/p
#: C/creating-a-child-user.page:11
msgid ""
"Parental controls can only be applied to non-administrator accounts. Such an "
"account may have been created when the computer was initially set up. If "
"not, a new child user may be created from the <app>Parental Controls</app> "
"application if no child users already exist; and otherwise may be created "
"from the <app>Control Center</app>."
msgstr ""
"A szülői felügyelet csak a nem rendszergazdai fiókokra alkalmazható. Ilyen "
"fiókot esetleg a számítógép kezdeti beállításakor hozhattak létre. Ha nem, "
"akkor új gyermekfelhasználó hozható létre a <app>Szülői felügyelet</app> "
"alkalmazásból, ha még nem létezik gyermekfelhasználó, egyébként pedig a "
"<app>Vezérlőközpont</app> alkalmazásból hozható létre."
#. (itstool) path: page/p
#: C/creating-a-child-user.page:17
msgid ""
"To create a new child user, see <link type=\"guide\" xref=\"help:gnome-help/"
"user-add\">Add a new user account</link>. As soon as the new user is "
"created, it will appear in the <app>Parental Controls</app> window so that "
"its parental controls settings can be configured."
msgstr ""
"Új gyermekfelhasználó létrehozásához nézze meg az <link type=\"guide\" xref="
"\"help:gnome-help/user-add\">Új felhasználói fiók hozzáadása</link> "
"fejezetet. Amint az új felhasználó létrejött, megjelenik a <app>Szülői "
"felügyelet</app> ablakban, így a szülői felügyeleti beállításai "
"konfigurálhatók."
#. (itstool) path: credit/name
#: C/index.page:6
msgid "Philip Withnall"
msgstr "Philip Withnall"
#. (itstool) path: credit/years
#: C/index.page:8
msgid "2020"
msgstr "2020"
#. (itstool) path: page/title
#: C/index.page:12
msgid "Parental Controls Help"
msgstr "Szülői felügyelet súgó"
#. (itstool) path: section/title
#: C/index.page:15
msgid "Introduction &amp; Setup"
msgstr "Bevezetés és beállítás"
#. (itstool) path: section/title
#: C/index.page:19
msgid "Controls to Apply"
msgstr "Alkalmazandó szabályozások"
#. (itstool) path: info/desc
#: C/internet.page:6
msgid "Restricting a child users access to the internet."
msgstr "Egy gyermekfelhasználó internet-hozzáférésének korlátozása."
#. (itstool) path: page/title
#: C/internet.page:9
msgid "Restricting Access to the Internet"
msgstr "Internet-hozzáférés korlátozása"
#. (itstool) path: page/p
#: C/internet.page:11
msgid ""
"You can restrict a users access to the internet. This will prevent them "
"using a web browser, but it will not prevent them using the internet (in "
"potentially more limited forms) through other applications. For example, it "
"will not prevent access to e-mail accounts using <app>Evolution</app>, and "
"it will not prevent software updates being downloaded and applied."
msgstr ""
"Korlátozhatja egy felhasználó internet-hozzáférését. Ez megakadályozza őt a "
"webböngésző használatában, de nem akadályozza meg abban, hogy az internetet "
"(esetleg korlátozottabb formában) más alkalmazásokon keresztül használja. "
"Például nem akadályozza meg az e-mail fiókokhoz való hozzáférést az "
"<app>Evolution</app> használatával, és nem akadályozza meg a "
"szoftverfrissítések letöltését és alkalmazását."
#. (itstool) path: page/p
#: C/internet.page:17
msgid "To restrict a users access to the internet:"
msgstr "Egy felhasználó internet-hozzáférésének korlátozásához:"
#. (itstool) path: item/p
#: C/internet.page:19 C/restricting-applications.page:20
#: C/software-installation.page:28 C/software-installation.page:54
msgid "Open the <app>Parental Controls</app> application."
msgstr "Nyissa meg a <app>Szülői felügyelet</app> alkalmazást."
#. (itstool) path: item/p
#: C/internet.page:20 C/restricting-applications.page:21
#: C/software-installation.page:29 C/software-installation.page:55
msgid "Select the user in the tabs at the top."
msgstr "Válassza ki a felhasználót a fenti lapokon."
#. (itstool) path: item/p
#: C/internet.page:21
msgid ""
"Enable the <gui style=\"checkbox\">Restrict Web Browsers</gui> checkbox."
msgstr ""
"Jelölje be a <gui style=\"checkbox\">Webböngészők korlátozása</gui> "
"jelölőnégyzetet."
#. (itstool) path: info/desc
#: C/introduction.page:6
msgid ""
"Overview of parental controls, the <app>Parental Controls</app> application "
"and its use in other situations where access restrictions are needed on a "
"user."
msgstr ""
"A szülői felügyelet áttekintése, a <app>Szülői felügyelet</app> alkalmazás "
"és annak használata olyan egyéb helyzetekben, amikor egy felhasználó "
"hozzáférésének korlátozásai szükségesek."
#. (itstool) path: page/title
#: C/introduction.page:12
msgid "Introduction to Parental Controls"
msgstr "Bevezetés a szülői felügyeletbe"
#. (itstool) path: page/p
#: C/introduction.page:14
msgid ""
"Parental controls are a way to restrict what non-administrator accounts can "
"do on the computer, with the aim of allowing parents to restrict what their "
"children can do when using the computer unsupervised or under limited "
"supervision."
msgstr ""
"A szülői felügyelet segítségével korlátozható, hogy a nem rendszergazdai "
"fiókok mit tehetnek a számítógépen, azzal a céllal, hogy a szülők "
"korlátozhassák, hogy mit tehetnek a gyermekeik, amikor felügyelet nélkül "
"vagy korlátozott felügyelet mellett használják a számítógépet."
#. (itstool) path: page/p
#: C/introduction.page:18
msgid ""
"This functionality can be used in other situations ­ such as other carer/"
"caree relationships but is labelled as parental controls so that its "
"easy to find, as thats what most people will be looking for."
msgstr ""
"Ez a funkció más helyzetekben is használható például egyéb gondozó-"
"gondozott kapcsolatokban , de „szülői felügyelet” címkével van ellátva, "
"hogy könnyen megtalálható legyen, mivel a legtöbb ember ezt keresi."
#. (itstool) path: page/p
#: C/introduction.page:21
msgid ""
"The parental controls for any user can be queried and set using the "
"<app>Parental Controls</app> application. This lists the non-administrator "
"accounts in tabs along its top bar, and shows their current parental "
"controls settings below. Changes to the parental controls apply immediately."
msgstr ""
"A szülői felügyelet bármely felhasználóhoz lekérdezhető és beállítható a "
"<app>Szülői felügyelet</app> alkalmazás használatával. Ez a felső sávjában "
"lévő lapokon felsorolja a nem rendszergazdai fiókokat, és alatta megjeleníti "
"az aktuális szülői felügyeleti beállításokat. A szülői felügyelet "
"változtatásai azonnal érvénybe lépnek."
#. (itstool) path: page/p
#: C/introduction.page:25
msgid ""
"Restrictions on using the computer can only be applied to non-administrator "
"accounts. The parental controls settings for a user can only be changed by "
"an administrator, although the administrator can do so from the users "
"account by entering their password when prompted by the <app>Parental "
"Controls</app> application."
msgstr ""
"A számítógép használatára vonatkozó korlátozások csak a nem rendszergazdai "
"fiókokra alkalmazhatók. Egy felhasználó szülői felügyeleti beállításait csak "
"egy rendszergazda változtathatja meg, bár a rendszergazda ezt a felhasználó "
"fiókjából is megteheti a jelszavának megadásával, amikor a <app>Szülői "
"felügyelet</app> alkalmazás erre kéri."
#. (itstool) path: p/link
#: C/legal.xml:4
msgid "Creative Commons Attribution-ShareAlike 3.0 Unported License"
msgstr "Creative Commons Nevezd meg! - Így add tovább! 3.0 átíratlan licenc"
#. (itstool) path: license/p
#: C/legal.xml:3
msgid "This work is licensed under a <_:link-1/>."
msgstr "Ez a mű a <_:link-1/> szerint licencelt."
#. (itstool) path: info/desc
#: C/restricting-applications.page:6
msgid "Restricting a child user from running already-installed applications."
msgstr ""
"Egy gyermekfelhasználó korlátozása a már telepített alkalmazások "
"futtatásában."
#. (itstool) path: page/title
#: C/restricting-applications.page:9
msgid "Restricting Access to Installed Applications"
msgstr "A telepített alkalmazásokhoz való hozzáférés korlátozása"
#. (itstool) path: page/p
#: C/restricting-applications.page:11
msgid ""
"You can prevent a user from running specific applications which are already "
"installed on the computer. This could be useful if other users need those "
"applications but they are not appropriate for a child."
msgstr ""
"Megakadályozhatja, hogy egy felhasználó a számítógépre már telepített "
"bizonyos alkalmazásokat futtasson. Ez akkor lehet hasznos, ha más "
"felhasználóknak szükségük van ezekre az alkalmazásokra, de egy gyermek "
"számára nem megfelelőek."
#. (itstool) path: page/p
#: C/restricting-applications.page:14
msgid ""
"When installing additional software, you should consider whether that needs "
"to be restricted for some users — newly installed software is usable by all "
"users by default."
msgstr ""
"További szoftverek telepítésekor meg kell fontolnia, hogy nem kell-e "
"korlátozni azokat egyes felhasználók számára, ugyanis az újonnan telepített "
"szoftverek alapértelmezetten minden felhasználó számára használhatóak."
#. (itstool) path: page/p
#: C/restricting-applications.page:18
msgid "To restrict a users access to a specific application:"
msgstr ""
"Egy felhasználó adott alkalmazáshoz való hozzáférésének korlátozásához:"
#. (itstool) path: item/p
#: C/restricting-applications.page:22
msgid "Press the <gui style=\"button\">Restrict Applications</gui> button."
msgstr ""
"Nyomja meg az <gui style=\"button\">Alkalmazások korlátozása</gui> gombot."
#. (itstool) path: item/p
#: C/restricting-applications.page:23
msgid ""
"Enable the switch in the row for each application you would like to restrict "
"the user from accessing."
msgstr ""
"Kapcsolja be a kapcsolót minden olyan alkalmazás sorában, amelyhez a "
"felhasználó hozzáférését korlátozni szeretné."
#. (itstool) path: item/p
#: C/restricting-applications.page:24
msgid "Close the <gui>Restrict Applications</gui> window."
msgstr "Zárja be az <gui>Alkalmazások korlátozása</gui> ablakot."
#. (itstool) path: page/p
#: C/restricting-applications.page:27
msgid ""
"Restricting access to specific applications is often used in conjunction "
"with <link xref=\"software-installation\"/> to prevent a user from "
"installing additional software which has not been vetted."
msgstr ""
"Bizonyos alkalmazásokhoz való hozzáférés korlátozását gyakran használják a "
"<link xref=\"software-installation\"/> korlátozással együtt, hogy "
"megakadályozzanak egy felhasználót a további, nem ellenőrzött szoftverek "
"telepítésében."
#. (itstool) path: info/desc
#: C/software-installation.page:6
msgid ""
"Restricting the software a child user can install, or preventing them "
"installing additional software entirely."
msgstr ""
"Egy gyermekfelhasználó által telepíthető szoftverek korlátozása, vagy "
"további szoftverek telepítésének teljes megakadályozása."
#. (itstool) path: page/title
#: C/software-installation.page:9
msgid "Restricting Software Installation"
msgstr "Szoftvertelepítés korlátozása"
#. (itstool) path: page/p
#: C/software-installation.page:11
msgid ""
"You can prevent a user from installing additional software on the system. "
"They will still be able to search for new software to install, but will need "
"an administrator to authorize the installation when they try to install an "
"application. This applies whether they are trying to install the application "
"system-wide (for all users) or just for themselves."
msgstr ""
"Megakadályozhat egy felhasználót abban, hogy további szoftvereket telepítsen "
"a rendszerre. A felhasználó továbbra is kereshet új telepítendő szoftvert, "
"de rendszergazdára lesz szüksége a telepítés felhatalmazásához, amikor "
"megpróbál telepíteni egy alkalmazást. Ez arra is vonatkozik, hogy az "
"alkalmazást rendszerszinten (minden felhasználónak) vagy csak saját magának "
"próbálja telepíteni."
#. (itstool) path: page/p
#: C/software-installation.page:17
msgid ""
"Additionally, you can restrict which software a user can browse or search "
"for in the <app>Software</app> catalog by age categories."
msgstr ""
"Ezenkívül azt is korlátozhatja az életkor kategória alapján, hogy egy "
"felhasználó milyen szoftvereket böngészhet vagy kereshet a <app>Szoftver</"
"app> katalógusában."
#. (itstool) path: page/p
#: C/software-installation.page:20
msgid ""
"To prevent a user from running an application which has already been "
"installed, see <link xref=\"restricting-applications\"/>."
msgstr ""
"Annak megakadályozásához, hogy egy felhasználó egy már telepített "
"alkalmazást futtasson, nézze meg az <link xref=\"restricting-applications\"/"
"> fejezetet."
#. (itstool) path: section/title
#: C/software-installation.page:24
msgid "Preventing Software Installation"
msgstr "Szoftvertelepítés megakadályozása"
#. (itstool) path: section/p
#: C/software-installation.page:26
msgid "To prevent a user from installing additional software:"
msgstr ""
"Annak megakadályozásához, hogy a felhasználó további szoftvereket telepítsen:"
#. (itstool) path: item/p
#: C/software-installation.page:30
msgid ""
"Enable the <gui style=\"checkbox\">Restrict Application Installation</gui> "
"checkbox."
msgstr ""
"Jelölje be az <gui style=\"checkbox\">Alkalmazástelepítés korlátozása</gui> "
"jelölőnégyzetet."
#. (itstool) path: section/title
#: C/software-installation.page:35
msgid "Restricting Software Installation by Age"
msgstr "Szoftvertelepítés korlátozása életkor alapján"
#. (itstool) path: section/p
#: C/software-installation.page:37
msgid ""
"Applications in the <app>Software</app> catalog have information about "
"content they contain which might be inappropriate for some ages — for "
"example, various forms of violence, unmoderated chat with other people on "
"the internet, or the possibility of spending money."
msgstr ""
"A <app>Szoftver</app> katalógusában található alkalmazások információval "
"rendelkeznek az általuk tartalmazott tartalommal kapcsolatban, hogy melyek "
"lehetnek bizonyos korosztályok számára nem megfelelőek például az erőszak "
"különböző formái, moderálatlan csevegés az interneten más emberekkel, vagy a "
"pénzköltés lehetősége."
#. (itstool) path: section/p
#: C/software-installation.page:41
msgid ""
"For each application, this information is summarized as the minimum age "
"child it is typically suitable to be used by — for example, “suitable for "
"ages 7+”. These age ratings are presented in region-specific schemes which "
"can be compared with the ratings schemes used for films and games."
msgstr ""
"Minden egyes alkalmazás esetében ez az információ összefoglalja, hogy az "
"adott alkalmazás jellemzően legalább milyen korú gyermek számára alkalmas "
"például „7 év felettiek számára alkalmas”. Ezek a korhatár-besorolások régió-"
"specifikus sémákban jelennek meg, amelyek összehasonlíthatók a filmek és "
"játékok esetében használt besorolási sémákkal."
#. (itstool) path: section/p
#: C/software-installation.page:45
msgid ""
"The applications shown to a user in the <app>Software</app> catalog can be "
"filtered by their age suitability. Applications which are not suitable for "
"the user will be hidden, and will not be installable by that user. They will "
"be installable by other users (if their age suitability is set high enough)."
msgstr ""
"A <app>Szoftver</app> katalógusában egy felhasználó számára megjelenített "
"alkalmazások szűrhetők az életkori alkalmasságuk alapján. A felhasználó "
"számára nem megfelelő alkalmazások el lesznek rejtve, és nem lesznek "
"telepíthetők az adott felhasználó számára. Más felhasználók számára "
"telepíthetők lesznek (ha az életkori alkalmasságuk elég magasra van állítva)."
#. (itstool) path: section/p
#: C/software-installation.page:51
msgid ""
"To filter the applications seen by a user in the <app>Software</app> catalog "
"to only those suitable for a certain age:"
msgstr ""
"A <app>Szoftver</app> katalógusában egy felhasználó által látott "
"alkalmazások szűréséhez, hogy csak egy bizonyos korosztály számára legyenek "
"alkalmasak:"
#. (itstool) path: item/p
#: C/software-installation.page:56
msgid ""
"In the <gui>Application Suitability</gui> list, select the age which "
"applications should be suitable for."
msgstr ""
"Az <gui>Alkalmazás alkalmassága</gui> listából válassza ki azt az életkort, "
"amelyre az alkalmazásoknak alkalmasnak kell lenniük."
#. (itstool) path: note/p
#: C/software-installation.page:60
msgid ""
"The users actual age is not stored, so the <gui>Application Suitability</"
"gui> is not automatically updated over time as the child grows older. You "
"must periodically re-assess the appropriate <gui>Application Suitability</"
"gui> for each user."
msgstr ""
"A felhasználó tényleges életkora nem kerül tárolásra, így az <gui>Alkalmazás "
"alkalmassága</gui> nem frissül automatikusan az idő múlásával, ahogy a "
"gyermek idősebbé válik. Rendszeresen újra kell értékelnie a megfelelő "
"<gui>Alkalmazás alkalmassága</gui> értéket minden egyes felhasználónál."

View File

@ -1,424 +0,0 @@
# Indonesian translation for malcontent.
# Copyright (C) 2020 malcontent's COPYRIGHT HOLDER
# This file is distributed under the same license as the malcontent package.
# Andika Triwidada <andika@gmail.com>, 2020, 2021.
#
msgid ""
msgstr ""
"Project-Id-Version: malcontent master\n"
"POT-Creation-Date: 2020-12-18 15:14+0000\n"
"PO-Revision-Date: 2021-08-30 18:26+0700\n"
"Last-Translator: Andika Triwidada <andika@gmail.com>\n"
"Language-Team: Indonesian <gnome-l10n-id@googlegroups.com>\n"
"Language: id\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.4.3\n"
#. Put one translator per line, in the form NAME <EMAIL>, YEAR1, YEAR2
msgctxt "_"
msgid "translator-credits"
msgstr "Andika Triwidada <andika@gmail.com>, 2020, 2021."
#. (itstool) path: info/desc
#: C/creating-a-child-user.page:6
msgid "Creating a child user on the computer."
msgstr "Membuat pengguna anak pada komputer."
#. (itstool) path: page/title
#: C/creating-a-child-user.page:9
msgid "Creating a Child User"
msgstr "Membuat Pengguna Anak"
#. (itstool) path: page/p
#: C/creating-a-child-user.page:11
msgid ""
"Parental controls can only be applied to non-administrator accounts. Such an "
"account may have been created when the computer was initially set up. If "
"not, a new child user may be created from the <app>Parental Controls</app> "
"application if no child users already exist; and otherwise may be created "
"from the <app>Control Center</app>."
msgstr ""
"Pengawasan orang tua hanya dapat diterapkan untuk akun non-administrator. "
"Akun tersebut mungkin telah dibuat saat komputer awalnya diatur. Jika tidak, "
"pengguna anak baru dapat dibuat dari aplikasi <app>Pengawasan Orang Tua</"
"app> jika tidak ada pengguna anak yang sudah ada; dan sebaliknya dapat "
"dibuat dari <app>Pusat Kontrol</app>."
#. (itstool) path: page/p
#: C/creating-a-child-user.page:17
msgid ""
"To create a new child user, see <link type=\"guide\" xref=\"help:gnome-help/"
"user-add\">Add a new user account</link>. As soon as the new user is "
"created, it will appear in the <app>Parental Controls</app> window so that "
"its parental controls settings can be configured."
msgstr ""
"Untuk membuat pengguna anak baru, lihat <link type=\"guide\" xref=\"help:"
"gnome-help/user-add\">Menambahkan akun pengguna baru</link>. Segera setelah "
"pengguna baru dibuat, itu akan muncul di jendela <app>Pengawasan Orang Tua</"
"app> sehingga pengaturan pengawasan orang tua dapat dikonfigurasi."
#. (itstool) path: credit/name
#: C/index.page:6
msgid "Philip Withnall"
msgstr "Philip Withnall"
#. (itstool) path: credit/years
#: C/index.page:8
msgid "2020"
msgstr "2020"
#. (itstool) path: page/title
#: C/index.page:12
msgid "Parental Controls Help"
msgstr "Bantuan Pengawasan Orang Tua"
#. (itstool) path: section/title
#: C/index.page:15
msgid "Introduction &amp; Setup"
msgstr "Pendahuluan &amp; Penyiapan"
#. (itstool) path: section/title
#: C/index.page:19
msgid "Controls to Apply"
msgstr "Pengawasan yang Diterapkan"
#. (itstool) path: info/desc
#: C/internet.page:6
msgid "Restricting a child users access to the internet."
msgstr "Membatasi akses pengguna anak ke Internet."
#. (itstool) path: page/title
#: C/internet.page:9
msgid "Restricting Access to the Internet"
msgstr "Membatasi Akses ke Internet"
#. (itstool) path: page/p
#: C/internet.page:11
msgid ""
"You can restrict a users access to the internet. This will prevent them "
"using a web browser, but it will not prevent them using the internet (in "
"potentially more limited forms) through other applications. For example, it "
"will not prevent access to e-mail accounts using <app>Evolution</app>, and "
"it will not prevent software updates being downloaded and applied."
msgstr ""
"Anda dapat membatasi akses pengguna ke internet. Ini akan mencegah mereka "
"menggunakan peramban web, tetapi tidak akan mencegah mereka menggunakan "
"internet (dalam bentuk yang berpotensi lebih terbatas) melalui aplikasi "
"lain. Sebagai contoh, itu tidak akan mencegah akses ke akun surel "
"menggunakan <app>Evolution</app>, dan tidak akan mencegah pembaruan "
"perangkat lunak yang diunduh dan diterapkan."
#. (itstool) path: page/p
#: C/internet.page:17
msgid "To restrict a users access to the internet:"
msgstr "Untuk membatasi akses pengguna ke internet:"
#. (itstool) path: item/p
#: C/internet.page:19 C/restricting-applications.page:20
#: C/software-installation.page:28 C/software-installation.page:54
msgid "Open the <app>Parental Controls</app> application."
msgstr "Buka aplikasi <app>Pengawasan Orang Tua</app>."
#. (itstool) path: item/p
#: C/internet.page:20 C/restricting-applications.page:21
#: C/software-installation.page:29 C/software-installation.page:55
msgid "Select the user in the tabs at the top."
msgstr "Pilih pengguna di tab di bagian atas."
#. (itstool) path: item/p
#: C/internet.page:21
msgid ""
"Enable the <gui style=\"checkbox\">Restrict Web Browsers</gui> checkbox."
msgstr ""
"Fungsikan kotak centang <gui style=\"checkbox\">Batasi Peramban Web</gui>."
#. (itstool) path: info/desc
#: C/introduction.page:6
msgid ""
"Overview of parental controls, the <app>Parental Controls</app> application "
"and its use in other situations where access restrictions are needed on a "
"user."
msgstr ""
"Ikhtisar pengawasan orang tua, aplikasi <app>Pengawasan Orang Tua</app>, dan "
"penggunaannya dalam situasi lain dimana pembatasan akses diperlukan pada "
"seorang pengguna."
#. (itstool) path: page/title
#: C/introduction.page:12
msgid "Introduction to Parental Controls"
msgstr "Pengenalan untuk Pengawasan Orang Tua"
#. (itstool) path: page/p
#: C/introduction.page:14
msgid ""
"Parental controls are a way to restrict what non-administrator accounts can "
"do on the computer, with the aim of allowing parents to restrict what their "
"children can do when using the computer unsupervised or under limited "
"supervision."
msgstr ""
"Pengawasan orang tua adalah cara untuk membatasi apa yang dapat dilakukan "
"oleh akun non-administrator pada komputer, dengan tujuan memperbolehkan "
"orangtua membatasi apa yang dapat dilakukan anak mereka saat menggunakan "
"komputer tanpa pengawasan atau di bawah supervisi yang terbatas."
#. (itstool) path: page/p
#: C/introduction.page:18
msgid ""
"This functionality can be used in other situations ­ such as other carer/"
"caree relationships but is labelled as parental controls so that its "
"easy to find, as thats what most people will be looking for."
msgstr ""
"Fungsi ini dapat digunakan dalam situasi lain seperti hubungan perawat/"
"terrawat lainnya tetapi diberi label sebagai 'pengawasan orang tua' "
"sehingga mudah ditemukan, karena itulah yang kebanyakan orang akan cari."
#. (itstool) path: page/p
#: C/introduction.page:21
msgid ""
"The parental controls for any user can be queried and set using the "
"<app>Parental Controls</app> application. This lists the non-administrator "
"accounts in tabs along its top bar, and shows their current parental "
"controls settings below. Changes to the parental controls apply immediately."
msgstr ""
"Pengawasan orang tua untuk setiap pengguna dapat ditanyakan dan diatur "
"menggunakan aplikasi <app>Pengawasan Orang Tua</app>. Ini mencantumkan akun "
"non-administrator di tab di sepanjang bilah atasnya, dan menunjukkan setelan "
"pengawasan orang tua mereka saat ini di bawah. Perubahan pada pengawasan "
"orang tua akan segera berlaku."
#. (itstool) path: page/p
#: C/introduction.page:25
msgid ""
"Restrictions on using the computer can only be applied to non-administrator "
"accounts. The parental controls settings for a user can only be changed by "
"an administrator, although the administrator can do so from the users "
"account by entering their password when prompted by the <app>Parental "
"Controls</app> application."
msgstr ""
"Pembatasan penggunaan komputer hanya dapat diterapkan pada akun non-"
"administrator. Setelan pengawasan orang tua untuk pengguna hanya dapat "
"diubah oleh administrator, meskipun administrator dapat melakukannya dari "
"akun pengguna dengan memasukkan kata sandi saat diminta oleh aplikasi "
"<app>Pengawasan Orang Tua</app> ."
#. (itstool) path: p/link
#: C/legal.xml:4
msgid "Creative Commons Attribution-ShareAlike 3.0 Unported License"
msgstr "Creative Commons Attribution-ShareAlike 3.0 Unported License"
#. (itstool) path: license/p
#: C/legal.xml:3
msgid "This work is licensed under a <_:link-1/>."
msgstr "Karya ini dilisensikan di bawah <_:link-1/>."
#. (itstool) path: info/desc
#: C/restricting-applications.page:6
msgid "Restricting a child user from running already-installed applications."
msgstr "Membatasi pengguna anak dari menjalankan aplikasi yang sudah diinstal."
#. (itstool) path: page/title
#: C/restricting-applications.page:9
msgid "Restricting Access to Installed Applications"
msgstr "Membatasi Akses ke Aplikasi yang Terinstal"
#. (itstool) path: page/p
#: C/restricting-applications.page:11
msgid ""
"You can prevent a user from running specific applications which are already "
"installed on the computer. This could be useful if other users need those "
"applications but they are not appropriate for a child."
msgstr ""
"Anda dapat mencegah pengguna menjalankan aplikasi tertentu yang telah "
"diinstal di komputer. Hal ini dapat berguna jika pengguna lain membutuhkan "
"aplikasi tersebut tetapi mereka tidak sesuai untuk anak."
#. (itstool) path: page/p
#: C/restricting-applications.page:14
msgid ""
"When installing additional software, you should consider whether that needs "
"to be restricted for some users — newly installed software is usable by all "
"users by default."
msgstr ""
"Ketika menginstal perangkat lunak tambahan, Anda harus mempertimbangkan "
"apakah yang perlu dibatasi untuk beberapa pengguna — perangkat lunak yang "
"baru diinstal dapat dipakai oleh semua pengguna secara baku."
#. (itstool) path: page/p
#: C/restricting-applications.page:18
msgid "To restrict a users access to a specific application:"
msgstr "Untuk membatasi akses pengguna ke aplikasi tertentu:"
#. (itstool) path: item/p
#: C/restricting-applications.page:22
msgid "Press the <gui style=\"button\">Restrict Applications</gui> button."
msgstr "Tekan tombol <gui style=\"button\">Batasi Aplikasi</gui>."
#. (itstool) path: item/p
#: C/restricting-applications.page:23
msgid ""
"Enable the switch in the row for each application you would like to restrict "
"the user from accessing."
msgstr ""
"Fungsikan saklar di baris untuk setiap aplikasi yang Anda ingin membatasi "
"pengguna dari mengaksesnya."
#. (itstool) path: item/p
#: C/restricting-applications.page:24
msgid "Close the <gui>Restrict Applications</gui> window."
msgstr "Tutup jendela <gui>Batasi Aplikasi</gui>."
#. (itstool) path: page/p
#: C/restricting-applications.page:27
msgid ""
"Restricting access to specific applications is often used in conjunction "
"with <link xref=\"software-installation\"/> to prevent a user from "
"installing additional software which has not been vetted."
msgstr ""
"Membatasi akses ke aplikasi tertentu sering digunakan dalam hubungannya "
"dengan <link xref=\"software-installation\"/> untuk mencegah pengguna dari "
"menginstal perangkat lunak tambahan yang belum diperiksa."
#. (itstool) path: info/desc
#: C/software-installation.page:6
msgid ""
"Restricting the software a child user can install, or preventing them "
"installing additional software entirely."
msgstr ""
"Membatasi perangkat lunak yang dapat dipasang pengguna anak, atau mencegah "
"mereka menginstal perangkat lunak tambahan sepenuhnya."
#. (itstool) path: page/title
#: C/software-installation.page:9
msgid "Restricting Software Installation"
msgstr "Membatasi Instalasi Perangkat Lunak"
#. (itstool) path: page/p
#: C/software-installation.page:11
msgid ""
"You can prevent a user from installing additional software on the system. "
"They will still be able to search for new software to install, but will need "
"an administrator to authorize the installation when they try to install an "
"application. This applies whether they are trying to install the application "
"system-wide (for all users) or just for themselves."
msgstr ""
"Anda dapat mencegah pengguna dari memasang perangkat lunak tambahan, baik "
"untuk seluruh sistem, atau hanya untuk diri mereka sendiri. Mereka masih "
"akan dapat mencari perangkat lunak baru untuk dipasang, tetapi akan "
"memerlukan administrator untuk mengesahkan instalasi ketika mereka mencoba "
"untuk memasang aplikasi."
#. (itstool) path: page/p
#: C/software-installation.page:17
msgid ""
"Additionally, you can restrict which software a user can browse or search "
"for in the <app>Software</app> catalog by age categories."
msgstr ""
"Selain itu, Anda dapat membatasi perangkat lunak yang dapat ditelusuri atau "
"dicari oleh pengguna di katalog <app>Perangkat Lunak</app> berdasarkan "
"kategori usia."
#. (itstool) path: page/p
#: C/software-installation.page:20
msgid ""
"To prevent a user from running an application which has already been "
"installed, see <link xref=\"restricting-applications\"/>."
msgstr ""
"Untuk mencegah pengguna menjalankan aplikasi yang sudah terinstal, lihat "
"<link xref=\"restricting-applications\"/> ."
#. (itstool) path: section/title
#: C/software-installation.page:24
msgid "Preventing Software Installation"
msgstr "Mencegah Instalasi Perangkat Lunak"
#. (itstool) path: section/p
#: C/software-installation.page:26
msgid "To prevent a user from installing additional software:"
msgstr "Untuk mencegah pengguna menginstal perangkat lunak tambahan:"
#. (itstool) path: item/p
#: C/software-installation.page:30
msgid ""
"Enable the <gui style=\"checkbox\">Restrict Application Installation</gui> "
"checkbox."
msgstr ""
"Fungsikan kotak centang <gui style=\"checkbox\">Batasi Pemasangan Aplikasi</"
"gui>."
#. (itstool) path: section/title
#: C/software-installation.page:35
msgid "Restricting Software Installation by Age"
msgstr "Membatasi Instalasi Perangkat Lunak berdasarkan Umur"
#. (itstool) path: section/p
#: C/software-installation.page:37
msgid ""
"Applications in the <app>Software</app> catalog have information about "
"content they contain which might be inappropriate for some ages — for "
"example, various forms of violence, unmoderated chat with other people on "
"the internet, or the possibility of spending money."
msgstr ""
"Aplikasi dalam katalog <app>Perangkat Lunak</app> memiliki informasi tentang "
"konten yang mereka kandung yang mungkin tidak pantas untuk usia tertentu — "
"misalnya, berbagai bentuk kekerasan, obrolan tanpa moderator dengan orang "
"lain di internet, atau kemungkinan membelanjakan uang."
#. (itstool) path: section/p
#: C/software-installation.page:41
msgid ""
"For each application, this information is summarized as the minimum age "
"child it is typically suitable to be used by — for example, “suitable for "
"ages 7+”. These age ratings are presented in region-specific schemes which "
"can be compared with the ratings schemes used for films and games."
msgstr ""
"Untuk setiap aplikasi, informasi ini diringkas sebagai yang biasanya cocok "
"untuk digunakan oleh usia minimum anak berapa — misalnya, \"cocok untuk usia "
"7+\". Peringkat usia ini disajikan dalam skema spesifik wilayah yang dapat "
"dibandingkan dengan skema penilaian yang digunakan untuk film dan permainan."
#. (itstool) path: section/p
#: C/software-installation.page:45
msgid ""
"The applications shown to a user in the <app>Software</app> catalog can be "
"filtered by their age suitability. Applications which are not suitable for "
"the user will be hidden, and will not be installable by that user. They will "
"be installable by other users (if their age suitability is set high enough)."
msgstr ""
"Aplikasi yang ditampilkan kepada pengguna di katalog <app>Perangkat Lunak</"
"app> dapat difilter menurut kesesuaian usia mereka. Aplikasi yang tidak "
"cocok untuk pengguna akan disembunyikan, dan tidak akan dapat diinstal oleh "
"pengguna tersebut. Mereka akan dapat diinstal oleh pengguna lain (jika "
"kesesuaian usia mereka ditetapkan cukup tinggi)."
#. (itstool) path: section/p
#: C/software-installation.page:51
msgid ""
"To filter the applications seen by a user in the <app>Software</app> catalog "
"to only those suitable for a certain age:"
msgstr ""
"Untuk menyaring aplikasi yang dilihat oleh pengguna dalam katalog "
"<app>Perangkat Lunak</app> agar hanya yang cocok untuk usia tertentu:"
#. (itstool) path: item/p
#: C/software-installation.page:56
msgid ""
"In the <gui>Application Suitability</gui> list, select the age which "
"applications should be suitable for."
msgstr ""
"Dalam daftar <gui>Kesesuaian Aplikasi</gui>, pilih usia mana aplikasi mesti "
"cocok."
#. (itstool) path: note/p
#: C/software-installation.page:60
msgid ""
"The users actual age is not stored, so the <gui>Application Suitability</"
"gui> is not automatically updated over time as the child grows older. You "
"must periodically re-assess the appropriate <gui>Application Suitability</"
"gui> for each user."
msgstr ""
"Usia pengguna yang sebenarnya tidak disimpan, sehingga <gui>Kesesuaian "
"Aplikasi</gui> tidak diperbarui secara otomatis dari waktu saat anak tumbuh "
"lebih tua. Anda harus secara berkala menilai kembali <gui>Kesesuaian "
"Aplikasi</gui> yang sesuai untuk setiap pengguna."

View File

@ -1,450 +0,0 @@
# Italian translations for malcontent.
# Copyright © 2020 the malcontent authors.
# This file is distributed under the same license as the malcontent package.
# Albano Battistella <albano_battistella@hotmail.com>, 2022.
#
msgid ""
msgstr ""
"Project-Id-Version: malcontent master\n"
"POT-Creation-Date: 2020-04-24 15:30+0000\n"
"PO-Revision-Date: 2022-01-07 15:41+0100\n"
"Last-Translator: Albano Battistella <albano_battistella@hotmail.com>\n"
"Language-Team: Italian\n"
"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 2.4.1\n"
#. Put one translator per line, in the form NAME <EMAIL>, YEAR1, YEAR2
msgctxt "_"
msgid "translator-credits"
msgstr "Albano Battistella <albano_battistella@hotmail.com>, 2022."
#. (itstool) path: info/desc
#: C/creating-a-child-user.page:6
msgid "Creating a child user on the computer."
msgstr "Creazione di un account per bambini sul computer."
#. (itstool) path: page/title
#: C/creating-a-child-user.page:9
msgid "Creating a Child User"
msgstr "Creazione un Account per Bambini"
#. (itstool) path: page/p
#: C/creating-a-child-user.page:11
msgid ""
"Parental controls can only be applied to non-administrator accounts. Such an "
"account may have been created when the computer was initially set up. If "
"not, a new child user may be created from the <app>Parental Controls</app> "
"application if no child users already exist; and otherwise may be created "
"from the <app>Control Center</app>."
msgstr ""
"Il controllo parentale può essere applicato solo agli account non-amministratore."
"Al momento potrebbe essere stato creato un account di questo tipo "
"dalla configurazione iniziale del computer. In caso contrario, è possibile creare un "
"nuovo account per bambino dall'applicazione <app>Controllo Parentale</app> o "
"tramite le <app>Impostazioni</app>."
#. (itstool) path: page/p
#: C/creating-a-child-user.page:17
msgid ""
"To create a new child user, see <link type=\"guide\" xref=\"help:gnome-help/"
"user-add\">Add a new user account</link>. As soon as the new user is "
"created, it will appear in the <app>Parental Controls</app> window so that "
"its parental controls settings can be configured."
msgstr ""
"Per creare un nuovo utente per bambino, vedere <link type =\"guide\" xref=\"help:gnome-help/"
"user-add\">Aggiungi un nuovo account utente</link>. Non appena il nuovo utente sarà "
"creato, apparirà nella finestra <app>Controllo Parentale</app> in modo che "
"le sue impostazioni di controllo parentale possano essere configurate."
#. (itstool) path: credit/name
#: C/index.page:6
msgid "Philip Withnall"
msgstr "Philip Withnall"
#. (itstool) path: credit/years
#: C/index.page:8
msgid "2020"
msgstr "2020"
#. (itstool) path: page/title
#: C/index.page:12
msgid "Parental Controls Help"
msgstr "Aiuto sui controlli parentali"
#. (itstool) path: section/title
#: C/index.page:15
msgid "Introduction &amp; Setup"
msgstr "Introduzione e configurazione"
#. (itstool) path: section/title
#: C/index.page:19
msgid "Controls to Apply"
msgstr "Controlli da applicare"
#. (itstool) path: info/desc
#: C/internet.page:6
msgid "Restricting a child users access to the internet."
msgstr "Limitare l'accesso a Internet da parte di un minore"
#. (itstool) path: page/title
#: C/internet.page:9
msgid "Restricting Access to the Internet"
msgstr "Limitare l'accesso a Internet"
#. (itstool) path: page/p
#: C/internet.page:11
msgid ""
"You can restrict a users access to the internet. This will prevent them "
"using a web browser, but it will not prevent them using the internet (in "
"potentially more limited forms) through other applications. For example, it "
"will not prevent access to e-mail accounts using <app>Evolution</app>, and "
"it will not prevent software updates being downloaded and applied."
msgstr ""
"È possibile limitare l'accesso di un utente a Internet. Questo gli impedirà "
"di usare un browser web, ma non limiterà la connessione a Internet (in forma limitata) di "
"altre applicazioni. Ad esempio, non impedirà l'accesso agli account di "
"e-mail utilizzando <app>Evolution</app>, né impedirà il download ed "
"applicazione di aggiornamenti software."
#. (itstool) path: page/p
#: C/internet.page:17
msgid "To restrict a users access to the internet:"
msgstr "Per limitare l'accesso di un utente a Internet:"
#. (itstool) path: item/p
#: C/internet.page:19 C/restricting-applications.page:20
#: C/software-installation.page:27 C/software-installation.page:64
msgid "Open the <app>Parental Controls</app> application."
msgstr "Apri l'app <app>Controllo Parentale</app>."
#. (itstool) path: item/p
#: C/internet.page:20 C/restricting-applications.page:21
#: C/software-installation.page:28 C/software-installation.page:65
msgid "Select the user in the tabs at the top."
msgstr "Nelle schede in alto, seleziona l'account desiderato."
#. (itstool) path: item/p
#: C/internet.page:21
msgid ""
"Enable the <gui style=\"checkbox\">Restrict Web Browsers</gui> checkbox."
msgstr ""
"Seleziona la casella <gui style=\"checkbox\">Limita i browser web</gui>."
#. (itstool) path: info/desc
#: C/introduction.page:6
msgid ""
"Overview of parental controls and the <app>Parental Controls</app> "
"application."
msgstr ""
"Panoramica del controllo parentale e dell'applicazione "
"<app>Controllo Parentale</app>."
#. (itstool) path: page/title
#: C/introduction.page:10
msgid "Introduction to Parental Controls"
msgstr "Introduzione al Controllo Parentale"
#. (itstool) path: page/p
#: C/introduction.page:12
msgid ""
"Parental controls are a way to restrict what non-administrator accounts can "
"do on the computer, with the aim of allowing parents to restrict what their "
"children can do when using the computer unsupervised or under limited "
"supervision."
msgstr ""
"Il controllo parentale è un modo per limitare ciò che gli account non-amministratore possono "
"fare al computer, con l'obiettivo di consentire ai genitori di limitare ciò che i loro "
"bambini possono fare quando usano il computer senza sorveglianza o sotto una supervisione "
"limitata."
#. (itstool) path: page/p
#: C/introduction.page:16
msgid ""
"This functionality can be used in other situations ­ such as other carer/"
"caree relationships but is labelled as parental controls so that its "
"easy to find."
msgstr ""
"Questa funzionalità può essere utilizzata in altre situazioni, ad esempio per altri tutori/"
"relazioni di carriera - ma è etichettato comecontrollo parentale in modo che sia "
"facile da trovare."
#. (itstool) path: page/p
#: C/introduction.page:19
msgid ""
"The parental controls for any user can be queried and set using the "
"<app>Parental Controls</app> application. This lists the non-administrator "
"accounts in tabs along its top bar, and shows their current parental "
"controls settings below. Changes to the parental controls apply immediately."
msgstr ""
"L'applicazione <app>Controllo Parentale</app> consente le query "
"a qualsiasi titolo e definisce i controlli per ciascuno. L'applicazione "
"elenca tutti gli account non-amministratore sotto forma di schede nella "
"barra superiore della finestra e sotto mostra i controlli definiti "
"attualmente. Le modifiche al controllo parentale hanno effetto immediato."
#. (itstool) path: page/p
#: C/introduction.page:23
msgid ""
"Restrictions on using the computer can only be applied to non-administrator "
"accounts. The parental controls settings for a user can only be changed by "
"an administrator, although the administrator can do so from the users "
"account by entering their password when prompted by the <app>Parental "
"Controls</app> application."
msgstr ""
"Le restrizioni sull'uso dei computer possono essere applicate solo agli account "
"non-amministratore. Le impostazioni del controllo parentale per un utente possono "
"essere modificate solo da un amministratore, anche se l'amministratore può farlo dall'utente "
"account inserendo la password quando richiesto dall'applicazione "
"<app>Controllo Parentale</app>."
#. (itstool) path: p/link
#: C/legal.xml:4
msgid "Creative Commons Attribution-ShareAlike 3.0 Unported License"
msgstr "Creative Commons Attribution-ShareAlike 3.0 Unported License"
#. (itstool) path: license/p
#: C/legal.xml:3
msgid "This work is licensed under a <_:link-1/>."
msgstr "Quest'opera è sotto licenza <_:link-1/>."
#. (itstool) path: info/desc
#: C/restricting-applications.page:6
msgid "Restricting a child user from running already-installed applications."
msgstr "Limita l'utilizzo di applicazioni già installate ai minori."
#. (itstool) path: page/title
#: C/restricting-applications.page:9
msgid "Restricting Access to Installed Applications"
msgstr "Limita l'accesso alle applicazioni installate"
#. (itstool) path: page/p
#: C/restricting-applications.page:11
msgid ""
"You can prevent a user from running specific applications which are already "
"installed on the computer. This could be useful if other users need those "
"applications but they are not appropriate for a child."
msgstr ""
"Puoi impedire ad un utente di eseguire applicazioni specifiche che sono già "
"installate nel computer. Questo potrebbe essere utile se altri utenti hanno bisogno "
"di queste applicazioni ma che non siano appropriate per un bambino."
#. (itstool) path: page/p
#: C/restricting-applications.page:14
msgid ""
"When installing additional software, you should consider whether that needs "
"to be restricted for some users — newly installed software is usable by all "
"users by default."
msgstr ""
"Durante l'installazione di software aggiuntivo, è necessario considerare se sia necessario "
"limitarlo per alcuni utenti: il software appena installato è utilizzabile da tutti gli "
"utenti per impostazione predefinita."
#. (itstool) path: page/p
#: C/restricting-applications.page:18
msgid "To restrict a users access to a specific application:"
msgstr "Per limitare l'accesso di un utente a un'applicazione specifica:"
#. (itstool) path: item/p
#: C/restricting-applications.page:22
msgid "Press the <gui style=\"button\">Restrict Applications</gui> button."
msgstr "Premi il pulsante <gui style=\"button\">Limita Applicazioni</gui>."
#. (itstool) path: item/p
#: C/restricting-applications.page:23
msgid ""
"Enable the switch in the row for each application you would like to restrict "
"the user from accessing."
msgstr ""
"Attiva l'interruttore nella riga per ogni app che desideri limitare."
#. (itstool) path: item/p
#: C/restricting-applications.page:24
msgid "Close the <gui>Restrict Applications</gui> window."
msgstr "Chiudi la finestra <gui>Limita Applicazioni</gui>."
#. (itstool) path: page/p
#: C/restricting-applications.page:27
msgid ""
"Restricting access to specific applications is often used in conjunction "
"with <link xref=\"software-installation\"/> to prevent a user from "
"installing additional software which has not been vetted."
msgstr ""
"Spesso viene utilizzata la limitazione dell'accesso a determinate applicazioni "
"Con <link xref=\"software-installation\"/> per evitare che venga installato "
"software senza che sia stato verificato."
#. (itstool) path: info/desc
#: C/software-installation.page:6
msgid ""
"Restricting the software a child user can install, or preventing them "
"installing additional software entirely."
msgstr ""
"Limita il software che un minore può installare o impediscigli di "
"installare completamente software aggiuntivo."
#. (itstool) path: page/title
#: C/software-installation.page:9
msgid "Restricting Software Installation"
msgstr "Limitare Installazione di Software"
#. (itstool) path: page/p
#: C/software-installation.page:11
msgid ""
"You can prevent a user from installing additional software, either for the "
"entire system, or just for themselves. They will still be able to search for "
"new software to install, but will need an administrator to authorize the "
"installation when they try to install an application."
msgstr ""
"Puoi impedire ad un utente di installare software aggiuntivo, sia per l'intero "
"sistema, sia per te stesso. Sarà ancora in grado di cercare nuovo software "
"da installare, ma se proverà ad installarlo dovrà avere l'aiuto di un "
"amministratore per l'autorizzazione."
#. (itstool) path: page/p
#: C/software-installation.page:16
msgid ""
"Additionally, you can restrict which software a user can browse or search "
"for in the <app>Software</app> catalog by age categories."
msgstr ""
"Inoltre, se utilizzi le categorie di età in <app>Software</app>, "
"puoi limitare quale software può essere sfogliato nel tuo catalogo."
#. (itstool) path: page/p
#: C/software-installation.page:19
msgid ""
"To prevent a user from running an application which has already been "
"installed, see <link xref=\"restricting-applications\"/>."
msgstr ""
"Per impedire a un utente di eseguire un'applicazione precedentemente installata, "
"vedere <link xref=\"restricting-applications\"/>."
#. (itstool) path: section/title
#: C/software-installation.page:23
msgid "Preventing Software Installation"
msgstr "Evitare l'installazione di software"
#. (itstool) path: section/p
#: C/software-installation.page:25
msgid "To prevent a user from installing additional software:"
msgstr ""
"Seguire questa procedura per impedire l'installazione di software aggiuntivo:"
#. (itstool) path: item/p
#: C/software-installation.page:29
msgid ""
"Enable the <gui style=\"checkbox\">Restrict Application Installation</gui> "
"checkbox."
msgstr ""
"Selezionare la casella <gui style=\"checkbox\">Limita l'installazione di "
"Applicazioni</gui>."
#. (itstool) path: item/p
#: C/software-installation.page:30
msgid ""
"Or enable the <gui style=\"checkbox\">Restrict Application Installation for "
"Others</gui> checkbox."
msgstr ""
"Oppure, seleziona la casella <gui style=\"checkbox\">Limita l'installazione di "
"applicazioni per gli altri</gui>."
#. (itstool) path: section/p
#: C/software-installation.page:33
msgid ""
"The <gui style=\"checkbox\">Restrict Application Installation for Others</"
"gui> checkbox allows the user to install additional software for themselves, "
"but prevents that software from being made available to other users. It "
"could be used, for exampcheckboxle, if there were two child users, one of whom is "
"mature enough to be allowed to install additional software, but the other "
"isnt — enabling <gui style=\"\">Restrict Application Installation "
"for Others</gui> would prevent the more mature child from installing "
"applications which are inappropriate for the other child and making them "
"available to the other child."
msgstr ""
"La casella <gui style=\"checkbox\">Limita l'installazione di applicazioni "
"ad altri</gui> consente l'installazione di software aggiuntivo per se stessi, "
"ma ne limita la disponibilità agli altri account. Potrebbe essere usato "
"approfittando di questa funzione, ad esempio, se hai due minorenni, di cui "
"solo uno è abbastanza maturo da potersi installare software "
"abilitando <gui style=\"checkbox\">Limita l'installazione di "
"applicazioni ad altri</gui> impedirà al minore più maturo di installare "
"applicazioni inadeguate per l'altro bambino."
#. (itstool) path: section/title
#: C/software-installation.page:45
msgid "Restricting Software Installation by Age"
msgstr "Limitare l'installazione del software in base all'età"
#. (itstool) path: section/p
#: C/software-installation.page:47
msgid ""
"Applications in the <app>Software</app> catalog have information about "
"content they contain which might be inappropriate for some ages — for "
"example, various forms of violence, unmoderated chat with other people on "
"the internet, or the possibility of spending money."
msgstr ""
"Le applicazioni incluse nel catalogo di <app>Software</app> "
"includono informazioni riguardanti il contenuto che possiedono e la sua idoneità "
"secondo l'età, annotando dettagli come: varie forme di violenza, chat non "
"moderate con altre persone tramite internet, o la capacità di spendere "
"soldi."
#. (itstool) path: section/p
#: C/software-installation.page:51
msgid ""
"For each application, this information is summarized as the minimum age "
"child it is typically suitable to be used by — for example, “suitable for "
"ages 7+”. These age ratings are presented in region-specific schemes which "
"can be compared with the ratings schemes used for films and games."
msgstr ""
"In ogni applicazione, questa informazione è condensata come l'età minima "
"che è ritenuta appropriata per un minore utilizzarla; ad esempio,“7 anni o +“. "
"Queste classificazioni sono presentate in conformità con alcuni "
"schemi regionali, paragonabili a quelli utilizzati per classificare "
"film e giochi."
#. (itstool) path: section/p
#: C/software-installation.page:55
msgid ""
"The applications shown to a user in the <app>Software</app> catalog can be "
"filtered by their age suitability. Applications which are not suitable for "
"the user will be hidden, and will not be installable by that user. They will "
"be installable by other users (if their age suitability is set high enough)."
msgstr ""
"Le applicazioni <app>Software</app> mostrate a ciascun utente possono essere "
"filtrate per adeguatezza all'età. Le applicazioni non adatte per un account "
"verranno nascoste dal catalogo e non potranno essere installate. "
"Altri utenti potranno installarle (se la loro fascia d'età è tale che lo si permetta)."
#. (itstool) path: section/p
#: C/software-installation.page:61
msgid ""
"To filter the applications seen by a user in the <app>Software</app> catalog "
"to only those suitable for a certain age:"
msgstr ""
"Per filtrare le applicazioni che vede un utente nel catalogo "
"<app>Software</app> e che solo quelli appropriati vengono mostrati per una "
"certa età:"
#. (itstool) path: item/p
#: C/software-installation.page:66
msgid ""
"In the <gui>Application Suitability</gui> list, select the age which "
"applications should be suitable for."
msgstr ""
"Nella lista <gui>Idoneità dell'applicazione</gui>, selezionare l'età desiderata."
#. (itstool) path: note/p
#: C/software-installation.page:70
msgid ""
"The users actual age is not stored, so the <gui>Application Suitability</"
"gui> is not automatically updated over time as the child grows older. You "
"must periodically re-assess the appropriate <gui>Application Suitability</"
"gui> for each user."
msgstr ""
"Poiché l'età dell'utente non viene memorizzata, l' <gui>Idoneità dell'applicazione</"
"gui> non viene aggiornata automaticamente man mano che il minore cresce. Si dovrebbe "
"rivalutare periodicamente il livello appropriato di <gui>Idoneità dell'applicazione</"
"gui> per ciascuno degli account."

View File

@ -1,17 +0,0 @@
help_media = [
]
help_files = [
'creating-a-child-user.page',
'index.page',
'internet.page',
'introduction.page',
'legal.xml',
'restricting-applications.page',
'software-installation.page',
]
gnome.yelp(meson.project_name(),
sources: help_files,
media: help_media,
symlink_media: true,
)

View File

@ -1,437 +0,0 @@
# Polish translation for malcontent help.
# Copyright © 2020 the malcontent authors.
# This file is distributed under the same license as the malcontent help.
# Piotr Drąg <piotrdrag@gmail.com>, 2020.
# Aviary.pl <community-poland@mozilla.org>, 2020.
#
msgid ""
msgstr ""
"Project-Id-Version: malcontent-help\n"
"POT-Creation-Date: 2020-12-18 15:14+0000\n"
"PO-Revision-Date: 2020-12-20 13:22+0100\n"
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
"Language-Team: Polish <community-poland@mozilla.org>\n"
"Language: pl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
"|| n%100>=20) ? 1 : 2);\n"
#. Put one translator per line, in the form NAME <EMAIL>, YEAR1, YEAR2
msgctxt "_"
msgid "translator-credits"
msgstr ""
"Piotr Drąg <piotrdrag@gmail.com>, 2020\n"
"Aviary.pl <community-poland@mozilla.org>, 2020"
#. (itstool) path: info/desc
#: C/creating-a-child-user.page:6
msgid "Creating a child user on the computer."
msgstr "Tworzenie konta dziecka na komputerze."
#. (itstool) path: page/title
#: C/creating-a-child-user.page:9
msgid "Creating a Child User"
msgstr "Tworzenie konta dziecka"
#. (itstool) path: page/p
#: C/creating-a-child-user.page:11
msgid ""
"Parental controls can only be applied to non-administrator accounts. Such an "
"account may have been created when the computer was initially set up. If "
"not, a new child user may be created from the <app>Parental Controls</app> "
"application if no child users already exist; and otherwise may be created "
"from the <app>Control Center</app>."
msgstr ""
"Kontrola rodzicielska może zostać zastosowana tylko na kontach niebędących "
"administratorami. Takie konto można utworzyć podczas początkowej "
"konfiguracji komputera. Jeśli nie zostało wtedy utworzone, to można to "
"zrobić w programie <app>Kontrola rodzicielska</app>, jeśli żadne konto "
"dziecka jeszcze nie istnieje. W przeciwnym wypadku można je utworzyć "
"w programie <app>Ustawienia</app>."
#. (itstool) path: page/p
#: C/creating-a-child-user.page:17
msgid ""
"To create a new child user, see <link type=\"guide\" xref=\"help:gnome-help/"
"user-add\">Add a new user account</link>. As soon as the new user is "
"created, it will appear in the <app>Parental Controls</app> window so that "
"its parental controls settings can be configured."
msgstr ""
"<link type=\"guide\" xref=\"help:gnome-help/user-add\">Dokumentacja "
"środowiska</link> zawiera informacje o tym, jak utworzyć nowe konto "
"użytkownika. Po utworzeniu pojawi się ono w oknie programu <app>Kontrola "
"rodzicielska</app>, gdzie można skonfigurować jego ustawienia kontroli "
"rodzicielskiej."
#. (itstool) path: credit/name
#: C/index.page:6
msgid "Philip Withnall"
msgstr "Philip Withnall"
#. (itstool) path: credit/years
#: C/index.page:8
msgid "2020"
msgstr "2020"
#. (itstool) path: page/title
#: C/index.page:12
msgid "Parental Controls Help"
msgstr "Kontrola rodzicielska"
#. (itstool) path: section/title
#: C/index.page:15
msgid "Introduction &amp; Setup"
msgstr "Wprowadzenie i konfiguracja"
#. (itstool) path: section/title
#: C/index.page:19
msgid "Controls to Apply"
msgstr "Ograniczenia do zastosowania"
#. (itstool) path: info/desc
#: C/internet.page:6
msgid "Restricting a child users access to the internet."
msgstr "Ograniczanie dostępu konta dziecka do Internetu."
#. (itstool) path: page/title
#: C/internet.page:9
msgid "Restricting Access to the Internet"
msgstr "Ograniczanie dostępu do Internetu"
#. (itstool) path: page/p
#: C/internet.page:11
msgid ""
"You can restrict a users access to the internet. This will prevent them "
"using a web browser, but it will not prevent them using the internet (in "
"potentially more limited forms) through other applications. For example, it "
"will not prevent access to e-mail accounts using <app>Evolution</app>, and "
"it will not prevent software updates being downloaded and applied."
msgstr ""
"Można ograniczyć użytkownikowi dostęp do Internetu. Uniemożliwi im to "
"używanie przeglądarki internetowej, ale nie uniemożliwi im korzystania "
"z Internetu (w potencjalnie bardziej ograniczonej formie) za pomocą innych "
"programów. Na przykład nie uniemożliwi dostępu do kont e-mail za pomocą "
"programu <app>Evolution</app> oraz nie zatrzyma pobierania i instalowania "
"aktualizacji oprogramowania."
#. (itstool) path: page/p
#: C/internet.page:17
msgid "To restrict a users access to the internet:"
msgstr "Aby ograniczyć dostęp użytkownika do Internetu:"
#. (itstool) path: item/p
#: C/internet.page:19 C/restricting-applications.page:20
#: C/software-installation.page:28 C/software-installation.page:54
msgid "Open the <app>Parental Controls</app> application."
msgstr "Otwórz program <app>Kontrola rodzicielska</app>."
#. (itstool) path: item/p
#: C/internet.page:20 C/restricting-applications.page:21
#: C/software-installation.page:29 C/software-installation.page:55
msgid "Select the user in the tabs at the top."
msgstr "Wybierz użytkownika z kart na górze."
#. (itstool) path: item/p
#: C/internet.page:21
msgid ""
"Enable the <gui style=\"checkbox\">Restrict Web Browsers</gui> checkbox."
msgstr ""
"Zaznacz pole <gui style=\"checkbox\">Ograniczanie przeglądarek "
"internetowych</gui>."
#. (itstool) path: info/desc
#: C/introduction.page:6
msgid ""
"Overview of parental controls, the <app>Parental Controls</app> application "
"and its use in other situations where access restrictions are needed on a "
"user."
msgstr ""
"Przegląd kontroli rodzicielskiej, programu <app>Kontrola rodzicielska</app> "
"i jego użycia w innych sytuacjach, w których potrzebne są ograniczenia "
"dostępu użytkownika."
#. (itstool) path: page/title
#: C/introduction.page:12
msgid "Introduction to Parental Controls"
msgstr "Wprowadzenie do kontroli rodzicielskiej"
#. (itstool) path: page/p
#: C/introduction.page:14
msgid ""
"Parental controls are a way to restrict what non-administrator accounts can "
"do on the computer, with the aim of allowing parents to restrict what their "
"children can do when using the computer unsupervised or under limited "
"supervision."
msgstr ""
"Kontrola rodzicielska to sposób na ograniczanie tego, co nieadministracyjne "
"konta mogą robić na komputerze, którego celem jest umożliwienie rodzicom "
"ograniczania, co ich dzieci mogą robić w czasie korzystania z komputera bez "
"nadzoru lub z minimalnym nadzorem."
#. (itstool) path: page/p
#: C/introduction.page:18
msgid ""
"This functionality can be used in other situations ­ such as other carer/"
"caree relationships but is labelled as parental controls so that its "
"easy to find, as thats what most people will be looking for."
msgstr ""
"Ta funkcjonalność może być używana w innych sytuacjach — takich jak inne "
"relacje opiekuńcze — ale nazywa się „kontrola rodzicielska”, aby można ją "
"było łatwo znaleźć, jako że większość osób będzie szukać tego terminu."
#. (itstool) path: page/p
#: C/introduction.page:21
msgid ""
"The parental controls for any user can be queried and set using the "
"<app>Parental Controls</app> application. This lists the non-administrator "
"accounts in tabs along its top bar, and shows their current parental "
"controls settings below. Changes to the parental controls apply immediately."
msgstr ""
"Za pomocą programu <app>Kontrola rodzicielska</app> można sprawdzać "
"i ustawiać kontrolę rodzicielską dla każdego konta. Zawiera on listę kont "
"niebędących administratorami w kartach na górnym pasku i ich obecne "
"ustawienia kontroli rodzicielskiej poniżej. Zmiany kontroli rodzicielskiej "
"są uwzględniane od razu."
#. (itstool) path: page/p
#: C/introduction.page:25
msgid ""
"Restrictions on using the computer can only be applied to non-administrator "
"accounts. The parental controls settings for a user can only be changed by "
"an administrator, although the administrator can do so from the users "
"account by entering their password when prompted by the <app>Parental "
"Controls</app> application."
msgstr ""
"Ograniczenia korzystania z komputera można stosować tylko na kontach "
"nieadministracyjnych. Ustawienia kontroli rodzicielskiej użytkownika mogą "
"być zmieniane tylko przez administratora, ale administrator może robić to "
"z konta użytkownika wpisując swoje hasło, kiedy program <app>Kontrola "
"rodzicielska</app> o nie poprosi."
#. (itstool) path: p/link
#: C/legal.xml:4
msgid "Creative Commons Attribution-ShareAlike 3.0 Unported License"
msgstr "Creative Commons Attribution-ShareAlike 3.0 Unported"
#. (itstool) path: license/p
#: C/legal.xml:3
msgid "This work is licensed under a <_:link-1/>."
msgstr "Na warunkach licencji <_:link-1/>."
#. (itstool) path: info/desc
#: C/restricting-applications.page:6
msgid "Restricting a child user from running already-installed applications."
msgstr ""
"Ograniczanie kontu dziecka możliwości uruchamiania już zainstalowanych "
"programów."
#. (itstool) path: page/title
#: C/restricting-applications.page:9
msgid "Restricting Access to Installed Applications"
msgstr "Ograniczanie dostępu do zainstalowanych programów"
#. (itstool) path: page/p
#: C/restricting-applications.page:11
msgid ""
"You can prevent a user from running specific applications which are already "
"installed on the computer. This could be useful if other users need those "
"applications but they are not appropriate for a child."
msgstr ""
"Można uniemożliwić użytkownikowi uruchamianie określonych programów, które "
"są już zainstalowane na komputerze. Może to być przydatne, jeśli pozostali "
"użytkownicy potrzebują tych programów, ale nie są one odpowiednie dla "
"dziecka."
#. (itstool) path: page/p
#: C/restricting-applications.page:14
msgid ""
"When installing additional software, you should consider whether that needs "
"to be restricted for some users — newly installed software is usable by all "
"users by default."
msgstr ""
"Podczas instalowania dodatkowego oprogramowania należy rozważyć, czy musi "
"ono być ograniczone dla części użytkowników — nowo zainstalowane "
"oprogramowanie domyślnie może być używane przez wszystkich użytkowników."
#. (itstool) path: page/p
#: C/restricting-applications.page:18
msgid "To restrict a users access to a specific application:"
msgstr "Aby ograniczyć dostęp użytkownika do danego programu:"
#. (itstool) path: item/p
#: C/restricting-applications.page:22
msgid "Press the <gui style=\"button\">Restrict Applications</gui> button."
msgstr "Kliknij przycisk <gui style=\"button\">Ograniczanie programów</gui>."
#. (itstool) path: item/p
#: C/restricting-applications.page:23
msgid ""
"Enable the switch in the row for each application you would like to restrict "
"the user from accessing."
msgstr ""
"Kliknij przełącznik w rzędzie każdego programu, do którego użytkownik ma "
"mieć ograniczony dostęp."
#. (itstool) path: item/p
#: C/restricting-applications.page:24
msgid "Close the <gui>Restrict Applications</gui> window."
msgstr "Zamknij okno <gui>Ograniczanie programów</gui>."
#. (itstool) path: page/p
#: C/restricting-applications.page:27
msgid ""
"Restricting access to specific applications is often used in conjunction "
"with <link xref=\"software-installation\"/> to prevent a user from "
"installing additional software which has not been vetted."
msgstr ""
"Ograniczanie dostępu do określonych programów jest często używane "
"jednocześnie z funkcją <link xref=\"software-installation\"/>, aby "
"uniemożliwić użytkownikowi instalowanie dodatkowego oprogramowania, które "
"nie zostało jeszcze zatwierdzone."
#. (itstool) path: info/desc
#: C/software-installation.page:6
msgid ""
"Restricting the software a child user can install, or preventing them "
"installing additional software entirely."
msgstr ""
"Ograniczanie oprogramowania, które dziecko może instalować lub całkowite "
"uniemożliwianie im instalowania dodatkowego oprogramowania."
#. (itstool) path: page/title
#: C/software-installation.page:9
msgid "Restricting Software Installation"
msgstr "Ograniczanie instalacji oprogramowania"
#. (itstool) path: page/p
#: C/software-installation.page:11
msgid ""
"You can prevent a user from installing additional software on the system. "
"They will still be able to search for new software to install, but will need "
"an administrator to authorize the installation when they try to install an "
"application. This applies whether they are trying to install the application "
"system-wide (for all users) or just for themselves."
msgstr ""
"Można uniemożliwić użytkownikowi instalowanie dodatkowego oprogramowania na "
"komputerze. Nadal będzie on mógł wyszukiwać nowe oprogramowanie, ale do jego "
"zainstalowania będzie potrzebował upoważnienia administratora. Ma to "
"zastosowanie niezależnie od tego, czy użytkownik próbuje zainstalować "
"program w systemie (dla wszystkich użytkowników) czy tylko dla siebie."
#. (itstool) path: page/p
#: C/software-installation.page:17
msgid ""
"Additionally, you can restrict which software a user can browse or search "
"for in the <app>Software</app> catalog by age categories."
msgstr ""
"Dodatkowe można ograniczyć, które oprogramowanie użytkownik może przeglądać "
"i wyszukiwać w katalogu <app>Menedżera oprogramowania</app> według kategorii "
"wiekowych."
#. (itstool) path: page/p
#: C/software-installation.page:20
msgid ""
"To prevent a user from running an application which has already been "
"installed, see <link xref=\"restricting-applications\"/>."
msgstr ""
"<link xref=\"restricting-applications\"/> zawiera informacje o tym, jak "
"uniemożliwić użytkownikowi uruchamianie już zainstalowanego programu."
#. (itstool) path: section/title
#: C/software-installation.page:24
msgid "Preventing Software Installation"
msgstr "Uniemożliwianie instalacji oprogramowania"
#. (itstool) path: section/p
#: C/software-installation.page:26
msgid "To prevent a user from installing additional software:"
msgstr ""
"Aby uniemożliwić użytkownikowi instalowanie dodatkowego oprogramowania:"
#. (itstool) path: item/p
#: C/software-installation.page:30
msgid ""
"Enable the <gui style=\"checkbox\">Restrict Application Installation</gui> "
"checkbox."
msgstr ""
"Zaznacz pole <gui style=\"checkbox\">Ograniczanie instalacji programów</gui>."
#. (itstool) path: section/title
#: C/software-installation.page:35
msgid "Restricting Software Installation by Age"
msgstr "Ograniczanie instalacji oprogramowania według wieku"
#. (itstool) path: section/p
#: C/software-installation.page:37
msgid ""
"Applications in the <app>Software</app> catalog have information about "
"content they contain which might be inappropriate for some ages — for "
"example, various forms of violence, unmoderated chat with other people on "
"the internet, or the possibility of spending money."
msgstr ""
"Programy w katalogu <app>Menedżera oprogramowania</app> mają informacje "
"o zawieranej treści, która może być nieodpowiednia dla osób w pewnym wieku — "
"na przykład różne formy przemocy, niemoderowany czat z innymi osobami "
"w Internecie lub możliwość wydawania pieniędzy."
#. (itstool) path: section/p
#: C/software-installation.page:41
msgid ""
"For each application, this information is summarized as the minimum age "
"child it is typically suitable to be used by — for example, “suitable for "
"ages 7+”. These age ratings are presented in region-specific schemes which "
"can be compared with the ratings schemes used for films and games."
msgstr ""
"Dla każdego programu ta informacja jest podsumowana jako minimalny wiek "
"dziecka, w jakim zazwyczaj jest odpowiedni — na przykład „odpowiednie dla "
"dzieci siedmioletnich i starszych”. Te oceny wiekowe są przestawiane "
"w formie dla danego regionu, które można porównywać z ocenami używanymi dla "
"filmów i gier."
#. (itstool) path: section/p
#: C/software-installation.page:45
msgid ""
"The applications shown to a user in the <app>Software</app> catalog can be "
"filtered by their age suitability. Applications which are not suitable for "
"the user will be hidden, and will not be installable by that user. They will "
"be installable by other users (if their age suitability is set high enough)."
msgstr ""
"Programy wyświetlane użytkownikowi w katalogu <app>Menedżera oprogramowania</"
"app> mogą być filtrowane według ich kategorii wiekowych. Programy "
"nieodpowiednie dla użytkownika będą ukryte i nie będzie on mógł ich "
"instalować. Pozostali użytkownicy będą mogli je instalować (jeśli ich "
"kategoria wiekowa jest ustawiona odpowiednio wysoko)."
#. (itstool) path: section/p
#: C/software-installation.page:51
msgid ""
"To filter the applications seen by a user in the <app>Software</app> catalog "
"to only those suitable for a certain age:"
msgstr ""
"Aby odfiltrować nieodpowiednie programy widoczne dla użytkownika w katalogu "
"<app>Menedżera oprogramowania</app>:"
#. (itstool) path: item/p
#: C/software-installation.page:56
msgid ""
"In the <gui>Application Suitability</gui> list, select the age which "
"applications should be suitable for."
msgstr ""
"Na liście <gui>Odpowiedniość programów</gui> wybierz wiek, dla którego "
"programy powinny być odpowiednie."
#. (itstool) path: note/p
#: C/software-installation.page:60
msgid ""
"The users actual age is not stored, so the <gui>Application Suitability</"
"gui> is not automatically updated over time as the child grows older. You "
"must periodically re-assess the appropriate <gui>Application Suitability</"
"gui> for each user."
msgstr ""
"Rzeczywisty wiek użytkownika nie jest przechowywany, więc opcja "
"<gui>Odpowiedniość programów</gui> nie jest automatycznie aktualizowana wraz "
"z upływem czasu i dorastania dziecka. Należy okresowo sprawdzać, czy opcja "
"<gui>Odpowiedniość programów</gui> jest właściwie ustawiona dla każdego "
"użytkownika."

View File

@ -1,455 +0,0 @@
# Brazilian Portuguese translation for malcontent.
# Copyright (C) 2020 malcontent's COPYRIGHT HOLDER
# This file is distributed under the same license as the malcontent package.
# Rafael Fontenelle <rafaelff@gnome.org>, 2020.
#
msgid ""
msgstr ""
"Project-Id-Version: malcontent master\n"
"POT-Creation-Date: 2020-04-24 15:30+0000\n"
"PO-Revision-Date: 2020-04-24 09:11-0300\n"
"Last-Translator: Rafael Fontenelle <rafaelff@gnome.org>\n"
"Language-Team: Brazilian Portuguese <gnome-pt_br-list@gnome.org>\n"
"Language: pt_BR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1)\n"
"X-Generator: Gtranslator 3.36.0\n"
#. Put one translator per line, in the form NAME <EMAIL>, YEAR1, YEAR2
msgctxt "_"
msgid "translator-credits"
msgstr "Rafael Fontenelle <rafaelff@gnome.org>, 2020"
#. (itstool) path: info/desc
#: C/creating-a-child-user.page:6
msgid "Creating a child user on the computer."
msgstr "Criando um usuário filho no computador."
#. (itstool) path: page/title
#: C/creating-a-child-user.page:9
msgid "Creating a Child User"
msgstr "Criando um usuário filho"
#. (itstool) path: page/p
#: C/creating-a-child-user.page:11
msgid ""
"Parental controls can only be applied to non-administrator accounts. Such an "
"account may have been created when the computer was initially set up. If "
"not, a new child user may be created from the <app>Parental Controls</app> "
"application if no child users already exist; and otherwise may be created "
"from the <app>Control Center</app>."
msgstr ""
"Os controles dos pais podem ser aplicados apenas a contas de não "
"administrador. Essa conta pode ter sido criada quando o computador foi "
"configurado inicialmente. Caso contrário, um novo usuário filho poderá ser "
"criado a partir do aplicativo <app>Controle parental</app> se nenhum usuário "
"filho já existir; e, caso contrário, pode ser criado no <app>Controle "
"parental</app>."
#. (itstool) path: page/p
#: C/creating-a-child-user.page:17
msgid ""
"To create a new child user, see <link type=\"guide\" xref=\"help:gnome-help/"
"user-add\">Add a new user account</link>. As soon as the new user is "
"created, it will appear in the <app>Parental Controls</app> window so that "
"its parental controls settings can be configured."
msgstr ""
"Para criar um novo usuário filho, consulte <link type=\"guide\" xref=\"help:"
"gnome-help/user-add\">Adicionando uma nova conta de usuário</link>. Assim "
"que o novo usuário for criado, ele aparecerá na janela do <app>Controle "
"parental</app> para que suas configurações de controle parental possam ser "
"definidas."
#. (itstool) path: credit/name
#: C/index.page:6
msgid "Philip Withnall"
msgstr "Philip Withnall"
#. (itstool) path: credit/years
#: C/index.page:8
msgid "2020"
msgstr "2020"
#. (itstool) path: page/title
#: C/index.page:12
msgid "Parental Controls Help"
msgstr "Ajuda do Controle parental"
#. (itstool) path: section/title
#: C/index.page:15
msgid "Introduction &amp; Setup"
msgstr "Introdução &amp; configuração"
#. (itstool) path: section/title
#: C/index.page:19
msgid "Controls to Apply"
msgstr "Controles para aplicar"
#. (itstool) path: info/desc
#: C/internet.page:6
msgid "Restricting a child users access to the internet."
msgstr "Restringindo o acesso do usuário filho à Internet."
#. (itstool) path: page/title
#: C/internet.page:9
msgid "Restricting Access to the Internet"
msgstr "Restringindo acesso à Internet"
#. (itstool) path: page/p
#: C/internet.page:11
msgid ""
"You can restrict a users access to the internet. This will prevent them "
"using a web browser, but it will not prevent them using the internet (in "
"potentially more limited forms) through other applications. For example, it "
"will not prevent access to e-mail accounts using <app>Evolution</app>, and "
"it will not prevent software updates being downloaded and applied."
msgstr ""
"Você pode restringir o acesso de um usuário à Internet. Isso os impedirá de "
"usar um navegador web, mas não os impedirá de usar a Internet (em formas "
"potencialmente mais limitadas) por meio de outros aplicativos. Por exemplo, "
"não impedirá o acesso a contas de e-mail usando o <app>Evolution</app>, nem "
"impedirá o download e aplicação de atualizações de software."
#. (itstool) path: page/p
#: C/internet.page:17
msgid "To restrict a users access to the internet:"
msgstr "Para restringir o acesso de um usuário à Internet:"
#. (itstool) path: item/p
#: C/internet.page:19 C/restricting-applications.page:20
#: C/software-installation.page:27 C/software-installation.page:64
msgid "Open the <app>Parental Controls</app> application."
msgstr "Abra o aplicativo <app>Controle parental</app>."
#. (itstool) path: item/p
#: C/internet.page:20 C/restricting-applications.page:21
#: C/software-installation.page:28 C/software-installation.page:65
msgid "Select the user in the tabs at the top."
msgstr "Selecione o usuário nas abas no topo."
#. (itstool) path: item/p
#: C/internet.page:21
msgid ""
"Enable the <gui style=\"checkbox\">Restrict Web Browsers</gui> checkbox."
msgstr ""
"Habilite a caixa de seleção <gui style=\"checkbox\">Restringir navegadores "
"web</gui>."
#. (itstool) path: info/desc
#: C/introduction.page:6
msgid ""
"Overview of parental controls and the <app>Parental Controls</app> "
"application."
msgstr ""
"Visão geral dos controles parentais e o aplicativo <app>Controle parental</"
"app>."
#. (itstool) path: page/title
#: C/introduction.page:10
msgid "Introduction to Parental Controls"
msgstr "Introdução ao Controle parental"
#. (itstool) path: page/p
#: C/introduction.page:12
msgid ""
"Parental controls are a way to restrict what non-administrator accounts can "
"do on the computer, with the aim of allowing parents to restrict what their "
"children can do when using the computer unsupervised or under limited "
"supervision."
msgstr ""
"O controle parental é uma maneira de restringir o que as contas não-"
"administradoras podem fazer no computador, com o objetivo de permitir que os "
"pais restrinjam o que seus filhos podem fazer ao usar o computador sem "
"supervisão ou sob supervisão limitada."
#. (itstool) path: page/p
#: C/introduction.page:16
msgid ""
"This functionality can be used in other situations ­ such as other carer/"
"caree relationships but is labelled as parental controls so that its "
"easy to find."
msgstr ""
"Essa funcionalidade pode ser usada em outras situações, como outras relações "
"de tutor/tutelado, mas é rotulada como “controle parental”, para facilitar a "
"localização."
#. (itstool) path: page/p
#: C/introduction.page:19
msgid ""
"The parental controls for any user can be queried and set using the "
"<app>Parental Controls</app> application. This lists the non-administrator "
"accounts in tabs along its top bar, and shows their current parental "
"controls settings below. Changes to the parental controls apply immediately."
msgstr ""
"O controle parental para qualquer usuário pode ser consultado e definido "
"usando o aplicativo <app>Controle parental</app>. Isso lista as contas de "
"não administrador nas abas na barra superior e mostra as configurações "
"atuais do controle parental abaixo. Alterações no controle parental se "
"aplicam imediatamente."
#. (itstool) path: page/p
#: C/introduction.page:23
msgid ""
"Restrictions on using the computer can only be applied to non-administrator "
"accounts. The parental controls settings for a user can only be changed by "
"an administrator, although the administrator can do so from the users "
"account by entering their password when prompted by the <app>Parental "
"Controls</app> application."
msgstr ""
"Restrições ao uso do computador podem ser aplicadas apenas a contas de não "
"administrador. As configurações de controle parental de um usuário só podem "
"ser alteradas por um administrador, embora o administrador possa fazer isso "
"da conta do usuário digitando sua senha quando solicitado pelo aplicativo "
"<app>Controle parental</app>."
#. (itstool) path: p/link
#: C/legal.xml:4
msgid "Creative Commons Attribution-ShareAlike 3.0 Unported License"
msgstr "Creative Commons Atribuição Compartilhada Igual 3.0 Não Adaptada"
#. (itstool) path: license/p
#: C/legal.xml:3
msgid "This work is licensed under a <_:link-1/>."
msgstr "Essa obra está licenciada sob uma licença <_:link-1/>."
#. (itstool) path: info/desc
#: C/restricting-applications.page:6
msgid "Restricting a child user from running already-installed applications."
msgstr "Restringindo um usuário filho de executar aplicativos já instalados."
#. (itstool) path: page/title
#: C/restricting-applications.page:9
msgid "Restricting Access to Installed Applications"
msgstr "Restringindo o acesso aos aplicativos instalados"
#. (itstool) path: page/p
#: C/restricting-applications.page:11
msgid ""
"You can prevent a user from running specific applications which are already "
"installed on the computer. This could be useful if other users need those "
"applications but they are not appropriate for a child."
msgstr ""
"Você pode impedir que um usuário execute aplicativos específicos que já "
"estão instalados no computador. Isso pode ser útil se outros usuários "
"precisarem desses aplicativos, mas não forem apropriados para uma criança."
#. (itstool) path: page/p
#: C/restricting-applications.page:14
msgid ""
"When installing additional software, you should consider whether that needs "
"to be restricted for some users — newly installed software is usable by all "
"users by default."
msgstr ""
"Ao instalar software adicional, considere se isso precisa ser restrito para "
"alguns usuários — o software recém-instalado é utilizável por todos os "
"usuários por padrão.­­"
#. (itstool) path: page/p
#: C/restricting-applications.page:18
msgid "To restrict a users access to a specific application:"
msgstr "Para restringir o acesso de um usuário a um aplicativo específico:"
#. (itstool) path: item/p
#: C/restricting-applications.page:22
msgid "Press the <gui style=\"button\">Restrict Applications</gui> button."
msgstr "Pressione o botão <gui style=\"button\">Restringir aplicativos</gui>. "
#. (itstool) path: item/p
#: C/restricting-applications.page:23
msgid ""
"Enable the switch in the row for each application you would like to restrict "
"the user from accessing."
msgstr ""
"Habilite a opção na linha de cada aplicativo que você gostaria de restringir "
"o acesso do usuário."
#. (itstool) path: item/p
#: C/restricting-applications.page:24
msgid "Close the <gui>Restrict Applications</gui> window."
msgstr "Feche a janela <gui>Restringir aplicativos</gui>."
#. (itstool) path: page/p
#: C/restricting-applications.page:27
msgid ""
"Restricting access to specific applications is often used in conjunction "
"with <link xref=\"software-installation\"/> to prevent a user from "
"installing additional software which has not been vetted."
msgstr ""
"A restrição de acesso a aplicativos específicos é frequentemente usada em "
"conjunto com <link xref=\"software-installation\"/> para impedir que um "
"usuário instale um software adicional que ainda não foi verificado."
#. (itstool) path: info/desc
#: C/software-installation.page:6
msgid ""
"Restricting the software a child user can install, or preventing them "
"installing additional software entirely."
msgstr ""
"Restringindo o software que um usuário filho pode instalar ou impedindo-o de "
"instalar completamente software adicional."
#. (itstool) path: page/title
#: C/software-installation.page:9
msgid "Restricting Software Installation"
msgstr "Restringindo instalação de software"
#. (itstool) path: page/p
#: C/software-installation.page:11
msgid ""
"You can prevent a user from installing additional software, either for the "
"entire system, or just for themselves. They will still be able to search for "
"new software to install, but will need an administrator to authorize the "
"installation when they try to install an application."
msgstr ""
"Você pode impedir que um usuário instale software adicional, seja para todo "
"o sistema ou apenas para si. Eles ainda poderão procurar um novo software "
"para instalar, mas precisarão de um administrador para autorizar a "
"instalação quando tentarem instalar um aplicativo."
#. (itstool) path: page/p
#: C/software-installation.page:16
msgid ""
"Additionally, you can restrict which software a user can browse or search "
"for in the <app>Software</app> catalog by age categories."
msgstr ""
"Além disso, você pode restringir o software que um usuário pode procurar ou "
"procurar no catálogo <app>Software</app> por categorias de idade."
#. (itstool) path: page/p
#: C/software-installation.page:19
msgid ""
"To prevent a user from running an application which has already been "
"installed, see <link xref=\"restricting-applications\"/>."
msgstr ""
"Para impedir que um usuário execute um aplicativo que já foi instalado, "
"consulte <link xref=\"restricting-applications\"/>."
#. (itstool) path: section/title
#: C/software-installation.page:23
msgid "Preventing Software Installation"
msgstr "Impedindo a instalação do software"
#. (itstool) path: section/p
#: C/software-installation.page:25
msgid "To prevent a user from installing additional software:"
msgstr "Para impedir que um usuário instale software adicional:"
#. (itstool) path: item/p
#: C/software-installation.page:29
msgid ""
"Enable the <gui style=\"checkbox\">Restrict Application Installation</gui> "
"checkbox."
msgstr ""
"Marque a caixa de seleção <gui style=\"checkbox\">Restringir instalação de "
"aplicativo</gui>."
#. (itstool) path: item/p
#: C/software-installation.page:30
msgid ""
"Or enable the <gui style=\"checkbox\">Restrict Application Installation for "
"Others</gui> checkbox."
msgstr ""
"Ou habilite a caixa de seleção <gui style=\"checkbox\">Restringir instalação "
"de aplicativo para outros</gui>."
#. (itstool) path: section/p
#: C/software-installation.page:33
msgid ""
"The <gui style=\"checkbox\">Restrict Application Installation for Others</"
"gui> checkbox allows the user to install additional software for themselves, "
"but prevents that software from being made available to other users. It "
"could be used, for example, if there were two child users, one of whom is "
"mature enough to be allowed to install additional software, but the other "
"isnt — enabling <gui style=\"checkbox\">Restrict Application Installation "
"for Others</gui> would prevent the more mature child from installing "
"applications which are inappropriate for the other child and making them "
"available to the other child."
msgstr ""
"A caixa de seleção <gui style=\"checkbox\">Restringir instalação de "
"aplicativo para outros</gui> permite ao usuário instalar software adicional "
"para eles mesmos, mas impede que esse software seja disponibilizado para "
"outros usuários. Poderia ser usado, por exemplo, se houvesse dois usuários "
"filhos, um deles maduro o suficiente para poder instalar software adicional, "
"mas o outro não — habilitando <gui style=\"checkbox\">Restringir a "
"instalação de aplicativo para outros</gui> impediria a criança mais madura "
"de instalar aplicativos inadequados para a outra criança e disponibilizá-los "
"para a outra criança."
#. (itstool) path: section/title
#: C/software-installation.page:45
msgid "Restricting Software Installation by Age"
msgstr "Restringindo instalação de software por idade"
#. (itstool) path: section/p
#: C/software-installation.page:47
msgid ""
"Applications in the <app>Software</app> catalog have information about "
"content they contain which might be inappropriate for some ages — for "
"example, various forms of violence, unmoderated chat with other people on "
"the internet, or the possibility of spending money."
msgstr ""
"Os aplicativos no catálogo <app> Software </app> contêm informações sobre o "
"conteúdo que podem ser inadequadas por algumas idades — por exemplo, várias "
"formas de violência, bate-papo moderado com outras pessoas na Internet ou a "
"possibilidade de gastar dinheiro."
#. (itstool) path: section/p
#: C/software-installation.page:51
msgid ""
"For each application, this information is summarized as the minimum age "
"child it is typically suitable to be used by — for example, “suitable for "
"ages 7+”. These age ratings are presented in region-specific schemes which "
"can be compared with the ratings schemes used for films and games."
msgstr ""
"Para cada aplicativo, essas informações são resumidas como a criança com "
"idade mínima em que normalmente é adequada para ser usada por — por exemplo, "
"“adequada para idades acima de 7 anos”. Essas classificações etárias são "
"apresentadas em esquemas de região específica que podem ser comparados com "
"os esquemas de classificação usados para filmes e jogos."
#. (itstool) path: section/p
#: C/software-installation.page:55
msgid ""
"The applications shown to a user in the <app>Software</app> catalog can be "
"filtered by their age suitability. Applications which are not suitable for "
"the user will be hidden, and will not be installable by that user. They will "
"be installable by other users (if their age suitability is set high enough)."
msgstr ""
"Os aplicativos mostrados a um usuário no catálogo <app>Software</app> podem "
"ser filtrados de acordo com a sua idade. Os aplicativos que não são "
"adequados para o usuário serão ocultados e não serão instaláveis por esse "
"usuário. Eles serão instaláveis por outros usuários (se a adequação à idade "
"for alta o suficiente)."
#. (itstool) path: section/p
#: C/software-installation.page:61
msgid ""
"To filter the applications seen by a user in the <app>Software</app> catalog "
"to only those suitable for a certain age:"
msgstr ""
"Para filtrar os aplicativos vistos por um usuário no catálogo <app>Software</"
"app> apenas para aqueles adequados para uma certa idade:"
#. (itstool) path: item/p
#: C/software-installation.page:66
msgid ""
"In the <gui>Application Suitability</gui> list, select the age which "
"applications should be suitable for."
msgstr ""
"Na lista <gui>Adequação do aplicativo</gui>, selecione a idade para a qual "
"os aplicativos devem ser adequados."
#. (itstool) path: note/p
#: C/software-installation.page:70
msgid ""
"The users actual age is not stored, so the <gui>Application Suitability</"
"gui> is not automatically updated over time as the child grows older. You "
"must periodically re-assess the appropriate <gui>Application Suitability</"
"gui> for each user."
msgstr ""
"A idade real do usuário não é armazenada, portanto, a <gui>Adequação do "
"aplicativo</gui> não é atualizada automaticamente ao longo do tempo à medida "
"que a criança cresce. Você deve reavaliar periodicamente a <gui>Adequação do "
"aplicativo</gui> para cada usuário."

View File

@ -1,435 +0,0 @@
# Russian translation for malcontent.
# Copyright (C) 2022 malcontent's COPYRIGHT HOLDER
# This file is distributed under the same license as the malcontent package.
# Sergej A. <sw@atrus.ru>, 2022.
#
msgid ""
msgstr ""
"Project-Id-Version: malcontent main\n"
"POT-Creation-Date: 2022-06-04 15:25+0000\n"
"PO-Revision-Date: 2022-06-05 11:41+1000\n"
"Last-Translator: Ser82-png <sw@atrus.ru>\n"
"Language-Team: Russian <gnome-cyr@gnome.org>\n"
"Language: ru\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"X-Generator: Poedit 2.3\n"
#. Put one translator per line, in the form NAME <EMAIL>, YEAR1, YEAR2
msgctxt "_"
msgid "translator-credits"
msgstr "Ser82-png <sw@atrus.ru>, 2022"
#. (itstool) path: info/desc
#: C/creating-a-child-user.page:6
msgid "Creating a child user on the computer."
msgstr "Создание записи пользователя-ребёнка на компьютере."
#. (itstool) path: page/title
#: C/creating-a-child-user.page:9
msgid "Creating a Child User"
msgstr "Создание записи пользователя-ребёнка"
#. (itstool) path: page/p
#: C/creating-a-child-user.page:11
msgid ""
"Parental controls can only be applied to non-administrator accounts. Such an "
"account may have been created when the computer was initially set up. If "
"not, a new child user may be created from the <app>Parental Controls</app> "
"application if no child users already exist; and otherwise may be created "
"from the <app>Control Center</app>."
msgstr ""
"Родительский контроль можно применять только к учётным записям без "
"административных прав. Такая учётная запись могла быть создана при "
"первоначальной настройке системы. Если этого не было сделано, можно создать "
"новую детскую учётную запись с помощью приложения <app>Родительский "
"контроль</app>. Кроме того, такую учётную запись можно создать с помощью "
"<app>Центра управления</app>."
#. (itstool) path: page/p
#: C/creating-a-child-user.page:17
msgid ""
"To create a new child user, see <link type=\"guide\" xref=\"help:gnome-help/"
"user-add\">Add a new user account</link>. As soon as the new user is "
"created, it will appear in the <app>Parental Controls</app> window so that "
"its parental controls settings can be configured."
msgstr ""
"Чтобы создать нового пользователя ребёнка, смотрите <link type=\"guide\" "
"xref=\"help:gnome-help/user-add\">Добавление новой учётной записи "
"пользователя</link>. Как только новый пользователь будет создан, он появится "
"в окне <app>Родительский контроль</app>, чтобы можно было для него настроить "
"параметры родительского контроля."
#. (itstool) path: credit/name
#: C/index.page:6
msgid "Philip Withnall"
msgstr "Philip Withnall"
#. (itstool) path: credit/years
#: C/index.page:8
msgid "2020"
msgstr "2020"
#. (itstool) path: page/title
#: C/index.page:12
msgid "Parental Controls Help"
msgstr "Справка по родительскому контролю"
#. (itstool) path: section/title
#: C/index.page:15
msgid "Introduction &amp; Setup"
msgstr "Введение &amp; Настройка"
#. (itstool) path: section/title
#: C/index.page:19
msgid "Controls to Apply"
msgstr "Средства контроля, которые можно применить"
#. (itstool) path: info/desc
#: C/internet.page:6
msgid "Restricting a child users access to the internet."
msgstr "Ограничение доступа ребёнка к интернету."
#. (itstool) path: page/title
#: C/internet.page:9
msgid "Restricting Access to the Internet"
msgstr "Ограничение доступа к интернету"
#. (itstool) path: page/p
#: C/internet.page:11
msgid ""
"You can restrict a users access to the internet. This will prevent them "
"using a web browser, but it will not prevent them using the internet (in "
"potentially more limited forms) through other applications. For example, it "
"will not prevent access to e-mail accounts using <app>Evolution</app>, and "
"it will not prevent software updates being downloaded and applied."
msgstr ""
"Вы можете ограничить доступ пользователя к интернету. Этим способом можно "
"запретить пользователю использовать веб-браузер, но доступ к сети интернет "
"будет сохранён (в потенциально более ограниченной форме) с помощью других "
"приложений. Например, пользователь будет иметь доступ к учётным записям "
"электронной почты с помощью <app>Evolution</app>, а также не будет "
"ограничений для загрузки и обновления программного обеспечения."
#. (itstool) path: page/p
#: C/internet.page:17
msgid "To restrict a users access to the internet:"
msgstr "Чтобы ограничить доступ пользователя к интернету:"
#. (itstool) path: item/p
#: C/internet.page:19 C/restricting-applications.page:20
#: C/software-installation.page:28 C/software-installation.page:54
msgid "Open the <app>Parental Controls</app> application."
msgstr "Откройте приложение <app>Родительский контроль</app>."
#. (itstool) path: item/p
#: C/internet.page:20 C/restricting-applications.page:21
#: C/software-installation.page:29 C/software-installation.page:55
msgid "Select the user in the tabs at the top."
msgstr "Выберите пользователя во вкладках верхней части окна."
#. (itstool) path: item/p
#: C/internet.page:21
msgid ""
"Enable the <gui style=\"checkbox\">Restrict Web Browsers</gui> checkbox."
msgstr ""
"Установите флажок <gui style=\"checkbox\">Ограничить доступ к Веб-браузерам</"
"gui>."
#. (itstool) path: info/desc
#: C/introduction.page:6
msgid ""
"Overview of parental controls, the <app>Parental Controls</app> application "
"and its use in other situations where access restrictions are needed on a "
"user."
msgstr ""
"Обзор родительского контроля, приложения <app>Родительский контроль</app> и "
"его использования в различных ситуациях, когда необходимо ограничить доступ "
"для пользователя."
#. (itstool) path: page/title
#: C/introduction.page:12
msgid "Introduction to Parental Controls"
msgstr "Введение в родительский контроль"
#. (itstool) path: page/p
#: C/introduction.page:14
msgid ""
"Parental controls are a way to restrict what non-administrator accounts can "
"do on the computer, with the aim of allowing parents to restrict what their "
"children can do when using the computer unsupervised or under limited "
"supervision."
msgstr ""
"Родительский контроль — это способ ограничить перечень возможных действий на "
"компьютере пользователям не имеющим учётных записей администратора. Целью "
"является ограничение родителями действий детей при работе на компьютере, "
"находящихся без присмотра или под ограниченным присмотром."
#. (itstool) path: page/p
#: C/introduction.page:18
msgid ""
"This functionality can be used in other situations ­ such as other carer/"
"caree relationships but is labelled as parental controls so that its "
"easy to find, as thats what most people will be looking for."
msgstr ""
"Эту функцию также можно использовать и в других ситуациях, например, в "
"отношениях «сиделка/пациент», но она помечена как «родительский контроль» "
"только для удобства поиска, поскольку именно это будут искать большинство "
"пользователей."
#. (itstool) path: page/p
#: C/introduction.page:21
msgid ""
"The parental controls for any user can be queried and set using the "
"<app>Parental Controls</app> application. This lists the non-administrator "
"accounts in tabs along its top bar, and shows their current parental "
"controls settings below. Changes to the parental controls apply immediately."
msgstr ""
"Для любого пользователя можно просмотреть и установить родительский контроль "
"с помощью приложения <app>Родительский контроль</app>. В окне программы на "
"вкладках вдоль верхней панели перечислены учётные записи без прав "
"администратора, а ниже показаны их текущие настройки родительского контроля. "
"Изменения в родительском контроле вступают в силу немедленно."
#. (itstool) path: page/p
#: C/introduction.page:25
msgid ""
"Restrictions on using the computer can only be applied to non-administrator "
"accounts. The parental controls settings for a user can only be changed by "
"an administrator, although the administrator can do so from the users "
"account by entering their password when prompted by the <app>Parental "
"Controls</app> application."
msgstr ""
"Ограничения на использование компьютера могут применяться только к учётным "
"записям без прав администратора. Настройки родительского контроля для "
"пользователя может изменить только администратор, хотя он может сделать это "
"из учётной записи пользователя, введя свой пароль при запросе приложения "
"<app>Родительский контроль</app>."
#. (itstool) path: p/link
#: C/legal.xml:4
msgid "Creative Commons Attribution-ShareAlike 3.0 Unported License"
msgstr "Creative Commons Attribution-ShareAlike 3.0 Unported License"
#. (itstool) path: license/p
#: C/legal.xml:3
msgid "This work is licensed under a <_:link-1/>."
msgstr "Данная работа находится под лицензией <_:link-1/>."
#. (itstool) path: info/desc
#: C/restricting-applications.page:6
msgid "Restricting a child user from running already-installed applications."
msgstr "Запретить ребёнку запускать уже установленные приложения."
#. (itstool) path: page/title
#: C/restricting-applications.page:9
msgid "Restricting Access to Installed Applications"
msgstr "Ограничение доступа к установленным приложениям"
#. (itstool) path: page/p
#: C/restricting-applications.page:11
msgid ""
"You can prevent a user from running specific applications which are already "
"installed on the computer. This could be useful if other users need those "
"applications but they are not appropriate for a child."
msgstr ""
"Вы можете запретить пользователю запускать определённые приложения, уже "
"установленные на компьютере. Это может быть полезно, если эти приложения "
"необходимы другим пользователям, но не подходят для ребёнка."
#. (itstool) path: page/p
#: C/restricting-applications.page:14
msgid ""
"When installing additional software, you should consider whether that needs "
"to be restricted for some users — newly installed software is usable by all "
"users by default."
msgstr ""
"При установке дополнительного программного обеспечения вам следует "
"учитывать, нужно ли ограничивать доступ для некоторых пользователей — новое "
"установленное программное обеспечение по умолчанию может использоваться "
"всеми пользователями."
#. (itstool) path: page/p
#: C/restricting-applications.page:18
msgid "To restrict a users access to a specific application:"
msgstr "Чтобы ограничить доступ пользователя к определенному приложению:"
#. (itstool) path: item/p
#: C/restricting-applications.page:22
msgid "Press the <gui style=\"button\">Restrict Applications</gui> button."
msgstr ""
"Нажмите кнопку <gui style=\"button\">Ограничить доступ к приложениям</gui>."
#. (itstool) path: item/p
#: C/restricting-applications.page:23
msgid ""
"Enable the switch in the row for each application you would like to restrict "
"the user from accessing."
msgstr ""
"Измените положение переключателя в строке для каждого приложения, к которому "
"вы хотите ограничить доступ пользователя."
#. (itstool) path: item/p
#: C/restricting-applications.page:24
msgid "Close the <gui>Restrict Applications</gui> window."
msgstr "Закройте окно <gui>Ограничить доступ к приложениям</gui>."
#. (itstool) path: page/p
#: C/restricting-applications.page:27
msgid ""
"Restricting access to specific applications is often used in conjunction "
"with <link xref=\"software-installation\"/> to prevent a user from "
"installing additional software which has not been vetted."
msgstr ""
"Ограничение доступа к определённым приложениям часто используется в "
"сочетании с <link xref=\"software-installation\"/>, чтобы запретить "
"пользователю устанавливать непроверенное программное обеспечение."
#. (itstool) path: info/desc
#: C/software-installation.page:6
msgid ""
"Restricting the software a child user can install, or preventing them "
"installing additional software entirely."
msgstr ""
"Ограничение перечная программного обеспечения, которое ребёнок может "
"установить, или полный запрет на его установку."
#. (itstool) path: page/title
#: C/software-installation.page:9
msgid "Restricting Software Installation"
msgstr "Ограничения на установку программного обеспечения по возрасту"
#. (itstool) path: page/p
#: C/software-installation.page:11
msgid ""
"You can prevent a user from installing additional software on the system. "
"They will still be able to search for new software to install, but will need "
"an administrator to authorize the installation when they try to install an "
"application. This applies whether they are trying to install the application "
"system-wide (for all users) or just for themselves."
msgstr ""
"Вы можете запретить пользователям устанавливать дополнительное программное "
"обеспечение. Хотя они по-прежнему смогут искать программное обеспечение для "
"установки, но при попытке установить приложение им потребуется разрешение "
"администратора. Это не зависит от того, пытаются ли установить приложение в "
"масштабах всей системы (для всех пользователей) или только для себя."
#. (itstool) path: page/p
#: C/software-installation.page:17
msgid ""
"Additionally, you can restrict which software a user can browse or search "
"for in the <app>Software</app> catalog by age categories."
msgstr ""
"Кроме того, вы можете ограничить по возрастному критерию, какое программное "
"обеспечение пользователь может просматривать или искать в <app>Центре "
"приложений</app>."
#. (itstool) path: page/p
#: C/software-installation.page:20
msgid ""
"To prevent a user from running an application which has already been "
"installed, see <link xref=\"restricting-applications\"/>."
msgstr ""
"Чтобы запретить пользователю запускать уже установленное приложение, "
"смотрите раздел <link xref=\"restricting-applications\"/>."
#. (itstool) path: section/title
#: C/software-installation.page:24
msgid "Preventing Software Installation"
msgstr "Предотвращение установки программного обеспечения"
#. (itstool) path: section/p
#: C/software-installation.page:26
msgid "To prevent a user from installing additional software:"
msgstr ""
"Чтобы запретить пользователю устанавливать дополнительное программное "
"обеспечение:"
#. (itstool) path: item/p
#: C/software-installation.page:30
msgid ""
"Enable the <gui style=\"checkbox\">Restrict Application Installation</gui> "
"checkbox."
msgstr ""
"Установите флажок <gui style=\"checkbox\">Ограничить установку приложений</"
"gui>."
#. (itstool) path: section/title
#: C/software-installation.page:35
msgid "Restricting Software Installation by Age"
msgstr "Ограничения на установку программного обеспечения по возрасту"
#. (itstool) path: section/p
#: C/software-installation.page:37
msgid ""
"Applications in the <app>Software</app> catalog have information about "
"content they contain which might be inappropriate for some ages — for "
"example, various forms of violence, unmoderated chat with other people on "
"the internet, or the possibility of spending money."
msgstr ""
"В описании к приложениям из каталога <app>Центра приложений</app> содержатся "
"сведения, которые могут быть неприемлемыми для определённых возрастных групп "
"— например, различные формы насилия, неограниченные возможности по общению с "
"другими людьми в интернете или возможность расходовать деньги."
#. (itstool) path: section/p
#: C/software-installation.page:41
msgid ""
"For each application, this information is summarized as the minimum age "
"child it is typically suitable to be used by — for example, “suitable for "
"ages 7+”. These age ratings are presented in region-specific schemes which "
"can be compared with the ratings schemes used for films and games."
msgstr ""
"Для каждого приложения в этих сведениях содержится информация о минимальном "
"возрасте ребенка, с которого его можно допустить к использованию данного "
"приложения. Например, «подходит для возраста 7+». Эти возрастные оценки "
"представлены в виде специфических для региона схем, сопоставимых со схемами "
"рейтингов для фильмов и видеоигр."
#. (itstool) path: section/p
#: C/software-installation.page:45
msgid ""
"The applications shown to a user in the <app>Software</app> catalog can be "
"filtered by their age suitability. Applications which are not suitable for "
"the user will be hidden, and will not be installable by that user. They will "
"be installable by other users (if their age suitability is set high enough)."
msgstr ""
"Приложения, показанные в каталоге <app>Центра приложений</app>, могут быть "
"отфильтрованы по возрастным критериям. Приложения, которые не подходят для "
"конкретного пользователя, будут скрыты и не смогут быть установлены. Но для "
"других пользователей они будут доступны (если пользователи будут "
"соответствовать установленным возрастным критериям)."
#. (itstool) path: section/p
#: C/software-installation.page:51
msgid ""
"To filter the applications seen by a user in the <app>Software</app> catalog "
"to only those suitable for a certain age:"
msgstr ""
"Чтобы отфильтровать приложения, представленные пользователю в каталоге "
"<app>Центра приложений</app>, по возрастному критерию:"
#. (itstool) path: item/p
#: C/software-installation.page:56
msgid ""
"In the <gui>Application Suitability</gui> list, select the age which "
"applications should be suitable for."
msgstr ""
"В списке <gui>Пригодность приложений</gui> выберите возраст, для которого "
"должны быть подходящими приложения."
#. (itstool) path: note/p
#: C/software-installation.page:60
msgid ""
"The users actual age is not stored, so the <gui>Application Suitability</"
"gui> is not automatically updated over time as the child grows older. You "
"must periodically re-assess the appropriate <gui>Application Suitability</"
"gui> for each user."
msgstr ""
"Возраст пользователя в системе не сохраняется, поэтому <gui>Пригодность "
"приложений</gui> по мере взросления ребёнка автоматически не обновляется. Вы "
"должны периодически пересматривать соответствующую для каждого пользователя "
"<gui>Пригодность приложений</gui>."

View File

@ -1,455 +0,0 @@
# Swedish translation for malcontent.
# Copyright (C) 2020 malcontent's COPYRIGHT HOLDER
# This file is distributed under the same license as the malcontent package.
# Anders Jonsson <anders.jonsson@norsjovallen.se>, 2020.
#
msgid ""
msgstr ""
"Project-Id-Version: malcontent master\n"
"POT-Creation-Date: 2020-12-08 15:28+0000\n"
"PO-Revision-Date: 2020-12-17 18:25+0100\n"
"Last-Translator: Anders Jonsson <anders.jonsson@norsjovallen.se>\n"
"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
"Language: sv\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 2.4.2\n"
#. Put one translator per line, in the form NAME <EMAIL>, YEAR1, YEAR2
msgctxt "_"
msgid "translator-credits"
msgstr "Anders Jonsson <anders.jonsson@norsjovallen.se>"
#. (itstool) path: info/desc
#: C/creating-a-child-user.page:6
msgid "Creating a child user on the computer."
msgstr "Skapa en barnanvändare på datorn."
#. (itstool) path: page/title
#: C/creating-a-child-user.page:9
msgid "Creating a Child User"
msgstr "Skapa en barnanvändare"
#. (itstool) path: page/p
#: C/creating-a-child-user.page:11
msgid ""
"Parental controls can only be applied to non-administrator accounts. Such an "
"account may have been created when the computer was initially set up. If "
"not, a new child user may be created from the <app>Parental Controls</app> "
"application if no child users already exist; and otherwise may be created "
"from the <app>Control Center</app>."
msgstr ""
"Föräldrakontroller kan endast tillämpas på konton som inte är "
"administratörer. Ett sådant konto kan ha skapats när datorn ursprungligen "
"konfigurerades. Om inte så kan en ny barnanvändare skapas från programmet "
"<app>Föräldrakontroller</app> om det inte redan finns några barnanvändare. "
"Annars kan de skapas från <app>Kontrollpanel</app>."
#. (itstool) path: page/p
#: C/creating-a-child-user.page:17
msgid ""
"To create a new child user, see <link type=\"guide\" xref=\"help:gnome-help/"
"user-add\">Add a new user account</link>. As soon as the new user is "
"created, it will appear in the <app>Parental Controls</app> window so that "
"its parental controls settings can be configured."
msgstr ""
"För att skapa en ny barnanvändare, se <link type=\"guide\" xref=\"help:gnome-"
"help/user-add\">Lägg till ett nytt användarkonto</link>. Så snart användaren "
"har skapats kommer den dyka upp i <app>Föräldrakontroller</app>-fönstret så "
"att dess inställningar för föräldrakontroll kan konfigureras."
#. (itstool) path: credit/name
#: C/index.page:6
msgid "Philip Withnall"
msgstr "Philip Withnall"
#. (itstool) path: credit/years
#: C/index.page:8
msgid "2020"
msgstr "2020"
#. (itstool) path: page/title
#: C/index.page:12
msgid "Parental Controls Help"
msgstr "Hjälp för Föräldrakontroller"
#. (itstool) path: section/title
#: C/index.page:15
msgid "Introduction &amp; Setup"
msgstr "Introduktion &amp; konfiguration"
#. (itstool) path: section/title
#: C/index.page:19
msgid "Controls to Apply"
msgstr "Kontroller att tillämpa"
#. (itstool) path: info/desc
#: C/internet.page:6
msgid "Restricting a child users access to the internet."
msgstr "Begränsa en barnanvändares åtkomst till internet."
#. (itstool) path: page/title
#: C/internet.page:9
msgid "Restricting Access to the Internet"
msgstr "Begränsa åtkomst till internet"
#. (itstool) path: page/p
#: C/internet.page:11
msgid ""
"You can restrict a users access to the internet. This will prevent them "
"using a web browser, but it will not prevent them using the internet (in "
"potentially more limited forms) through other applications. For example, it "
"will not prevent access to e-mail accounts using <app>Evolution</app>, and "
"it will not prevent software updates being downloaded and applied."
msgstr ""
"Du kan begränsa en användares åtkomst till internet. Detta kommer att "
"förhindra dem från att använda en webbläsare, men det kommer inte att hindra "
"dem från att använda internet (potentiellt i mer begränsade former) genom "
"andra program. Det kommer till exempel inte förhindra åtkomst till e-"
"postkonton genom <app>Evolution</app>, och kommer inte förhindra att "
"programvaruuppdateringar hämtas och tillämpas."
#. (itstool) path: page/p
#: C/internet.page:17
msgid "To restrict a users access to the internet:"
msgstr "För att begränsa en användares åtkomst till internet:"
#. (itstool) path: item/p
#: C/internet.page:19 C/restricting-applications.page:20
#: C/software-installation.page:28 C/software-installation.page:54
msgid "Open the <app>Parental Controls</app> application."
msgstr "Öppna programmet <app>Föräldrakontroller</app>."
#. (itstool) path: item/p
#: C/internet.page:20 C/restricting-applications.page:21
#: C/software-installation.page:29 C/software-installation.page:55
msgid "Select the user in the tabs at the top."
msgstr "Välj användaren i flikarna högst upp."
#. (itstool) path: item/p
#: C/internet.page:21
msgid ""
"Enable the <gui style=\"checkbox\">Restrict Web Browsers</gui> checkbox."
msgstr "Aktivera kryssrutan <gui style=\"checkbox\">Begränsa webbläsare</gui>."
#. (itstool) path: info/desc
#: C/introduction.page:6
msgid ""
"Overview of parental controls, the <app>Parental Controls</app> application "
"and its use in other situations where access restrictions are needed on a "
"user."
msgstr ""
"Översikt över föräldrakontroller, programmet <app>Föräldrakontroller</app> "
"och dess användning i andra situationer där åtkomstbegränsningar behövs för "
"en användare."
#. (itstool) path: page/title
#: C/introduction.page:12
msgid "Introduction to Parental Controls"
msgstr "Introduktion till Föräldrakontroller"
#. (itstool) path: page/p
#: C/introduction.page:14
msgid ""
"Parental controls are a way to restrict what non-administrator accounts can "
"do on the computer, with the aim of allowing parents to restrict what their "
"children can do when using the computer unsupervised or under limited "
"supervision."
msgstr ""
"Föräldrakontroller är ett sätt att begränsa vad icke-administratörskonton "
"kan göra på datorn, med målet att låta föräldrar begränsa vad deras barn kan "
"göra när de använder datorn utan översikt eller med begränsad översikt."
#. (itstool) path: page/p
#: C/introduction.page:18
msgid ""
"This functionality can be used in other situations ­ such as other carer/"
"caree relationships but is labelled as parental controls so that its "
"easy to find, as thats what most people will be looking for."
msgstr ""
"Denna funktionalitet kan användas i andra situationer som i andra "
"relationer där ena parten har ansvar för den andra men kallas "
"”föräldrakontroller” för att vara lätt att hitta, då det är vad de flesta "
"kommer att söka efter."
#. (itstool) path: page/p
#: C/introduction.page:21
msgid ""
"The parental controls for any user can be queried and set using the "
"<app>Parental Controls</app> application. This lists the non-administrator "
"accounts in tabs along its top bar, and shows their current parental "
"controls settings below. Changes to the parental controls apply immediately."
msgstr ""
"Föräldrakontrollerna för alla användare kan efterfrågas och ställas in med "
"programmet <app>Föräldrakontroller</app>. Detta listar icke-"
"administratörskontona i flikar i en rad högst upp, och visar deras aktuella "
"inställningar för föräldrakontroller nedanför. Ändringar till "
"föräldrakontrollerna tillämpas omedelbart."
#. (itstool) path: page/p
#: C/introduction.page:25
msgid ""
"Restrictions on using the computer can only be applied to non-administrator "
"accounts. The parental controls settings for a user can only be changed by "
"an administrator, although the administrator can do so from the users "
"account by entering their password when prompted by the <app>Parental "
"Controls</app> application."
msgstr ""
"Begränsningar på användning av datorn kan endast ställas in för konton som "
"inte är administratörer. Inställningarna för föräldrakontroller för en "
"användare kan endast ändras av en administratör, även om administratören kan "
"göra det från användarens konto genom att ange sitt lösenord då programmet "
"<app>Föräldrakontroller</app> efterfrågar det."
#. (itstool) path: p/link
#: C/legal.xml:4
msgid "Creative Commons Attribution-ShareAlike 3.0 Unported License"
msgstr "Creative Commons Erkännande-DelaLika 3.0 Unported"
#. (itstool) path: license/p
#: C/legal.xml:3
msgid "This work is licensed under a <_:link-1/>."
msgstr "Detta verk licensieras under licensen <_:link-1/>."
#. (itstool) path: info/desc
#: C/restricting-applications.page:6
msgid "Restricting a child user from running already-installed applications."
msgstr "Begränsa en barnanvändare från att köra redan installerade program."
#. (itstool) path: page/title
#: C/restricting-applications.page:9
msgid "Restricting Access to Installed Applications"
msgstr "Begränsa åtkomst till installerade program"
#. (itstool) path: page/p
#: C/restricting-applications.page:11
msgid ""
"You can prevent a user from running specific applications which are already "
"installed on the computer. This could be useful if other users need those "
"applications but they are not appropriate for a child."
msgstr ""
"Du kan förhindra en användare från att köra specifika program som redan "
"finns installerade på datorn. Detta kan vara användbart om andra användare "
"behöver de programmen men de inte är lämpliga för barn."
#. (itstool) path: page/p
#: C/restricting-applications.page:14
msgid ""
"When installing additional software, you should consider whether that needs "
"to be restricted for some users — newly installed software is usable by all "
"users by default."
msgstr ""
"När du installerar ytterligare programvara bör du överväga om den behöver "
"begränsas för vissa användare — programvara som installeras kan som standard "
"användas av alla användare."
#. (itstool) path: page/p
#: C/restricting-applications.page:18
msgid "To restrict a users access to a specific application:"
msgstr "För att begränsa en användares åtkomst till ett specifikt program:"
#. (itstool) path: item/p
#: C/restricting-applications.page:22
msgid "Press the <gui style=\"button\">Restrict Applications</gui> button."
msgstr "Tryck på knappen <gui style=\"button\">Begränsa program</gui>."
#. (itstool) path: item/p
#: C/restricting-applications.page:23
msgid ""
"Enable the switch in the row for each application you would like to restrict "
"the user from accessing."
msgstr ""
"Aktivera växelknappen i raden för varje program som du vill begränsa "
"användaren från att komma åt."
#. (itstool) path: item/p
#: C/restricting-applications.page:24
msgid "Close the <gui>Restrict Applications</gui> window."
msgstr "Stäng fönstret <gui>Begränsa program</gui>."
#. (itstool) path: page/p
#: C/restricting-applications.page:27
msgid ""
"Restricting access to specific applications is often used in conjunction "
"with <link xref=\"software-installation\"/> to prevent a user from "
"installing additional software which has not been vetted."
msgstr ""
"Att begränsa åtkomst till vissa program används ofta tillsammans med <link "
"xref=\"software-installation\"/> för att förhindra en användare från att "
"installera ytterligare programvara som inte har granskats."
#. (itstool) path: info/desc
#: C/software-installation.page:6
msgid ""
"Restricting the software a child user can install, or preventing them "
"installing additional software entirely."
msgstr ""
"Begränsa vilken programvara som en barnanvändare kan installera, eller "
"förhindra dem helt från att installera ytterligare programvara."
#. (itstool) path: page/title
#: C/software-installation.page:9
msgid "Restricting Software Installation"
msgstr "Begränsa installation av programvara"
#. (itstool) path: page/p
#: C/software-installation.page:11
msgid ""
"You can prevent a user from installing additional software on the system. "
"They will still be able to search for new software to install, but will need "
"an administrator to authorize the installation when they try to install an "
"application. This applies whether they are trying to install the application "
"system-wide (for all users) or just for themselves."
msgstr ""
"Du kan förhindra en användare från att installera ytterligare programvara på "
"systemet. De kommer fortfarande kunna söka efter ny programvara att "
"installera, men kommer behöva att en administratör godkänner installationen "
"när de försöker installera ett program. Detta gäller oavsett om de försöker "
"installera programmet systemomfattande (för alla användare) eller bara för "
"sig själva."
#. (itstool) path: page/p
#: C/software-installation.page:17
msgid ""
"Additionally, you can restrict which software a user can browse or search "
"for in the <app>Software</app> catalog by age categories."
msgstr ""
"Du kan dessutom begränsa vilken programvara en användare kan bläddra bland "
"eller söka efter i katalogen för <app>Programvara</app> enligt "
"ålderskategorier."
#. (itstool) path: page/p
#: C/software-installation.page:20
msgid ""
"To prevent a user from running an application which has already been "
"installed, see <link xref=\"restricting-applications\"/>."
msgstr ""
"För att förhindra en användare från att köra ett program som redan har "
"installerats, se <link xref=\"restricting-applications\"/>."
#. (itstool) path: section/title
#: C/software-installation.page:24
msgid "Preventing Software Installation"
msgstr "Förhindra installation av programvara"
#. (itstool) path: section/p
#: C/software-installation.page:26
msgid "To prevent a user from installing additional software:"
msgstr ""
"För att förhindra en användare från att installera ytterligare programvara:"
#. (itstool) path: item/p
#: C/software-installation.page:30
msgid ""
"Enable the <gui style=\"checkbox\">Restrict Application Installation</gui> "
"checkbox."
msgstr ""
"Aktivera kryssrutan <gui style=\"checkbox\">Begränsa installation av "
"program</gui>."
#. (itstool) path: section/title
#: C/software-installation.page:35
msgid "Restricting Software Installation by Age"
msgstr "Begränsning av programvaruinstallation enligt ålder"
#. (itstool) path: section/p
#: C/software-installation.page:37
msgid ""
"Applications in the <app>Software</app> catalog have information about "
"content they contain which might be inappropriate for some ages — for "
"example, various forms of violence, unmoderated chat with other people on "
"the internet, or the possibility of spending money."
msgstr ""
"Program i katalogen för <app>Programvara</app> har information om innehåll "
"de har som kan vara olämpligt för vissa åldrar — exempelvis olika sorters "
"våld, oövervakad chatt med andra personer över internet, eller möjligheten "
"att spendera pengar."
#. (itstool) path: section/p
#: C/software-installation.page:41
msgid ""
"For each application, this information is summarized as the minimum age "
"child it is typically suitable to be used by — for example, “suitable for "
"ages 7+”. These age ratings are presented in region-specific schemes which "
"can be compared with the ratings schemes used for films and games."
msgstr ""
"För varje program sammanfattas denna information som den lägsta åldern på "
"ett barn som det lämpligen kan användas av — exempelvis ”Lämpligt för åldrar "
"7+”. Dessa åldersgränser presenteras i regionsspecifika klassifikationer som "
"kan jämföras med klassifikationerna som används för film och spel."
#. (itstool) path: section/p
#: C/software-installation.page:45
msgid ""
"The applications shown to a user in the <app>Software</app> catalog can be "
"filtered by their age suitability. Applications which are not suitable for "
"the user will be hidden, and will not be installable by that user. They will "
"be installable by other users (if their age suitability is set high enough)."
msgstr ""
"Programmen som visas för en användare i katalogen för <app>Programvara</app> "
"kan filtreras enligt deras lämplighetsålder. Program som inte är lämpliga "
"för användaren kommer att döljas, och kommer inte kunna installeras av den "
"användaren. De kan installeras av andra användare (om deras lämplighetsålder "
"är satt tillräckligt högt)."
#. (itstool) path: section/p
#: C/software-installation.page:51
msgid ""
"To filter the applications seen by a user in the <app>Software</app> catalog "
"to only those suitable for a certain age:"
msgstr ""
"För att filtrera programmen som en användare ser i katalogen för "
"<app>Programvara</app> till att bara vara de som är lämpliga för en viss "
"ålder:"
#. (itstool) path: item/p
#: C/software-installation.page:56
msgid ""
"In the <gui>Application Suitability</gui> list, select the age which "
"applications should be suitable for."
msgstr ""
"I listan <gui>Lämplighet för program</gui>, välj åldern som programmen ska "
"vara lämpliga för."
#. (itstool) path: note/p
#: C/software-installation.page:60
msgid ""
"The users actual age is not stored, so the <gui>Application Suitability</"
"gui> is not automatically updated over time as the child grows older. You "
"must periodically re-assess the appropriate <gui>Application Suitability</"
"gui> for each user."
msgstr ""
"Användarens faktiska ålder lagras inte, så <gui>Lämplighet för program</gui> "
"uppdateras inte automatiskt då barnet blir äldre. Du måste periodiskt "
"utvärdera den rätta <gui>Lämplighet för program</gui> för varje användare på "
"nytt."
#~ msgid ""
#~ "Or enable the <gui style=\"checkbox\">Restrict Application Installation "
#~ "for Others</gui> checkbox."
#~ msgstr ""
#~ "Eller aktivera kryssrutan <gui style=\"checkbox\">Begränsa installation "
#~ "av program åt andra</gui>."
#~ msgid ""
#~ "The <gui style=\"checkbox\">Restrict Application Installation for Others</"
#~ "gui> checkbox allows the user to install additional software for "
#~ "themselves, but prevents that software from being made available to other "
#~ "users. It could be used, for example, if there were two child users, one "
#~ "of whom is mature enough to be allowed to install additional software, "
#~ "but the other isnt — enabling <gui style=\"checkbox\">Restrict "
#~ "Application Installation for Others</gui> would prevent the more mature "
#~ "child from installing applications which are inappropriate for the other "
#~ "child and making them available to the other child."
#~ msgstr ""
#~ "Kryssrutan <gui style=\"checkbox\">Begränsa installation av program åt "
#~ "andra</gui> låter användaren installera ytterligare programvara åt sig "
#~ "själv, men förhindrar den programvaran från att bli tillgänglig för andra "
#~ "användare. Det kan till exempel användas om det finns två barnanvändare, "
#~ "en som är mogen nog för att tillåtas installera ytterligare programvara, "
#~ "och en som inte är det — att aktivera <gui style=\"checkbox\">Begränsa "
#~ "installation av program åt andra</gui> skulle förhindra det mognare "
#~ "barnet från att installera program som är olämpliga så att de blir "
#~ "tillgängliga för det andra barnet."

View File

@ -1,427 +0,0 @@
# Turkish translation for malcontent.
# Copyright (C) 2023 malcontent's COPYRIGHT HOLDER
# This file is distributed under the same license as the malcontent package.
#
# Sabri Ünal <libreajans@gmail.com>, 2023.
#
msgid ""
msgstr ""
"Project-Id-Version: malcontent main\n"
"POT-Creation-Date: 2023-03-08 15:25+0000\n"
"PO-Revision-Date: 2023-03-09 03:38+0300\n"
"Last-Translator: Sabri Ünal <libreajans@gmail.com>\n"
"Language-Team: Turkish <tr@li.org>\n"
"Language: tr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Poedit 3.1.1\n"
#. Put one translator per line, in the form NAME <EMAIL>, YEAR1, YEAR2
msgctxt "_"
msgid "translator-credits"
msgstr "Sabri Ünal <libreajans@gmail.com>, 2023."
#. (itstool) path: info/desc
#: C/creating-a-child-user.page:6
msgid "Creating a child user on the computer."
msgstr "Bilgisayarda çocuk kullanıcı oluşturmak."
#. (itstool) path: page/title
#: C/creating-a-child-user.page:9
msgid "Creating a Child User"
msgstr "Çocuk Kullanıcı Oluşturmak"
# Control Center için ayarlar çevirisini kullanıyoruz. Burada eski adı kullanılmış.
#. (itstool) path: page/p
#: C/creating-a-child-user.page:11
msgid ""
"Parental controls can only be applied to non-administrator accounts. Such an "
"account may have been created when the computer was initially set up. If "
"not, a new child user may be created from the <app>Parental Controls</app> "
"application if no child users already exist; and otherwise may be created "
"from the <app>Control Center</app>."
msgstr ""
"Ebeveyn denetimleri yalnızca yönetici olmayan hesaplara uygulanabilir. Bu "
"tip hesap, bilgisayar ilk kurulduğunda oluşturulmuş olabilir. Değilse, hiç "
"çocuk kullanıcı yoksa, <app>Ebeveyn Denetimleri</app> uygulamasından yeni "
"çocuk kullanıcı oluşturulabilir; aksi halde <app>Ayarlar</app>ʼdan "
"oluşturulabilir."
#. (itstool) path: page/p
#: C/creating-a-child-user.page:17
msgid ""
"To create a new child user, see <link type=\"guide\" xref=\"help:gnome-help/"
"user-add\">Add a new user account</link>. As soon as the new user is "
"created, it will appear in the <app>Parental Controls</app> window so that "
"its parental controls settings can be configured."
msgstr ""
"Yeni çocuk kullanıcı oluşturmak için <link type=\"guide\" xref=\"help:gnome-"
"help/user-add\">Yeni kullanıcı hesabı ekle</link>ʼye bakın. Yeni kullanıcı "
"oluşturulunca, ebeveyn denetimleri ayarlarının yapılandırılabilmesi için "
"<app>Ebeveyn Denetimleri</app> penceresi görünecektir."
#. (itstool) path: credit/name
#: C/index.page:6
msgid "Philip Withnall"
msgstr "Philip Withnall"
#. (itstool) path: credit/years
#: C/index.page:8
msgid "2020"
msgstr "2020"
#. (itstool) path: page/title
#: C/index.page:12
msgid "Parental Controls Help"
msgstr "Ebeveyn Denetimleri Yardım"
#. (itstool) path: section/title
#: C/index.page:15
msgid "Introduction &amp; Setup"
msgstr "Giriş ve Kurulum"
#. (itstool) path: section/title
#: C/index.page:19
msgid "Controls to Apply"
msgstr "Uygulanacak Denetimler"
#. (itstool) path: info/desc
#: C/internet.page:6
msgid "Restricting a child users access to the internet."
msgstr "Çocuk kullanıcının internete erişimini kısıtlamak."
#. (itstool) path: page/title
#: C/internet.page:9
msgid "Restricting Access to the Internet"
msgstr "İnternet Erişimini Kısıtlama"
#. (itstool) path: page/p
#: C/internet.page:11
msgid ""
"You can restrict a users access to the internet. This will prevent them "
"using a web browser, but it will not prevent them using the internet (in "
"potentially more limited forms) through other applications. For example, it "
"will not prevent access to e-mail accounts using <app>Evolution</app>, and "
"it will not prevent software updates being downloaded and applied."
msgstr ""
"Kullanıcının internete erişimini kısıtlayabilirsiniz. Bu, web tarayıcısı "
"kullanmalarını engelleyecektir, ancak diğer uygulamalar aracılığıyla "
"(muhtemelen daha sınırlı biçimlerde) interneti kullanmalarını "
"engellemeyecektir. Örneğin, <app>Evolution</app> kullanarak e-posta "
"hesaplarına erişimi engellemez ve yazılım güncellemelerinin indirilip "
"uygulanmasını engellemez."
#. (itstool) path: page/p
#: C/internet.page:17
msgid "To restrict a users access to the internet:"
msgstr "Kullanıcının internet erişimini kısıtlamak için:"
#. (itstool) path: item/p
#: C/internet.page:19 C/restricting-applications.page:20
#: C/software-installation.page:28 C/software-installation.page:54
msgid "Open the <app>Parental Controls</app> application."
msgstr "<app>Ebeveyn Denetimleri</app> uygulamasınıın."
#. (itstool) path: item/p
#: C/internet.page:20 C/restricting-applications.page:21
#: C/software-installation.page:29 C/software-installation.page:55
msgid "Select the user in the tabs at the top."
msgstr "Üstteki sekmelerde kullanıcıyı seçin."
#. (itstool) path: item/p
#: C/internet.page:21
msgid ""
"Enable the <gui style=\"checkbox\">Restrict Web Browsers</gui> checkbox."
msgstr ""
"<gui style=\"checkbox\">Web Tarayıcılarını Kısıtla</gui> onay kutusunu "
"etkinleştirin."
#. (itstool) path: info/desc
#: C/introduction.page:6
msgid ""
"Overview of parental controls, the <app>Parental Controls</app> application "
"and its use in other situations where access restrictions are needed on a "
"user."
msgstr ""
"Ebeveyn denetimlerine, <app>Ebeveyn Denetimleri</app> uygulamasına ve "
"kullanıcı için erişim kısıtlamalarının gereksinildiği diğer durumlarda "
"kullanımına genel bakış."
#. (itstool) path: page/title
#: C/introduction.page:12
msgid "Introduction to Parental Controls"
msgstr "Ebeveyn Denetimleriʼne Giriş"
#. (itstool) path: page/p
#: C/introduction.page:14
msgid ""
"Parental controls are a way to restrict what non-administrator accounts can "
"do on the computer, with the aim of allowing parents to restrict what their "
"children can do when using the computer unsupervised or under limited "
"supervision."
msgstr ""
"Ebeveyn denetimleri, bilgisayarda yönetici hesabı olmayan hesapların ne "
"yapabileceğini sınırlamanın bir yoludur. Amacı, ebeveynlerin çocukları "
"bilgisayarı gözetimsiz veya sınırlı gözetim altında kullandıklarında ne "
"yapabileceklerini sınırlamalarını sağlamaktır."
#. (itstool) path: page/p
#: C/introduction.page:18
msgid ""
"This functionality can be used in other situations ­ such as other carer/"
"caree relationships but is labelled as parental controls so that its "
"easy to find, as thats what most people will be looking for."
msgstr ""
"Bu işlevsellik diğer bakıcı/bakılan ilişkileri gibi diğer durumlarda da "
"kullanılabilir, ancak çoğu insanın ebeveyn denetimleri olarak arayacağı "
"varsayılarak, bulması kolay olsun diye bu şekilde adlandırılmıştır."
#. (itstool) path: page/p
#: C/introduction.page:21
msgid ""
"The parental controls for any user can be queried and set using the "
"<app>Parental Controls</app> application. This lists the non-administrator "
"accounts in tabs along its top bar, and shows their current parental "
"controls settings below. Changes to the parental controls apply immediately."
msgstr ""
"Herhangi bir kullanıcı için ebeveyn denetimleri, <app>Ebeveyn Denetimleri</"
"app> uygulaması kullanılarak sorgulanabilir ve ayarlanabilir. Bu, yönetici "
"olmayan hesapları üst çubuğundaki sekmelerde listeler ve altında geçerli "
"ebeveyn denetimleri ayarlarını gösterir. Ebeveyn denetimlerinde yapılan "
"değişiklikler hemen uygulanır."
#. (itstool) path: page/p
#: C/introduction.page:25
msgid ""
"Restrictions on using the computer can only be applied to non-administrator "
"accounts. The parental controls settings for a user can only be changed by "
"an administrator, although the administrator can do so from the users "
"account by entering their password when prompted by the <app>Parental "
"Controls</app> application."
msgstr ""
"Bilgisayar kullanımıyla ilgili kısıtlamalar yalnızca yönetici olmayan "
"hesaplara uygulanabilir. Bir kullanıcının ebeveyn denetimleri ayarları "
"yalnızca bir yönetici tarafından değiştirilebilir, ancak yönetici "
"<app>Ebeveyn Denetimleri</app> uygulaması tarafından istendiğinde parolasını "
"girerek kullanıcının hesabından bunu yapabilir."
#. (itstool) path: p/link
#: C/legal.xml:4
msgid "Creative Commons Attribution-ShareAlike 3.0 Unported License"
msgstr "Creative Commons Attribution-ShareAlike 3.0 Unported License"
#. (itstool) path: license/p
#: C/legal.xml:3
msgid "This work is licensed under a <_:link-1/>."
msgstr "Bu çalışma <_:link-1/> altında lisanslanmıştır."
#. (itstool) path: info/desc
#: C/restricting-applications.page:6
msgid "Restricting a child user from running already-installed applications."
msgstr ""
"Çocuk kullanıcının zaten kurulmuş uygulamaları çalıştırmasını kısıtlama."
#. (itstool) path: page/title
#: C/restricting-applications.page:9
msgid "Restricting Access to Installed Applications"
msgstr "Kurulu Uygulamalara Erişimi Kısıtlama"
#. (itstool) path: page/p
#: C/restricting-applications.page:11
msgid ""
"You can prevent a user from running specific applications which are already "
"installed on the computer. This could be useful if other users need those "
"applications but they are not appropriate for a child."
msgstr ""
"Kullanıcının zaten bilgisayarda kurulu olan belirli uygulamaları "
"çalıştırmasını engelleyebilirsiniz. Bu, diğer kullanıcıların bu uygulamalara "
"ihtiyacı varsa ancak çocuk için uygun değilse faydalı olabilir."
#. (itstool) path: page/p
#: C/restricting-applications.page:14
msgid ""
"When installing additional software, you should consider whether that needs "
"to be restricted for some users — newly installed software is usable by all "
"users by default."
msgstr ""
"Ek yazılım kurarken, bunun bazı kullanıcılar için kısıtlanması gerekip "
"gerekmediğini değerlendirmelisiniz. Yeni kurulan yazılımlar öntanımlı olarak "
"tüm kullanıcılar tarafından kullanılabilir."
#. (itstool) path: page/p
#: C/restricting-applications.page:18
msgid "To restrict a users access to a specific application:"
msgstr "Bir kullanıcının belirli bir uygulamaya erişimini kısıtlamak için:"
#. (itstool) path: item/p
#: C/restricting-applications.page:22
msgid "Press the <gui style=\"button\">Restrict Applications</gui> button."
msgstr "<gui style=\"button\">Uygulamaları Kısıtla</gui> düğmesine basın."
#. (itstool) path: item/p
#: C/restricting-applications.page:23
msgid ""
"Enable the switch in the row for each application you would like to restrict "
"the user from accessing."
msgstr ""
"Kullanıcının erişimini kısıtlamak istediğiniz her uygulamanın anahtarını "
"etkinleştirin."
#. (itstool) path: item/p
#: C/restricting-applications.page:24
msgid "Close the <gui>Restrict Applications</gui> window."
msgstr "<gui style=\"button\">Uygulamaları Kısıtla</gui> benceresini kapatın."
#. (itstool) path: page/p
#: C/restricting-applications.page:27
msgid ""
"Restricting access to specific applications is often used in conjunction "
"with <link xref=\"software-installation\"/> to prevent a user from "
"installing additional software which has not been vetted."
msgstr ""
"Belirli uygulamalara erişimin kısıtlanması, kullanıcının incelenmemiş ek "
"yazılımlar kurmasını önlemek için genellikle <link xref=\"software-"
"installation\"/> ile birlikte kullanılır."
#. (itstool) path: info/desc
#: C/software-installation.page:6
msgid ""
"Restricting the software a child user can install, or preventing them "
"installing additional software entirely."
msgstr ""
"Çocuk kullanıcının kurabileceği yazılımı kısıtlamak ya da ek yazılım "
"kurmasını tamamen engellemek."
#. (itstool) path: page/title
#: C/software-installation.page:9
msgid "Restricting Software Installation"
msgstr "Yazılım Kurulumunu Kısıtlama"
#. (itstool) path: page/p
#: C/software-installation.page:11
msgid ""
"You can prevent a user from installing additional software on the system. "
"They will still be able to search for new software to install, but will need "
"an administrator to authorize the installation when they try to install an "
"application. This applies whether they are trying to install the application "
"system-wide (for all users) or just for themselves."
msgstr ""
"Kullanıcının sisteme ek yazılım kurmasını engelleyebilirsiniz. Yine de "
"kurulum için yeni yazılım arayabilecekler, ancak uygulama kurmaya "
"çalıştıklarında kurulumu yetkilendirmek için yöneticiye ihtiyaçları olacak. "
"Bu, uygulamayı sistem geneline (tüm kullanıcılar için) ya da yalnızca "
"kendileri için kurmaya çalışsalar da geçerlidir."
#. (itstool) path: page/p
#: C/software-installation.page:17
msgid ""
"Additionally, you can restrict which software a user can browse or search "
"for in the <app>Software</app> catalog by age categories."
msgstr ""
"Ayrıca, kullanıcının <app>Yazılımlar</app> kataloğunda hangi yazılımlara göz "
"atabileceğini ya da arayabileceğini yaş kategorilerine göre "
"sınırlayabilirsiniz."
#. (itstool) path: page/p
#: C/software-installation.page:20
msgid ""
"To prevent a user from running an application which has already been "
"installed, see <link xref=\"restricting-applications\"/>."
msgstr ""
"Bir kullanıcının zaten kurulu bir uygulamayı çalıştırmasını engellemek için "
"bkz. <link xref=\"restricting-applications\"/>."
#. (itstool) path: section/title
#: C/software-installation.page:24
msgid "Preventing Software Installation"
msgstr "Yazılım Kurulumunu Engelleme"
#. (itstool) path: section/p
#: C/software-installation.page:26
msgid "To prevent a user from installing additional software:"
msgstr "Kullanıcının ek yazılım kurmasını engellemek için:"
#. (itstool) path: item/p
#: C/software-installation.page:30
msgid ""
"Enable the <gui style=\"checkbox\">Restrict Application Installation</gui> "
"checkbox."
msgstr ""
"<gui style=\"checkbox\">Uygulama Kurulumunu Kısıtla</gui> onay kutusunu "
"etkinleştirin."
#. (itstool) path: section/title
#: C/software-installation.page:35
msgid "Restricting Software Installation by Age"
msgstr "Yazılım Kurulumunu Yaşa Göre Kısıtlama"
#. (itstool) path: section/p
#: C/software-installation.page:37
msgid ""
"Applications in the <app>Software</app> catalog have information about "
"content they contain which might be inappropriate for some ages — for "
"example, various forms of violence, unmoderated chat with other people on "
"the internet, or the possibility of spending money."
msgstr ""
"<app>Yazılımlar</app> kataloğundaki uygulamalar, kimi yaş grupları için "
"uygun olmayabilecek içerikleri hakkında bilgiler içerir - örneğin, çeşitli "
"şiddet türleri, internet üzerinden diğer kişilerle denetlenmeyen sohbet, ya "
"da para harcama olasılığı gibi."
#. (itstool) path: section/p
#: C/software-installation.page:41
msgid ""
"For each application, this information is summarized as the minimum age "
"child it is typically suitable to be used by — for example, “suitable for "
"ages 7+”. These age ratings are presented in region-specific schemes which "
"can be compared with the ratings schemes used for films and games."
msgstr ""
"Her uygulama için, bu bilgi genellikle kullanımı için uygun en düşük yaş "
"grubu olarak özetlenir - örneğin, \"7 yaş ve üzeri için uygun\". Bu yaş "
"derecelendirmeleri, filmler ve oyunlar için kullanılan derecelendirme "
"şemaları ile karşılaştırılabilen bölgesel şemalarda sunulur."
#. (itstool) path: section/p
#: C/software-installation.page:45
msgid ""
"The applications shown to a user in the <app>Software</app> catalog can be "
"filtered by their age suitability. Applications which are not suitable for "
"the user will be hidden, and will not be installable by that user. They will "
"be installable by other users (if their age suitability is set high enough)."
msgstr ""
"<app>Yazılımlar</app> kataloğunda kullanıcıya gösterilen uygulamalar, yaş "
"uygunluğuna göre süzülerek gösterilebilir. Kullanıcı için uygun olmayan "
"uygulamalar gizlenir ve kullanıcı tarafından kurulamaz. Bu uygulamalar, yaş "
"uygunluğu yeterince yüksek olan diğer kullanıcılarca kurulabilir."
#. (itstool) path: section/p
#: C/software-installation.page:51
msgid ""
"To filter the applications seen by a user in the <app>Software</app> catalog "
"to only those suitable for a certain age:"
msgstr ""
"Kullanıcının <app>Yazılımlar</app> kataloğunda gördüğü uygulamaları yalnızca "
"belirli yaşa uygun olacak şekilde süzmek için:"
#. (itstool) path: item/p
#: C/software-installation.page:56
msgid ""
"In the <gui>Application Suitability</gui> list, select the age which "
"applications should be suitable for."
msgstr ""
"<gui>Uygulama Uygunluğu</gui> listesinde, uygulamaların hangi yaş için uygun "
"olduğunu seçin."
#. (itstool) path: note/p
#: C/software-installation.page:60
msgid ""
"The users actual age is not stored, so the <gui>Application Suitability</"
"gui> is not automatically updated over time as the child grows older. You "
"must periodically re-assess the appropriate <gui>Application Suitability</"
"gui> for each user."
msgstr ""
"Kullanıcının gerçek yaşı depolanmadığı için, <gui>Uygulama Uygunluğu</gui> "
"çocuk büyüdükçe zamanla kendiliğinden güncellenmez. <gui>Uygulama Uygunluğu</"
"gui> her kullanıcı için düzenli olarak yeniden belirlenmelidir."

View File

@ -1,474 +0,0 @@
# Ukrainian translation for malcontent.
# Copyright (C) 2020 malcontent's COPYRIGHT HOLDER
# This file is distributed under the same license as the malcontent package.
#
# Yuri Chornoivan <yurchor@ukr.net>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: malcontent master\n"
"POT-Creation-Date: 2020-12-08 15:28+0000\n"
"PO-Revision-Date: 2020-12-08 22:19+0200\n"
"Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
"Language-Team: Ukrainian <trans-uk@lists.fedoraproject.org>\n"
"Language: uk\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=n==1 ? 3 : n%10==1 && n%100!=11 ? 0 : n"
"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"X-Generator: Lokalize 20.11.70\n"
#. Put one translator per line, in the form NAME <EMAIL>, YEAR1, YEAR2
msgctxt "_"
msgid "translator-credits"
msgstr "Юрій Чорноіван <yurchor@ukr.net>, 2020"
#. (itstool) path: info/desc
#: C/creating-a-child-user.page:6
msgid "Creating a child user on the computer."
msgstr "Створення запису користувача-дитини на комп'ютері."
#. (itstool) path: page/title
#: C/creating-a-child-user.page:9
msgid "Creating a Child User"
msgstr "Створення запису користувача-дитини"
#. (itstool) path: page/p
#: C/creating-a-child-user.page:11
msgid ""
"Parental controls can only be applied to non-administrator accounts. Such an "
"account may have been created when the computer was initially set up. If "
"not, a new child user may be created from the <app>Parental Controls</app> "
"application if no child users already exist; and otherwise may be created "
"from the <app>Control Center</app>."
msgstr ""
"Батьківський контроль можна застосовувати лише до облікових записів без "
"адміністративних прав. Такий обліковий запис могло бути створено під час "
"початкового налаштовування системи. Якщо цього не було зроблено, можна "
"створити новий дитячий обліковий запис за допомогою програми "
"<app>Батьківський контроль</app>. Крім того, такий обліковий запис можна "
"створити за допомогою <app>Центру керування</app>."
#. (itstool) path: page/p
#: C/creating-a-child-user.page:17
msgid ""
"To create a new child user, see <link type=\"guide\" xref=\"help:gnome-help/"
"user-add\">Add a new user account</link>. As soon as the new user is "
"created, it will appear in the <app>Parental Controls</app> window so that "
"its parental controls settings can be configured."
msgstr ""
"Щоб створити дитячий обліковий запис, ознайомтеся із розділом довідки <link "
"type=\"guide\" xref=\"help:gnome-help/user-add\">Додавання нового облікового "
"запису користувача</link>. Щойно запис нового користувача буде створено, "
"його буде показано у вікні програми <app>Батьківський контроль</app>, отже, "
"ви зможете налаштувати параметри батьківського контролю."
#. (itstool) path: credit/name
#: C/index.page:6
msgid "Philip Withnall"
msgstr "Philip Withnall"
#. (itstool) path: credit/years
#: C/index.page:8
msgid "2020"
msgstr "2020"
#. (itstool) path: page/title
#: C/index.page:12
msgid "Parental Controls Help"
msgstr "Допомога у батьківському контролі"
#. (itstool) path: section/title
#: C/index.page:15
msgid "Introduction &amp; Setup"
msgstr "Вступ і налаштування"
#. (itstool) path: section/title
#: C/index.page:19
msgid "Controls to Apply"
msgstr "Засоби контролю, які можна застосувати"
#. (itstool) path: info/desc
#: C/internet.page:6
msgid "Restricting a child users access to the internet."
msgstr "Обмеження доступу дитячого облікового запису до інтернету."
#. (itstool) path: page/title
#: C/internet.page:9
msgid "Restricting Access to the Internet"
msgstr "Обмеження доступу до інтернету"
#. (itstool) path: page/p
#: C/internet.page:11
msgid ""
"You can restrict a users access to the internet. This will prevent them "
"using a web browser, but it will not prevent them using the internet (in "
"potentially more limited forms) through other applications. For example, it "
"will not prevent access to e-mail accounts using <app>Evolution</app>, and "
"it will not prevent software updates being downloaded and applied."
msgstr ""
"Ви можете обмежити доступ користувача до інтернету. Таким чином можна "
"заборонити користувачу користуватися браузером, але користувач збереже "
"доступ до інтернету (у потенційно обмеженішій формі) за допомогою інших "
"програм. Наприклад, користувач матиме доступ до облікових записів "
"електронної пошти за допомогою <app>Evolution</app>. Заборона також не "
"стосуватиметься отримання і застосування оновлень програмного забезпечення."
#. (itstool) path: page/p
#: C/internet.page:17
msgid "To restrict a users access to the internet:"
msgstr "Щоб обмежити доступ користувача до інтернету, виконайте такі дії:"
#. (itstool) path: item/p
#: C/internet.page:19 C/restricting-applications.page:20
#: C/software-installation.page:28 C/software-installation.page:54
msgid "Open the <app>Parental Controls</app> application."
msgstr "Відкрийте вікно програми <app>Батьківський контроль</app>."
#. (itstool) path: item/p
#: C/internet.page:20 C/restricting-applications.page:21
#: C/software-installation.page:29 C/software-installation.page:55
msgid "Select the user in the tabs at the top."
msgstr "Виберіть користувача у вкладках верхньої частини вікна."
#. (itstool) path: item/p
#: C/internet.page:21
msgid ""
"Enable the <gui style=\"checkbox\">Restrict Web Browsers</gui> checkbox."
msgstr "Позначте пункт <gui style=\"checkbox\">Обмежити браузери</gui>."
#. (itstool) path: info/desc
#: C/introduction.page:6
#| msgid ""
#| "Overview of parental controls and the <app>Parental Controls</app> "
#| "application."
msgid ""
"Overview of parental controls, the <app>Parental Controls</app> application "
"and its use in other situations where access restrictions are needed on a "
"user."
msgstr ""
"Огляд батьківського контролю, програми <app>Батьківський контроль</app> та її"
" використання у інших ситуаціях, коли потрібне обмеження доступу для"
" користувача."
#. (itstool) path: page/title
#: C/introduction.page:12
msgid "Introduction to Parental Controls"
msgstr "Вступ до «Батьківського контролю»"
#. (itstool) path: page/p
#: C/introduction.page:14
msgid ""
"Parental controls are a way to restrict what non-administrator accounts can "
"do on the computer, with the aim of allowing parents to restrict what their "
"children can do when using the computer unsupervised or under limited "
"supervision."
msgstr ""
"Батьківський контроль — спосіб обмежити діапазон дій, які зможуть виконувати "
"користувачі неадміністративних облікових записів на комп'ютері. Метою є "
"уможливлення обмеження батьками дій, які можуть вчиняти на комп'ютері діти "
"без нагляду або із обмеженим наглядом."
#. (itstool) path: page/p
#: C/introduction.page:18
#| msgid ""
#| "This functionality can be used in other situations ­ such as other carer/"
#| "caree relationships but is labelled as parental controls so that its "
#| "easy to find."
msgid ""
"This functionality can be used in other situations ­ such as other carer/"
"caree relationships but is labelled as parental controls so that its "
"easy to find, as thats what most people will be looking for."
msgstr ""
"Цими функціональними можливостями можна скористатися і в інших ситуаціях — "
"зокрема у ситуаціях із стосунками доглядач-пацієнт, — ми назвали це "
"«батьківський контроль» лише для зручності пошуку, оскільки саме це шукають"
" більшість наших користувачів."
#. (itstool) path: page/p
#: C/introduction.page:21
msgid ""
"The parental controls for any user can be queried and set using the "
"<app>Parental Controls</app> application. This lists the non-administrator "
"accounts in tabs along its top bar, and shows their current parental "
"controls settings below. Changes to the parental controls apply immediately."
msgstr ""
"Переглянути і встановити батьківський контроль для будь-якого користувача "
"можна за допомогою програми <app>Батьківський контроль</app>. У вікні "
"програми буде показано список неадміністративних облікових записів уздовж "
"верхньої панелі, а також параметри поточного батьківського контролю на "
"панелі під списком. Зміни у батьківському контролі буде застосовано негайно."
#. (itstool) path: page/p
#: C/introduction.page:25
msgid ""
"Restrictions on using the computer can only be applied to non-administrator "
"accounts. The parental controls settings for a user can only be changed by "
"an administrator, although the administrator can do so from the users "
"account by entering their password when prompted by the <app>Parental "
"Controls</app> application."
msgstr ""
"Обмеження у користуванні комп'ютером можна запроваджувати лише для облікових "
"записів, які не є адміністративними. Параметри батьківського контролю для "
"користувача може бути змінено лише адміністратором, хоча адміністратор може "
"зробити це з облікового запису користувача, якщо введе пароль, коли про "
"нього запитає програма <app>Батьківський контроль</app>."
#. (itstool) path: p/link
#: C/legal.xml:4
msgid "Creative Commons Attribution-ShareAlike 3.0 Unported License"
msgstr "Creative Commons Attribution-ShareAlike 3.0 Unported License"
#. (itstool) path: license/p
#: C/legal.xml:3
msgid "This work is licensed under a <_:link-1/>."
msgstr "Ця робота розповсюджується за умов дотримання <_:link-1/>."
#. (itstool) path: info/desc
#: C/restricting-applications.page:6
msgid "Restricting a child user from running already-installed applications."
msgstr "Обмеження запуску з дитячого облікового вже встановлених програм."
#. (itstool) path: page/title
#: C/restricting-applications.page:9
msgid "Restricting Access to Installed Applications"
msgstr "Обмеження доступу до встановлених програм"
#. (itstool) path: page/p
#: C/restricting-applications.page:11
msgid ""
"You can prevent a user from running specific applications which are already "
"installed on the computer. This could be useful if other users need those "
"applications but they are not appropriate for a child."
msgstr ""
"Ви можете заборонити користувачу запускати певні програми, які вже "
"встановлено на комп'ютері. Це може бути корисним, якщо ці програми потрібні "
"іншим користувачам, але є непридатними для користування дитиною."
#. (itstool) path: page/p
#: C/restricting-applications.page:14
msgid ""
"When installing additional software, you should consider whether that needs "
"to be restricted for some users — newly installed software is usable by all "
"users by default."
msgstr ""
"При встановленні додаткового програмного забезпечення вам слід зважати на "
"те, чи слід обмежувати доступ до нього для інших користувачів — типово, усе "
"нововстановлене програмне забезпечення є доступним для усіх користувачів "
"комп'ютера."
#. (itstool) path: page/p
#: C/restricting-applications.page:18
msgid "To restrict a users access to a specific application:"
msgstr ""
"Щоб обмежити доступ користувача до певної програми, виконайте такі дії:"
#. (itstool) path: item/p
#: C/restricting-applications.page:22
msgid "Press the <gui style=\"button\">Restrict Applications</gui> button."
msgstr ""
"Натисніть кнопку <gui style=\"button\">Обмеження доступу до програм</gui>."
#. (itstool) path: item/p
#: C/restricting-applications.page:23
msgid ""
"Enable the switch in the row for each application you would like to restrict "
"the user from accessing."
msgstr ""
"Увімкніть перемикач у рядку для кожної з програм, доступ до якої ви хочете "
"обмежити."
#. (itstool) path: item/p
#: C/restricting-applications.page:24
msgid "Close the <gui>Restrict Applications</gui> window."
msgstr "Закрийте вікно <gui>Обмеження доступу до програм</gui>."
#. (itstool) path: page/p
#: C/restricting-applications.page:27
msgid ""
"Restricting access to specific applications is often used in conjunction "
"with <link xref=\"software-installation\"/> to prevent a user from "
"installing additional software which has not been vetted."
msgstr ""
"Обмеження доступу до певної програми часто використовується у поєднанні із "
"<link xref=\"software-installation\"/> для запобігання встановленню "
"користувачем додаткового програмного забезпечення, доступ до якого не "
"обмежено."
#. (itstool) path: info/desc
#: C/software-installation.page:6
msgid ""
"Restricting the software a child user can install, or preventing them "
"installing additional software entirely."
msgstr ""
"Обмеження можливостей зі встановлення програмного забезпечення власником "
"дитячого облікового запису або повна заборона встановлення програмного "
"забезпечення для дитячого облікового запису."
#. (itstool) path: page/title
#: C/software-installation.page:9
msgid "Restricting Software Installation"
msgstr "Обмеження встановлення програмного забезпечення"
#. (itstool) path: page/p
#: C/software-installation.page:11
msgid ""
"You can prevent a user from installing additional software on the system. "
"They will still be able to search for new software to install, but will need "
"an administrator to authorize the installation when they try to install an "
"application. This applies whether they are trying to install the application "
"system-wide (for all users) or just for themselves."
msgstr ""
"Ви можете заборонити користувачеві встановлювати додаткове програмне "
"забезпечення. Користувачі зможуть виконувати пошук нового програмного "
"забезпечення для встановлення, але потребуватимуть пароля адміністратора для "
"уповноваження на встановлення. Запит щодо пароля буде показано, коли "
"користувач спробує встановити програму. Це стосується ситуацій, коли "
"користувачі намагаються встановити програму на загальносистемному рівні (для "
"усіх користувачів) або лише для себе."
#. (itstool) path: page/p
#: C/software-installation.page:17
msgid ""
"Additionally, you can restrict which software a user can browse or search "
"for in the <app>Software</app> catalog by age categories."
msgstr ""
"Крім того, ви можете обмежити перелік програмного забезпечення, яке зможе "
"бачити або шукати користувач у каталозі програми <app>Програмне "
"забезпечення</app>, за віковими категоріями."
#. (itstool) path: page/p
#: C/software-installation.page:20
msgid ""
"To prevent a user from running an application which has already been "
"installed, see <link xref=\"restricting-applications\"/>."
msgstr ""
"Щоб заборонити користувачу запускати програму, яку вже встановлено, "
"ознайомтеся із вмістом розділу <link xref=\"restricting-applications\"/>."
#. (itstool) path: section/title
#: C/software-installation.page:24
msgid "Preventing Software Installation"
msgstr "Заборона встановлення програмного забезпечення"
#. (itstool) path: section/p
#: C/software-installation.page:26
msgid "To prevent a user from installing additional software:"
msgstr ""
"Щоб заборонити користувачеві встановлення додаткового програмного "
"забезпечення:"
#. (itstool) path: item/p
#: C/software-installation.page:30
msgid ""
"Enable the <gui style=\"checkbox\">Restrict Application Installation</gui> "
"checkbox."
msgstr ""
"Позначте пункт <gui style=\"checkbox\">Обмежити встановлення програм</gui>."
#. (itstool) path: section/title
#: C/software-installation.page:35
msgid "Restricting Software Installation by Age"
msgstr "Обмеження встановлення програмного забезпечення за віком"
#. (itstool) path: section/p
#: C/software-installation.page:37
msgid ""
"Applications in the <app>Software</app> catalog have information about "
"content they contain which might be inappropriate for some ages — for "
"example, various forms of violence, unmoderated chat with other people on "
"the internet, or the possibility of spending money."
msgstr ""
"У пакунках програми з каталогу програми <app>Програмне забезпечення</app> "
"містяться відомості щодо вмісту пакунків, який може бути неприйнятним для "
"певних вікових груп. Наприклад, у програмах можуть бути посилання на різні "
"форми насильства, необмежені можливості спілкування зі сторонніми особами у "
"інтернеті або можливості з витрачання грошей."
#. (itstool) path: section/p
#: C/software-installation.page:41
msgid ""
"For each application, this information is summarized as the minimum age "
"child it is typically suitable to be used by — for example, “suitable for "
"ages 7+”. These age ratings are presented in region-specific schemes which "
"can be compared with the ratings schemes used for films and games."
msgstr ""
"Для кожної програми у цих відомостях щодо програми містяться дані щодо "
"мінімального віку дітей, з якого їх можна допускати до користування "
"програмою, наприклад, «придатна для віку 7+». Ці оцінки віку представлено у "
"вигляді специфічних для регіону схем, які можна порівняти із схемами "
"рейтингів для фільмів та відеоігор."
#. (itstool) path: section/p
#: C/software-installation.page:45
msgid ""
"The applications shown to a user in the <app>Software</app> catalog can be "
"filtered by their age suitability. Applications which are not suitable for "
"the user will be hidden, and will not be installable by that user. They will "
"be installable by other users (if their age suitability is set high enough)."
msgstr ""
"Програми, які буде показано користувачеві у каталозі <app>Програмне "
"забезпечення</app>, можна фільтрувати за придатністю для вікових груп. "
"Програми, які є непридатними для користувача, буде приховано — користувач не "
"зможе їх встановити. Їх зможуть встановлювати інші користувачі (якщо їхній "
"вік є відповідним до вікової категорії програм)."
#. (itstool) path: section/p
#: C/software-installation.page:51
msgid ""
"To filter the applications seen by a user in the <app>Software</app> catalog "
"to only those suitable for a certain age:"
msgstr ""
"Щоб налаштувати фільтрування програм, пункти яких буде показано "
"користувачеві у програмі <app>Програмне забезпечення</app> лише програмами, "
"які рекомендовано для певного вікового діапазону, виконайте такі дії:"
#. (itstool) path: item/p
#: C/software-installation.page:56
msgid ""
"In the <gui>Application Suitability</gui> list, select the age which "
"applications should be suitable for."
msgstr ""
"У списку <gui>Придатність програм</gui> виберіть вік, для якого мають бути "
"придатними програми."
#. (itstool) path: note/p
#: C/software-installation.page:60
msgid ""
"The users actual age is not stored, so the <gui>Application Suitability</"
"gui> is not automatically updated over time as the child grows older. You "
"must periodically re-assess the appropriate <gui>Application Suitability</"
"gui> for each user."
msgstr ""
"Програма не зберігає дані щодо віку користувача, тому список "
"<gui>Придатність програм</gui> не оновлюється автоматично з дорослішанням "
"дитини. Вам слід час від часу оновлювати дані списку <gui>Придатність "
"програм</gui> для кожного користувача."
#~ msgid ""
#~ "Or enable the <gui style=\"checkbox\">Restrict Application Installation "
#~ "for Others</gui> checkbox."
#~ msgstr ""
#~ "Або позначте пункт <gui style=\"checkbox\">Обмежити встановлення програм "
#~ "для інших</gui>."
#~ msgid ""
#~ "The <gui style=\"checkbox\">Restrict Application Installation for Others</"
#~ "gui> checkbox allows the user to install additional software for "
#~ "themselves, but prevents that software from being made available to other "
#~ "users. It could be used, for example, if there were two child users, one "
#~ "of whom is mature enough to be allowed to install additional software, "
#~ "but the other isnt — enabling <gui style=\"checkbox\">Restrict "
#~ "Application Installation for Others</gui> would prevent the more mature "
#~ "child from installing applications which are inappropriate for the other "
#~ "child and making them available to the other child."
#~ msgstr ""
#~ "За допомогою пункту <gui style=\"checkbox\">Обмежити встановлення програм "
#~ "для інших</gui> можна дозволити користувачеві встановлювати додаткове "
#~ "програмне забезпечення для себе, але заборонити доступ до встановленого "
#~ "програмного забезпечення для інших користувачів. Цим можна скористатися, "
#~ "наприклад, якщо у вас двоє дітей, з яких одна дитина достатньо доросла, "
#~ "щоб дозволити їй встановлювати додаткові програми, але інша є надто "
#~ "малою. Позначення пункту <gui style=\"checkbox\">Обмежити встановлення "
#~ "програм для інших</gui> заборонить старшій дитині встановлювати програми, "
#~ "доступ до яких для молодшої дитини слід обмежити."

View File

@ -0,0 +1,968 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2015-2016 Richard Hughes <richard@hughsie.com>
*
* Licensed under the GNU General Public License Version 2
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include <glib/gi18n.h>
#include <string.h>
#include "gs-content-rating.h"
const gchar *
gs_content_rating_system_to_str (GsContentRatingSystem system)
{
if (system == GS_CONTENT_RATING_SYSTEM_INCAA)
return "INCAA";
if (system == GS_CONTENT_RATING_SYSTEM_ACB)
return "ACB";
if (system == GS_CONTENT_RATING_SYSTEM_DJCTQ)
return "DJCTQ";
if (system == GS_CONTENT_RATING_SYSTEM_GSRR)
return "GSRR";
if (system == GS_CONTENT_RATING_SYSTEM_PEGI)
return "PEGI";
if (system == GS_CONTENT_RATING_SYSTEM_KAVI)
return "KAVI";
if (system == GS_CONTENT_RATING_SYSTEM_USK)
return "USK";
if (system == GS_CONTENT_RATING_SYSTEM_ESRA)
return "ESRA";
if (system == GS_CONTENT_RATING_SYSTEM_CERO)
return "CERO";
if (system == GS_CONTENT_RATING_SYSTEM_OFLCNZ)
return "OFLCNZ";
if (system == GS_CONTENT_RATING_SYSTEM_RUSSIA)
return "RUSSIA";
if (system == GS_CONTENT_RATING_SYSTEM_MDA)
return "MDA";
if (system == GS_CONTENT_RATING_SYSTEM_GRAC)
return "GRAC";
if (system == GS_CONTENT_RATING_SYSTEM_ESRB)
return "ESRB";
if (system == GS_CONTENT_RATING_SYSTEM_IARC)
return "IARC";
return NULL;
}
const gchar *
gs_content_rating_key_value_to_str (const gchar *id, MctAppFilterOarsValue value)
{
guint i;
const struct {
const gchar *id;
MctAppFilterOarsValue value;
const gchar *desc;
} tab[] = {
{ "violence-cartoon", MCT_APP_FILTER_OARS_VALUE_NONE,
/* TRANSLATORS: content rating description */
_("No cartoon violence") },
{ "violence-cartoon", MCT_APP_FILTER_OARS_VALUE_MILD,
/* TRANSLATORS: content rating description */
_("Cartoon characters in unsafe situations") },
{ "violence-cartoon", MCT_APP_FILTER_OARS_VALUE_MODERATE,
/* TRANSLATORS: content rating description */
_("Cartoon characters in aggressive conflict") },
{ "violence-cartoon", MCT_APP_FILTER_OARS_VALUE_INTENSE,
/* TRANSLATORS: content rating description */
_("Graphic violence involving cartoon characters") },
{ "violence-fantasy", MCT_APP_FILTER_OARS_VALUE_NONE,
/* TRANSLATORS: content rating description */
_("No fantasy violence") },
{ "violence-fantasy", MCT_APP_FILTER_OARS_VALUE_MILD,
/* TRANSLATORS: content rating description */
_("Characters in unsafe situations easily distinguishable from reality") },
{ "violence-fantasy", MCT_APP_FILTER_OARS_VALUE_MODERATE,
/* TRANSLATORS: content rating description */
_("Characters in aggressive conflict easily distinguishable from reality") },
{ "violence-fantasy", MCT_APP_FILTER_OARS_VALUE_INTENSE,
/* TRANSLATORS: content rating description */
_("Graphic violence easily distinguishable from reality") },
{ "violence-realistic", MCT_APP_FILTER_OARS_VALUE_NONE,
/* TRANSLATORS: content rating description */
_("No realistic violence") },
{ "violence-realistic", MCT_APP_FILTER_OARS_VALUE_MILD,
/* TRANSLATORS: content rating description */
_("Mildly realistic characters in unsafe situations") },
{ "violence-realistic", MCT_APP_FILTER_OARS_VALUE_MODERATE,
/* TRANSLATORS: content rating description */
_("Depictions of realistic characters in aggressive conflict") },
{ "violence-realistic", MCT_APP_FILTER_OARS_VALUE_INTENSE,
/* TRANSLATORS: content rating description */
_("Graphic violence involving realistic characters") },
{ "violence-bloodshed", MCT_APP_FILTER_OARS_VALUE_NONE,
/* TRANSLATORS: content rating description */
_("No bloodshed") },
{ "violence-bloodshed", MCT_APP_FILTER_OARS_VALUE_MILD,
/* TRANSLATORS: content rating description */
_("Unrealistic bloodshed") },
{ "violence-bloodshed", MCT_APP_FILTER_OARS_VALUE_MODERATE,
/* TRANSLATORS: content rating description */
_("Realistic bloodshed") },
{ "violence-bloodshed", MCT_APP_FILTER_OARS_VALUE_INTENSE,
/* TRANSLATORS: content rating description */
_("Depictions of bloodshed and the mutilation of body parts") },
{ "violence-sexual", MCT_APP_FILTER_OARS_VALUE_NONE,
/* TRANSLATORS: content rating description */
_("No sexual violence") },
{ "violence-sexual", MCT_APP_FILTER_OARS_VALUE_INTENSE,
/* TRANSLATORS: content rating description */
_("Rape or other violent sexual behavior") },
{ "drugs-alcohol", MCT_APP_FILTER_OARS_VALUE_NONE,
/* TRANSLATORS: content rating description */
_("No references to alcohol") },
{ "drugs-alcohol", MCT_APP_FILTER_OARS_VALUE_MILD,
/* TRANSLATORS: content rating description */
_("References to alcoholic beverages") },
{ "drugs-alcohol", MCT_APP_FILTER_OARS_VALUE_MODERATE,
/* TRANSLATORS: content rating description */
_("Use of alcoholic beverages") },
{ "drugs-narcotics", MCT_APP_FILTER_OARS_VALUE_NONE,
/* TRANSLATORS: content rating description */
_("No references to illicit drugs") },
{ "drugs-narcotics", MCT_APP_FILTER_OARS_VALUE_MILD,
/* TRANSLATORS: content rating description */
_("References to illicit drugs") },
{ "drugs-narcotics", MCT_APP_FILTER_OARS_VALUE_MODERATE,
/* TRANSLATORS: content rating description */
_("Use of illicit drugs") },
{ "drugs-tobacco", MCT_APP_FILTER_OARS_VALUE_MILD,
/* TRANSLATORS: content rating description */
_("References to tobacco products") },
{ "drugs-tobacco", MCT_APP_FILTER_OARS_VALUE_MODERATE,
/* TRANSLATORS: content rating description */
_("Use of tobacco products") },
{ "sex-nudity", MCT_APP_FILTER_OARS_VALUE_NONE,
/* TRANSLATORS: content rating description */
_("No nudity of any sort") },
{ "sex-nudity", MCT_APP_FILTER_OARS_VALUE_MILD,
/* TRANSLATORS: content rating description */
_("Brief artistic nudity") },
{ "sex-nudity", MCT_APP_FILTER_OARS_VALUE_MODERATE,
/* TRANSLATORS: content rating description */
_("Prolonged nudity") },
{ "sex-themes", MCT_APP_FILTER_OARS_VALUE_NONE,
/* TRANSLATORS: content rating description */
_("No references or depictions of sexual nature") },
{ "sex-themes", MCT_APP_FILTER_OARS_VALUE_MILD,
/* TRANSLATORS: content rating description */
_("Provocative references or depictions") },
{ "sex-themes", MCT_APP_FILTER_OARS_VALUE_MODERATE,
/* TRANSLATORS: content rating description */
_("Sexual references or depictions") },
{ "sex-themes", MCT_APP_FILTER_OARS_VALUE_INTENSE,
/* TRANSLATORS: content rating description */
_("Graphic sexual behavior") },
{ "language-profanity", MCT_APP_FILTER_OARS_VALUE_NONE,
/* TRANSLATORS: content rating description */
_("No profanity of any kind") },
{ "language-profanity", MCT_APP_FILTER_OARS_VALUE_MILD,
/* TRANSLATORS: content rating description */
_("Mild or infrequent use of profanity") },
{ "language-profanity", MCT_APP_FILTER_OARS_VALUE_MODERATE,
/* TRANSLATORS: content rating description */
_("Moderate use of profanity") },
{ "language-profanity", MCT_APP_FILTER_OARS_VALUE_INTENSE,
/* TRANSLATORS: content rating description */
_("Strong or frequent use of profanity") },
{ "language-humor", MCT_APP_FILTER_OARS_VALUE_NONE,
/* TRANSLATORS: content rating description */
_("No inappropriate humor") },
{ "language-humor", MCT_APP_FILTER_OARS_VALUE_MILD,
/* TRANSLATORS: content rating description */
_("Slapstick humor") },
{ "language-humor", MCT_APP_FILTER_OARS_VALUE_MODERATE,
/* TRANSLATORS: content rating description */
_("Vulgar or bathroom humor") },
{ "language-humor", MCT_APP_FILTER_OARS_VALUE_INTENSE,
/* TRANSLATORS: content rating description */
_("Mature or sexual humor") },
{ "language-discrimination", MCT_APP_FILTER_OARS_VALUE_NONE,
/* TRANSLATORS: content rating description */
_("No discriminatory language of any kind") },
{ "language-discrimination", MCT_APP_FILTER_OARS_VALUE_MILD,
/* TRANSLATORS: content rating description */
_("Negativity towards a specific group of people") },
{ "language-discrimination", MCT_APP_FILTER_OARS_VALUE_MODERATE,
/* TRANSLATORS: content rating description */
_("Discrimination designed to cause emotional harm") },
{ "language-discrimination", MCT_APP_FILTER_OARS_VALUE_INTENSE,
/* TRANSLATORS: content rating description */
_("Explicit discrimination based on gender, sexuality, race or religion") },
{ "money-advertising", MCT_APP_FILTER_OARS_VALUE_NONE,
/* TRANSLATORS: content rating description */
_("No advertising of any kind") },
{ "money-advertising", MCT_APP_FILTER_OARS_VALUE_MILD,
/* TRANSLATORS: content rating description */
_("Product placement") },
{ "money-advertising", MCT_APP_FILTER_OARS_VALUE_MODERATE,
/* TRANSLATORS: content rating description */
_("Explicit references to specific brands or trademarked products") },
{ "money-advertising", MCT_APP_FILTER_OARS_VALUE_INTENSE,
/* TRANSLATORS: content rating description */
_("Users are encouraged to purchase specific real-world items") },
{ "money-gambling", MCT_APP_FILTER_OARS_VALUE_NONE,
/* TRANSLATORS: content rating description */
_("No gambling of any kind") },
{ "money-gambling", MCT_APP_FILTER_OARS_VALUE_MILD,
/* TRANSLATORS: content rating description */
_("Gambling on random events using tokens or credits") },
{ "money-gambling", MCT_APP_FILTER_OARS_VALUE_MODERATE,
/* TRANSLATORS: content rating description */
_("Gambling using “play” money") },
{ "money-gambling", MCT_APP_FILTER_OARS_VALUE_INTENSE,
/* TRANSLATORS: content rating description */
_("Gambling using real money") },
{ "money-purchasing", MCT_APP_FILTER_OARS_VALUE_NONE,
/* TRANSLATORS: content rating description */
_("No ability to spend money") },
{ "money-purchasing", MCT_APP_FILTER_OARS_VALUE_MILD, /* v1.1 */
/* TRANSLATORS: content rating description */
_("Users are encouraged to donate real money") },
{ "money-purchasing", MCT_APP_FILTER_OARS_VALUE_INTENSE,
/* TRANSLATORS: content rating description */
_("Ability to spend real money in-game") },
{ "social-chat", MCT_APP_FILTER_OARS_VALUE_NONE,
/* TRANSLATORS: content rating description */
_("No way to chat with other users") },
{ "social-chat", MCT_APP_FILTER_OARS_VALUE_MILD,
/* TRANSLATORS: content rating description */
_("User-to-user game interactions without chat functionality") },
{ "social-chat", MCT_APP_FILTER_OARS_VALUE_MODERATE,
/* TRANSLATORS: content rating description */
_("Moderated chat functionality between users") },
{ "social-chat", MCT_APP_FILTER_OARS_VALUE_INTENSE,
/* TRANSLATORS: content rating description */
_("Uncontrolled chat functionality between users") },
{ "social-audio", MCT_APP_FILTER_OARS_VALUE_NONE,
/* TRANSLATORS: content rating description */
_("No way to talk with other users") },
{ "social-audio", MCT_APP_FILTER_OARS_VALUE_INTENSE,
/* TRANSLATORS: content rating description */
_("Uncontrolled audio or video chat functionality between users") },
{ "social-contacts", MCT_APP_FILTER_OARS_VALUE_NONE,
/* TRANSLATORS: content rating description */
_("No sharing of social network usernames or email addresses") },
{ "social-contacts", MCT_APP_FILTER_OARS_VALUE_INTENSE,
/* TRANSLATORS: content rating description */
_("Sharing social network usernames or email addresses") },
{ "social-info", MCT_APP_FILTER_OARS_VALUE_NONE,
/* TRANSLATORS: content rating description */
_("No sharing of user information with 3rd parties") },
{ "social-info", MCT_APP_FILTER_OARS_VALUE_MILD, /* v1.1 */
/* TRANSLATORS: content rating description */
_("Checking for the latest application version") },
{ "social-info", MCT_APP_FILTER_OARS_VALUE_MODERATE, /* v1.1 */
/* TRANSLATORS: content rating description */
_("Sharing diagnostic data that does not let others identify the user") },
{ "social-info", MCT_APP_FILTER_OARS_VALUE_INTENSE,
/* TRANSLATORS: content rating description */
_("Sharing information that lets others identify the user") },
{ "social-location", MCT_APP_FILTER_OARS_VALUE_NONE,
/* TRANSLATORS: content rating description */
_("No sharing of physical location to other users") },
{ "social-location", MCT_APP_FILTER_OARS_VALUE_INTENSE,
/* TRANSLATORS: content rating description */
_("Sharing physical location to other users") },
/* v1.1 */
{ "sex-homosexuality", MCT_APP_FILTER_OARS_VALUE_NONE,
/* TRANSLATORS: content rating description */
_("No references to homosexuality") },
{ "sex-homosexuality", MCT_APP_FILTER_OARS_VALUE_MILD,
/* TRANSLATORS: content rating description */
_("Indirect references to homosexuality") },
{ "sex-homosexuality", MCT_APP_FILTER_OARS_VALUE_MODERATE,
/* TRANSLATORS: content rating description */
_("Kissing between people of the same gender") },
{ "sex-homosexuality", MCT_APP_FILTER_OARS_VALUE_INTENSE,
/* TRANSLATORS: content rating description */
_("Graphic sexual behavior between people of the same gender") },
{ "sex-prostitution", MCT_APP_FILTER_OARS_VALUE_NONE,
/* TRANSLATORS: content rating description */
_("No references to prostitution") },
{ "sex-prostitution", MCT_APP_FILTER_OARS_VALUE_MILD,
/* TRANSLATORS: content rating description */
_("Indirect references to prostitution") },
{ "sex-prostitution", MCT_APP_FILTER_OARS_VALUE_MODERATE,
/* TRANSLATORS: content rating description */
_("Direct references to prostitution") },
{ "sex-prostitution", MCT_APP_FILTER_OARS_VALUE_INTENSE,
/* TRANSLATORS: content rating description */
_("Graphic depictions of the act of prostitution") },
{ "sex-adultery", MCT_APP_FILTER_OARS_VALUE_NONE,
/* TRANSLATORS: content rating description */
_("No references to adultery") },
{ "sex-adultery", MCT_APP_FILTER_OARS_VALUE_MILD,
/* TRANSLATORS: content rating description */
_("Indirect references to adultery") },
{ "sex-adultery", MCT_APP_FILTER_OARS_VALUE_MODERATE,
/* TRANSLATORS: content rating description */
_("Direct references to adultery") },
{ "sex-adultery", MCT_APP_FILTER_OARS_VALUE_INTENSE,
/* TRANSLATORS: content rating description */
_("Graphic depictions of the act of adultery") },
{ "sex-appearance", MCT_APP_FILTER_OARS_VALUE_NONE,
/* TRANSLATORS: content rating description */
_("No sexualized characters") },
{ "sex-appearance", MCT_APP_FILTER_OARS_VALUE_MODERATE,
/* TRANSLATORS: content rating description */
_("Scantily clad human characters") },
{ "sex-appearance", MCT_APP_FILTER_OARS_VALUE_INTENSE,
/* TRANSLATORS: content rating description */
_("Overtly sexualized human characters") },
{ "violence-worship", MCT_APP_FILTER_OARS_VALUE_NONE,
/* TRANSLATORS: content rating description */
_("No references to desecration") },
{ "violence-worship", MCT_APP_FILTER_OARS_VALUE_MILD,
/* TRANSLATORS: content rating description */
_("Depictions or references to historical desecration") },
{ "violence-worship", MCT_APP_FILTER_OARS_VALUE_MODERATE,
/* TRANSLATORS: content rating description */
_("Depictions of modern-day human desecration") },
{ "violence-worship", MCT_APP_FILTER_OARS_VALUE_INTENSE,
/* TRANSLATORS: content rating description */
_("Graphic depictions of modern-day desecration") },
{ "violence-desecration", MCT_APP_FILTER_OARS_VALUE_NONE,
/* TRANSLATORS: content rating description */
_("No visible dead human remains") },
{ "violence-desecration", MCT_APP_FILTER_OARS_VALUE_MILD,
/* TRANSLATORS: content rating description */
_("Visible dead human remains") },
{ "violence-desecration", MCT_APP_FILTER_OARS_VALUE_MODERATE,
/* TRANSLATORS: content rating description */
_("Dead human remains that are exposed to the elements") },
{ "violence-desecration", MCT_APP_FILTER_OARS_VALUE_INTENSE,
/* TRANSLATORS: content rating description */
_("Graphic depictions of desecration of human bodies") },
{ "violence-slavery", MCT_APP_FILTER_OARS_VALUE_NONE,
/* TRANSLATORS: content rating description */
_("No references to slavery") },
{ "violence-slavery", MCT_APP_FILTER_OARS_VALUE_MILD,
/* TRANSLATORS: content rating description */
_("Depictions or references to historical slavery") },
{ "violence-slavery", MCT_APP_FILTER_OARS_VALUE_MODERATE,
/* TRANSLATORS: content rating description */
_("Depictions of modern-day slavery") },
{ "violence-slavery", MCT_APP_FILTER_OARS_VALUE_INTENSE,
/* TRANSLATORS: content rating description */
_("Graphic depictions of modern-day slavery") },
{ NULL, 0, NULL } };
for (i = 0; tab[i].id != NULL; i++) {
if (g_strcmp0 (tab[i].id, id) == 0 && tab[i].value == value)
return tab[i].desc;
}
return NULL;
}
/* data obtained from https://en.wikipedia.org/wiki/Video_game_rating_system */
const gchar *
gs_utils_content_rating_age_to_str (GsContentRatingSystem system, guint age)
{
if (system == GS_CONTENT_RATING_SYSTEM_INCAA) {
if (age >= 18)
return "+18";
if (age >= 13)
return "+13";
return "ATP";
}
if (system == GS_CONTENT_RATING_SYSTEM_ACB) {
if (age >= 18)
return "R18+";
if (age >= 15)
return "MA15+";
return "PG";
}
if (system == GS_CONTENT_RATING_SYSTEM_DJCTQ) {
if (age >= 18)
return "18";
if (age >= 16)
return "16";
if (age >= 14)
return "14";
if (age >= 12)
return "12";
if (age >= 10)
return "10";
return "L";
}
if (system == GS_CONTENT_RATING_SYSTEM_GSRR) {
if (age >= 18)
return "限制";
if (age >= 15)
return "輔15";
if (age >= 12)
return "輔12";
if (age >= 6)
return "保護";
return "普通";
}
if (system == GS_CONTENT_RATING_SYSTEM_PEGI) {
if (age >= 18)
return "18";
if (age >= 16)
return "16";
if (age >= 12)
return "12";
if (age >= 7)
return "7";
if (age >= 3)
return "3";
return NULL;
}
if (system == GS_CONTENT_RATING_SYSTEM_KAVI) {
if (age >= 18)
return "18+";
if (age >= 16)
return "16+";
if (age >= 12)
return "12+";
if (age >= 7)
return "7+";
if (age >= 3)
return "3+";
return NULL;
}
if (system == GS_CONTENT_RATING_SYSTEM_USK) {
if (age >= 18)
return "18";
if (age >= 16)
return "16";
if (age >= 12)
return "12";
if (age >= 6)
return "6";
return "0";
}
/* Reference: http://www.esra.org.ir/ */
if (system == GS_CONTENT_RATING_SYSTEM_ESRA) {
if (age >= 18)
return "+18";
if (age >= 15)
return "+15";
if (age >= 12)
return "+12";
if (age >= 7)
return "+7";
if (age >= 3)
return "+3";
return NULL;
}
if (system == GS_CONTENT_RATING_SYSTEM_CERO) {
if (age >= 18)
return "Z";
if (age >= 17)
return "D";
if (age >= 15)
return "C";
if (age >= 12)
return "B";
return "A";
}
if (system == GS_CONTENT_RATING_SYSTEM_OFLCNZ) {
if (age >= 18)
return "R18";
if (age >= 16)
return "R16";
if (age >= 15)
return "R15";
if (age >= 13)
return "R13";
return "G";
}
if (system == GS_CONTENT_RATING_SYSTEM_RUSSIA) {
if (age >= 18)
return "18+";
if (age >= 16)
return "16+";
if (age >= 12)
return "12+";
if (age >= 6)
return "6+";
return "0+";
}
if (system == GS_CONTENT_RATING_SYSTEM_MDA) {
if (age >= 18)
return "M18";
if (age >= 16)
return "ADV";
return "General";
}
if (system == GS_CONTENT_RATING_SYSTEM_GRAC) {
if (age >= 18)
return "18";
if (age >= 15)
return "15";
if (age >= 12)
return "12";
return "ALL";
}
if (system == GS_CONTENT_RATING_SYSTEM_ESRB) {
if (age >= 18)
return "Adults Only";
if (age >= 17)
return "Mature";
if (age >= 13)
return "Teen";
if (age >= 10)
return "Everyone 10+";
if (age >= 6)
return "Everyone";
return "Early Childhood";
}
/* IARC = everything else */
if (age >= 18)
return "18+";
if (age >= 16)
return "16+";
if (age >= 12)
return "12+";
if (age >= 7)
return "7+";
if (age >= 3)
return "3+";
return NULL;
}
/*
* parse_locale:
* @locale: (transfer full): a locale to parse
* @language_out: (out) (optional) (nullable): return location for the parsed
* language, or %NULL to ignore
* @territory_out: (out) (optional) (nullable): return location for the parsed
* territory, or %NULL to ignore
* @codeset_out: (out) (optional) (nullable): return location for the parsed
* codeset, or %NULL to ignore
* @modifier_out: (out) (optional) (nullable): return location for the parsed
* modifier, or %NULL to ignore
*
* Parse @locale as a locale string of the form
* `language[_territory][.codeset][@modifier]` see `man 3 setlocale` for
* details.
*
* On success, %TRUE will be returned, and the components of the locale will be
* returned in the given addresses, with each component not including any
* separators. Otherwise, %FALSE will be returned and the components will be set
* to %NULL.
*
* @locale is modified, and any returned non-%NULL pointers will point inside
* it.
*
* Returns: %TRUE on success, %FALSE otherwise
*/
static gboolean
parse_locale (gchar *locale /* (transfer full) */,
const gchar **language_out,
const gchar **territory_out,
const gchar **codeset_out,
const gchar **modifier_out)
{
gchar *separator;
const gchar *language = NULL, *territory = NULL, *codeset = NULL, *modifier = NULL;
separator = strrchr (locale, '@');
if (separator != NULL) {
modifier = separator + 1;
*separator = '\0';
}
separator = strrchr (locale, '.');
if (separator != NULL) {
codeset = separator + 1;
*separator = '\0';
}
separator = strrchr (locale, '_');
if (separator != NULL) {
territory = separator + 1;
*separator = '\0';
}
language = locale;
/* Parse failure? */
if (*language == '\0') {
language = NULL;
territory = NULL;
codeset = NULL;
modifier = NULL;
}
if (language_out != NULL)
*language_out = language;
if (territory_out != NULL)
*territory_out = territory;
if (codeset_out != NULL)
*codeset_out = codeset;
if (modifier_out != NULL)
*modifier_out = modifier;
return (language != NULL);
}
/* data obtained from https://en.wikipedia.org/wiki/Video_game_rating_system */
GsContentRatingSystem
gs_utils_content_rating_system_from_locale (const gchar *locale)
{
g_autofree gchar *locale_copy = g_strdup (locale);
const gchar *language, *territory;
/* Default to IARC for locales which cant be parsed. */
if (!parse_locale (locale_copy, &language, &territory, NULL, NULL))
return GS_CONTENT_RATING_SYSTEM_IARC;
/* Argentina */
if (g_strcmp0 (language, "ar") == 0)
return GS_CONTENT_RATING_SYSTEM_INCAA;
/* Australia */
if (g_strcmp0 (language, "au") == 0)
return GS_CONTENT_RATING_SYSTEM_ACB;
/* Brazil */
if (g_strcmp0 (language, "pt") == 0 &&
g_strcmp0 (territory, "BR") == 0)
return GS_CONTENT_RATING_SYSTEM_DJCTQ;
/* Taiwan */
if (g_strcmp0 (language, "zh") == 0 &&
g_strcmp0 (territory, "TW") == 0)
return GS_CONTENT_RATING_SYSTEM_GSRR;
/* Europe (but not Finland or Germany), India, Israel,
* Pakistan, Quebec, South Africa */
if ((g_strcmp0 (language, "en") == 0 &&
g_strcmp0 (territory, "GB") == 0) ||
g_strcmp0 (language, "gb") == 0 ||
g_strcmp0 (language, "al") == 0 ||
g_strcmp0 (language, "ad") == 0 ||
g_strcmp0 (language, "am") == 0 ||
g_strcmp0 (language, "at") == 0 ||
g_strcmp0 (language, "az") == 0 ||
g_strcmp0 (language, "by") == 0 ||
g_strcmp0 (language, "be") == 0 ||
g_strcmp0 (language, "ba") == 0 ||
g_strcmp0 (language, "bg") == 0 ||
g_strcmp0 (language, "hr") == 0 ||
g_strcmp0 (language, "cy") == 0 ||
g_strcmp0 (language, "cz") == 0 ||
g_strcmp0 (language, "dk") == 0 ||
g_strcmp0 (language, "ee") == 0 ||
g_strcmp0 (language, "fr") == 0 ||
g_strcmp0 (language, "ge") == 0 ||
g_strcmp0 (language, "gr") == 0 ||
g_strcmp0 (language, "hu") == 0 ||
g_strcmp0 (language, "is") == 0 ||
g_strcmp0 (language, "it") == 0 ||
g_strcmp0 (language, "kz") == 0 ||
g_strcmp0 (language, "xk") == 0 ||
g_strcmp0 (language, "lv") == 0 ||
g_strcmp0 (language, "fl") == 0 ||
g_strcmp0 (language, "lu") == 0 ||
g_strcmp0 (language, "lt") == 0 ||
g_strcmp0 (language, "mk") == 0 ||
g_strcmp0 (language, "mt") == 0 ||
g_strcmp0 (language, "md") == 0 ||
g_strcmp0 (language, "mc") == 0 ||
g_strcmp0 (language, "me") == 0 ||
g_strcmp0 (language, "nl") == 0 ||
g_strcmp0 (language, "no") == 0 ||
g_strcmp0 (language, "pl") == 0 ||
g_strcmp0 (language, "pt") == 0 ||
g_strcmp0 (language, "ro") == 0 ||
g_strcmp0 (language, "sm") == 0 ||
g_strcmp0 (language, "rs") == 0 ||
g_strcmp0 (language, "sk") == 0 ||
g_strcmp0 (language, "si") == 0 ||
g_strcmp0 (language, "es") == 0 ||
g_strcmp0 (language, "se") == 0 ||
g_strcmp0 (language, "ch") == 0 ||
g_strcmp0 (language, "tr") == 0 ||
g_strcmp0 (language, "ua") == 0 ||
g_strcmp0 (language, "va") == 0 ||
g_strcmp0 (language, "in") == 0 ||
g_strcmp0 (language, "il") == 0 ||
g_strcmp0 (language, "pk") == 0 ||
g_strcmp0 (language, "za") == 0)
return GS_CONTENT_RATING_SYSTEM_PEGI;
/* Finland */
if (g_strcmp0 (language, "fi") == 0)
return GS_CONTENT_RATING_SYSTEM_KAVI;
/* Germany */
if (g_strcmp0 (language, "de") == 0)
return GS_CONTENT_RATING_SYSTEM_USK;
/* Iran */
if (g_strcmp0 (language, "ir") == 0)
return GS_CONTENT_RATING_SYSTEM_ESRA;
/* Japan */
if (g_strcmp0 (language, "jp") == 0)
return GS_CONTENT_RATING_SYSTEM_CERO;
/* New Zealand */
if (g_strcmp0 (language, "nz") == 0)
return GS_CONTENT_RATING_SYSTEM_OFLCNZ;
/* Russia: Content rating law */
if (g_strcmp0 (language, "ru") == 0)
return GS_CONTENT_RATING_SYSTEM_RUSSIA;
/* Singapore */
if (g_strcmp0 (language, "sg") == 0)
return GS_CONTENT_RATING_SYSTEM_MDA;
/* South Korea */
if (g_strcmp0 (language, "kr") == 0)
return GS_CONTENT_RATING_SYSTEM_GRAC;
/* USA, Canada, Mexico */
if ((g_strcmp0 (language, "en") == 0 &&
g_strcmp0 (territory, "US") == 0) ||
g_strcmp0 (language, "us") == 0 ||
g_strcmp0 (language, "ca") == 0 ||
g_strcmp0 (language, "mx") == 0)
return GS_CONTENT_RATING_SYSTEM_ESRB;
/* everything else is IARC */
return GS_CONTENT_RATING_SYSTEM_IARC;
}
static const gchar *content_rating_strings[GS_CONTENT_RATING_SYSTEM_LAST][7] = {
{ "3+", "7+", "12+", "16+", "18+", NULL }, /* GS_CONTENT_RATING_SYSTEM_UNKNOWN */
{ "ATP", "+13", "+18", NULL }, /* GS_CONTENT_RATING_SYSTEM_INCAA */
{ "PG", "MA15+", "R18+", NULL }, /* GS_CONTENT_RATING_SYSTEM_ACB */
{ "L", "10", "12", "14", "16", "18", NULL }, /* GS_CONTENT_RATING_SYSTEM_DJCTQ */
{ "普通", "保護", "輔12", "輔15", "限制", NULL }, /* GS_CONTENT_RATING_SYSTEM_GSRR */
{ "3", "7", "12", "16", "18", NULL }, /* GS_CONTENT_RATING_SYSTEM_PEGI */
{ "3+", "7+", "12+", "16+", "18+", NULL }, /* GS_CONTENT_RATING_SYSTEM_KAVI */
{ "0", "6", "12", "16", "18", NULL}, /* GS_CONTENT_RATING_SYSTEM_USK */
{ "+3", "+7", "+12", "+15", "+18", NULL }, /* GS_CONTENT_RATING_SYSTEM_ESRA */
{ "A", "B", "C", "D", "Z", NULL }, /* GS_CONTENT_RATING_SYSTEM_CERO */
{ "G", "R13", "R15", "R16", "R18", NULL }, /* GS_CONTENT_RATING_SYSTEM_OFLCNZ */
{ "0+", "6+", "12+", "16+", "18+", NULL }, /* GS_CONTENT_RATING_SYSTEM_RUSSIA */
{ "General", "ADV", "M18", NULL }, /* GS_CONTENT_RATING_SYSTEM_MDA */
{ "ALL", "12", "15", "18", NULL }, /* GS_CONTENT_RATING_SYSTEM_GRAC */
{ "Early Childhood", "Everyone", "Everyone 10+", "Teen", "Mature", "Adults Only", NULL }, /* GS_CONTENT_RATING_SYSTEM_ESRB */
{ "3+", "7+", "12+", "16+", "18+", NULL }, /* GS_CONTENT_RATING_SYSTEM_IARC */
};
const gchar * const *
gs_utils_content_rating_get_values (GsContentRatingSystem system)
{
g_assert (system < GS_CONTENT_RATING_SYSTEM_LAST);
return content_rating_strings[system];
}
static guint content_rating_ages[GS_CONTENT_RATING_SYSTEM_LAST][7] = {
{ 3, 7, 12, 16, 18 }, /* GS_CONTENT_RATING_SYSTEM_UNKNOWN */
{ 0, 13, 18 }, /* GS_CONTENT_RATING_SYSTEM_INCAA */
{ 0, 15, 18 }, /* GS_CONTENT_RATING_SYSTEM_ACB */
{ 0, 10, 12, 14, 16, 18 }, /* GS_CONTENT_RATING_SYSTEM_DJCTQ */
{ 0, 6, 12, 15, 18 }, /* GS_CONTENT_RATING_SYSTEM_GSRR */
{ 3, 7, 12, 16, 18 }, /* GS_CONTENT_RATING_SYSTEM_PEGI */
{ 3, 7, 12, 16, 18 }, /* GS_CONTENT_RATING_SYSTEM_KAVI */
{ 0, 6, 12, 16, 18 }, /* GS_CONTENT_RATING_SYSTEM_USK */
{ 3, 7, 12, 15, 18 }, /* GS_CONTENT_RATING_SYSTEM_ESRA */
{ 0, 12, 15, 17, 18 }, /* GS_CONTENT_RATING_SYSTEM_CERO */
{ 0, 13, 15, 16, 18 }, /* GS_CONTENT_RATING_SYSTEM_OFLCNZ */
{ 0, 6, 12, 16, 18 }, /* GS_CONTENT_RATING_SYSTEM_RUSSIA */
{ 0, 16, 18 }, /* GS_CONTENT_RATING_SYSTEM_MDA */
{ 0, 12, 15, 18 }, /* GS_CONTENT_RATING_SYSTEM_GRAC */
{ 0, 6, 10, 13, 17, 18 }, /* GS_CONTENT_RATING_SYSTEM_ESRB */
{ 3, 7, 12, 16, 18 }, /* GS_CONTENT_RATING_SYSTEM_IARC */
};
const guint *
gs_utils_content_rating_get_ages (GsContentRatingSystem system)
{
g_assert (system < GS_CONTENT_RATING_SYSTEM_LAST);
return content_rating_ages[system];
}
const struct {
const gchar *id;
MctAppFilterOarsValue value;
guint csm_age;
} id_to_csm_age[] = {
/* v1.0 */
{ "violence-cartoon", MCT_APP_FILTER_OARS_VALUE_NONE, 0 },
{ "violence-cartoon", MCT_APP_FILTER_OARS_VALUE_MILD, 3 },
{ "violence-cartoon", MCT_APP_FILTER_OARS_VALUE_MODERATE, 4 },
{ "violence-cartoon", MCT_APP_FILTER_OARS_VALUE_INTENSE, 6 },
{ "violence-fantasy", MCT_APP_FILTER_OARS_VALUE_NONE, 0 },
{ "violence-fantasy", MCT_APP_FILTER_OARS_VALUE_MILD, 3 },
{ "violence-fantasy", MCT_APP_FILTER_OARS_VALUE_MODERATE, 7 },
{ "violence-fantasy", MCT_APP_FILTER_OARS_VALUE_INTENSE, 8 },
{ "violence-realistic", MCT_APP_FILTER_OARS_VALUE_NONE, 0 },
{ "violence-realistic", MCT_APP_FILTER_OARS_VALUE_MILD, 4 },
{ "violence-realistic", MCT_APP_FILTER_OARS_VALUE_MODERATE, 9 },
{ "violence-realistic", MCT_APP_FILTER_OARS_VALUE_INTENSE, 14 },
{ "violence-bloodshed", MCT_APP_FILTER_OARS_VALUE_NONE, 0 },
{ "violence-bloodshed", MCT_APP_FILTER_OARS_VALUE_MILD, 9 },
{ "violence-bloodshed", MCT_APP_FILTER_OARS_VALUE_MODERATE, 11 },
{ "violence-bloodshed", MCT_APP_FILTER_OARS_VALUE_INTENSE, 18 },
{ "violence-sexual", MCT_APP_FILTER_OARS_VALUE_NONE, 0 },
{ "violence-sexual", MCT_APP_FILTER_OARS_VALUE_INTENSE, 18 },
{ "drugs-alcohol", MCT_APP_FILTER_OARS_VALUE_NONE, 0 },
{ "drugs-alcohol", MCT_APP_FILTER_OARS_VALUE_MILD, 11 },
{ "drugs-alcohol", MCT_APP_FILTER_OARS_VALUE_MODERATE, 13 },
{ "drugs-narcotics", MCT_APP_FILTER_OARS_VALUE_NONE, 0 },
{ "drugs-narcotics", MCT_APP_FILTER_OARS_VALUE_MILD, 12 },
{ "drugs-narcotics", MCT_APP_FILTER_OARS_VALUE_MODERATE, 14 },
{ "drugs-tobacco", MCT_APP_FILTER_OARS_VALUE_NONE, 0 },
{ "drugs-tobacco", MCT_APP_FILTER_OARS_VALUE_MILD, 10 },
{ "drugs-tobacco", MCT_APP_FILTER_OARS_VALUE_MODERATE, 13 },
{ "sex-nudity", MCT_APP_FILTER_OARS_VALUE_NONE, 0 },
{ "sex-nudity", MCT_APP_FILTER_OARS_VALUE_MILD, 12 },
{ "sex-nudity", MCT_APP_FILTER_OARS_VALUE_MODERATE, 14 },
{ "sex-themes", MCT_APP_FILTER_OARS_VALUE_NONE, 0 },
{ "sex-themes", MCT_APP_FILTER_OARS_VALUE_MILD, 13 },
{ "sex-themes", MCT_APP_FILTER_OARS_VALUE_MODERATE, 14 },
{ "sex-themes", MCT_APP_FILTER_OARS_VALUE_INTENSE, 15 },
{ "language-profanity", MCT_APP_FILTER_OARS_VALUE_NONE, 0 },
{ "language-profanity", MCT_APP_FILTER_OARS_VALUE_MILD, 8 },
{ "language-profanity", MCT_APP_FILTER_OARS_VALUE_MODERATE, 11 },
{ "language-profanity", MCT_APP_FILTER_OARS_VALUE_INTENSE, 14 },
{ "language-humor", MCT_APP_FILTER_OARS_VALUE_NONE, 0 },
{ "language-humor", MCT_APP_FILTER_OARS_VALUE_MILD, 3 },
{ "language-humor", MCT_APP_FILTER_OARS_VALUE_MODERATE, 8 },
{ "language-humor", MCT_APP_FILTER_OARS_VALUE_INTENSE, 14 },
{ "language-discrimination", MCT_APP_FILTER_OARS_VALUE_NONE, 0 },
{ "language-discrimination", MCT_APP_FILTER_OARS_VALUE_MILD, 9 },
{ "language-discrimination", MCT_APP_FILTER_OARS_VALUE_MODERATE,10 },
{ "language-discrimination", MCT_APP_FILTER_OARS_VALUE_INTENSE, 11 },
{ "money-advertising", MCT_APP_FILTER_OARS_VALUE_NONE, 0 },
{ "money-advertising", MCT_APP_FILTER_OARS_VALUE_MILD, 7 },
{ "money-advertising", MCT_APP_FILTER_OARS_VALUE_MODERATE, 8 },
{ "money-advertising", MCT_APP_FILTER_OARS_VALUE_INTENSE, 10 },
{ "money-gambling", MCT_APP_FILTER_OARS_VALUE_NONE, 0 },
{ "money-gambling", MCT_APP_FILTER_OARS_VALUE_MILD, 7 },
{ "money-gambling", MCT_APP_FILTER_OARS_VALUE_MODERATE, 10 },
{ "money-gambling", MCT_APP_FILTER_OARS_VALUE_INTENSE, 18 },
{ "money-purchasing", MCT_APP_FILTER_OARS_VALUE_NONE, 0 },
{ "money-purchasing", MCT_APP_FILTER_OARS_VALUE_INTENSE, 15 },
{ "social-chat", MCT_APP_FILTER_OARS_VALUE_NONE, 0 },
{ "social-chat", MCT_APP_FILTER_OARS_VALUE_MILD, 4 },
{ "social-chat", MCT_APP_FILTER_OARS_VALUE_MODERATE, 10 },
{ "social-chat", MCT_APP_FILTER_OARS_VALUE_INTENSE, 13 },
{ "social-audio", MCT_APP_FILTER_OARS_VALUE_NONE, 0 },
{ "social-audio", MCT_APP_FILTER_OARS_VALUE_INTENSE, 15 },
{ "social-contacts", MCT_APP_FILTER_OARS_VALUE_NONE, 0 },
{ "social-contacts", MCT_APP_FILTER_OARS_VALUE_INTENSE, 12 },
{ "social-info", MCT_APP_FILTER_OARS_VALUE_NONE, 0 },
{ "social-info", MCT_APP_FILTER_OARS_VALUE_INTENSE, 13 },
{ "social-location", MCT_APP_FILTER_OARS_VALUE_NONE, 0 },
{ "social-location", MCT_APP_FILTER_OARS_VALUE_INTENSE, 13 },
/* v1.1 additions */
{ "social-info", MCT_APP_FILTER_OARS_VALUE_MILD, 0 },
{ "social-info", MCT_APP_FILTER_OARS_VALUE_MODERATE, 13 },
{ "money-purchasing", MCT_APP_FILTER_OARS_VALUE_MILD, 12 },
{ "social-chat", MCT_APP_FILTER_OARS_VALUE_MODERATE, 14 },
{ "sex-homosexuality", MCT_APP_FILTER_OARS_VALUE_NONE, 0 },
{ "sex-homosexuality", MCT_APP_FILTER_OARS_VALUE_MILD, 10 },
{ "sex-homosexuality", MCT_APP_FILTER_OARS_VALUE_MODERATE, 13 },
{ "sex-homosexuality", MCT_APP_FILTER_OARS_VALUE_INTENSE, 18 },
{ "sex-prostitution", MCT_APP_FILTER_OARS_VALUE_NONE, 0 },
{ "sex-prostitution", MCT_APP_FILTER_OARS_VALUE_MILD, 12 },
{ "sex-prostitution", MCT_APP_FILTER_OARS_VALUE_MODERATE, 14 },
{ "sex-prostitution", MCT_APP_FILTER_OARS_VALUE_INTENSE, 18 },
{ "sex-adultery", MCT_APP_FILTER_OARS_VALUE_NONE, 0 },
{ "sex-adultery", MCT_APP_FILTER_OARS_VALUE_MILD, 8 },
{ "sex-adultery", MCT_APP_FILTER_OARS_VALUE_MODERATE, 10 },
{ "sex-adultery", MCT_APP_FILTER_OARS_VALUE_INTENSE, 18 },
{ "sex-appearance", MCT_APP_FILTER_OARS_VALUE_NONE, 0 },
{ "sex-appearance", MCT_APP_FILTER_OARS_VALUE_MODERATE, 10 },
{ "sex-appearance", MCT_APP_FILTER_OARS_VALUE_INTENSE, 15 },
{ "violence-worship", MCT_APP_FILTER_OARS_VALUE_NONE, 0 },
{ "violence-worship", MCT_APP_FILTER_OARS_VALUE_MILD, 13 },
{ "violence-worship", MCT_APP_FILTER_OARS_VALUE_MODERATE, 15 },
{ "violence-worship", MCT_APP_FILTER_OARS_VALUE_INTENSE, 18 },
{ "violence-desecration", MCT_APP_FILTER_OARS_VALUE_NONE, 0 },
{ "violence-desecration", MCT_APP_FILTER_OARS_VALUE_MILD, 13 },
{ "violence-desecration", MCT_APP_FILTER_OARS_VALUE_MODERATE, 15 },
{ "violence-desecration", MCT_APP_FILTER_OARS_VALUE_INTENSE, 18 },
{ "violence-slavery", MCT_APP_FILTER_OARS_VALUE_NONE, 0 },
{ "violence-slavery", MCT_APP_FILTER_OARS_VALUE_MILD, 13 },
{ "violence-slavery", MCT_APP_FILTER_OARS_VALUE_MODERATE, 15 },
{ "violence-slavery", MCT_APP_FILTER_OARS_VALUE_INTENSE, 18 },
/* EOS customisation to add at least one CSM ↔ OARS mapping for ages 16 and 17,
* as these are used in many locale-specific ratings systems. Without them,
* mapping (e.g.) OFLCNZ R16 CSM 16 OARS CSM gives CSM 15, which then maps
* back to OFLCNZ R15, which is not what we want. The addition of these two
* mappings should not expose younger users to content they would not have seen
* with the default upstream mappings; it instead slightly raises the age at
* which users are allowed to see intense content in these two categories.
*
* See https://phabricator.endlessm.com/T23897#666769. */
{ "drugs-alcohol", MCT_APP_FILTER_OARS_VALUE_INTENSE, 16 },
{ "drugs-narcotics", MCT_APP_FILTER_OARS_VALUE_INTENSE, 17 },
{ NULL, 0, 0 } };
/**
* as_content_rating_id_value_to_csm_age:
* @id: the subsection ID e.g. "violence-cartoon"
* @value: the #AsContentRatingValue, e.g. %MCT_APP_FILTER_OARS_VALUE_INTENSE
*
* Gets the Common Sense Media approved age for a specific rating level.
*
* Returns: The age in years, or 0 for no details.
*
* Since: 0.5.12
**/
guint
as_content_rating_id_value_to_csm_age (const gchar *id, MctAppFilterOarsValue value)
{
guint i;
for (i = 0; id_to_csm_age[i].id != NULL; i++) {
if (value == id_to_csm_age[i].value &&
g_strcmp0 (id, id_to_csm_age[i].id) == 0)
return id_to_csm_age[i].csm_age;
}
return 0;
}
/**
* as_content_rating_id_csm_age_to_value:
* @id: the subsection ID e.g. "violence-cartoon"
* @age: the age
*
* Gets the #MctAppFilterOarsValue for a given age.
*
* Returns: the #MctAppFilterOarsValue
**/
MctAppFilterOarsValue
as_content_rating_id_csm_age_to_value (const gchar *id, guint age)
{
MctAppFilterOarsValue value;
guint i;
value = MCT_APP_FILTER_OARS_VALUE_UNKNOWN;
for (i = 0; id_to_csm_age[i].id != NULL; i++) {
if (age >= id_to_csm_age[i].csm_age &&
g_strcmp0 (id, id_to_csm_age[i].id) == 0)
value = MAX (value, id_to_csm_age[i].value);
}
return value;
}

View File

@ -0,0 +1,61 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2015-2016 Richard Hughes <richard@hughsie.com>
*
* Licensed under the GNU General Public License Version 2
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#pragma once
G_BEGIN_DECLS
#include <glib-object.h>
#include <libmalcontent/malcontent.h>
typedef enum {
GS_CONTENT_RATING_SYSTEM_UNKNOWN,
GS_CONTENT_RATING_SYSTEM_INCAA,
GS_CONTENT_RATING_SYSTEM_ACB,
GS_CONTENT_RATING_SYSTEM_DJCTQ,
GS_CONTENT_RATING_SYSTEM_GSRR,
GS_CONTENT_RATING_SYSTEM_PEGI,
GS_CONTENT_RATING_SYSTEM_KAVI,
GS_CONTENT_RATING_SYSTEM_USK,
GS_CONTENT_RATING_SYSTEM_ESRA,
GS_CONTENT_RATING_SYSTEM_CERO,
GS_CONTENT_RATING_SYSTEM_OFLCNZ,
GS_CONTENT_RATING_SYSTEM_RUSSIA,
GS_CONTENT_RATING_SYSTEM_MDA,
GS_CONTENT_RATING_SYSTEM_GRAC,
GS_CONTENT_RATING_SYSTEM_ESRB,
GS_CONTENT_RATING_SYSTEM_IARC,
/*< private >*/
GS_CONTENT_RATING_SYSTEM_LAST
} GsContentRatingSystem;
const gchar *gs_utils_content_rating_age_to_str (GsContentRatingSystem system,
guint age);
GsContentRatingSystem gs_utils_content_rating_system_from_locale (const gchar *locale);
const gchar *gs_content_rating_key_value_to_str (const gchar *id,
MctAppFilterOarsValue value);
const gchar *gs_content_rating_system_to_str (GsContentRatingSystem system);
const gchar * const *gs_utils_content_rating_get_values (GsContentRatingSystem system);
const guint *gs_utils_content_rating_get_ages (GsContentRatingSystem system);
guint as_content_rating_id_value_to_csm_age (const gchar *id, MctAppFilterOarsValue value);
MctAppFilterOarsValue as_content_rating_id_csm_age_to_value (const gchar *id, guint age);
G_END_DECLS

View File

@ -4,7 +4,6 @@
<gresource prefix="/org/freedesktop/MalcontentUi/ui">
<file preprocess="xml-stripblanks">restrict-applications-dialog.ui</file>
<file preprocess="xml-stripblanks">restrict-applications-selector.ui</file>
<file>restricts-switch.css</file>
<file preprocess="xml-stripblanks">user-controls.ui</file>
</gresource>
</gresources>

View File

@ -1,4 +1,4 @@
libmalcontent_ui_api_version = '1'
libmalcontent_ui_api_version = '0'
libmalcontent_ui_api_name = 'malcontent-ui-' + libmalcontent_ui_api_version
if not cc.has_function('atexit')
@ -8,10 +8,11 @@ endif
resources = gnome.compile_resources(
'resources',
'malcontent-ui.gresource.xml',
source_dir: meson.current_source_dir(),
source_dir: meson.source_root(),
)
libmalcontent_ui_sources = [
'gs-content-rating.c',
'restrict-applications-dialog.c',
'restrict-applications-selector.c',
'user-controls.c',
@ -22,18 +23,19 @@ libmalcontent_ui_headers = [
'restrict-applications-selector.h',
'user-controls.h',
]
libmalcontent_ui_private_headers = [
'gs-content-rating.h',
]
libmalcontent_ui_public_deps = [
dependency('accountsservice', version: '>= 0.6.39'),
dependency('gio-2.0', version: '>= 2.44'),
dependency('glib-2.0', version: '>= 2.54.2'),
dependency('gobject-2.0', version: '>= 2.54'),
gtk_dep,
libadwaita_dep,
dependency('gtk+-3.0', version: '>= 3.24'),
libmalcontent_dep,
]
libmalcontent_ui_private_deps = [
dependency('appstream', version: '>= 0.12.10'),
dependency('flatpak'),
]
@ -41,7 +43,7 @@ libmalcontent_ui_private_deps = [
libmalcontent_ui_include_subdir = join_paths(libmalcontent_ui_api_name, 'libmalcontent-ui')
libmalcontent_ui = library(libmalcontent_ui_api_name,
libmalcontent_ui_sources + libmalcontent_ui_headers,
libmalcontent_ui_sources + libmalcontent_ui_headers + libmalcontent_ui_private_headers,
dependencies: libmalcontent_ui_public_deps + libmalcontent_ui_private_deps,
include_directories: root_inc,
install: true,
@ -68,26 +70,26 @@ pkgconfig.generate(libmalcontent_ui,
libraries_private: libmalcontent_ui_private_deps,
)
libmalcontent_ui_gir = gnome.generate_gir(libmalcontent_ui,
sources: libmalcontent_ui_sources + libmalcontent_ui_headers,
gnome.generate_gir(libmalcontent_ui,
sources: libmalcontent_ui_sources + libmalcontent_ui_headers + libmalcontent_ui_private_headers,
nsversion: libmalcontent_ui_api_version,
namespace: 'MalcontentUi',
symbol_prefix: 'mct_',
identifier_prefix: 'Mct',
export_packages: 'libmalcontent-ui',
includes: ['AccountsService-1.0', 'Gio-2.0', 'GObject-2.0', 'Gtk-4.0', 'Adw-1', libmalcontent_gir[0]],
includes: ['AccountsService-1.0', 'Gio-2.0', 'GObject-2.0', 'Gtk-3.0'],
install: true,
dependencies: libmalcontent_ui_dep,
)
xmllint = find_program('xmllint', required: false)
if xmllint.found()
gtk_prefix = gtk_dep.get_variable(pkgconfig: 'prefix')
gtk_prefix = dependency('gtk+-3.0').get_pkgconfig_variable('prefix')
test(
'validate-ui', xmllint,
args: [
'--nonet', '--noblanks', '--noout',
'--relaxng', join_paths(gtk_prefix, 'share', 'gtk-4.0', 'gtk4builder.rng'),
'--relaxng', join_paths(gtk_prefix, 'share', 'gtk-3.0', 'gtkbuilder.rng'),
files(
'restrict-applications-dialog.ui',
'restrict-applications-selector.ui',

View File

@ -19,14 +19,12 @@
* - Philip Withnall <withnall@endlessm.com>
*/
#include "config.h"
#include <act/act.h>
#include <gio/gio.h>
#include <glib.h>
#include <glib-object.h>
#include <glib/gi18n-lib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <adwaita.h>
#include "restrict-applications-dialog.h"
#include "restrict-applications-selector.h"
@ -54,28 +52,21 @@ struct _MctRestrictApplicationsDialog
GtkDialog parent_instance;
MctRestrictApplicationsSelector *selector;
AdwPreferencesGroup *group;
GtkSearchEntry *search_entry;
GtkLabel *description;
MctAppFilter *app_filter; /* (owned) (not nullable) */
gchar *user_display_name; /* (owned) (nullable) */
ActUser *user; /* (owned) (nullable) */
};
static void search_entry_stop_search_cb (GtkSearchEntry *search_entry,
gpointer user_data);
static gboolean focus_search_cb (GtkWidget *widget,
GVariant *arguments,
gpointer user_data);
G_DEFINE_TYPE (MctRestrictApplicationsDialog, mct_restrict_applications_dialog, ADW_TYPE_PREFERENCES_WINDOW)
G_DEFINE_TYPE (MctRestrictApplicationsDialog, mct_restrict_applications_dialog, GTK_TYPE_DIALOG)
typedef enum
{
PROP_APP_FILTER = 1,
PROP_USER_DISPLAY_NAME,
PROP_USER,
} MctRestrictApplicationsDialogProperty;
static GParamSpec *properties[PROP_USER_DISPLAY_NAME + 1];
static GParamSpec *properties[PROP_USER + 1];
static void
mct_restrict_applications_dialog_constructed (GObject *obj)
@ -83,9 +74,7 @@ mct_restrict_applications_dialog_constructed (GObject *obj)
MctRestrictApplicationsDialog *self = MCT_RESTRICT_APPLICATIONS_DIALOG (obj);
g_assert (self->app_filter != NULL);
g_assert (self->user_display_name == NULL ||
(*self->user_display_name != '\0' &&
g_utf8_validate (self->user_display_name, -1, NULL)));
g_assert (self->user == NULL || ACT_IS_USER (self->user));
G_OBJECT_CLASS (mct_restrict_applications_dialog_parent_class)->constructed (obj);
}
@ -104,8 +93,8 @@ mct_restrict_applications_dialog_get_property (GObject *object,
g_value_set_boxed (value, self->app_filter);
break;
case PROP_USER_DISPLAY_NAME:
g_value_set_string (value, self->user_display_name);
case PROP_USER:
g_value_set_object (value, self->user);
break;
default:
@ -127,8 +116,8 @@ mct_restrict_applications_dialog_set_property (GObject *object,
mct_restrict_applications_dialog_set_app_filter (self, g_value_get_boxed (value));
break;
case PROP_USER_DISPLAY_NAME:
mct_restrict_applications_dialog_set_user_display_name (self, g_value_get_string (value));
case PROP_USER:
mct_restrict_applications_dialog_set_user (self, g_value_get_object (value));
break;
default:
@ -142,24 +131,11 @@ mct_restrict_applications_dialog_dispose (GObject *object)
MctRestrictApplicationsDialog *self = (MctRestrictApplicationsDialog *)object;
g_clear_pointer (&self->app_filter, mct_app_filter_unref);
g_clear_pointer (&self->user_display_name, g_free);
g_clear_object (&self->user);
G_OBJECT_CLASS (mct_restrict_applications_dialog_parent_class)->dispose (object);
}
static void
mct_restrict_applications_dialog_map (GtkWidget *widget)
{
MctRestrictApplicationsDialog *self = (MctRestrictApplicationsDialog *)widget;
GTK_WIDGET_CLASS (mct_restrict_applications_dialog_parent_class)->map (widget);
/* Clear and focus the search entry, in case the dialogue is being shown for
* a second time. */
gtk_editable_set_text (GTK_EDITABLE (self->search_entry), "");
gtk_widget_grab_focus (GTK_WIDGET (self->search_entry));
}
static void
mct_restrict_applications_dialog_class_init (MctRestrictApplicationsDialogClass *klass)
{
@ -171,8 +147,6 @@ mct_restrict_applications_dialog_class_init (MctRestrictApplicationsDialogClass
object_class->set_property = mct_restrict_applications_dialog_set_property;
object_class->dispose = mct_restrict_applications_dialog_dispose;
widget_class->map = mct_restrict_applications_dialog_map;
/**
* MctRestrictApplicationsDialog:app-filter: (not nullable)
*
@ -194,22 +168,19 @@ mct_restrict_applications_dialog_class_init (MctRestrictApplicationsDialogClass
G_PARAM_EXPLICIT_NOTIFY);
/**
* MctRestrictApplicationsDialog:user-display-name: (nullable)
* MctRestrictApplicationsDialog:user: (nullable)
*
* The display name for the currently selected user account, or %NULL if no
* user is selected. This will typically be the users full name (if known)
* or their username.
*
* If set, it must be valid UTF-8 and non-empty.
* The currently selected user account, or %NULL if no user is selected.
*
* Since: 0.5.0
*/
properties[PROP_USER_DISPLAY_NAME] =
g_param_spec_string ("user-display-name",
"User Display Name",
"The display name for the currently selected user account, or %NULL if no user is selected.",
NULL,
properties[PROP_USER] =
g_param_spec_object ("user",
"User",
"The currently selected user account, or %NULL if no user is selected.",
ACT_TYPE_USER,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS |
G_PARAM_EXPLICIT_NOTIFY);
@ -218,16 +189,7 @@ mct_restrict_applications_dialog_class_init (MctRestrictApplicationsDialogClass
gtk_widget_class_set_template_from_resource (widget_class, "/org/freedesktop/MalcontentUi/ui/restrict-applications-dialog.ui");
gtk_widget_class_bind_template_child (widget_class, MctRestrictApplicationsDialog, selector);
gtk_widget_class_bind_template_child (widget_class, MctRestrictApplicationsDialog, group);
gtk_widget_class_bind_template_child (widget_class, MctRestrictApplicationsDialog, search_entry);
gtk_widget_class_bind_template_callback (widget_class, search_entry_stop_search_cb);
gtk_widget_class_add_binding (widget_class,
GDK_KEY_f, GDK_CONTROL_MASK,
focus_search_cb,
NULL);
gtk_widget_class_bind_template_child (widget_class, MctRestrictApplicationsDialog, description);
}
static void
@ -237,8 +199,25 @@ mct_restrict_applications_dialog_init (MctRestrictApplicationsDialog *self)
g_type_ensure (MCT_TYPE_RESTRICT_APPLICATIONS_SELECTOR);
gtk_widget_init_template (GTK_WIDGET (self));
}
gtk_search_entry_set_key_capture_widget (self->search_entry, GTK_WIDGET (self));
static const gchar *
get_user_display_name (ActUser *user)
{
const gchar *display_name;
g_return_val_if_fail (ACT_IS_USER (user), _("unknown"));
display_name = act_user_get_real_name (user);
if (display_name != NULL)
return display_name;
display_name = act_user_get_user_name (user);
if (display_name != NULL)
return display_name;
/* Translators: this is the full name for an unknown user account. */
return _("unknown");
}
static void
@ -246,42 +225,23 @@ update_description (MctRestrictApplicationsDialog *self)
{
g_autofree gchar *description = NULL;
if (self->user_display_name == NULL)
if (self->user == NULL)
{
adw_preferences_group_set_description (self->group, NULL);
gtk_widget_hide (GTK_WIDGET (self->description));
return;
}
/* Translators: the placeholder is a users full name */
description = g_strdup_printf (_("Restrict %s from using the following installed applications."),
self->user_display_name);
adw_preferences_group_set_description (self->group, description);
}
static void
search_entry_stop_search_cb (GtkSearchEntry *search_entry,
gpointer user_data)
{
/* Clear the search text as the search filtering is bound to that. */
gtk_editable_set_text (GTK_EDITABLE (search_entry), "");
}
static gboolean
focus_search_cb (GtkWidget *widget,
GVariant *arguments,
gpointer user_data)
{
MctRestrictApplicationsDialog *self = MCT_RESTRICT_APPLICATIONS_DIALOG (widget);
gtk_widget_grab_focus (GTK_WIDGET (self->search_entry));
return TRUE;
description = g_strdup_printf (_("Allow %s to use the following installed applications."),
get_user_display_name (self->user));
gtk_label_set_text (self->description, description);
gtk_widget_show (GTK_WIDGET (self->description));
}
/**
* mct_restrict_applications_dialog_new:
* @app_filter: (transfer none): the initial app filter configuration to show
* @user_display_name: (transfer none) (nullable): the display name of the user
* to show the app filter for, or %NULL if no user is selected
* @user: (transfer none) (nullable): the user to show the app filter for
*
* Create a new #MctRestrictApplicationsDialog widget.
*
@ -290,16 +250,14 @@ focus_search_cb (GtkWidget *widget,
*/
MctRestrictApplicationsDialog *
mct_restrict_applications_dialog_new (MctAppFilter *app_filter,
const gchar *user_display_name)
ActUser *user)
{
g_return_val_if_fail (app_filter != NULL, NULL);
g_return_val_if_fail (user_display_name == NULL ||
(*user_display_name != '\0' &&
g_utf8_validate (user_display_name, -1, NULL)), NULL);
g_return_val_if_fail (user == NULL || ACT_IS_USER (user), NULL);
return g_object_new (MCT_TYPE_RESTRICT_APPLICATIONS_DIALOG,
"app-filter", app_filter,
"user-display-name", user_display_name,
"user", user,
NULL);
}
@ -360,50 +318,45 @@ mct_restrict_applications_dialog_set_app_filter (MctRestrictApplicationsDialog *
}
/**
* mct_restrict_applications_dialog_get_user_display_name:
* mct_restrict_applications_dialog_get_user:
* @self: an #MctRestrictApplicationsDialog
*
* Get the value of #MctRestrictApplicationsDialog:user-display-name.
* Get the value of #MctRestrictApplicationsDialog:user.
*
* Returns: (transfer none) (nullable): the display name of the user the dialog
* is configured for, or %NULL if unknown
* Returns: (transfer none) (nullable): the user the dialog is configured for,
* or %NULL if unknown
* Since: 0.5.0
*/
const gchar *
mct_restrict_applications_dialog_get_user_display_name (MctRestrictApplicationsDialog *self)
ActUser *
mct_restrict_applications_dialog_get_user (MctRestrictApplicationsDialog *self)
{
g_return_val_if_fail (MCT_IS_RESTRICT_APPLICATIONS_DIALOG (self), NULL);
return self->user_display_name;
return self->user;
}
/**
* mct_restrict_applications_dialog_set_user_display_name:
* mct_restrict_applications_dialog_set_user:
* @self: an #MctRestrictApplicationsDialog
* @user_display_name: (nullable) (transfer none): the display name of the user
* to configure the dialog for, or %NULL if unknown
* @user: (nullable) (transfer none): the user to configure the dialog for,
* or %NULL if unknown
*
* Set the value of #MctRestrictApplicationsDialog:user-display-name.
* Set the value of #MctRestrictApplicationsDialog:user.
*
* Since: 0.5.0
*/
void
mct_restrict_applications_dialog_set_user_display_name (MctRestrictApplicationsDialog *self,
const gchar *user_display_name)
mct_restrict_applications_dialog_set_user (MctRestrictApplicationsDialog *self,
ActUser *user)
{
g_return_if_fail (MCT_IS_RESTRICT_APPLICATIONS_DIALOG (self));
g_return_if_fail (user_display_name == NULL ||
(*user_display_name != '\0' &&
g_utf8_validate (user_display_name, -1, NULL)));
g_return_if_fail (user == NULL || ACT_IS_USER (user));
if (g_strcmp0 (self->user_display_name, user_display_name) == 0)
return;
g_clear_pointer (&self->user_display_name, g_free);
self->user_display_name = g_strdup (user_display_name);
update_description (self);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_USER_DISPLAY_NAME]);
if (g_set_object (&self->user, user))
{
update_description (self);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_USER]);
}
}
/**

View File

@ -21,28 +21,28 @@
#pragma once
#include <act/act.h>
#include <glib.h>
#include <glib-object.h>
#include <gtk/gtk.h>
#include <adwaita.h>
#include <libmalcontent/manager.h>
G_BEGIN_DECLS
#define MCT_TYPE_RESTRICT_APPLICATIONS_DIALOG (mct_restrict_applications_dialog_get_type ())
G_DECLARE_FINAL_TYPE (MctRestrictApplicationsDialog, mct_restrict_applications_dialog, MCT, RESTRICT_APPLICATIONS_DIALOG, AdwPreferencesWindow)
G_DECLARE_FINAL_TYPE (MctRestrictApplicationsDialog, mct_restrict_applications_dialog, MCT, RESTRICT_APPLICATIONS_DIALOG, GtkDialog)
MctRestrictApplicationsDialog *mct_restrict_applications_dialog_new (MctAppFilter *app_filter,
const gchar *user_display_name);
ActUser *user);
MctAppFilter *mct_restrict_applications_dialog_get_app_filter (MctRestrictApplicationsDialog *self);
void mct_restrict_applications_dialog_set_app_filter (MctRestrictApplicationsDialog *self,
MctAppFilter *app_filter);
const gchar *mct_restrict_applications_dialog_get_user_display_name (MctRestrictApplicationsDialog *self);
void mct_restrict_applications_dialog_set_user_display_name (MctRestrictApplicationsDialog *self,
const gchar *user_display_name);
ActUser *mct_restrict_applications_dialog_get_user (MctRestrictApplicationsDialog *self);
void mct_restrict_applications_dialog_set_user (MctRestrictApplicationsDialog *self,
ActUser *user);
void mct_restrict_applications_dialog_build_app_filter (MctRestrictApplicationsDialog *self,
MctAppFilterBuilder *builder);

View File

@ -1,38 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright © 2020 Endless, Inc. -->
<interface domain="malcontent">
<interface>
<requires lib="gtk+" version="3.12"/>
<template class="MctRestrictApplicationsDialog" parent="AdwPreferencesWindow">
<template class="MctRestrictApplicationsDialog" parent="GtkDialog">
<property name="title" translatable="yes">Restrict Applications</property>
<property name="default-width">500</property>
<property name="skip-taskbar-hint">True</property>
<property name="default-width">300</property>
<property name="default-height">500</property>
<property name="search-enabled">False</property>
<child>
<object class="AdwPreferencesPage">
<child internal-child="headerbar">
<object class="GtkHeaderBar">
<property name="title" translatable="yes">Restrict Applications</property>
<property name="show-close-button">False</property>
</object>
</child>
<child internal-child="vbox">
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="visible">True</property>
<property name="margin">18</property>
<property name="spacing">12</property>
<child>
<object class="AdwPreferencesGroup" id="group">
<object class="GtkLabel" id="description">
<!-- Translated dynamically: -->
<property name="description">Restrict {username} from using the following installed applications.</property>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="spacing">12</property>
<child>
<object class="GtkSearchEntry" id="search_entry">
<property name="placeholder-text" translatable="yes">Search for applications…</property>
<signal name="stop-search" handler="search_entry_stop_search_cb" />
</object>
</child>
<child>
<object class="MctRestrictApplicationsSelector" id="selector">
<property name="search" bind-source="search_entry" bind-property="text" />
</object>
</child>
<property name="label">Allow {username} to use the following installed applications.</property>
<property name="visible">False</property>
<child internal-child="accessible">
<object class="AtkObject">
<property name="accessible-role">static</property>
</object>
</child>
</object>
</child>
<child>
<object class="MctRestrictApplicationsSelector" id="selector">
<property name="visible">True</property>
</object>
<packing>
<property name="expand">True</property>
</packing>
</child>
</object>
</child>
<child type="action">
<object class="GtkButton" id="button_save">
<property name="can-default">True</property>
<property name="visible">True</property>
<property name="label" translatable="yes">_Save</property>
<property name="use-underline">True</property>
</object>
</child>
<action-widgets>
<action-widget response="apply" default="true">button_save</action-widget>
</action-widgets>
</template>
</interface>

View File

@ -19,16 +19,13 @@
* - Philip Withnall <withnall@endlessm.com>
*/
#include "config.h"
#include <flatpak.h>
#include <gio/gdesktopappinfo.h>
#include <gio/gio.h>
#include <glib.h>
#include <glib-object.h>
#include <glib/gi18n-lib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <adwaita.h>
#include <libmalcontent/app-filter.h>
#include "restrict-applications-selector.h"
@ -41,7 +38,6 @@ static void app_info_changed_cb (GAppInfoMonitor *monitor,
static void reload_apps (MctRestrictApplicationsSelector *self);
static GtkWidget *create_row_for_app_cb (gpointer item,
gpointer user_data);
static char *app_info_dup_name (GAppInfo *app_info);
/**
* MctRestrictApplicationsSelector:
@ -55,11 +51,6 @@ static char *app_info_dup_name (GAppInfo *app_info);
* #MctAppFilterBuilder using
* mct_restrict_applications_selector_build_app_filter().
*
* Search terms may be applied using #MctRestrictApplicationsSelector:search.
* These will filter the list of displayed apps so that only ones matching the
* search terms (by name, using UTF-8 normalisation and casefolding) will be
* displayed.
*
* Since: 0.5.0
*/
struct _MctRestrictApplicationsSelector
@ -68,22 +59,15 @@ struct _MctRestrictApplicationsSelector
GtkListBox *listbox;
GList *cached_apps; /* (nullable) (owned) (element-type GAppInfo) */
GListStore *apps;
GtkFilterListModel *filtered_apps;
GtkStringFilter *search_filter;
GListStore *apps; /* (owned) */
GAppInfoMonitor *app_info_monitor; /* (owned) */
gulong app_info_monitor_changed_id;
GHashTable *blocklisted_apps; /* (owned) (element-type GAppInfo) */
GHashTable *blacklisted_apps; /* (owned) (element-type GAppInfo) */
MctAppFilter *app_filter; /* (owned) */
FlatpakInstallation *system_installation; /* (owned) */
FlatpakInstallation *user_installation; /* (owned) */
GtkCssProvider *css_provider; /* (owned) */
gchar *search; /* (nullable) (owned) */
};
G_DEFINE_TYPE (MctRestrictApplicationsSelector, mct_restrict_applications_selector, GTK_TYPE_BOX)
@ -91,10 +75,9 @@ G_DEFINE_TYPE (MctRestrictApplicationsSelector, mct_restrict_applications_select
typedef enum
{
PROP_APP_FILTER = 1,
PROP_SEARCH,
} MctRestrictApplicationsSelectorProperty;
static GParamSpec *properties[PROP_SEARCH + 1];
static GParamSpec *properties[PROP_APP_FILTER + 1];
enum {
SIGNAL_CHANGED,
@ -116,9 +99,6 @@ mct_restrict_applications_selector_constructed (GObject *obj)
g_assert (self->app_filter != NULL);
/* Load the apps. */
reload_apps (self);
G_OBJECT_CLASS (mct_restrict_applications_selector_parent_class)->constructed (obj);
}
@ -135,9 +115,6 @@ mct_restrict_applications_selector_get_property (GObject *object,
case PROP_APP_FILTER:
g_value_set_boxed (value, self->app_filter);
break;
case PROP_SEARCH:
g_value_set_string (value, self->search);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -157,9 +134,6 @@ mct_restrict_applications_selector_set_property (GObject *object,
case PROP_APP_FILTER:
mct_restrict_applications_selector_set_app_filter (self, g_value_get_boxed (value));
break;
case PROP_SEARCH:
mct_restrict_applications_selector_set_search (self, g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -171,8 +145,8 @@ mct_restrict_applications_selector_dispose (GObject *object)
{
MctRestrictApplicationsSelector *self = (MctRestrictApplicationsSelector *)object;
g_clear_pointer (&self->blocklisted_apps, g_hash_table_unref);
g_clear_list (&self->cached_apps, g_object_unref);
g_clear_pointer (&self->blacklisted_apps, g_hash_table_unref);
g_clear_object (&self->apps);
if (self->app_info_monitor != NULL && self->app_info_monitor_changed_id != 0)
{
@ -183,8 +157,6 @@ mct_restrict_applications_selector_dispose (GObject *object)
g_clear_pointer (&self->app_filter, mct_app_filter_unref);
g_clear_object (&self->system_installation);
g_clear_object (&self->user_installation);
g_clear_object (&self->css_provider);
g_clear_pointer (&self->search, g_free);
G_OBJECT_CLASS (mct_restrict_applications_selector_parent_class)->dispose (object);
}
@ -219,23 +191,6 @@ mct_restrict_applications_selector_class_init (MctRestrictApplicationsSelectorCl
G_PARAM_STATIC_STRINGS |
G_PARAM_EXPLICIT_NOTIFY);
/**
* MctRestrictApplicationsSelector:search: (nullable)
*
* Search terms to filter the displayed list of apps by, or %NULL to not
* filter the search.
*
* Since: 0.12.0
*/
properties[PROP_SEARCH] =
g_param_spec_string ("search",
"Search",
"Search terms to filter the displayed list of apps by.",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS |
G_PARAM_EXPLICIT_NOTIFY);
g_object_class_install_properties (object_class, G_N_ELEMENTS (properties), properties);
/**
@ -257,41 +212,33 @@ mct_restrict_applications_selector_class_init (MctRestrictApplicationsSelectorCl
gtk_widget_class_set_template_from_resource (widget_class, "/org/freedesktop/MalcontentUi/ui/restrict-applications-selector.ui");
gtk_widget_class_bind_template_child (widget_class, MctRestrictApplicationsSelector, listbox);
gtk_widget_class_bind_template_child (widget_class, MctRestrictApplicationsSelector, apps);
gtk_widget_class_bind_template_child (widget_class, MctRestrictApplicationsSelector, filtered_apps);
gtk_widget_class_bind_template_child (widget_class, MctRestrictApplicationsSelector, search_filter);
gtk_widget_class_bind_template_callback (widget_class, app_info_dup_name);
}
static void
mct_restrict_applications_selector_init (MctRestrictApplicationsSelector *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
self->apps = g_list_store_new (G_TYPE_APP_INFO);
self->app_info_monitor = g_app_info_monitor_get ();
self->app_info_monitor_changed_id =
g_signal_connect (self->app_info_monitor, "changed",
(GCallback) app_info_changed_cb, self);
gtk_list_box_bind_model (self->listbox,
G_LIST_MODEL (self->filtered_apps),
G_LIST_MODEL (self->apps),
create_row_for_app_cb,
self,
NULL);
self->blocklisted_apps = g_hash_table_new_full (g_direct_hash,
self->blacklisted_apps = g_hash_table_new_full (g_direct_hash,
g_direct_equal,
g_object_unref,
NULL);
self->system_installation = flatpak_installation_new_system (NULL, NULL);
self->user_installation = flatpak_installation_new_user (NULL, NULL);
self->css_provider = gtk_css_provider_new ();
gtk_css_provider_load_from_resource (self->css_provider,
"/org/freedesktop/MalcontentUi/ui/restricts-switch.css");
}
static void
@ -304,45 +251,30 @@ on_switch_active_changed_cb (GtkSwitch *s,
gboolean allowed;
app = g_object_get_data (G_OBJECT (s), "GAppInfo");
allowed = !gtk_switch_get_active (s);
allowed = gtk_switch_get_active (s);
if (allowed)
{
gboolean removed;
g_debug ("Removing %s from blocklisted apps", g_app_info_get_id (app));
g_debug ("Removing %s from blacklisted apps", g_app_info_get_id (app));
removed = g_hash_table_remove (self->blocklisted_apps, app);
removed = g_hash_table_remove (self->blacklisted_apps, app);
g_assert (removed);
}
else
{
gboolean added;
g_debug ("Blocklisting %s", g_app_info_get_id (app));
g_debug ("Blacklisting %s", g_app_info_get_id (app));
added = g_hash_table_add (self->blocklisted_apps, g_object_ref (app));
added = g_hash_table_add (self->blacklisted_apps, g_object_ref (app));
g_assert (added);
}
g_signal_emit (self, signals[SIGNAL_CHANGED], 0);
}
static void
update_listbox_row_switch (MctRestrictApplicationsSelector *self,
GtkSwitch *w)
{
GAppInfo *app = g_object_get_data (G_OBJECT (w), "GAppInfo");
gboolean allowed = mct_app_filter_is_appinfo_allowed (self->app_filter, app);
gtk_switch_set_active (w, !allowed);
if (allowed)
g_hash_table_remove (self->blocklisted_apps, app);
else
g_hash_table_add (self->blocklisted_apps, g_object_ref (app));
}
static GtkWidget *
create_row_for_app_cb (gpointer item,
gpointer user_data)
@ -350,9 +282,10 @@ create_row_for_app_cb (gpointer item,
MctRestrictApplicationsSelector *self = MCT_RESTRICT_APPLICATIONS_SELECTOR (user_data);
GAppInfo *app = G_APP_INFO (item);
g_autoptr(GIcon) icon = NULL;
GtkWidget *row, *w;
GtkWidget *box, *w;
gboolean allowed;
const gchar *app_name;
GtkStyleContext *context;
gint size;
app_name = g_app_info_get_name (app);
@ -364,43 +297,46 @@ create_row_for_app_cb (gpointer item,
else
g_object_ref (icon);
row = adw_action_row_new ();
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
gtk_container_set_border_width (GTK_CONTAINER (box), 12);
gtk_widget_set_margin_end (box, 12);
/* Icon */
w = gtk_image_new_from_gicon (icon);
gtk_image_set_icon_size (GTK_IMAGE (w), GTK_ICON_SIZE_LARGE);
adw_action_row_add_prefix (ADW_ACTION_ROW (row), w);
w = gtk_image_new_from_gicon (icon, GTK_ICON_SIZE_DIALOG);
gtk_icon_size_lookup (GTK_ICON_SIZE_DND, &size, NULL);
gtk_image_set_pixel_size (GTK_IMAGE (w), size);
gtk_container_add (GTK_CONTAINER (box), w);
/* App name label */
adw_preferences_row_set_title (ADW_PREFERENCES_ROW (row), app_name);
w = g_object_new (GTK_TYPE_LABEL,
"label", app_name,
"hexpand", TRUE,
"xalign", 0.0,
NULL);
gtk_container_add (GTK_CONTAINER (box), w);
/* Switch */
w = g_object_new (GTK_TYPE_SWITCH,
"valign", GTK_ALIGN_CENTER,
NULL);
context = gtk_widget_get_style_context (w);
gtk_style_context_add_class (context, "restricts");
gtk_style_context_add_provider (context,
GTK_STYLE_PROVIDER (self->css_provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION - 1);
adw_action_row_add_suffix (ADW_ACTION_ROW (row), w);
adw_action_row_set_activatable_widget (ADW_ACTION_ROW (row), w);
gtk_container_add (GTK_CONTAINER (box), w);
gtk_widget_set_focusable (GTK_WIDGET (row), FALSE);
gtk_widget_show_all (box);
/* Fetch status from AccountService */
g_object_set_data (G_OBJECT (row), "GtkSwitch", w);
allowed = mct_app_filter_is_appinfo_allowed (self->app_filter, app);
gtk_switch_set_active (GTK_SWITCH (w), allowed);
g_object_set_data_full (G_OBJECT (w), "GAppInfo", g_object_ref (app), g_object_unref);
update_listbox_row_switch (self, GTK_SWITCH (w));
if (allowed)
g_hash_table_remove (self->blacklisted_apps, app);
else
g_hash_table_add (self->blacklisted_apps, g_object_ref (app));
g_signal_connect (w, "notify::active", G_CALLBACK (on_switch_active_changed_cb), self);
return row;
}
static char *
app_info_dup_name (GAppInfo *app_info)
{
return g_strdup (g_app_info_get_name (app_info));
return box;
}
static gint
@ -411,8 +347,8 @@ compare_app_info_cb (gconstpointer a,
GAppInfo *app_a = (GAppInfo*) a;
GAppInfo *app_b = (GAppInfo*) b;
return g_utf8_collate (g_app_info_get_name (app_a),
g_app_info_get_name (app_b));
return g_utf8_collate (g_app_info_get_display_name (app_a),
g_app_info_get_display_name (app_b));
}
static gint
@ -421,7 +357,6 @@ app_compare_id_length_cb (gconstpointer a,
{
GAppInfo *info_a = (GAppInfo *) a, *info_b = (GAppInfo *) b;
const gchar *id_a, *id_b;
gsize id_a_len, id_b_len;
id_a = g_app_info_get_id (info_a);
id_b = g_app_info_get_id (info_b);
@ -433,76 +368,17 @@ app_compare_id_length_cb (gconstpointer a,
else if (id_b == NULL)
return 1;
id_a_len = strlen (id_a);
id_b_len = strlen (id_b);
if (id_a_len == id_b_len)
return strcmp (id_a, id_b);
else
return id_a_len - id_b_len;
return strlen (id_a) - strlen (id_b);
}
/* Elements in @added_out and @removed_out are valid as long as @old_apps and
* @new_apps are valid.
*
* Both lists have to be sorted the same before calling this function. */
static void
diff_app_lists (GList *old_apps,
GList *new_apps,
GPtrArray **added_out,
GPtrArray **removed_out)
{
g_autoptr(GPtrArray) added = g_ptr_array_new_with_free_func (NULL);
g_autoptr(GPtrArray) removed = g_ptr_array_new_with_free_func (NULL);
GList *o, *n;
g_return_if_fail (added_out != NULL);
g_return_if_fail (removed_out != NULL);
for (o = old_apps, n = new_apps; o != NULL || n != NULL;)
{
int comparison;
if (o == NULL)
comparison = 1;
else if (n == NULL)
comparison = -1;
else
comparison = app_compare_id_length_cb (o->data, n->data);
if (comparison < 0)
{
g_ptr_array_add (removed, o->data);
o = o->next;
}
else if (comparison > 0)
{
g_ptr_array_add (added, n->data);
n = n->next;
}
else
{
o = o->next;
n = n->next;
}
}
*added_out = g_steal_pointer (&added);
*removed_out = g_steal_pointer (&removed);
}
/* This is quite expensive to call, as theres no way to avoid calling
* g_app_info_get_all() to see if anythings changed; and thats quite expensive. */
static void
reload_apps (MctRestrictApplicationsSelector *self)
{
g_autolist(GAppInfo) old_apps = NULL;
g_autolist(GAppInfo) new_apps = NULL;
g_autoptr(GPtrArray) added_apps = NULL, removed_apps = NULL;
GList *iter, *apps;
g_autoptr(GHashTable) seen_flatpak_ids = NULL;
g_autoptr(GHashTable) seen_executables = NULL;
old_apps = g_steal_pointer (&self->cached_apps);
new_apps = g_app_info_get_all ();
apps = g_app_info_get_all ();
/* Sort the apps by increasing length of #GAppInfo ID. When coupled with the
* deduplication of flatpak IDs and executable paths, below, this should ensure that we
@ -511,46 +387,20 @@ reload_apps (MctRestrictApplicationsSelector *self)
*
* This is designed to avoid listing all the components of LibreOffice for example,
* which all share an app ID and hence have the same entry in the parental controls
* app filter.
*
* Then diff the old and new lists so that the code below doesnt end up
* removing more rows than are necessary, and hence potentially losing
* in-progress user input. */
new_apps = g_list_sort (new_apps, app_compare_id_length_cb);
diff_app_lists (old_apps, new_apps, &added_apps, &removed_apps);
g_debug ("%s: Diffed old and new app lists: %u apps added, %u apps removed",
G_STRFUNC, added_apps->len, removed_apps->len);
* app filter. */
apps = g_list_sort (apps, app_compare_id_length_cb);
seen_flatpak_ids = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
seen_executables = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
/* Remove items first. */
for (guint i = 0; i < removed_apps->len; i++)
g_list_store_remove_all (self->apps);
for (iter = apps; iter; iter = iter->next)
{
GAppInfo *app = removed_apps->pdata[i];
guint pos;
gboolean found;
found = g_list_store_find_with_equal_func (self->apps, app,
(GEqualFunc) g_app_info_equal, &pos);
/* The app being removed may have not passed the condition checks below
* to have been added to self->apps. */
if (!found)
continue;
g_debug ("Removing app %s", g_app_info_get_id (app));
g_list_store_remove (self->apps, pos);
}
/* Now add the new items. */
for (guint i = 0; i < added_apps->len; i++)
{
GAppInfo *app = added_apps->pdata[i];
GAppInfo *app;
const gchar *app_name;
const gchar * const *supported_types;
app = iter->data;
app_name = g_app_info_get_name (app);
supported_types = g_app_info_get_supported_types (app);
@ -558,9 +408,11 @@ reload_apps (MctRestrictApplicationsSelector *self)
if (!G_IS_DESKTOP_APP_INFO (app) ||
!g_app_info_should_show (app) ||
app_name[0] == '\0' ||
/* Endless' link apps have the "eos-link" prefix, and should be ignored too */
g_str_has_prefix (g_app_info_get_id (app), "eos-link") ||
/* FIXME: Only list flatpak apps and apps with X-Parental-Controls
* key set for now; we really need a system-wide MAC to be able to
* reliably support blocklisting system programs. */
* reliably support blacklisting system programs. */
(!g_desktop_app_info_has_key (G_DESKTOP_APP_INFO (app), "X-Flatpak") &&
!g_desktop_app_info_has_key (G_DESKTOP_APP_INFO (app), "X-Parental-Controls")) ||
/* Web browsers are special cased */
@ -619,17 +471,21 @@ reload_apps (MctRestrictApplicationsSelector *self)
self);
}
/* Update the cache for next time. */
self->cached_apps = g_steal_pointer (&new_apps);
g_list_free_full (apps, g_object_unref);
}
static void
app_info_changed_cb (GAppInfoMonitor *monitor,
gpointer user_data)
{
/* FIXME: We should update the list of apps here, but we cant call
* reload_apps() because that will dump and reload the entire list, losing
* any changes the user has already made to the set of switches. We need
* something more fine-grained.
MctRestrictApplicationsSelector *self = MCT_RESTRICT_APPLICATIONS_SELECTOR (user_data);
reload_apps (self);
*/
}
/* Will return %NULL if @flatpak_id is not installed. */
@ -716,7 +572,7 @@ mct_restrict_applications_selector_build_app_filter (MctRestrictApplicationsSele
g_return_if_fail (MCT_IS_RESTRICT_APPLICATIONS_SELECTOR (self));
g_return_if_fail (builder != NULL);
g_hash_table_iter_init (&iter, self->blocklisted_apps);
g_hash_table_iter_init (&iter, self->blacklisted_apps);
while (g_hash_table_iter_next (&iter, (gpointer) &app, NULL))
{
g_autofree gchar *flatpak_id = NULL;
@ -731,12 +587,12 @@ mct_restrict_applications_selector_build_app_filter (MctRestrictApplicationsSele
if (!flatpak_ref)
{
g_warning ("Skipping blocklisting Flatpak ID %s due to it not being installed", flatpak_id);
g_warning ("Skipping blacklisting Flatpak ID %s due to it not being installed", flatpak_id);
continue;
}
g_debug ("\t\t → Blocklisting Flatpak ref: %s", flatpak_ref);
mct_app_filter_builder_blocklist_flatpak_ref (builder, flatpak_ref);
g_debug ("\t\t → Blacklisting Flatpak ref: %s", flatpak_ref);
mct_app_filter_builder_blacklist_flatpak_ref (builder, flatpak_ref);
}
else
{
@ -745,12 +601,12 @@ mct_restrict_applications_selector_build_app_filter (MctRestrictApplicationsSele
if (!path)
{
g_warning ("Skipping blocklisting executable %s due to it not being found", executable);
g_warning ("Skipping blacklisting executable %s due to it not being found", executable);
continue;
}
g_debug ("\t\t → Blocklisting path: %s", path);
mct_app_filter_builder_blocklist_path (builder, path);
g_debug ("\t\t → Blacklisting path: %s", path);
mct_app_filter_builder_blacklist_path (builder, path);
}
}
}
@ -792,7 +648,6 @@ mct_restrict_applications_selector_set_app_filter (MctRestrictApplicationsSelect
MctAppFilter *app_filter)
{
g_autoptr(MctAppFilter) owned_app_filter = NULL;
guint n_apps;
g_return_if_fail (MCT_IS_RESTRICT_APPLICATIONS_SELECTOR (self));
@ -810,70 +665,6 @@ mct_restrict_applications_selector_set_app_filter (MctRestrictApplicationsSelect
g_clear_pointer (&self->app_filter, mct_app_filter_unref);
self->app_filter = mct_app_filter_ref (app_filter);
/* Update the status of each app row. */
n_apps = g_list_model_get_n_items (G_LIST_MODEL (self->filtered_apps));
for (guint i = 0; i < n_apps; i++)
{
GtkListBoxRow *row;
GtkWidget *w;
/* Navigate the widget hierarchy set up in create_row_for_app_cb(). */
row = gtk_list_box_get_row_at_index (self->listbox, i);
g_assert (row != NULL && GTK_IS_LIST_BOX_ROW (row));
w = g_object_get_data (G_OBJECT (row), "GtkSwitch");
g_assert (w != NULL && GTK_IS_SWITCH (w));
update_listbox_row_switch (self, GTK_SWITCH (w));
}
reload_apps (self);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_APP_FILTER]);
}
/**
* mct_restrict_applications_selector_get_search:
* @self: an #MctRestrictApplicationsSelector
*
* Get the value of #MctRestrictApplicationsSelector:search.
*
* Returns: current search terms, or %NULL if no search filtering is active
* Since: 0.12.0
*/
const gchar *
mct_restrict_applications_selector_get_search (MctRestrictApplicationsSelector *self)
{
g_return_val_if_fail (MCT_IS_RESTRICT_APPLICATIONS_SELECTOR (self), NULL);
return self->search;
}
/**
* mct_restrict_applications_selector_set_search:
* @self: an #MctRestrictApplicationsSelector
* @search: (nullable): search terms, or %NULL to not filter the app list
*
* Set the value of #MctRestrictApplicationsSelector:search, or clear it to
* %NULL.
*
* Since: 0.12.0
*/
void
mct_restrict_applications_selector_set_search (MctRestrictApplicationsSelector *self,
const gchar *search)
{
g_return_if_fail (MCT_IS_RESTRICT_APPLICATIONS_SELECTOR (self));
/* Squash empty search terms down to nothing. */
if (search != NULL && *search == '\0')
search = NULL;
if (g_strcmp0 (search, self->search) == 0)
return;
g_clear_pointer (&self->search, g_free);
self->search = g_strdup (search);
gtk_string_filter_set_search (self->search_filter, self->search);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SEARCH]);
}

View File

@ -21,6 +21,7 @@
#pragma once
#include <act/act.h>
#include <glib.h>
#include <glib-object.h>
#include <gtk/gtk.h>
@ -41,8 +42,4 @@ void mct_restrict_applications_selector_set_app_filter (MctRestrictAppl
void mct_restrict_applications_selector_build_app_filter (MctRestrictApplicationsSelector *self,
MctAppFilterBuilder *builder);
const gchar *mct_restrict_applications_selector_get_search (MctRestrictApplicationsSelector *self);
void mct_restrict_applications_selector_set_search (MctRestrictApplicationsSelector *self,
const gchar *search);
G_END_DECLS

View File

@ -1,40 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright © 2020 Endless, Inc. -->
<interface domain="malcontent">
<interface>
<requires lib="gtk+" version="3.12"/>
<template class="MctRestrictApplicationsSelector" parent="GtkBox">
<child>
<object class="GtkListBox" id="listbox">
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="hexpand">True</property>
<property name="selection-mode">none</property>
<property name="hscrollbar-policy">never</property>
<property name="min-content-height">100</property>
<property name="max-content-height">400</property>
<property name="propagate-natural-height">True</property>
<property name="shadow-type">etched-in</property>
<child type="placeholder">
<object class="GtkLabel">
<property name="label" translatable="yes">No applications found to restrict.</property>
<property name="margin-top">12</property>
<property name="margin-bottom">12</property>
<child>
<object class="GtkListBox" id="listbox">
<property name="visible">True</property>
<property name="selection-mode">none</property>
<child type="placeholder">
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">No applications found to restrict.</property>
</object>
</child>
</object>
</child>
<style>
<class name="content"/>
</style>
</object>
</child>
</template>
<object class="GListStore" id="apps">
<property name="item-type">GAppInfo</property>
</object>
<object class="GtkFilterListModel" id="filtered_apps">
<property name="model">apps</property>
<property name="filter">search_filter</property>
</object>
<object class="GtkStringFilter" id="search_filter">
<property name="expression">
<closure type="gchararray" function="app_info_dup_name" />
</property>
</object>
</interface>

View File

@ -1,18 +0,0 @@
/* FIXME: This negative variant of a GtkSwitch should probably be
* upstreamed to GTK. See https://gitlab.gnome.org/GNOME/gtk/issues/2470 */
switch:checked.restricts {
background-color: @yellow_5;
}
switch:checked.restricts, switch:checked.restricts slider {
border-color: @yellow_3;
}
switch:disabled.restricts {
border-color: @borders;
background-color: @insensitive_bg_color;
}
switch:disabled.restricts slider {
filter: grayscale(100%);
}

File diff suppressed because it is too large Load Diff

View File

@ -23,18 +23,13 @@
#pragma once
#include <act/act.h>
#include <gio/gio.h>
#include <glib.h>
#include <glib-object.h>
#include <gtk/gtk.h>
#include <adwaita.h>
#include <libmalcontent/malcontent.h>
G_BEGIN_DECLS
#define MCT_TYPE_USER_CONTROLS (mct_user_controls_get_type())
G_DECLARE_FINAL_TYPE (MctUserControls, mct_user_controls, MCT, USER_CONTROLS, AdwBin)
G_DECLARE_FINAL_TYPE (MctUserControls, mct_user_controls, MCT, USER_CONTROLS, GtkGrid)
ActUser *mct_user_controls_get_user (MctUserControls *self);
void mct_user_controls_set_user (MctUserControls *self,
@ -44,26 +39,4 @@ GPermission *mct_user_controls_get_permission (MctUserControls *self);
void mct_user_controls_set_permission (MctUserControls *self,
GPermission *permission);
MctAppFilter *mct_user_controls_get_app_filter (MctUserControls *self);
void mct_user_controls_set_app_filter (MctUserControls *self,
MctAppFilter *app_filter);
ActUserAccountType mct_user_controls_get_user_account_type (MctUserControls *self);
void mct_user_controls_set_user_account_type (MctUserControls *self,
ActUserAccountType user_account_type);
const gchar *mct_user_controls_get_user_locale (MctUserControls *self);
void mct_user_controls_set_user_locale (MctUserControls *self,
const gchar *user_locale);
const gchar *mct_user_controls_get_user_display_name (MctUserControls *self);
void mct_user_controls_set_user_display_name (MctUserControls *self,
const gchar *user_display_name);
void mct_user_controls_set_description (MctUserControls *self,
const gchar *description);
void mct_user_controls_build_app_filter (MctUserControls *self,
MctAppFilterBuilder *builder);
G_END_DECLS

View File

@ -1,134 +1,535 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright © 2018, 2019, 2020 Endless, Inc. -->
<interface domain="malcontent">
<interface>
<requires lib="gtk+" version="3.12"/>
<template class="MctUserControls" parent="AdwBin">
<template class="MctUserControls" parent="GtkGrid">
<property name="visible">True</property>
<property name="margin-top">18</property>
<property name="row-spacing">6</property>
<property name="column-spacing">12</property>
<property name="valign">start</property>
<!-- Application Usage Restrictions -->
<child>
<object class="GtkBox">
<property name="spacing">24</property>
<property name="orientation">vertical</property>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="xalign">0.0</property>
<property name="label" translatable="yes">Application Usage Restrictions</property>
<attributes>
<attribute name="weight" value="bold" />
</attributes>
</object>
<packing>
<property name="top-attach">0</property>
<property name="left-attach">0</property>
</packing>
</child>
<child>
<object class="GtkFrame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">in</property>
<child>
<object class="AdwPreferencesGroup">
<object class="GtkListBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="selection_mode">none</property>
<property name="activate_on_single_click">False</property>
<child>
<object class="GtkLabel" id="description_label">
<property name="wrap">True</property>
<property name="xalign">0.0</property>
<property name="yalign">0.0</property>
</object>
</child>
</object>
</child>
<!-- Application Usage Restrictions -->
<child>
<object class="AdwPreferencesGroup">
<property name="title" translatable="yes">Application Usage Restrictions</property>
<child>
<object class="AdwActionRow" id="restrict_web_browsers_row">
<property name="title" translatable="yes">Restrict _Web Browsers</property>
<property name="use_underline">True</property>
<property name="activatable_widget">restrict_web_browsers_switch</property>
<!-- Set dynamically from user-controls.c: -->
<property name="subtitle">Prevents {username} from running web browsers. Limited web content may still be available in other applications.</property>
<property name="subtitle_lines">0</property>
<property name="focusable">False</property>
<object class="GtkListBoxRow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="activatable">False</property>
<property name="selectable">False</property>
<child>
<object class="GtkSwitch" id="restrict_web_browsers_switch">
<property name="halign">end</property>
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">center</property>
<signal name="notify::active" handler="on_restrict_web_browsers_switch_active_changed_cb" object="MctUserControls" swapped="no" />
<style>
<class name="restricts" />
</style>
<property name="margin-left">12</property>
<property name="margin-right">12</property>
<property name="margin-top">8</property>
<property name="margin-bottom">8</property>
<property name="row-spacing">4</property>
<property name="column-spacing">4</property>
<child>
<object class="GtkLabel" id="allow_web_browsers_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
<property name="ellipsize">end</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Allow _Web Browsers</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">allow_web_browsers_switch</property>
<accessibility>
<relation target="allow_web_browsers_switch" type="label-for"/>
</accessibility>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="allow_web_browsers_description">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
<property name="ellipsize">end</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Prevents the user from running web browsers, but limited web content may still be available in other applications</property>
<attributes>
<attribute name="scale" value="0.88"/>
</attributes>
<style>
<class name="dim-label" />
</style>
<accessibility>
<relation target="allow_web_browsers_switch" type="description-for"/>
</accessibility>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<object class="GtkSwitch" id="allow_web_browsers_switch">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="halign">end</property>
<property name="valign">center</property>
<signal name="notify::active" handler="on_allow_web_browsers_switch_active_changed_cb" object="MctUserControls" swapped="no" />
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
<property name="height">2</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow" id="restrict_applications_row">
<property name="activatable">True</property>
<property name="title" translatable="yes">_Restrict Applications</property>
<property name="use_underline">True</property>
<!-- Set dynamically from user-controls.c: -->
<property name="subtitle">Prevents specified applications from being used by {username}.</property>
<property name="subtitle_lines">0</property>
<property name="action-name">permissions.restrict-applications</property>
<object class="GtkListBoxRow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="activatable">False</property>
<property name="selectable">False</property>
<child>
<object class="GtkImage">
<property name="icon-name">go-next-symbolic</property>
</object>
</child>
</object>
</child>
<style>
<class name="content"/>
</style>
</object>
</child>
<!-- Software Installation Restrictions -->
<child>
<object class="AdwPreferencesGroup">
<property name="title" translatable="yes">Software Installation Restrictions</property>
<child>
<object class="AdwActionRow" id="restrict_software_installation_row">
<property name="visible" bind-source="restrict_software_installation_switch" bind-property="visible" bind-flags="default|sync-create" />
<property name="title" translatable="yes">Restrict Application _Installation</property>
<property name="use_underline">True</property>
<property name="activatable_widget">restrict_software_installation_switch</property>
<!-- Set dynamically from user-controls.c: -->
<property name="subtitle">Prevents {username} from installing applications.</property>
<property name="subtitle_lines">0</property>
<property name="focusable">False</property>
<child>
<object class="GtkSwitch" id="restrict_software_installation_switch">
<property name="halign">end</property>
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">center</property>
<signal name="notify::active" handler="on_restrict_installation_switch_active_changed_cb" object="MctUserControls" swapped="no" />
<style>
<class name="restricts" />
</style>
<property name="margin-left">12</property>
<property name="margin-right">12</property>
<property name="margin-top">8</property>
<property name="margin-bottom">8</property>
<property name="row-spacing">4</property>
<property name="column-spacing">4</property>
<child>
<object class="GtkLabel" id="restrict_applications_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
<property name="ellipsize">end</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">_Restrict Applications</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">restrict_applications_button</property>
<accessibility>
<relation target="restrict_applications_button" type="label-for"/>
</accessibility>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="restrict_applications_description">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
<property name="ellipsize">end</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Prevents particular applications from being used</property>
<attributes>
<attribute name="scale" value="0.88"/>
</attributes>
<style>
<class name="dim-label" />
</style>
<accessibility>
<relation target="restrict_applications_button" type="description-for"/>
</accessibility>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="restrict_applications_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="halign">end</property>
<property name="valign">center</property>
<property name="relief">none</property>
<signal name="clicked" handler="on_restrict_applications_button_clicked_cb" object="MctUserControls" swapped="no" />
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="icon-name">pan-end-symbolic</property>
<property name="icon-size">4</property><!-- GTK_ICON_SIZE_BUTTON -->
</object>
</child>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
<property name="height">2</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Application _Suitability</property>
<property name="use_underline">True</property>
<property name="activatable_widget">oars_button</property>
<property name="subtitle" translatable="yes">Restricts the browsing or installation of applications unsuitable for this age or younger.</property>
<property name="subtitle_lines">0</property>
<property name="focusable">False</property>
<child>
<object class="GtkMenuButton" id="oars_button">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="popover">oars_popover</property>
<property name="always-show-arrow">True</property>
</object>
</child>
</object>
</child>
<style>
<class name="content"/>
</style>
</object>
</child>
</object>
<packing>
<property name="top-attach">1</property>
<property name="left-attach">0</property>
</packing>
</child>
<!-- Software Installation Restrictions -->
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="margin-top">12</property>
<property name="xalign">0.0</property>
<property name="label" translatable="yes">Software Installation Restrictions</property>
<attributes>
<attribute name="weight" value="bold" />
</attributes>
</object>
<packing>
<property name="top-attach">2</property>
<property name="left-attach">0</property>
</packing>
</child>
<child>
<object class="GtkFrame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkListBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="selection_mode">none</property>
<property name="activate_on_single_click">False</property>
<child>
<object class="GtkListBoxRow">
<property name="visible" bind-source="allow_user_installation_switch" bind-property="visible" bind-flags="default|sync-create" />
<property name="can_focus">True</property>
<property name="activatable">False</property>
<property name="selectable">False</property>
<child>
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">center</property>
<property name="margin-left">12</property>
<property name="margin-right">12</property>
<property name="margin-top">8</property>
<property name="margin-bottom">8</property>
<property name="row-spacing">4</property>
<property name="column-spacing">4</property>
<child>
<object class="GtkLabel" id="allow_user_installation_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
<property name="ellipsize">end</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Application _Installation</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">allow_user_installation_switch</property>
<accessibility>
<relation target="allow_user_installation_switch" type="label-for"/>
</accessibility>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="allow_user_installation_description">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
<property name="ellipsize">end</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Restricts the user from installing applications</property>
<attributes>
<attribute name="scale" value="0.88"/>
</attributes>
<style>
<class name="dim-label" />
</style>
<accessibility>
<relation target="allow_user_installation_switch" type="description-for"/>
</accessibility>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<object class="GtkSwitch" id="allow_user_installation_switch">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="halign">end</property>
<property name="valign">center</property>
<signal name="notify::active" handler="on_allow_installation_switch_active_changed_cb" object="MctUserControls" swapped="no" />
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
<property name="height">2</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBoxRow">
<property name="visible" bind-source="allow_system_installation_switch" bind-property="visible" bind-flags="default|sync-create" />
<property name="can_focus">True</property>
<property name="activatable">False</property>
<property name="selectable">False</property>
<child>
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">center</property>
<property name="margin-left">12</property>
<property name="margin-right">12</property>
<property name="margin-top">8</property>
<property name="margin-bottom">8</property>
<property name="row-spacing">4</property>
<property name="column-spacing">4</property>
<child>
<object class="GtkLabel" id="allow_system_installation_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
<property name="ellipsize">end</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Application Installation for _Others</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">allow_system_installation_switch</property>
<accessibility>
<relation target="allow_system_installation_switch" type="label-for"/>
</accessibility>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="allow_system_installation_description">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
<property name="ellipsize">end</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Restricts the user from installing applications for all users</property>
<attributes>
<attribute name="scale" value="0.88"/>
</attributes>
<style>
<class name="dim-label" />
</style>
<accessibility>
<relation target="allow_system_installation_switch" type="description-for"/>
</accessibility>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<object class="GtkSwitch" id="allow_system_installation_switch">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="halign">end</property>
<property name="valign">center</property>
<signal name="notify::active" handler="on_allow_installation_switch_active_changed_cb" object="MctUserControls" swapped="no" />
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
<property name="height">2</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBoxRow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="activatable">False</property>
<property name="selectable">False</property>
<child>
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">center</property>
<property name="margin-left">12</property>
<property name="margin-right">12</property>
<property name="margin-top">8</property>
<property name="margin-bottom">8</property>
<property name="row-spacing">4</property>
<property name="column-spacing">4</property>
<child>
<object class="GtkLabel" id="restriction_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
<property name="ellipsize">end</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Application _Suitability</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">restriction_button</property>
<accessibility>
<relation target="restriction_button" type="label-for"/>
<relation target="restriction_button" type="flows-to"/>
</accessibility>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="restriction_description">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
<property name="ellipsize">end</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Restricts the applications the user can browse or install to those suitable for certain ages</property>
<attributes>
<attribute name="scale" value="0.88"/>
</attributes>
<style>
<class name="dim-label" />
</style>
<accessibility>
<relation target="restriction_button" type="description-for"/>
</accessibility>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<object class="GtkMenuButton" id="restriction_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="halign">end</property>
<property name="valign">center</property>
<property name="popover">restriction_popover</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
<property name="height">2</property>
</packing>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="top-attach">3</property>
<property name="left-attach">0</property>
</packing>
</child>
</template>
<object class="GtkPopoverMenu" id="oars_popover" />
<object class="GtkPopoverMenu" id="restriction_popover">
<accessibility>
<relation target="restriction_button" type="popup-for"/>
</accessibility>
</object>
<menu id="age_menu" />
<object class="GtkSizeGroup">
<property name="mode">horizontal</property>
<widgets>
<widget name="restriction_button" />
<widget name="restriction_popover" />
</widgets>
</object>
<object class="GtkSizeGroup">
<property name="mode">horizontal</property>
<widgets>
<widget name="allow_web_browsers_label" />
<widget name="allow_web_browsers_description" />
<widget name="restrict_applications_label" />
<widget name="restrict_applications_description" />
<widget name="restriction_label" />
<widget name="allow_user_installation_label" />
<widget name="allow_system_installation_label" />
</widgets>
</object>
<object class="MctRestrictApplicationsDialog" id="restrict_applications_dialog">
<property name="visible">False</property>
<property name="modal">True</property>
<property name="destroy-with-parent">False</property>
<signal name="close-request" handler="on_restrict_applications_dialog_close_request_cb" />
<property name="use-header-bar">1</property>
<signal name="delete-event" handler="on_restrict_applications_dialog_delete_event_cb" />
<signal name="response" handler="on_restrict_applications_dialog_response_cb" />
</object>
</interface>

View File

@ -31,9 +31,9 @@ G_BEGIN_DECLS
/**
* MctAppFilterListType:
* @MCT_APP_FILTER_LIST_BLOCKLIST: Any program in the list is not allowed to
* @MCT_APP_FILTER_LIST_BLACKLIST: Any program in the list is not allowed to
* be run.
* @MCT_APP_FILTER_LIST_ALLOWLIST: Any program not in the list is not allowed
* @MCT_APP_FILTER_LIST_WHITELIST: Any program not in the list is not allowed
* to be run.
*
* Different semantics for interpreting an application list.
@ -42,18 +42,17 @@ G_BEGIN_DECLS
*/
typedef enum
{
MCT_APP_FILTER_LIST_BLOCKLIST,
MCT_APP_FILTER_LIST_ALLOWLIST,
MCT_APP_FILTER_LIST_BLACKLIST,
MCT_APP_FILTER_LIST_WHITELIST,
} MctAppFilterListType;
struct _MctAppFilter
{
/*< private >*/
gint ref_count;
uid_t user_id;
gchar **app_list; /* (not nullable) (owned) (array zero-terminated=1) */
gchar **app_list; /* (owned) (array zero-terminated=1) */
MctAppFilterListType app_list_type;
GVariant *oars_ratings; /* (type a{ss}) (owned non-floating) */

View File

@ -96,7 +96,7 @@ mct_app_filter_unref (MctAppFilter *filter)
*
* Get the user ID of the user this #MctAppFilter is for.
*
* Returns: user ID of the relevant user, or `(uid_t) -1` if unknown
* Returns: user ID of the relevant user
* Since: 0.2.0
*/
uid_t
@ -108,69 +108,6 @@ mct_app_filter_get_user_id (MctAppFilter *filter)
return filter->user_id;
}
static MctAppFilterOarsValue
oars_str_to_enum (const gchar *value_str)
{
if (g_str_equal (value_str, "none"))
return MCT_APP_FILTER_OARS_VALUE_NONE;
else if (g_str_equal (value_str, "mild"))
return MCT_APP_FILTER_OARS_VALUE_MILD;
else if (g_str_equal (value_str, "moderate"))
return MCT_APP_FILTER_OARS_VALUE_MODERATE;
else if (g_str_equal (value_str, "intense"))
return MCT_APP_FILTER_OARS_VALUE_INTENSE;
else
return MCT_APP_FILTER_OARS_VALUE_UNKNOWN;
}
/**
* mct_app_filter_is_enabled:
* @filter: an #MctAppFilter
*
* Check whether the app filter is enabled and is going to impose at least one
* restriction on the user. This gives a high level view of whether app filter
* parental controls are enabled for the given user.
*
* Returns: %TRUE if the app filter contains at least one non-default value,
* %FALSE if its entirely default
* Since: 0.7.0
*/
gboolean
mct_app_filter_is_enabled (MctAppFilter *filter)
{
gboolean oars_ratings_all_intense_or_unknown;
GVariantIter iter;
const gchar *oars_value;
g_return_val_if_fail (filter != NULL, FALSE);
g_return_val_if_fail (filter->ref_count >= 1, FALSE);
/* The least restrictive OARS filter has all values as intense, or unknown. */
oars_ratings_all_intense_or_unknown = TRUE;
g_variant_iter_init (&iter, filter->oars_ratings);
while (g_variant_iter_loop (&iter, "{&s&s}", NULL, &oars_value))
{
MctAppFilterOarsValue value = oars_str_to_enum (oars_value);
if (value != MCT_APP_FILTER_OARS_VALUE_UNKNOWN &&
value != MCT_APP_FILTER_OARS_VALUE_INTENSE)
{
oars_ratings_all_intense_or_unknown = FALSE;
break;
}
}
/* Check all fields against their default values. Ignore
* `allow_system_installation` since its false by default, so the default
* value is already the most restrictive. */
return ((filter->app_list_type == MCT_APP_FILTER_LIST_BLOCKLIST &&
filter->app_list[0] != NULL) ||
filter->app_list_type == MCT_APP_FILTER_LIST_ALLOWLIST ||
!oars_ratings_all_intense_or_unknown ||
!filter->allow_user_installation);
}
/**
* mct_app_filter_is_path_allowed:
* @filter: an #MctAppFilter
@ -202,9 +139,9 @@ mct_app_filter_is_path_allowed (MctAppFilter *filter,
switch (filter->app_list_type)
{
case MCT_APP_FILTER_LIST_BLOCKLIST:
case MCT_APP_FILTER_LIST_BLACKLIST:
return !path_in_list;
case MCT_APP_FILTER_LIST_ALLOWLIST:
case MCT_APP_FILTER_LIST_WHITELIST:
return path_in_list;
default:
g_assert_not_reached ();
@ -265,9 +202,9 @@ mct_app_filter_is_flatpak_ref_allowed (MctAppFilter *filter,
switch (filter->app_list_type)
{
case MCT_APP_FILTER_LIST_BLOCKLIST:
case MCT_APP_FILTER_LIST_BLACKLIST:
return !ref_in_list;
case MCT_APP_FILTER_LIST_ALLOWLIST:
case MCT_APP_FILTER_LIST_WHITELIST:
return ref_in_list;
default:
g_assert_not_reached ();
@ -281,7 +218,7 @@ mct_app_filter_is_flatpak_ref_allowed (MctAppFilter *filter,
*
* Check whether the flatpak app with the given @app_id is allowed to be run
* according to this app filter. This is a globbing match, matching @app_id
* against potentially multiple entries in the blocklist, as the blocklist
* against potentially multiple entries in the blacklist, as the blacklist
* contains flatpak refs (for example, `app/org.gnome.Builder/x86_64/master`)
* which contain architecture and branch information. App IDs (for example,
* `org.gnome.Builder`) do not contain architecture or branch information.
@ -315,9 +252,9 @@ mct_app_filter_is_flatpak_app_allowed (MctAppFilter *filter,
switch (filter->app_list_type)
{
case MCT_APP_FILTER_LIST_BLOCKLIST:
case MCT_APP_FILTER_LIST_BLACKLIST:
return !id_in_list;
case MCT_APP_FILTER_LIST_ALLOWLIST:
case MCT_APP_FILTER_LIST_WHITELIST:
return id_in_list;
default:
g_assert_not_reached ();
@ -431,8 +368,8 @@ is_valid_content_type (const gchar *content_type)
* according to this app filter.
*
* Note that this method doesnt match content subtypes. For example, if
* `application/xml` is added to the blocklist but `application/xspf+xml` is not,
* a check for whether `application/xspf+xml` is blocklisted would return false.
* `application/xml` is added to the blacklist but `application/xspf+xml` is not,
* a check for whether `application/xspf+xml` is blacklisted would return false.
*
* Returns: %TRUE if the user this @filter corresponds to is allowed to run
* programs handling @content_type according to the @filter policy;
@ -453,9 +390,9 @@ mct_app_filter_is_content_type_allowed (MctAppFilter *filter,
switch (filter->app_list_type)
{
case MCT_APP_FILTER_LIST_BLOCKLIST:
case MCT_APP_FILTER_LIST_BLACKLIST:
return !ref_in_list;
case MCT_APP_FILTER_LIST_ALLOWLIST:
case MCT_APP_FILTER_LIST_WHITELIST:
return ref_in_list;
default:
g_assert_not_reached ();
@ -540,7 +477,16 @@ mct_app_filter_get_oars_value (MctAppFilter *filter,
if (!g_variant_lookup (filter->oars_ratings, oars_section, "&s", &value_str))
return MCT_APP_FILTER_OARS_VALUE_UNKNOWN;
return oars_str_to_enum (value_str);
if (g_str_equal (value_str, "none"))
return MCT_APP_FILTER_OARS_VALUE_NONE;
else if (g_str_equal (value_str, "mild"))
return MCT_APP_FILTER_OARS_VALUE_MILD;
else if (g_str_equal (value_str, "moderate"))
return MCT_APP_FILTER_OARS_VALUE_MODERATE;
else if (g_str_equal (value_str, "intense"))
return MCT_APP_FILTER_OARS_VALUE_INTENSE;
else
return MCT_APP_FILTER_OARS_VALUE_UNKNOWN;
}
/**
@ -587,201 +533,6 @@ mct_app_filter_is_system_installation_allowed (MctAppFilter *filter)
return filter->allow_system_installation;
}
/**
* _mct_app_filter_build_app_filter_variant:
* @filter: an #MctAppFilter
*
* Build a #GVariant which contains the app filter from @filter, in the format
* used for storing it in AccountsService.
*
* Returns: (transfer floating): a new, floating #GVariant containing the app
* filter
*/
static GVariant *
_mct_app_filter_build_app_filter_variant (MctAppFilter *filter)
{
g_auto(GVariantBuilder) builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("(bas)"));
g_return_val_if_fail (filter != NULL, NULL);
g_return_val_if_fail (filter->ref_count >= 1, NULL);
g_variant_builder_add (&builder, "b",
(filter->app_list_type == MCT_APP_FILTER_LIST_ALLOWLIST));
g_variant_builder_open (&builder, G_VARIANT_TYPE ("as"));
for (gsize i = 0; filter->app_list[i] != NULL; i++)
g_variant_builder_add (&builder, "s", filter->app_list[i]);
g_variant_builder_close (&builder);
return g_variant_builder_end (&builder);
}
/**
* mct_app_filter_serialize:
* @filter: an #MctAppFilter
*
* Build a #GVariant which contains the app filter from @filter, in an opaque
* variant format. This format may change in future, but
* mct_app_filter_deserialize() is guaranteed to always be able to load any
* variant produced by the current or any previous version of
* mct_app_filter_serialize().
*
* Returns: (transfer floating): a new, floating #GVariant containing the app
* filter
* Since: 0.7.0
*/
GVariant *
mct_app_filter_serialize (MctAppFilter *filter)
{
g_auto(GVariantBuilder) builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a{sv}"));
g_return_val_if_fail (filter != NULL, NULL);
g_return_val_if_fail (filter->ref_count >= 1, NULL);
/* The serialisation format is exactly the
* `com.endlessm.ParentalControls.AppFilter` D-Bus interface. */
g_variant_builder_add (&builder, "{sv}", "AppFilter",
_mct_app_filter_build_app_filter_variant (filter));
g_variant_builder_add (&builder, "{sv}", "OarsFilter",
g_variant_new ("(s@a{ss})", "oars-1.1",
filter->oars_ratings));
g_variant_builder_add (&builder, "{sv}", "AllowUserInstallation",
g_variant_new_boolean (filter->allow_user_installation));
g_variant_builder_add (&builder, "{sv}", "AllowSystemInstallation",
g_variant_new_boolean (filter->allow_system_installation));
return g_variant_builder_end (&builder);
}
/**
* mct_app_filter_deserialize:
* @variant: a serialized app filter variant
* @user_id: the ID of the user the app filter relates to
* @error: return location for a #GError, or %NULL
*
* Deserialize an app filter previously serialized with
* mct_app_filter_serialize(). This function guarantees to be able to
* deserialize any serialized form from this version or older versions of
* libmalcontent.
*
* If deserialization fails, %MCT_MANAGER_ERROR_INVALID_DATA will be returned.
*
* Returns: (transfer full): deserialized app filter
* Since: 0.7.0
*/
MctAppFilter *
mct_app_filter_deserialize (GVariant *variant,
uid_t user_id,
GError **error)
{
gboolean is_allowlist;
g_auto(GStrv) app_list = NULL;
const gchar *content_rating_kind;
g_autoptr(GVariant) oars_variant = NULL;
gboolean allow_user_installation;
gboolean allow_system_installation;
g_autoptr(MctAppFilter) app_filter = NULL;
g_return_val_if_fail (variant != NULL, NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
/* Check the overall type. */
if (!g_variant_is_of_type (variant, G_VARIANT_TYPE ("a{sv}")))
{
g_set_error (error, MCT_MANAGER_ERROR,
MCT_MANAGER_ERROR_INVALID_DATA,
_("App filter for user %u was in an unrecognized format"),
(guint) user_id);
return NULL;
}
/* Extract the properties we care about. The default values here should be
* kept in sync with those in the `com.endlessm.ParentalControls.AppFilter`
* D-Bus interface. */
if (!g_variant_lookup (variant, "AppFilter", "(b^as)",
&is_allowlist, &app_list))
{
/* Default value. */
is_allowlist = FALSE;
app_list = g_new0 (gchar *, 1);
}
if (!g_variant_lookup (variant, "OarsFilter", "(&s@a{ss})",
&content_rating_kind, &oars_variant))
{
/* Default value. */
content_rating_kind = "oars-1.1";
oars_variant = g_variant_new ("a{ss}", NULL);
}
/* Check that the OARS filter is in a format we support. Currently, thats
* only oars-1.0 and oars-1.1. */
if (!g_str_equal (content_rating_kind, "oars-1.0") &&
!g_str_equal (content_rating_kind, "oars-1.1"))
{
g_set_error (error, MCT_MANAGER_ERROR,
MCT_MANAGER_ERROR_INVALID_DATA,
_("OARS filter for user %u has an unrecognized kind %s"),
(guint) user_id, content_rating_kind);
return NULL;
}
if (!g_variant_lookup (variant, "AllowUserInstallation", "b",
&allow_user_installation))
{
/* Default value. */
allow_user_installation = TRUE;
}
if (!g_variant_lookup (variant, "AllowSystemInstallation", "b",
&allow_system_installation))
{
/* Default value. */
allow_system_installation = FALSE;
}
/* Success. Create an #MctAppFilter object to contain the results. */
app_filter = g_new0 (MctAppFilter, 1);
app_filter->ref_count = 1;
app_filter->user_id = user_id;
app_filter->app_list = g_steal_pointer (&app_list);
app_filter->app_list_type =
is_allowlist ? MCT_APP_FILTER_LIST_ALLOWLIST : MCT_APP_FILTER_LIST_BLOCKLIST;
app_filter->oars_ratings = g_steal_pointer (&oars_variant);
app_filter->allow_user_installation = allow_user_installation;
app_filter->allow_system_installation = allow_system_installation;
return g_steal_pointer (&app_filter);
}
/**
* mct_app_filter_equal:
* @a: (not nullable): an #MctAppFilter
* @b: (not nullable): an #MctAppFilter
*
* Check whether app filters @a and @b are equal.
*
* Returns: %TRUE if @a and @b are equal, %FALSE otherwise
* Since: 0.10.0
*/
gboolean
mct_app_filter_equal (MctAppFilter *a,
MctAppFilter *b)
{
g_return_val_if_fail (a != NULL, FALSE);
g_return_val_if_fail (a->ref_count >= 1, FALSE);
g_return_val_if_fail (b != NULL, FALSE);
g_return_val_if_fail (b->ref_count >= 1, FALSE);
return (a->user_id == b->user_id &&
a->app_list_type == b->app_list_type &&
a->allow_user_installation == b->allow_user_installation &&
a->allow_system_installation == b->allow_system_installation &&
g_strv_equal ((const gchar * const *) a->app_list, (const gchar * const *) b->app_list) &&
g_variant_equal (a->oars_ratings, b->oars_ratings));
}
/*
* Actual implementation of #MctAppFilterBuilder.
*
@ -789,7 +540,7 @@ mct_app_filter_equal (MctAppFilter *a,
*/
typedef struct
{
GPtrArray *blocklist; /* (nullable) (owned) (element-type utf8) */
GPtrArray *blacklist; /* (nullable) (owned) (element-type utf8) */
GHashTable *oars; /* (nullable) (owned) (element-type utf8 MctAppFilterOarsValue) */
gboolean allow_user_installation;
gboolean allow_system_installation;
@ -827,7 +578,7 @@ mct_app_filter_builder_init (MctAppFilterBuilder *builder)
MctAppFilterBuilderReal *_builder = (MctAppFilterBuilderReal *) builder;
g_return_if_fail (_builder != NULL);
g_return_if_fail (_builder->blocklist == NULL);
g_return_if_fail (_builder->blacklist == NULL);
g_return_if_fail (_builder->oars == NULL);
memcpy (builder, &local_builder, sizeof (local_builder));
@ -853,7 +604,7 @@ mct_app_filter_builder_clear (MctAppFilterBuilder *builder)
g_return_if_fail (_builder != NULL);
g_clear_pointer (&_builder->blocklist, g_ptr_array_unref);
g_clear_pointer (&_builder->blacklist, g_ptr_array_unref);
g_clear_pointer (&_builder->oars, g_hash_table_unref);
}
@ -903,8 +654,8 @@ mct_app_filter_builder_copy (MctAppFilterBuilder *builder)
_copy = (MctAppFilterBuilderReal *) copy;
mct_app_filter_builder_clear (copy);
if (_builder->blocklist != NULL)
_copy->blocklist = g_ptr_array_ref (_builder->blocklist);
if (_builder->blacklist != NULL)
_copy->blacklist = g_ptr_array_ref (_builder->blacklist);
if (_builder->oars != NULL)
_copy->oars = g_hash_table_ref (_builder->oars);
_copy->allow_user_installation = _builder->allow_user_installation;
@ -954,11 +705,11 @@ mct_app_filter_builder_end (MctAppFilterBuilder *builder)
g_autoptr(GVariant) oars_variant = NULL;
g_return_val_if_fail (_builder != NULL, NULL);
g_return_val_if_fail (_builder->blocklist != NULL, NULL);
g_return_val_if_fail (_builder->blacklist != NULL, NULL);
g_return_val_if_fail (_builder->oars != NULL, NULL);
/* Ensure the paths list is %NULL-terminated. */
g_ptr_array_add (_builder->blocklist, NULL);
g_ptr_array_add (_builder->blacklist, NULL);
/* Build the OARS variant. */
g_hash_table_iter_init (&iter, _builder->oars);
@ -989,8 +740,8 @@ mct_app_filter_builder_end (MctAppFilterBuilder *builder)
app_filter = g_new0 (MctAppFilter, 1);
app_filter->ref_count = 1;
app_filter->user_id = -1;
app_filter->app_list = (gchar **) g_ptr_array_free (g_steal_pointer (&_builder->blocklist), FALSE);
app_filter->app_list_type = MCT_APP_FILTER_LIST_BLOCKLIST;
app_filter->app_list = (gchar **) g_ptr_array_free (g_steal_pointer (&_builder->blacklist), FALSE);
app_filter->app_list_type = MCT_APP_FILTER_LIST_BLACKLIST;
app_filter->oars_ratings = g_steal_pointer (&oars_variant);
app_filter->allow_user_installation = _builder->allow_user_installation;
app_filter->allow_system_installation = _builder->allow_system_installation;
@ -1001,24 +752,24 @@ mct_app_filter_builder_end (MctAppFilterBuilder *builder)
}
/**
* mct_app_filter_builder_blocklist_path:
* mct_app_filter_builder_blacklist_path:
* @builder: an initialised #MctAppFilterBuilder
* @path: (type filename): an absolute path to blocklist
* @path: (type filename): an absolute path to blacklist
*
* Add @path to the blocklist of app paths in the filter under construction. It
* Add @path to the blacklist of app paths in the filter under construction. It
* will be canonicalised (without doing any I/O) before being added.
* The canonicalised @path will not be added again if its already been added.
*
* Since: 0.2.0
*/
void
mct_app_filter_builder_blocklist_path (MctAppFilterBuilder *builder,
mct_app_filter_builder_blacklist_path (MctAppFilterBuilder *builder,
const gchar *path)
{
MctAppFilterBuilderReal *_builder = (MctAppFilterBuilderReal *) builder;
g_return_if_fail (_builder != NULL);
g_return_if_fail (_builder->blocklist != NULL);
g_return_if_fail (_builder->blacklist != NULL);
g_return_if_fail (path != NULL);
g_return_if_fail (g_path_is_absolute (path));
@ -1027,67 +778,67 @@ mct_app_filter_builder_blocklist_path (MctAppFilterBuilder *builder,
NULL, NULL, NULL);
g_return_if_fail (canonical_path_utf8 != NULL);
if (!g_ptr_array_find_with_equal_func (_builder->blocklist,
if (!g_ptr_array_find_with_equal_func (_builder->blacklist,
canonical_path_utf8, g_str_equal, NULL))
g_ptr_array_add (_builder->blocklist, g_steal_pointer (&canonical_path_utf8));
g_ptr_array_add (_builder->blacklist, g_steal_pointer (&canonical_path_utf8));
}
/**
* mct_app_filter_builder_blocklist_flatpak_ref:
* mct_app_filter_builder_blacklist_flatpak_ref:
* @builder: an initialised #MctAppFilterBuilder
* @app_ref: a flatpak app ref to blocklist
* @app_ref: a flatpak app ref to blacklist
*
* Add @app_ref to the blocklist of flatpak refs in the filter under
* Add @app_ref to the blacklist of flatpak refs in the filter under
* construction. The @app_ref will not be added again if its already been
* added.
*
* Since: 0.2.0
*/
void
mct_app_filter_builder_blocklist_flatpak_ref (MctAppFilterBuilder *builder,
mct_app_filter_builder_blacklist_flatpak_ref (MctAppFilterBuilder *builder,
const gchar *app_ref)
{
MctAppFilterBuilderReal *_builder = (MctAppFilterBuilderReal *) builder;
g_return_if_fail (_builder != NULL);
g_return_if_fail (_builder->blocklist != NULL);
g_return_if_fail (_builder->blacklist != NULL);
g_return_if_fail (app_ref != NULL);
g_return_if_fail (is_valid_flatpak_ref (app_ref));
if (!g_ptr_array_find_with_equal_func (_builder->blocklist,
if (!g_ptr_array_find_with_equal_func (_builder->blacklist,
app_ref, g_str_equal, NULL))
g_ptr_array_add (_builder->blocklist, g_strdup (app_ref));
g_ptr_array_add (_builder->blacklist, g_strdup (app_ref));
}
/**
* mct_app_filter_builder_blocklist_content_type:
* mct_app_filter_builder_blacklist_content_type:
* @builder: an initialised #MctAppFilterBuilder
* @content_type: a content type to blocklist
* @content_type: a content type to blacklist
*
* Add @content_type to the blocklist of content types in the filter under
* Add @content_type to the blacklist of content types in the filter under
* construction. The @content_type will not be added again if its already been
* added.
*
* Note that this method doesnt handle content subtypes. For example, if
* `application/xml` is added to the blocklist but `application/xspf+xml` is not,
* a check for whether `application/xspf+xml` is blocklisted would return false.
* `application/xml` is added to the blacklist but `application/xspf+xml` is not,
* a check for whether `application/xspf+xml` is blacklisted would return false.
*
* Since: 0.4.0
*/
void
mct_app_filter_builder_blocklist_content_type (MctAppFilterBuilder *builder,
mct_app_filter_builder_blacklist_content_type (MctAppFilterBuilder *builder,
const gchar *content_type)
{
MctAppFilterBuilderReal *_builder = (MctAppFilterBuilderReal *) builder;
g_return_if_fail (_builder != NULL);
g_return_if_fail (_builder->blocklist != NULL);
g_return_if_fail (_builder->blacklist != NULL);
g_return_if_fail (content_type != NULL);
g_return_if_fail (is_valid_content_type (content_type));
if (!g_ptr_array_find_with_equal_func (_builder->blocklist,
if (!g_ptr_array_find_with_equal_func (_builder->blacklist,
content_type, g_str_equal, NULL))
g_ptr_array_add (_builder->blocklist, g_strdup (content_type));
g_ptr_array_add (_builder->blacklist, g_strdup (content_type));
}
/**

View File

@ -78,9 +78,6 @@ void mct_app_filter_unref (MctAppFilter *filter);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (MctAppFilter, mct_app_filter_unref)
uid_t mct_app_filter_get_user_id (MctAppFilter *filter);
gboolean mct_app_filter_is_enabled (MctAppFilter *filter);
gboolean mct_app_filter_is_path_allowed (MctAppFilter *filter,
const gchar *path);
gboolean mct_app_filter_is_flatpak_ref_allowed (MctAppFilter *filter,
@ -99,14 +96,6 @@ MctAppFilterOarsValue mct_app_filter_get_oars_value (MctAppFilter *filter,
gboolean mct_app_filter_is_user_installation_allowed (MctAppFilter *filter);
gboolean mct_app_filter_is_system_installation_allowed (MctAppFilter *filter);
GVariant *mct_app_filter_serialize (MctAppFilter *filter);
MctAppFilter *mct_app_filter_deserialize (GVariant *variant,
uid_t user_id,
GError **error);
gboolean mct_app_filter_equal (MctAppFilter *a,
MctAppFilter *b);
/**
* MctAppFilterBuilder:
*
@ -168,11 +157,11 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (MctAppFilterBuilder, mct_app_filter_builder_free)
MctAppFilter *mct_app_filter_builder_end (MctAppFilterBuilder *builder);
void mct_app_filter_builder_blocklist_path (MctAppFilterBuilder *builder,
void mct_app_filter_builder_blacklist_path (MctAppFilterBuilder *builder,
const gchar *path);
void mct_app_filter_builder_blocklist_flatpak_ref (MctAppFilterBuilder *builder,
void mct_app_filter_builder_blacklist_flatpak_ref (MctAppFilterBuilder *builder,
const gchar *app_ref);
void mct_app_filter_builder_blocklist_content_type (MctAppFilterBuilder *builder,
void mct_app_filter_builder_blacklist_content_type (MctAppFilterBuilder *builder,
const gchar *content_type);
void mct_app_filter_builder_set_oars_value (MctAppFilterBuilder *builder,

View File

@ -1,122 +0,0 @@
/*
If G_HAS_CONSTRUCTORS is true then the compiler support *both* constructors and
destructors, in a sane way, including e.g. on library unload. If not you're on
your own.
Some compilers need #pragma to handle this, which does not work with macros,
so the way you need to use this is (for constructors):
#ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA
#pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(my_constructor)
#endif
G_DEFINE_CONSTRUCTOR(my_constructor)
static void my_constructor(void) {
...
}
*/
#ifndef __GTK_DOC_IGNORE__
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
#define G_HAS_CONSTRUCTORS 1
#define G_DEFINE_CONSTRUCTOR(_func) static void __attribute__((constructor)) _func (void);
#define G_DEFINE_DESTRUCTOR(_func) static void __attribute__((destructor)) _func (void);
#elif defined (_MSC_VER) && (_MSC_VER >= 1500)
/* Visual studio 2008 and later has _Pragma */
#include <stdlib.h>
#define G_HAS_CONSTRUCTORS 1
/* We do some weird things to avoid the constructors being optimized
* away on VS2015 if WholeProgramOptimization is enabled. First we
* make a reference to the array from the wrapper to make sure its
* references. Then we use a pragma to make sure the wrapper function
* symbol is always included at the link stage. Also, the symbols
* need to be extern (but not dllexport), even though they are not
* really used from another object file.
*/
/* We need to account for differences between the mangling of symbols
* for Win32 (x86) and x64 programs, as symbols on Win32 are prefixed
* with an underscore but symbols on x64 are not.
*/
#ifdef _WIN64
#define G_MSVC_SYMBOL_PREFIX ""
#else
#define G_MSVC_SYMBOL_PREFIX "_"
#endif
#define G_DEFINE_CONSTRUCTOR(_func) G_MSVC_CTOR (_func, G_MSVC_SYMBOL_PREFIX)
#define G_DEFINE_DESTRUCTOR(_func) G_MSVC_DTOR (_func, G_MSVC_SYMBOL_PREFIX)
#define G_MSVC_CTOR(_func,_sym_prefix) \
static void _func(void); \
extern int (* _array ## _func)(void); \
int _func ## _wrapper(void) { _func(); g_slist_find (NULL, _array ## _func); return 0; } \
__pragma(comment(linker,"/include:" _sym_prefix # _func "_wrapper")) \
__pragma(section(".CRT$XCU",read)) \
__declspec(allocate(".CRT$XCU")) int (* _array ## _func)(void) = _func ## _wrapper;
#define G_MSVC_DTOR(_func,_sym_prefix) \
static void _func(void); \
extern int (* _array ## _func)(void); \
int _func ## _constructor(void) { atexit (_func); g_slist_find (NULL, _array ## _func); return 0; } \
__pragma(comment(linker,"/include:" _sym_prefix # _func "_constructor")) \
__pragma(section(".CRT$XCU",read)) \
__declspec(allocate(".CRT$XCU")) int (* _array ## _func)(void) = _func ## _constructor;
#elif defined (_MSC_VER)
#define G_HAS_CONSTRUCTORS 1
/* Pre Visual studio 2008 must use #pragma section */
#define G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA 1
#define G_DEFINE_DESTRUCTOR_NEEDS_PRAGMA 1
#define G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(_func) \
section(".CRT$XCU",read)
#define G_DEFINE_CONSTRUCTOR(_func) \
static void _func(void); \
static int _func ## _wrapper(void) { _func(); return 0; } \
__declspec(allocate(".CRT$XCU")) static int (*p)(void) = _func ## _wrapper;
#define G_DEFINE_DESTRUCTOR_PRAGMA_ARGS(_func) \
section(".CRT$XCU",read)
#define G_DEFINE_DESTRUCTOR(_func) \
static void _func(void); \
static int _func ## _constructor(void) { atexit (_func); return 0; } \
__declspec(allocate(".CRT$XCU")) static int (* _array ## _func)(void) = _func ## _constructor;
#elif defined(__SUNPRO_C)
/* This is not tested, but i believe it should work, based on:
* http://opensource.apple.com/source/OpenSSL098/OpenSSL098-35/src/fips/fips_premain.c
*/
#define G_HAS_CONSTRUCTORS 1
#define G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA 1
#define G_DEFINE_DESTRUCTOR_NEEDS_PRAGMA 1
#define G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(_func) \
init(_func)
#define G_DEFINE_CONSTRUCTOR(_func) \
static void _func(void);
#define G_DEFINE_DESTRUCTOR_PRAGMA_ARGS(_func) \
fini(_func)
#define G_DEFINE_DESTRUCTOR(_func) \
static void _func(void);
#else
/* constructors not supported for this compiler */
#endif
#endif /* __GTK_DOC_IGNORE__ */

View File

@ -23,6 +23,5 @@
#pragma once
#include <libmalcontent/app-filter.h>
#include <libmalcontent/enums.h>
#include <libmalcontent/manager.h>
#include <libmalcontent/session-limits.h>

View File

@ -29,6 +29,7 @@
#include <libmalcontent/app-filter.h>
#include <libmalcontent/manager.h>
#include <libmalcontent/session-limits.h>
#include <systemd/sd-journal.h>
#include "libmalcontent/app-filter-private.h"
#include "libmalcontent/session-limits-private.h"
@ -98,7 +99,7 @@ mct_manager_set_property (GObject *object,
switch ((MctManagerProperty) property_id)
{
case PROP_CONNECTION:
/* Construct-only. May not be %NULL. */
/* Construct-only. May be %NULL. */
g_assert (self->connection == NULL);
self->connection = g_value_dup_object (value);
g_assert (self->connection != NULL);
@ -167,7 +168,7 @@ mct_manager_class_init (MctManagerClass *klass)
object_class->set_property = mct_manager_set_property;
/**
* MctManager:connection: (not nullable)
* MctManager:connection:
*
* A connection to the system bus, where accounts-service runs. Its provided
* mostly for testing purposes, or to allow an existing connection to be
@ -257,6 +258,37 @@ _mct_manager_user_changed_cb (GDBusConnection *connection,
g_signal_emit_by_name (manager, "app-filter-changed", uid);
}
/**
* _mct_app_filter_build_app_filter_variant:
* @filter: an #MctAppFilter
*
* Build a #GVariant which contains the app filter from @filter, in the format
* used for storing it in AccountsService.
*
* Returns: (transfer floating): a new, floating #GVariant containing the app
* filter
* Since: 0.2.0
*/
static GVariant *
_mct_app_filter_build_app_filter_variant (MctAppFilter *filter)
{
g_auto(GVariantBuilder) builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("(bas)"));
g_return_val_if_fail (filter != NULL, NULL);
g_return_val_if_fail (filter->ref_count >= 1, NULL);
g_variant_builder_add (&builder, "b",
(filter->app_list_type == MCT_APP_FILTER_LIST_WHITELIST));
g_variant_builder_open (&builder, G_VARIANT_TYPE ("as"));
for (gsize i = 0; filter->app_list[i] != NULL; i++)
g_variant_builder_add (&builder, "s", filter->app_list[i]);
g_variant_builder_close (&builder);
return g_variant_builder_end (&builder);
}
/* Check if @error is a D-Bus remote error matching @expected_error_name. */
static gboolean
bus_remote_error_matches (const GError *error,
@ -280,20 +312,12 @@ bus_error_to_manager_error (const GError *bus_error,
if (g_error_matches (bus_error, G_DBUS_ERROR, G_DBUS_ERROR_ACCESS_DENIED) ||
bus_remote_error_matches (bus_error, "org.freedesktop.Accounts.Error.PermissionDenied"))
return g_error_new (MCT_MANAGER_ERROR, MCT_MANAGER_ERROR_PERMISSION_DENIED,
_("Not allowed to query parental controls data for user %u"),
_("Not allowed to query app filter data for user %u"),
(guint) user_id);
else if (g_error_matches (bus_error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD) ||
bus_remote_error_matches (bus_error, "org.freedesktop.Accounts.Error.Failed"))
return g_error_new (MCT_MANAGER_ERROR, MCT_MANAGER_ERROR_INVALID_USER,
_("User %u does not exist"), (guint) user_id);
else if (g_error_matches (bus_error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN) ||
g_error_matches (bus_error, G_DBUS_ERROR, G_DBUS_ERROR_NAME_HAS_NO_OWNER))
/* If accountsservice is not available on the system bus, then the
* com.endlessm.ParentalControls.AppFilter extension interface
* certainly can't be available. */
return g_error_new_literal (MCT_MANAGER_ERROR,
MCT_MANAGER_ERROR_DISABLED,
_("System accounts service not available"));
else
return g_error_copy (bus_error);
}
@ -363,6 +387,13 @@ mct_manager_get_app_filter (MctManager *self,
g_autoptr(GVariant) result_variant = NULL;
g_autoptr(GVariant) properties = NULL;
g_autoptr(GError) local_error = NULL;
g_autoptr(MctAppFilter) app_filter = NULL;
gboolean is_whitelist;
g_auto(GStrv) app_list = NULL;
const gchar *content_rating_kind;
g_autoptr(GVariant) oars_variant = NULL;
gboolean allow_user_installation;
gboolean allow_system_installation;
g_return_val_if_fail (MCT_IS_MANAGER (self), NULL);
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
@ -413,16 +444,62 @@ mct_manager_get_app_filter (MctManager *self,
/* Extract the properties we care about. They may be silently omitted from the
* results if we dont have permission to access them. */
properties = g_variant_get_child_value (result_variant, 0);
if (!g_variant_lookup (properties, "AppFilter", "(b^as)", NULL, NULL))
if (!g_variant_lookup (properties, "AppFilter", "(b^as)",
&is_whitelist, &app_list))
{
g_set_error (error, MCT_MANAGER_ERROR,
MCT_MANAGER_ERROR_PERMISSION_DENIED,
_("Not allowed to query parental controls data for user %u"),
_("Not allowed to query app filter data for user %u"),
(guint) user_id);
return NULL;
}
return mct_app_filter_deserialize (properties, user_id, error);
if (!g_variant_lookup (properties, "OarsFilter", "(&s@a{ss})",
&content_rating_kind, &oars_variant))
{
/* Default value. */
content_rating_kind = "oars-1.1";
oars_variant = g_variant_new ("a{ss}", NULL);
}
/* Check that the OARS filter is in a format we support. Currently, thats
* only oars-1.0 and oars-1.1. */
if (!g_str_equal (content_rating_kind, "oars-1.0") &&
!g_str_equal (content_rating_kind, "oars-1.1"))
{
g_set_error (error, MCT_MANAGER_ERROR,
MCT_MANAGER_ERROR_INVALID_DATA,
_("OARS filter for user %u has an unrecognized kind %s"),
(guint) user_id, content_rating_kind);
return NULL;
}
if (!g_variant_lookup (properties, "AllowUserInstallation", "b",
&allow_user_installation))
{
/* Default value. */
allow_user_installation = TRUE;
}
if (!g_variant_lookup (properties, "AllowSystemInstallation", "b",
&allow_system_installation))
{
/* Default value. */
allow_system_installation = FALSE;
}
/* Success. Create an #MctAppFilter object to contain the results. */
app_filter = g_new0 (MctAppFilter, 1);
app_filter->ref_count = 1;
app_filter->user_id = user_id;
app_filter->app_list = g_steal_pointer (&app_list);
app_filter->app_list_type =
is_whitelist ? MCT_APP_FILTER_LIST_WHITELIST : MCT_APP_FILTER_LIST_BLACKLIST;
app_filter->oars_ratings = g_steal_pointer (&oars_variant);
app_filter->allow_user_installation = allow_user_installation;
app_filter->allow_system_installation = allow_system_installation;
return g_steal_pointer (&app_filter);
}
static void get_app_filter_thread_cb (GTask *task,
@ -556,10 +633,14 @@ mct_manager_set_app_filter (MctManager *self,
GError **error)
{
g_autofree gchar *object_path = NULL;
g_autoptr(GVariant) properties_variant = NULL;
g_autoptr(GVariant) properties_value = NULL;
const gchar *properties_key = NULL;
GVariantIter iter;
g_autoptr(GVariant) app_filter_variant = NULL;
g_autoptr(GVariant) oars_filter_variant = NULL;
g_autoptr(GVariant) allow_user_installation_variant = NULL;
g_autoptr(GVariant) allow_system_installation_variant = NULL;
g_autoptr(GVariant) app_filter_result_variant = NULL;
g_autoptr(GVariant) oars_filter_result_variant = NULL;
g_autoptr(GVariant) allow_user_installation_result_variant = NULL;
g_autoptr(GVariant) allow_system_installation_result_variant = NULL;
g_autoptr(GError) local_error = NULL;
g_return_val_if_fail (MCT_IS_MANAGER (self), FALSE);
@ -574,35 +655,102 @@ mct_manager_set_app_filter (MctManager *self,
if (object_path == NULL)
return FALSE;
properties_variant = mct_app_filter_serialize (app_filter);
app_filter_variant = _mct_app_filter_build_app_filter_variant (app_filter);
oars_filter_variant = g_variant_new ("(s@a{ss})", "oars-1.1",
app_filter->oars_ratings);
allow_user_installation_variant = g_variant_new_boolean (app_filter->allow_user_installation);
allow_system_installation_variant = g_variant_new_boolean (app_filter->allow_system_installation);
g_variant_iter_init (&iter, properties_variant);
while (g_variant_iter_loop (&iter, "{&sv}", &properties_key, &properties_value))
app_filter_result_variant =
g_dbus_connection_call_sync (self->connection,
"org.freedesktop.Accounts",
object_path,
"org.freedesktop.DBus.Properties",
"Set",
g_variant_new ("(ssv)",
"com.endlessm.ParentalControls.AppFilter",
"AppFilter",
g_steal_pointer (&app_filter_variant)),
G_VARIANT_TYPE ("()"),
(flags & MCT_MANAGER_SET_VALUE_FLAGS_INTERACTIVE)
? G_DBUS_CALL_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION
: G_DBUS_CALL_FLAGS_NONE,
-1, /* timeout, ms */
cancellable,
&local_error);
if (local_error != NULL)
{
g_autoptr(GVariant) result_variant = NULL;
g_propagate_error (error, bus_error_to_manager_error (local_error, user_id));
return FALSE;
}
result_variant =
g_dbus_connection_call_sync (self->connection,
"org.freedesktop.Accounts",
object_path,
"org.freedesktop.DBus.Properties",
"Set",
g_variant_new ("(ssv)",
"com.endlessm.ParentalControls.AppFilter",
properties_key,
properties_value),
G_VARIANT_TYPE ("()"),
(flags & MCT_MANAGER_SET_VALUE_FLAGS_INTERACTIVE)
? G_DBUS_CALL_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION
: G_DBUS_CALL_FLAGS_NONE,
-1, /* timeout, ms */
cancellable,
&local_error);
if (local_error != NULL)
{
g_propagate_error (error, bus_error_to_manager_error (local_error, user_id));
return FALSE;
}
oars_filter_result_variant =
g_dbus_connection_call_sync (self->connection,
"org.freedesktop.Accounts",
object_path,
"org.freedesktop.DBus.Properties",
"Set",
g_variant_new ("(ssv)",
"com.endlessm.ParentalControls.AppFilter",
"OarsFilter",
g_steal_pointer (&oars_filter_variant)),
G_VARIANT_TYPE ("()"),
(flags & MCT_MANAGER_SET_VALUE_FLAGS_INTERACTIVE)
? G_DBUS_CALL_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION
: G_DBUS_CALL_FLAGS_NONE,
-1, /* timeout, ms */
cancellable,
&local_error);
if (local_error != NULL)
{
g_propagate_error (error, bus_error_to_manager_error (local_error, user_id));
return FALSE;
}
allow_user_installation_result_variant =
g_dbus_connection_call_sync (self->connection,
"org.freedesktop.Accounts",
object_path,
"org.freedesktop.DBus.Properties",
"Set",
g_variant_new ("(ssv)",
"com.endlessm.ParentalControls.AppFilter",
"AllowUserInstallation",
g_steal_pointer (&allow_user_installation_variant)),
G_VARIANT_TYPE ("()"),
(flags & MCT_MANAGER_SET_VALUE_FLAGS_INTERACTIVE)
? G_DBUS_CALL_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION
: G_DBUS_CALL_FLAGS_NONE,
-1, /* timeout, ms */
cancellable,
&local_error);
if (local_error != NULL)
{
g_propagate_error (error, bus_error_to_manager_error (local_error, user_id));
return FALSE;
}
allow_system_installation_result_variant =
g_dbus_connection_call_sync (self->connection,
"org.freedesktop.Accounts",
object_path,
"org.freedesktop.DBus.Properties",
"Set",
g_variant_new ("(ssv)",
"com.endlessm.ParentalControls.AppFilter",
"AllowSystemInstallation",
g_steal_pointer (&allow_system_installation_variant)),
G_VARIANT_TYPE ("()"),
(flags & MCT_MANAGER_SET_VALUE_FLAGS_INTERACTIVE)
? G_DBUS_CALL_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION
: G_DBUS_CALL_FLAGS_NONE,
-1, /* timeout, ms */
cancellable,
&local_error);
if (local_error != NULL)
{
g_propagate_error (error, bus_error_to_manager_error (local_error, user_id));
return FALSE;
}
return TRUE;
@ -746,6 +894,9 @@ mct_manager_get_session_limits (MctManager *self,
g_autoptr(GVariant) result_variant = NULL;
g_autoptr(GVariant) properties = NULL;
g_autoptr(GError) local_error = NULL;
g_autoptr(MctSessionLimits) session_limits = NULL;
guint32 limit_type;
guint32 daily_start_time, daily_end_time;
g_return_val_if_fail (MCT_IS_MANAGER (self), NULL);
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
@ -796,16 +947,55 @@ mct_manager_get_session_limits (MctManager *self,
/* Extract the properties we care about. They may be silently omitted from the
* results if we dont have permission to access them. */
properties = g_variant_get_child_value (result_variant, 0);
if (!g_variant_lookup (properties, "LimitType", "u", NULL))
if (!g_variant_lookup (properties, "LimitType", "u",
&limit_type))
{
g_set_error (error, MCT_MANAGER_ERROR,
MCT_MANAGER_ERROR_PERMISSION_DENIED,
_("Not allowed to query parental controls data for user %u"),
_("Not allowed to query session limits data for user %u"),
(guint) user_id);
return NULL;
}
return mct_session_limits_deserialize (properties, user_id, error);
/* Check that the limit type is something we support. */
G_STATIC_ASSERT (sizeof (limit_type) >= sizeof (MctSessionLimitsType));
if ((guint) limit_type > MCT_SESSION_LIMITS_TYPE_DAILY_SCHEDULE)
{
g_set_error (error, MCT_MANAGER_ERROR,
MCT_MANAGER_ERROR_INVALID_DATA,
_("Session limit for user %u has an unrecognized type %u"),
(guint) user_id, limit_type);
return NULL;
}
if (!g_variant_lookup (properties, "DailySchedule", "(uu)",
&daily_start_time, &daily_end_time))
{
/* Default value. */
daily_start_time = 0;
daily_end_time = 24 * 60 * 60;
}
if (daily_start_time >= daily_end_time ||
daily_end_time > 24 * 60 * 60)
{
g_set_error (error, MCT_MANAGER_ERROR,
MCT_MANAGER_ERROR_INVALID_DATA,
_("Session limit for user %u has invalid daily schedule %u%u"),
(guint) user_id, daily_start_time, daily_end_time);
return NULL;
}
/* Success. Create an #MctSessionLimits object to contain the results. */
session_limits = g_new0 (MctSessionLimits, 1);
session_limits->ref_count = 1;
session_limits->user_id = user_id;
session_limits->limit_type = limit_type;
session_limits->daily_start_time = daily_start_time;
session_limits->daily_end_time = daily_end_time;
return g_steal_pointer (&session_limits);
}
static void get_session_limits_thread_cb (GTask *task,
@ -939,12 +1129,11 @@ mct_manager_set_session_limits (MctManager *self,
GError **error)
{
g_autofree gchar *object_path = NULL;
g_autoptr(GVariant) limit_variant = NULL;
const gchar *limit_property_name = NULL;
g_autoptr(GVariant) limit_type_variant = NULL;
g_autoptr(GVariant) limit_result_variant = NULL;
g_autoptr(GVariant) limit_type_result_variant = NULL;
g_autoptr(GVariant) properties_variant = NULL;
g_autoptr(GVariant) properties_value = NULL;
const gchar *properties_key = NULL;
GVariantIter iter;
g_autoptr(GError) local_error = NULL;
g_return_val_if_fail (MCT_IS_MANAGER (self), FALSE);
@ -959,22 +1148,29 @@ mct_manager_set_session_limits (MctManager *self,
if (object_path == NULL)
return FALSE;
properties_variant = mct_session_limits_serialize (session_limits);
g_variant_iter_init (&iter, properties_variant);
while (g_variant_iter_loop (&iter, "{&sv}", &properties_key, &properties_value))
switch (session_limits->limit_type)
{
g_autoptr(GVariant) result_variant = NULL;
case MCT_SESSION_LIMITS_TYPE_DAILY_SCHEDULE:
limit_variant = g_variant_new ("(uu)",
session_limits->daily_start_time,
session_limits->daily_end_time);
limit_property_name = "DailySchedule";
break;
case MCT_SESSION_LIMITS_TYPE_NONE:
limit_variant = NULL;
limit_property_name = NULL;
break;
default:
g_assert_not_reached ();
}
/* Change the limit type last, so all the details of the new limit are
* correct by the time its changed over. */
if (g_str_equal (properties_key, "LimitType"))
{
limit_type_variant = g_steal_pointer (&properties_value);
continue;
}
limit_type_variant = g_variant_new_uint32 (session_limits->limit_type);
result_variant =
if (limit_property_name != NULL)
{
/* Change the details of the new limit first, so that all the properties are
* correct by the time the limit type is changed over. */
limit_result_variant =
g_dbus_connection_call_sync (self->connection,
"org.freedesktop.Accounts",
object_path,
@ -982,8 +1178,8 @@ mct_manager_set_session_limits (MctManager *self,
"Set",
g_variant_new ("(ssv)",
"com.endlessm.ParentalControls.SessionLimits",
properties_key,
properties_value),
limit_property_name,
g_steal_pointer (&limit_variant)),
G_VARIANT_TYPE ("()"),
(flags & MCT_MANAGER_SET_VALUE_FLAGS_INTERACTIVE)
? G_DBUS_CALL_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION
@ -1007,7 +1203,7 @@ mct_manager_set_session_limits (MctManager *self,
g_variant_new ("(ssv)",
"com.endlessm.ParentalControls.SessionLimits",
"LimitType",
limit_type_variant),
g_steal_pointer (&limit_type_variant)),
G_VARIANT_TYPE ("()"),
(flags & MCT_MANAGER_SET_VALUE_FLAGS_INTERACTIVE)
? G_DBUS_CALL_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION
@ -1138,3 +1334,132 @@ mct_manager_set_session_limits_finish (MctManager *self,
return g_task_propagate_boolean (G_TASK (result), error);
}
G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC (sd_journal, sd_journal_close)
/* TODO Docs */
MctSessionHistory *
mct_manager_get_session_history (MctManager *self,
uid_t user_id,
GDateTime *start,
GDateTime *end,
MctManagerGetValueFlags flags,
GCancellable *cancellable,
GError **error)
{
g_auto(sd_journal) *journal = NULL;
int ret;
const gchar * const match_message_ids[] =
{
"MESSAGE_ID=8d45620c1a4348dbb17410da57c60c66", /* new session */
"MESSAGE_ID=3354939424b4456d9802ca8333ed424a", /* session ended */
"MESSAGE_ID=6bbd95ee977941e497c48be27c254128", /* entering sleep */
"MESSAGE_ID=8811e6df2a8e40f58a94cea26f8ebf14", /* leaving sleep */
"MESSAGE_ID=b07a249cd024414a82dd00cd181378ff", /* startup complete */
"MESSAGE_ID=98268866d1d54a499c4e98921d93bc40", /* starting to shut down */
/* TODO: need to add messages to gnome-shell for when the user locks and unlocks the screen,
* including logging in and out and switching user */
};
const size_t message_id_len = sizeof (match_message_ids[0]);
g_autoptr(GPtrArray) active_periods = g_ptr_array_new_with_free_func (NULL); /* TODO */
g_return_val_if_fail (MCT_IS_MANAGER (self), NULL);
g_return_val_if_fail (start != NULL, NULL);
g_return_val_if_fail (end != NULL, NULL);
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
ret = sd_journal_open (&journal, SD_JOURNAL_SYSTEM);
if (ret < 0)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Error opening journal: %s", g_strerror (-ret));
return NULL;
}
/* TODO: work out what data threshold is needed and set with sd_journal_set_data_threshold() */
/* Add matches. */
for (gsize i = 0; i < G_N_ELEMENTS (match_message_ids); i++)
{
ret = sd_journal_add_match (journal, "MESSAGE_ID=TODO", 0);
if (ret < 0)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, /* TODO More specific error codes throughout */
"Error applying matches in journal: %s", g_strerror (-ret));
return NULL;
}
}
ret = sd_journal_seek_realtime_usec (journal, (uint64_t) g_date_time_to_unix (start) * G_USEC_PER_SEC);
if (ret < 0)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, /* TODO More specific error codes throughout */
"Error finding start entry in journal: %s", g_strerror (-ret));
return NULL;
}
while (TRUE)
{
uint64_t entry_realtime = 0;
const void *data = NULL;
size_t data_len = 0;
ret = sd_journal_next (journal);
if (ret < 0)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Error seeking journal: %s", g_strerror (-ret));
return NULL;
}
else if (ret == 0)
{
/* Reached EOF. */
break;
}
ret = sd_journal_get_realtime_usec (journal, &entry_realtime);
if (ret < 0)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Error reading journal: %s", g_strerror (-ret));
return NULL;
}
if (entry_realtime / G_USEC_PER_SEC >= g_date_time_to_unix (end))
{
/* Reached the end of the search range. */
break;
}
/* Check the type of the record. */
ret = sd_journal_get_data (journal, "MESSAGE_ID", &data, &data_len);
if (ret < 0)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Error reading journal: %s", g_strerror (-ret));
return NULL;
}
if (data_len != message_id_len)
{
g_debug ("Unexpected field %s, ignoring", data);
continue;
}
/* TODO: need to filter by uid */
if (memcmp (data, "MESSAGE_ID=8d45620c1a4348dbb17410da57c60c66", message_id_len) == 0)
{
/* New session. */
g_ptr_array_add (active_periods, TODO);
}
/* TODO */
"MESSAGE_ID=3354939424b4456d9802ca8333ed424a", /* session ended */
"MESSAGE_ID=6bbd95ee977941e497c48be27c254128", /* entering sleep */
"MESSAGE_ID=8811e6df2a8e40f58a94cea26f8ebf14", /* leaving sleep */
"MESSAGE_ID=b07a249cd024414a82dd00cd181378ff", /* startup complete */
"MESSAGE_ID=98268866d1d54a499c4e98921d93bc40", /* starting to shut down */
}
}

View File

@ -168,4 +168,13 @@ gboolean mct_manager_set_session_limits_finish (MctManager *
GAsyncResult *result,
GError **error);
/* TODO */
MctSessionHistory *mct_manager_get_session_history (MctManager *self,
uid_t user_id,
GDateTime *start,
GDateTime *end,
MctManagerGetValueFlags flags,
GCancellable *cancellable,
GError **error);
G_END_DECLS

View File

@ -2,19 +2,20 @@ libmalcontent_api_version = '0'
libmalcontent_api_name = 'malcontent-' + libmalcontent_api_version
libmalcontent_sources = [
'app-filter.c',
'init.c',
'manager.c',
'session-history.c',
'session-limits.c',
]
libmalcontent_headers = [
'app-filter.h',
'malcontent.h',
'manager.h',
'session-history.h',
'session-limits.h',
]
libmalcontent_private_headers = [
'app-filter-private.h',
'gconstructor.h',
'session-history-private.h',
'session-limits-private.h',
]
@ -30,14 +31,8 @@ libmalcontent_private_deps = [
# FIXME: Would be good to use subdir here: https://github.com/mesonbuild/meson/issues/2969
libmalcontent_include_subdir = join_paths(libmalcontent_api_name, 'libmalcontent')
enums = gnome.mkenums_simple('enums',
sources: libmalcontent_headers,
install_header: true,
install_dir: join_paths(includedir, libmalcontent_include_subdir),
)
libmalcontent = library(libmalcontent_api_name,
libmalcontent_sources + libmalcontent_headers + libmalcontent_private_headers + enums,
libmalcontent_sources + libmalcontent_headers + libmalcontent_private_headers,
dependencies: libmalcontent_public_deps + libmalcontent_private_deps,
include_directories: root_inc,
install: true,
@ -47,7 +42,6 @@ libmalcontent = library(libmalcontent_api_name,
libmalcontent_dep = declare_dependency(
link_with: libmalcontent,
include_directories: root_inc,
sources: libmalcontent_headers + [enums[1]],
)
# Public library bits.
@ -65,8 +59,8 @@ pkgconfig.generate(libmalcontent,
libraries_private: libmalcontent_private_deps,
)
libmalcontent_gir = gnome.generate_gir(libmalcontent,
sources: libmalcontent_sources + libmalcontent_headers + enums,
gnome.generate_gir(libmalcontent,
sources: libmalcontent_sources + libmalcontent_headers + libmalcontent_private_headers,
nsversion: libmalcontent_api_version,
namespace: 'Malcontent',
symbol_prefix: 'mct_',
@ -77,4 +71,4 @@ libmalcontent_gir = gnome.generate_gir(libmalcontent,
dependencies: libmalcontent_dep,
)
subdir('tests')
subdir('tests')

View File

@ -20,32 +20,23 @@
* - Philip Withnall <withnall@endlessm.com>
*/
#include "config.h"
#pragma once
#include <glib/gi18n-lib.h>
#include "gconstructor.h"
#include <gio/gio.h>
#include <glib.h>
#include <glib-object.h>
#include <libmalcontent/session-history.h>
G_BEGIN_DECLS
static void
mct_init (void)
struct _MctSessionHistory
{
bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
}
gint ref_count;
#ifdef G_HAS_CONSTRUCTORS
uid_t user_id;
#ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA
#pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(mct_init_ctor)
#endif
G_DEFINE_CONSTRUCTOR(mct_init_ctor)
GDateTime *start; /* (owned) */
GDateTime *end; /* (owned) */
};
static void
mct_init_ctor (void)
{
mct_init ();
}
#else
#error Your platform/compiler is missing constructor support
#endif
G_END_DECLS

View File

@ -0,0 +1,100 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
* Copyright © 2020 Endless Mobile, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Authors:
* - Philip Withnall <withnall@endlessm.com>
*/
#include "config.h"
#include <glib.h>
#include <glib-object.h>
#include <glib/gi18n-lib.h>
#include <gio/gio.h>
#include <libmalcontent/session-history.h>
#include "libmalcontent/session-history-private.h"
/* struct _MctSessionHistory is defined in session-history-private.h */
G_DEFINE_BOXED_TYPE (MctSessionHistory, mct_session_history,
mct_session_history_ref, mct_session_history_unref)
/**
* mct_session_history_ref:
* @history: (transfer none): an #MctSessionHistory
*
* Increment the reference count of @history, and return the same pointer to it.
*
* Returns: (transfer full): the same pointer as @history
* Since: 0.5.0
*/
MctSessionHistory *
mct_session_history_ref (MctSessionHistory *history)
{
g_return_val_if_fail (history != NULL, NULL);
g_return_val_if_fail (history->ref_count >= 1, NULL);
g_return_val_if_fail (history->ref_count <= G_MAXINT - 1, NULL);
history->ref_count++;
return history;
}
/**
* mct_session_history_unref:
* @history: (transfer full): an #MctSessionHistory
*
* Decrement the reference count of @history. If the reference count reaches
* zero, free the @history and all its resources.
*
* Since: 0.5.0
*/
void
mct_session_history_unref (MctSessionHistory *history)
{
g_return_if_fail (history != NULL);
g_return_if_fail (history->ref_count >= 1);
history->ref_count--;
if (history->ref_count <= 0)
{
g_clear_pointer (&history->start, g_date_time_unref);
g_clear_pointer (&history->end, g_date_time_unref);
g_free (history);
}
}
/**
* mct_session_history_get_user_id:
* @history: an #MctSessionHistory
*
* Get the user ID of the user this #MctSessionHistory is for.
*
* Returns: user ID of the relevant user
* Since: 0.5.0
*/
uid_t
mct_session_history_get_user_id (MctSessionHistory *history)
{
g_return_val_if_fail (history != NULL, (uid_t) -1);
g_return_val_if_fail (history->ref_count >= 1, (uid_t) -1);
return history->user_id;
}

View File

@ -0,0 +1,59 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
* Copyright © 2020 Endless Mobile, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Authors:
* - Philip Withnall <withnall@endlessm.com>
*/
#pragma once
#include <gio/gio.h>
#include <glib.h>
#include <glib-object.h>
G_BEGIN_DECLS
/**
* MctSessionHistory:
*
* TODO
* #MctSessionLimits is an opaque, immutable structure which contains a snapshot
* of the session limits settings for a user at a given time. This includes
* whether session limits are being enforced, and the limit policy for
* example, the times of day when a user is allowed to use the computer.
*
* Typically, session limits settings can only be changed by the administrator,
* and are read-only for non-administrative users. The precise policy is set
* using polkit.
*
* Since: 0.5.0
*/
typedef struct _MctSessionHistory MctSessionHistory;
GType mct_session_history_get_type (void);
#define MCT_TYPE_SESSION_HISTORY mct_session_history_get_type ()
MctSessionHistory *mct_session_history_ref (MctSessionHistory *history);
void mct_session_history_unref (MctSessionHistory *history);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (MctSessionHistory, mct_session_history_unref)
uid_t mct_session_history_get_user_id (MctSessionHistory *history);
GDateTime *mct_session_history_get_start (MctSessionHistory *history);
GDateTime *mct_session_history_get_end (MctSessionHistory *history);
G_END_DECLS

View File

@ -50,7 +50,6 @@ typedef enum
struct _MctSessionLimits
{
/*< private >*/
gint ref_count;
uid_t user_id;

View File

@ -26,7 +26,6 @@
#include <glib-object.h>
#include <glib/gi18n-lib.h>
#include <gio/gio.h>
#include <libmalcontent/manager.h>
#include <libmalcontent/session-limits.h>
#include "libmalcontent/session-limits-private.h"
@ -86,7 +85,7 @@ mct_session_limits_unref (MctSessionLimits *limits)
*
* Get the user ID of the user this #MctSessionLimits is for.
*
* Returns: user ID of the relevant user, or `(uid_t) -1` if unknown
* Returns: user ID of the relevant user
* Since: 0.5.0
*/
uid_t
@ -98,31 +97,6 @@ mct_session_limits_get_user_id (MctSessionLimits *limits)
return limits->user_id;
}
/**
* mct_session_limits_is_enabled:
* @limits: an #MctSessionLimits
*
* Check whether any session limits are enabled and are going to impose at least
* one restriction on the user. This gives a high level view of whether session
* limit parental controls are enabled for the given user.
*
* This function is equivalent to the value returned by the
* `time_limit_enabled_out` argument of
* mct_session_limits_check_time_remaining().
*
* Returns: %TRUE if the session limits object contains at least one restrictive
* session limit, %FALSE if there are no limits in place
* Since: 0.7.0
*/
gboolean
mct_session_limits_is_enabled (MctSessionLimits *limits)
{
g_return_val_if_fail (limits != NULL, FALSE);
g_return_val_if_fail (limits->ref_count >= 1, FALSE);
return (limits->limit_type != MCT_SESSION_LIMITS_TYPE_NONE);
}
/**
* mct_session_limits_check_time_remaining:
* @limits: an #MctSessionLimits
@ -216,149 +190,6 @@ out:
return user_allowed_now;
}
/**
* mct_session_limits_serialize:
* @limits: an #MctSessionLimits
*
* Build a #GVariant which contains the session limits from @limits, in an
* opaque variant format. This format may change in future, but
* mct_session_limits_deserialize() is guaranteed to always be able to load any
* variant produced by the current or any previous version of
* mct_session_limits_serialize().
*
* Returns: (transfer floating): a new, floating #GVariant containing the
* session limits
* Since: 0.7.0
*/
GVariant *
mct_session_limits_serialize (MctSessionLimits *limits)
{
g_auto(GVariantBuilder) builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a{sv}"));
g_autoptr(GVariant) limit_variant = NULL;
const gchar *limit_property_name;
g_return_val_if_fail (limits != NULL, NULL);
g_return_val_if_fail (limits->ref_count >= 1, NULL);
/* The serialisation format is exactly the
* `com.endlessm.ParentalControls.SessionLimits` D-Bus interface. */
switch (limits->limit_type)
{
case MCT_SESSION_LIMITS_TYPE_DAILY_SCHEDULE:
limit_variant = g_variant_new ("(uu)",
limits->daily_start_time,
limits->daily_end_time);
limit_property_name = "DailySchedule";
break;
case MCT_SESSION_LIMITS_TYPE_NONE:
limit_variant = NULL;
limit_property_name = NULL;
break;
default:
g_assert_not_reached ();
}
if (limit_property_name != NULL)
{
g_variant_builder_add (&builder, "{sv}", limit_property_name,
g_steal_pointer (&limit_variant));
}
g_variant_builder_add (&builder, "{sv}", "LimitType",
g_variant_new_uint32 (limits->limit_type));
return g_variant_builder_end (&builder);
}
/**
* mct_session_limits_deserialize:
* @variant: a serialized session limits variant
* @user_id: the ID of the user the session limits relate to
* @error: return location for a #GError, or %NULL
*
* Deserialize a set of session limits previously serialized with
* mct_session_limits_serialize(). This function guarantees to be able to
* deserialize any serialized form from this version or older versions of
* libmalcontent.
*
* If deserialization fails, %MCT_MANAGER_ERROR_INVALID_DATA will be returned.
*
* Returns: (transfer full): deserialized session limits
* Since: 0.7.0
*/
MctSessionLimits *
mct_session_limits_deserialize (GVariant *variant,
uid_t user_id,
GError **error)
{
g_autoptr(MctSessionLimits) session_limits = NULL;
guint32 limit_type;
guint32 daily_start_time, daily_end_time;
g_return_val_if_fail (variant != NULL, NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
/* Check the overall type. */
if (!g_variant_is_of_type (variant, G_VARIANT_TYPE ("a{sv}")))
{
g_set_error (error, MCT_MANAGER_ERROR,
MCT_MANAGER_ERROR_INVALID_DATA,
_("Session limit for user %u was in an unrecognized format"),
(guint) user_id);
return NULL;
}
/* Extract the properties we care about. The default values here should be
* kept in sync with those in the `com.endlessm.ParentalControls.SessionLimits`
* D-Bus interface. */
if (!g_variant_lookup (variant, "LimitType", "u",
&limit_type))
{
/* Default value. */
limit_type = MCT_SESSION_LIMITS_TYPE_NONE;
}
/* Check that the limit type is something we support. */
G_STATIC_ASSERT (sizeof (limit_type) >= sizeof (MctSessionLimitsType));
if ((guint) limit_type > MCT_SESSION_LIMITS_TYPE_DAILY_SCHEDULE)
{
g_set_error (error, MCT_MANAGER_ERROR,
MCT_MANAGER_ERROR_INVALID_DATA,
_("Session limit for user %u has an unrecognized type %u"),
(guint) user_id, limit_type);
return NULL;
}
if (!g_variant_lookup (variant, "DailySchedule", "(uu)",
&daily_start_time, &daily_end_time))
{
/* Default value. */
daily_start_time = 0;
daily_end_time = 24 * 60 * 60;
}
if (daily_start_time >= daily_end_time ||
daily_end_time > 24 * 60 * 60)
{
g_set_error (error, MCT_MANAGER_ERROR,
MCT_MANAGER_ERROR_INVALID_DATA,
_("Session limit for user %u has invalid daily schedule %u%u"),
(guint) user_id, daily_start_time, daily_end_time);
return NULL;
}
/* Success. Create an #MctSessionLimits object to contain the results. */
session_limits = g_new0 (MctSessionLimits, 1);
session_limits->ref_count = 1;
session_limits->user_id = user_id;
session_limits->limit_type = limit_type;
session_limits->daily_start_time = daily_start_time;
session_limits->daily_end_time = daily_end_time;
return g_steal_pointer (&session_limits);
}
/*
* Actual implementation of #MctSessionLimitsBuilder.
*

View File

@ -52,19 +52,11 @@ void mct_session_limits_unref (MctSessionLimits *limits);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (MctSessionLimits, mct_session_limits_unref)
uid_t mct_session_limits_get_user_id (MctSessionLimits *limits);
gboolean mct_session_limits_is_enabled (MctSessionLimits *limits);
gboolean mct_session_limits_check_time_remaining (MctSessionLimits *limits,
guint64 now_usecs,
guint64 *time_remaining_secs_out,
gboolean *time_limit_enabled_out);
GVariant *mct_session_limits_serialize (MctSessionLimits *limits);
MctSessionLimits *mct_session_limits_deserialize (GVariant *variant,
uid_t user_id,
GError **error);
/**
* MctSessionLimitsBuilder:
*

View File

@ -85,191 +85,6 @@ test_app_filter_refs (void)
/* Final ref is dropped by g_autoptr(). */
}
/* Basic test of mct_app_filter_serialize() on an app filter. */
static void
test_app_filter_serialize (void)
{
g_auto(MctAppFilterBuilder) builder = MCT_APP_FILTER_BUILDER_INIT ();
g_autoptr(MctAppFilter) filter = NULL;
g_autoptr(GVariant) serialized = NULL;
/* Use an empty #MctAppFilter. */
filter = mct_app_filter_builder_end (&builder);
/* We cant assert anything about the serialisation format, since its opaque. */
serialized = mct_app_filter_serialize (filter);
g_assert_nonnull (serialized);
}
/* Basic test of mct_app_filter_deserialize() on various current and historic
* serialised app filter variants. */
static void
test_app_filter_deserialize (void)
{
/* These are all opaque. Older versions should be kept around to test
* backwards compatibility. */
const gchar *valid_app_filters[] =
{
"@a{sv} {}",
"{ 'AppFilter': <(true, @as [])> }",
"{ 'OarsFilter': <('oars-1.1', { 'violence-cartoon': 'mild' })> }",
"{ 'AllowUserInstallation': <true> }",
"{ 'AllowSystemInstallation': <true> }",
};
for (gsize i = 0; i < G_N_ELEMENTS (valid_app_filters); i++)
{
g_autoptr(GVariant) serialized = NULL;
g_autoptr(MctAppFilter) filter = NULL;
g_autoptr(GError) local_error = NULL;
g_test_message ("%" G_GSIZE_FORMAT ": %s", i, valid_app_filters[i]);
serialized = g_variant_parse (NULL, valid_app_filters[i], NULL, NULL, NULL);
g_assert (serialized != NULL);
filter = mct_app_filter_deserialize (serialized, 1, &local_error);
g_assert_no_error (local_error);
g_assert_nonnull (filter);
}
}
/* Test of mct_app_filter_deserialize() on various invalid variants. */
static void
test_app_filter_deserialize_invalid (void)
{
const gchar *invalid_app_filters[] =
{
"false",
"()",
"{ 'OarsFilter': <('invalid', { 'violence-cartoon': 'mild' })> }",
};
for (gsize i = 0; i < G_N_ELEMENTS (invalid_app_filters); i++)
{
g_autoptr(GVariant) serialized = NULL;
g_autoptr(MctAppFilter) filter = NULL;
g_autoptr(GError) local_error = NULL;
g_test_message ("%" G_GSIZE_FORMAT ": %s", i, invalid_app_filters[i]);
serialized = g_variant_parse (NULL, invalid_app_filters[i], NULL, NULL, NULL);
g_assert (serialized != NULL);
filter = mct_app_filter_deserialize (serialized, 1, &local_error);
g_assert_error (local_error, MCT_MANAGER_ERROR, MCT_MANAGER_ERROR_INVALID_DATA);
g_assert_null (filter);
}
}
/* Test that mct_app_filter_equal() returns the correct results on various
* app filters. */
static void
test_app_filter_equal (void)
{
g_auto(MctAppFilterBuilder) builder = MCT_APP_FILTER_BUILDER_INIT ();
MctAppFilter *equal_filters[2];
const gchar *unequal_filters_serialised[] =
{
"{ 'AppFilter': <(true, @as ['/usr/bin/gnome-software'])> }",
"{ 'AppFilter': <(false, @as ['/usr/bin/gnome-software'])> }",
"{ 'AllowUserInstallation': <true> }",
"{ 'AllowSystemInstallation': <true> }",
"{ 'OarsFilter': <('oars-1.1', { 'violence-cartoon': 'mild' })> }",
};
MctAppFilter *unequal_filters[G_N_ELEMENTS (unequal_filters_serialised)];
/* Build a couple of filters which are identical. */
equal_filters[0] = mct_app_filter_builder_end (&builder);
mct_app_filter_builder_init (&builder);
equal_filters[1] = mct_app_filter_builder_end (&builder);
/* And a load of filters which are not. */
for (gsize i = 0; i < G_N_ELEMENTS (unequal_filters_serialised); i++)
{
g_autoptr(GVariant) serialized = NULL;
serialized = g_variant_parse (NULL, unequal_filters_serialised[i], NULL, NULL, NULL);
g_assert (serialized != NULL);
unequal_filters[i] = mct_app_filter_deserialize (serialized, 1, NULL);
g_assert (unequal_filters[i] != NULL);
}
/* Test the equality checks on them all. */
for (gsize i = 0; i < G_N_ELEMENTS (equal_filters); i++)
for (gsize j = 0; j < G_N_ELEMENTS (equal_filters); j++)
g_assert_true (mct_app_filter_equal (equal_filters[i], equal_filters[j]));
for (gsize i = 0; i < G_N_ELEMENTS (unequal_filters); i++)
{
for (gsize j = 0; j < G_N_ELEMENTS (equal_filters); j++)
g_assert_false (mct_app_filter_equal (unequal_filters[i], equal_filters[j]));
for (gsize j = 0; j < G_N_ELEMENTS (unequal_filters); j++)
{
if (i != j)
g_assert_false (mct_app_filter_equal (unequal_filters[i], unequal_filters[j]));
else
g_assert_true (mct_app_filter_equal (unequal_filters[i], unequal_filters[j]));
}
}
for (gsize i = 0; i < G_N_ELEMENTS (equal_filters); i++)
mct_app_filter_unref (equal_filters[i]);
for (gsize i = 0; i < G_N_ELEMENTS (unequal_filters); i++)
mct_app_filter_unref (unequal_filters[i]);
}
/* Test that mct_app_filter_is_enabled() returns the correct results on various
* app filters. */
static void
test_app_filter_is_enabled (void)
{
const struct
{
const gchar *serialized;
gboolean is_enabled;
}
app_filters[] =
{
{ "@a{sv} {}", FALSE },
{ "{ 'AppFilter': <(true, @as [])> }", TRUE },
{ "{ 'AppFilter': <(false, @as [])> }", FALSE },
{ "{ 'AppFilter': <(false, @as [ '/usr/bin/gnome-software' ])> }", TRUE },
{ "{ 'OarsFilter': <('oars-1.1', @a{ss} {})> }", FALSE },
{ "{ 'OarsFilter': <('oars-1.1', { 'violence-cartoon': 'mild' })> }", TRUE },
{ "{ 'OarsFilter': <('oars-1.1', { 'violence-cartoon': 'intense' })> }", FALSE },
{ "{ 'OarsFilter': <('oars-1.1', { 'violence-cartoon': '' })> }", FALSE }, /* technically an invalid serialisation */
{ "{ 'OarsFilter': <('oars-1.1', { 'violence-cartoon': 'none' })> }", TRUE },
{ "{ 'OarsFilter': <('oars-1.1', { 'violence-cartoon': 'mild', 'violence-realistic': 'intense' })> }", TRUE },
{ "{ 'OarsFilter': <('oars-1.1', { 'violence-cartoon': 'mild', 'violence-realistic': 'none' })> }", TRUE },
{ "{ 'AllowUserInstallation': <true> }", FALSE },
{ "{ 'AllowUserInstallation': <false> }", TRUE },
{ "{ 'AllowSystemInstallation': <true> }", FALSE },
{ "{ 'AllowSystemInstallation': <false> }", FALSE },
};
for (gsize i = 0; i < G_N_ELEMENTS (app_filters); i++)
{
g_autoptr(GVariant) variant = NULL;
g_autoptr(MctAppFilter) filter = NULL;
g_test_message ("%" G_GSIZE_FORMAT ": %s", i, app_filters[i].serialized);
variant = g_variant_parse (NULL, app_filters[i].serialized, NULL, NULL, NULL);
g_assert (variant != NULL);
filter = mct_app_filter_deserialize (variant, 1, NULL);
g_assert (filter != NULL);
if (app_filters[i].is_enabled)
g_assert_true (mct_app_filter_is_enabled (filter));
else
g_assert_false (mct_app_filter_is_enabled (filter));
}
}
/* Fixture for tests which use an #MctAppFilterBuilder. The builder can either
* be heap- or stack-allocated. @builder will always be a valid pointer to it.
*/
@ -334,13 +149,13 @@ test_app_filter_builder_non_empty (BuilderFixture *fixture,
g_autoptr(MctAppFilter) filter = NULL;
g_autofree const gchar **sections = NULL;
mct_app_filter_builder_blocklist_path (fixture->builder, "/bin/true");
mct_app_filter_builder_blocklist_path (fixture->builder, "/usr/bin/gnome-software");
mct_app_filter_builder_blacklist_path (fixture->builder, "/bin/true");
mct_app_filter_builder_blacklist_path (fixture->builder, "/usr/bin/gnome-software");
mct_app_filter_builder_blocklist_flatpak_ref (fixture->builder,
"app/org.doom.Doom/x86_64/stable");
mct_app_filter_builder_blacklist_flatpak_ref (fixture->builder,
"app/org.doom.Doom/x86_64/master");
mct_app_filter_builder_blocklist_content_type (fixture->builder,
mct_app_filter_builder_blacklist_content_type (fixture->builder,
"x-scheme-handler/http");
mct_app_filter_builder_set_oars_value (fixture->builder, "drugs-alcohol",
@ -352,17 +167,15 @@ test_app_filter_builder_non_empty (BuilderFixture *fixture,
filter = mct_app_filter_builder_end (fixture->builder);
g_assert_true (mct_app_filter_is_enabled (filter));
g_assert_true (mct_app_filter_is_path_allowed (filter, "/bin/false"));
g_assert_false (mct_app_filter_is_path_allowed (filter,
"/usr/bin/gnome-software"));
g_assert_true (mct_app_filter_is_flatpak_ref_allowed (filter,
"app/org.gnome.Ponies/x86_64/stable"));
"app/org.gnome.Ponies/x86_64/master"));
g_assert_true (mct_app_filter_is_flatpak_app_allowed (filter, "org.gnome.Ponies"));
g_assert_false (mct_app_filter_is_flatpak_ref_allowed (filter,
"app/org.doom.Doom/x86_64/stable"));
"app/org.doom.Doom/x86_64/master"));
g_assert_false (mct_app_filter_is_flatpak_app_allowed (filter, "org.doom.Doom"));
g_assert_false (mct_app_filter_is_content_type_allowed (filter,
@ -395,17 +208,15 @@ test_app_filter_builder_empty (BuilderFixture *fixture,
filter = mct_app_filter_builder_end (fixture->builder);
g_assert_false (mct_app_filter_is_enabled (filter));
g_assert_true (mct_app_filter_is_path_allowed (filter, "/bin/false"));
g_assert_true (mct_app_filter_is_path_allowed (filter,
"/usr/bin/gnome-software"));
g_assert_true (mct_app_filter_is_flatpak_ref_allowed (filter,
"app/org.gnome.Ponies/x86_64/stable"));
"app/org.gnome.Ponies/x86_64/master"));
g_assert_true (mct_app_filter_is_flatpak_app_allowed (filter, "org.gnome.Ponies"));
g_assert_true (mct_app_filter_is_flatpak_ref_allowed (filter,
"app/org.doom.Doom/x86_64/stable"));
"app/org.doom.Doom/x86_64/master"));
g_assert_true (mct_app_filter_is_flatpak_app_allowed (filter, "org.doom.Doom"));
g_assert_true (mct_app_filter_is_content_type_allowed (filter,
@ -439,12 +250,11 @@ test_app_filter_builder_copy_empty (void)
builder_copy = mct_app_filter_builder_copy (builder);
mct_app_filter_builder_init (builder_copy);
mct_app_filter_builder_blocklist_path (builder_copy, "/bin/true");
mct_app_filter_builder_blocklist_content_type (builder_copy,
mct_app_filter_builder_blacklist_path (builder_copy, "/bin/true");
mct_app_filter_builder_blacklist_content_type (builder_copy,
"x-scheme-handler/http");
filter = mct_app_filter_builder_end (builder_copy);
g_assert_true (mct_app_filter_is_enabled (filter));
g_assert_true (mct_app_filter_is_path_allowed (filter, "/bin/false"));
g_assert_false (mct_app_filter_is_path_allowed (filter, "/bin/true"));
g_assert_true (mct_app_filter_is_content_type_allowed (filter,
@ -464,15 +274,14 @@ test_app_filter_builder_copy_full (void)
g_autoptr(MctAppFilterBuilder) builder_copy = NULL;
g_autoptr(MctAppFilter) filter = NULL;
mct_app_filter_builder_blocklist_path (builder, "/bin/true");
mct_app_filter_builder_blocklist_content_type (builder,
mct_app_filter_builder_blacklist_path (builder, "/bin/true");
mct_app_filter_builder_blacklist_content_type (builder,
"x-scheme-handler/http");
mct_app_filter_builder_set_allow_user_installation (builder, FALSE);
mct_app_filter_builder_set_allow_system_installation (builder, TRUE);
builder_copy = mct_app_filter_builder_copy (builder);
filter = mct_app_filter_builder_end (builder_copy);
g_assert_true (mct_app_filter_is_enabled (filter));
g_assert_true (mct_app_filter_is_path_allowed (filter, "/bin/false"));
g_assert_false (mct_app_filter_is_path_allowed (filter, "/bin/true"));
g_assert_true (mct_app_filter_is_content_type_allowed (filter,
@ -604,9 +413,9 @@ test_app_filter_appinfo (void)
"MimeType=x-scheme-handler/http\n" },
};
mct_app_filter_builder_blocklist_path (&builder, "/bin/false");
mct_app_filter_builder_blocklist_flatpak_ref (&builder, "app/org.gnome.Nasty/x86_64/stable");
mct_app_filter_builder_blocklist_content_type (&builder, "x-scheme-handler/http");
mct_app_filter_builder_blacklist_path (&builder, "/bin/false");
mct_app_filter_builder_blacklist_flatpak_ref (&builder, "app/org.gnome.Nasty/x86_64/stable");
mct_app_filter_builder_blacklist_content_type (&builder, "x-scheme-handler/http");
filter = mct_app_filter_builder_end (&builder);
@ -805,18 +614,17 @@ test_app_filter_bus_get (BusFixture *fixture,
/* Check the app filter properties. */
g_assert_cmpuint (mct_app_filter_get_user_id (app_filter), ==, fixture->valid_uid);
g_assert_true (mct_app_filter_is_enabled (app_filter));
g_assert_false (mct_app_filter_is_flatpak_app_allowed (app_filter, "org.gnome.Builder"));
g_assert_true (mct_app_filter_is_flatpak_app_allowed (app_filter, "org.gnome.Chess"));
}
/* Test that getting an #MctAppFilter containing a allowlist from the mock D-Bus
* service works, and that the #MctAppFilter methods handle the allowlist
/* Test that getting an #MctAppFilter containing a whitelist from the mock D-Bus
* service works, and that the #MctAppFilter methods handle the whitelist
* correctly.
*
* The mock D-Bus replies are generated in get_app_filter_server_cb(). */
static void
test_app_filter_bus_get_allowlist (BusFixture *fixture,
test_app_filter_bus_get_whitelist (BusFixture *fixture,
gconstpointer test_data)
{
g_autoptr(MctAppFilter) app_filter = NULL;
@ -828,8 +636,8 @@ test_app_filter_bus_get_allowlist (BusFixture *fixture,
"'AllowUserInstallation': <true>,"
"'AllowSystemInstallation': <true>,"
"'AppFilter': <(true, ["
"'app/org.gnome.Allowlisted1/x86_64/stable',"
"'app/org.gnome.Allowlisted2/x86_64/stable',"
"'app/org.gnome.Whitelisted1/x86_64/stable',"
"'app/org.gnome.Whitelisted2/x86_64/stable',"
"'/usr/bin/true',"
"'text/plain'"
"])>,"
@ -848,15 +656,14 @@ test_app_filter_bus_get_allowlist (BusFixture *fixture,
g_assert_no_error (local_error);
g_assert_nonnull (app_filter);
/* Check the app filter properties. The returned filter is a allowlist,
* whereas typically a blocklist is returned. */
/* Check the app filter properties. The returned filter is a whitelist,
* whereas typically a blacklist is returned. */
g_assert_cmpuint (mct_app_filter_get_user_id (app_filter), ==, fixture->valid_uid);
g_assert_true (mct_app_filter_is_enabled (app_filter));
g_assert_false (mct_app_filter_is_flatpak_app_allowed (app_filter, "org.gnome.Builder"));
g_assert_true (mct_app_filter_is_flatpak_app_allowed (app_filter, "org.gnome.Allowlisted1"));
g_assert_true (mct_app_filter_is_flatpak_app_allowed (app_filter, "org.gnome.Allowlisted2"));
g_assert_true (mct_app_filter_is_flatpak_ref_allowed (app_filter, "app/org.gnome.Allowlisted1/x86_64/stable"));
g_assert_false (mct_app_filter_is_flatpak_ref_allowed (app_filter, "app/org.gnome.Allowlisted1/x86_64/unknown"));
g_assert_true (mct_app_filter_is_flatpak_app_allowed (app_filter, "org.gnome.Whitelisted1"));
g_assert_true (mct_app_filter_is_flatpak_app_allowed (app_filter, "org.gnome.Whitelisted2"));
g_assert_true (mct_app_filter_is_flatpak_ref_allowed (app_filter, "app/org.gnome.Whitelisted1/x86_64/stable"));
g_assert_false (mct_app_filter_is_flatpak_ref_allowed (app_filter, "app/org.gnome.Whitelisted1/x86_64/unknown"));
g_assert_true (mct_app_filter_is_path_allowed (app_filter, "/usr/bin/true"));
g_assert_false (mct_app_filter_is_path_allowed (app_filter, "/usr/bin/false"));
g_assert_true (mct_app_filter_is_content_type_allowed (app_filter,
@ -907,7 +714,6 @@ test_app_filter_bus_get_all_oars_values (BusFixture *fixture,
/* Check the OARS filter properties. Each OARS value should have been parsed
* correctly, except for the unknown `other` one. */
g_assert_cmpuint (mct_app_filter_get_user_id (app_filter), ==, fixture->valid_uid);
g_assert_true (mct_app_filter_is_enabled (app_filter));
g_assert_cmpint (mct_app_filter_get_oars_value (app_filter, "violence-bloodshed"), ==,
MCT_APP_FILTER_OARS_VALUE_NONE);
g_assert_cmpint (mct_app_filter_get_oars_value (app_filter, "violence-sexual"), ==,
@ -955,7 +761,6 @@ test_app_filter_bus_get_defaults (BusFixture *fixture,
/* Check the default values for the properties. */
g_assert_cmpuint (mct_app_filter_get_user_id (app_filter), ==, fixture->valid_uid);
g_assert_false (mct_app_filter_is_enabled (app_filter));
oars_sections = mct_app_filter_get_oars_sections (app_filter);
g_assert_cmpuint (g_strv_length ((gchar **) oars_sections), ==, 0);
g_assert_cmpint (mct_app_filter_get_oars_value (app_filter, "violence-bloodshed"), ==,
@ -1359,10 +1164,10 @@ test_app_filter_bus_set (BusFixture *fixture,
};
/* Build an app filter. */
mct_app_filter_builder_blocklist_path (&builder, "/usr/bin/false");
mct_app_filter_builder_blocklist_path (&builder, "/usr/bin/banned");
mct_app_filter_builder_blocklist_flatpak_ref (&builder, "app/org.gnome.Nasty/x86_64/stable");
mct_app_filter_builder_blocklist_content_type (&builder, "x-scheme-handler/http");
mct_app_filter_builder_blacklist_path (&builder, "/usr/bin/false");
mct_app_filter_builder_blacklist_path (&builder, "/usr/bin/banned");
mct_app_filter_builder_blacklist_flatpak_ref (&builder, "app/org.gnome.Nasty/x86_64/stable");
mct_app_filter_builder_blacklist_content_type (&builder, "x-scheme-handler/http");
mct_app_filter_builder_set_oars_value (&builder, "violence-fantasy", MCT_APP_FILTER_OARS_VALUE_INTENSE);
mct_app_filter_builder_set_allow_user_installation (&builder, TRUE);
mct_app_filter_builder_set_allow_system_installation (&builder, TRUE);
@ -1576,14 +1381,6 @@ main (int argc,
g_test_add_func ("/app-filter/types", test_app_filter_types);
g_test_add_func ("/app-filter/refs", test_app_filter_refs);
g_test_add_func ("/app-filter/serialize", test_app_filter_serialize);
g_test_add_func ("/app-filter/deserialize", test_app_filter_deserialize);
g_test_add_func ("/app-filter/deserialize/invalid", test_app_filter_deserialize_invalid);
g_test_add_func ("/app-filter/equal", test_app_filter_equal);
g_test_add_func ("/app-filter/is-enabled", test_app_filter_is_enabled);
g_test_add ("/app-filter/builder/stack/non-empty", BuilderFixture, NULL,
builder_set_up_stack, test_app_filter_builder_non_empty,
builder_tear_down_stack);
@ -1613,8 +1410,8 @@ main (int argc,
bus_set_up, test_app_filter_bus_get, bus_tear_down);
g_test_add ("/app-filter/bus/get/sync", BusFixture, GUINT_TO_POINTER (FALSE),
bus_set_up, test_app_filter_bus_get, bus_tear_down);
g_test_add ("/app-filter/bus/get/allowlist", BusFixture, NULL,
bus_set_up, test_app_filter_bus_get_allowlist, bus_tear_down);
g_test_add ("/app-filter/bus/get/whitelist", BusFixture, NULL,
bus_set_up, test_app_filter_bus_get_whitelist, bus_tear_down);
g_test_add ("/app-filter/bus/get/all-oars-values", BusFixture, NULL,
bus_set_up, test_app_filter_bus_get_all_oars_values, bus_tear_down);
g_test_add ("/app-filter/bus/get/defaults", BusFixture, NULL,

View File

@ -3,8 +3,8 @@ deps = [
dependency('gio-unix-2.0', version: '>= 2.44'),
dependency('glib-2.0', version: '>= 2.60.0'),
dependency('gobject-2.0', version: '>= 2.44'),
dependency('glib-testing-0', fallback: ['libglib-testing', 'libglib_testing_dep']),
libmalcontent_dep,
libglib_testing_dep,
]
envs = test_env + [
@ -34,8 +34,8 @@ accounts_service_iface_c = custom_target(
)
accounts_service_extension_ifaces = [
join_paths(meson.current_source_dir(), '..', '..', 'accounts-service', 'com.endlessm.ParentalControls.AppFilter.xml'),
join_paths(meson.current_source_dir(), '..', '..', 'accounts-service', 'com.endlessm.ParentalControls.SessionLimits.xml'),
join_paths(meson.source_root(), 'accounts-service', 'com.endlessm.ParentalControls.AppFilter.xml'),
join_paths(meson.source_root(), 'accounts-service', 'com.endlessm.ParentalControls.SessionLimits.xml'),
]
accounts_service_extension_iface_h = custom_target(

View File

@ -92,84 +92,6 @@ test_session_limits_check_time_remaining_invalid_time (void)
g_assert_true (time_limit_enabled);
}
/* Basic test of mct_session_limits_serialize() on session limits. */
static void
test_session_limits_serialize (void)
{
g_auto(MctSessionLimitsBuilder) builder = MCT_SESSION_LIMITS_BUILDER_INIT ();
g_autoptr(MctSessionLimits) limits = NULL;
g_autoptr(GVariant) serialized = NULL;
/* Use an empty #MctSessionLimits. */
limits = mct_session_limits_builder_end (&builder);
/* We cant assert anything about the serialisation format, since its opaque. */
serialized = mct_session_limits_serialize (limits);
g_assert_nonnull (serialized);
}
/* Basic test of mct_session_limits_deserialize() on various current and historic
* serialised app filter variants. */
static void
test_session_limits_deserialize (void)
{
/* These are all opaque. Older versions should be kept around to test
* backwards compatibility. */
const gchar *valid_session_limits[] =
{
"@a{sv} {}",
"{ 'LimitType': <@u 0> }",
"{ 'LimitType': <@u 1>, 'DailySchedule': <(@u 0, @u 100)> }",
"{ 'DailySchedule': <(@u 0, @u 100)> }",
};
for (gsize i = 0; i < G_N_ELEMENTS (valid_session_limits); i++)
{
g_autoptr(GVariant) serialized = NULL;
g_autoptr(MctSessionLimits) limits = NULL;
g_autoptr(GError) local_error = NULL;
g_test_message ("%" G_GSIZE_FORMAT ": %s", i, valid_session_limits[i]);
serialized = g_variant_parse (NULL, valid_session_limits[i], NULL, NULL, NULL);
g_assert (serialized != NULL);
limits = mct_session_limits_deserialize (serialized, 1, &local_error);
g_assert_no_error (local_error);
g_assert_nonnull (limits);
}
}
/* Test of mct_session_limits_deserialize() on various invalid variants. */
static void
test_session_limits_deserialize_invalid (void)
{
const gchar *invalid_session_limits[] =
{
"false",
"()",
"{ 'LimitType': <@u 100> }",
"{ 'DailySchedule': <(@u 100, @u 0)> }",
"{ 'DailySchedule': <(@u 0, @u 4294967295)> }",
};
for (gsize i = 0; i < G_N_ELEMENTS (invalid_session_limits); i++)
{
g_autoptr(GVariant) serialized = NULL;
g_autoptr(MctSessionLimits) limits = NULL;
g_autoptr(GError) local_error = NULL;
g_test_message ("%" G_GSIZE_FORMAT ": %s", i, invalid_session_limits[i]);
serialized = g_variant_parse (NULL, invalid_session_limits[i], NULL, NULL, NULL);
g_assert (serialized != NULL);
limits = mct_session_limits_deserialize (serialized, 1, &local_error);
g_assert_error (local_error, MCT_MANAGER_ERROR, MCT_MANAGER_ERROR_INVALID_DATA);
g_assert_null (limits);
}
}
/* Fixture for tests which use an #MctSessionLimitsBuilder. The builder can
* either be heap- or stack-allocated. @builder will always be a valid pointer
* to it.
@ -518,7 +440,6 @@ test_session_limits_bus_get (BusFixture *fixture,
/* Check the session limits properties. */
g_assert_cmpuint (mct_session_limits_get_user_id (session_limits), ==, fixture->valid_uid);
g_assert_true (mct_session_limits_is_enabled (session_limits));
g_assert_false (mct_session_limits_check_time_remaining (session_limits, usec (0),
&time_remaining_secs, &time_limit_enabled));
g_assert_true (time_limit_enabled);
@ -581,7 +502,6 @@ test_session_limits_bus_get_none (BusFixture *fixture,
/* Check the session limits properties. */
g_assert_cmpuint (mct_session_limits_get_user_id (session_limits), ==, fixture->valid_uid);
g_assert_false (mct_session_limits_is_enabled (session_limits));
g_assert_true (mct_session_limits_check_time_remaining (session_limits, usec (0),
&time_remaining_secs, &time_limit_enabled));
g_assert_false (time_limit_enabled);
@ -1210,10 +1130,6 @@ main (int argc,
g_test_add_func ("/session-limits/check-time-remaining/invalid-time",
test_session_limits_check_time_remaining_invalid_time);
g_test_add_func ("/session-limits/serialize", test_session_limits_serialize);
g_test_add_func ("/session-limits/deserialize", test_session_limits_deserialize);
g_test_add_func ("/session-limits/deserialize/invalid", test_session_limits_deserialize_invalid);
g_test_add ("/session-limits/builder/stack/non-empty", BuilderFixture, NULL,
builder_set_up_stack, test_session_limits_builder_non_empty,
builder_tear_down_stack);

View File

@ -1,11 +1,11 @@
.\" Manpage for malcontent\-client.
.\" Documentation is under the same licence as the malcontent
.\" package.
.TH man 8 "27 Oct 2020" "1.2" "malcontent\-client man page"
.TH man 8 "13 Jun 2019" "1.1" "malcontent\-client man page"
.\"
.SH NAME
.IX Header "NAME"
malcontent\-client \- Parental Controls Access Utility
malcontent\-client Parental Controls Access Utility
.\"
.SH SYNOPSIS
.IX Header "SYNOPSIS"
@ -13,27 +13,19 @@ malcontent\-client \- Parental Controls Access Utility
\fBmalcontent\-client get\-app\-filter [\-q] [\-n] [\fPUSER\fB]
.PP
\fBmalcontent\-client check\-app\-filter [\-q] [\-n] [\fPUSER\fB] \fPARG\fB
.PP
\fBmalcontent\-client set\-app\-filter [\-q] [\-n] [\fPUSER\fB] \fPARG\fB
.PP
\fBmalcontent\-client oars\-section [\-q] [\-n] [\fPUSER\fB] \fPSECTION\fB
.PP
\fBmalcontent\-client get\-session\-limits [\-q] [\-n] [\fPUSER\fB]
.PP
\fBmalcontent\-client monitor [\-q] [\fPUSER\fB]
.\"
.SH DESCRIPTION
.IX Header "DESCRIPTION"
.\"
\fBmalcontent\-client\fP is a utility for querying and updating the
parental controls settings for users on the system. It will typically require
administrator access to do anything more than query the current users parental
adminstrator access to do anything more than query the current users parental
controls.
.PP
It communicates with accounts-service, which stores parental controls data.
.PP
Its first argument is a command to run. The supported commands are documented
below.
Its first argument is a command to run. Currently, the only supported commands
are \fBget\-app\-filter\fP and \fBcheck\-app\-filter\fP.
.PP
The command line API and output format are unstable and likely to change in
future versions of \fBmalcontent\-client\fP.
@ -41,13 +33,6 @@ future versions of \fBmalcontent\-client\fP.
.SH \fBget\-app\-filter\fP OPTIONS
.IX Header "get\-app\-filter OPTIONS"
.\"
Get the app filter for a user. For example:
.RS
.ad l
# malcontent\-client get\-app\-filter timmy
.ad b
.RE
.\"
.IP "\fBUSER\fP"
Username or ID of the user to get the app filter for. If not specified, the
current user will be used by default.
@ -64,18 +49,6 @@ authorization.)
.SH \fBcheck\-app\-filter\fP OPTIONS
.IX Header "check\-app\-filter OPTIONS"
.\"
Check if a given program, content type or flatpak ref is permitted to be used by
a user, according to their current app filter. For example:
.RS
.ad l
# malcontent\-client check\-app\-filter timmy $(which gnome\-calculator)
.PP
# malcontent\-client check\-app\-filter timmy x\-scheme\-handler/http
.PP
# malcontent\-client check\-app\-filter timmy app/com.realm667.WolfenDoom_Blade_of_Agony/x86_64/stable
.ad b
.RE
.\"
.IP "\fBUSER\fP"
Username or ID of the user to get the app filter for. If not specified, the
current user will be used by default.
@ -93,127 +66,6 @@ Do not allow interactive authorization with polkit. If this is needed to
complete the operation, the operation will fail. (Default: Allow interactive
authorization.)
.\"
.SH \fBset\-app\-filter\fP OPTIONS
.IX Header "set\-app\-filter OPTIONS"
.\"
Set the app filter for a user, replacing all previous values in it. For example:
.RS
.ad l
# malcontent\-client set\-app\-filter timmy \\
\-\-disallow\-user\-installation \\
$(which gnome\-calculator) \\
x\-scheme\-handler/http \\
app/com.realm667.WolfenDoom_Blade_of_Agony/x86_64/stable
.ad b
.RE
.\"
.IP "\fBUSER\fP"
Username or ID of the user to set the app filter for. If not specified, the
current user will be used by default.
.\"
.IP "\fBARG\fP"
Item to filter in the users app filter. This could either be an absolute path
or flatpak ref of a program to block; a content type to block all programs
handling that type; or an OARS \fBsection=value\fP pair to block installation of
apps with a more extreme rating for that OARS section. Multiple items may be
specified, and they will replace the users current app filter in entirety. If
zero items are specified, the app filter is cleared.
.\"
.IP "\fB\-\-allow\-user\-installation\fP"
Allow the user to install flatpaks to their user repository.
.\"
.IP "\fB\-\-disallow\-user\-installation\fP"
Disallow the user from installing flatpaks to their user repository.
.\"
.IP "\fB\-\-allow\-system\-installation\fP"
Allow the user to install flatpaks to the system repository.
.\"
.IP "\fB\-\-disallow\-system\-installation\fP"
Disallow the user from installing flatpaks to the system repository.
.\"
.IP "\fB\-q\fP, \fB\-\-quiet\fP"
Only output error messages, and no informational messages, as the operation
progresses. (Default: Output informational messages.)
.\"
.IP "\fB\-n\fP, \fB\-\-no\-interactive\fP"
Do not allow interactive authorization with polkit. If this is needed to
complete the operation, the operation will fail. (Default: Allow interactive
authorization.)
.\"
.SH \fBoars\-section\fP OPTIONS
.IX Header "oars\-section OPTIONS"
.\"
Get the value set for a specific OARS section from the app filter of the given
user. For example:
.RS
.ad l
# malcontent\-client oars\-section timmy language\-profanity
.ad b
.RE
.\"
.IP "\fBUSER\fP"
Username or ID of the user to get the OARS filter for. If not specified, the
current user will be used by default.
.\"
.IP "\fBSECTION\fP"
OARS section to get the restriction level of the given user for.
For example, \fBlanguage\-profanity\fP.
.\"
.IP "\fB\-q\fP, \fB\-\-quiet\fP"
Only output error messages, and no informational messages, as the operation
progresses. (Default: Output informational messages.)
.\"
.IP "\fB\-n\fP, \fB\-\-no\-interactive\fP"
Do not allow interactive authorization with polkit. If this is needed to
complete the operation, the operation will fail. (Default: Allow interactive
authorization.)
.\"
.SH \fBget\-session\-limits\fP OPTIONS
.IX Header "get\-session\-limits OPTIONS"
.\"
Get the session limits set for a user. For example:
.RS
.ad l
# malcontent\-client get\-session\-limits timmy
.ad b
.RE
.\"
.IP "\fBUSER\fP"
Username or ID of the user to get the session limits for. If not specified, the
current user will be used by default.
.\"
.IP "\fB\-q\fP, \fB\-\-quiet\fP"
Only output error messages, and no informational messages, as the operation
progresses. (Default: Output informational messages.)
.\"
.IP "\fB\-n\fP, \fB\-\-no\-interactive\fP"
Do not allow interactive authorization with polkit. If this is needed to
complete the operation, the operation will fail. (Default: Allow interactive
authorization.)
.\"
.IP "\fB\-\-now yyyy\-mm\-ddThh:mm:ssZ\fP"
Check session limits (in particular, session expiry time) against the given
date/time, provided in ISO 8601 format. (Default: Current date/time.)
.\"
.SH \fBmonitor\fP OPTIONS
.IX Header "monitor OPTIONS"
.\"
Monitor changes to the parental controls settings for a specific user. For
example:
.RS
.ad l
# malcontent\-client monitor timmy
.ad b
.RE
.\"
.IP "\fBUSER\fP"
Username or ID of the user to monitor the parental controls for. If not
specified, the current user will be used by default.
.\"
.IP "\fB\-q\fP, \fB\-\-quiet\fP"
Only output error messages, and no informational messages, as the operation
progresses. (Default: Output informational messages.)
.\"
.SH "ENVIRONMENT"
.IX Header "ENVIRONMENT"
.\"
@ -267,7 +119,7 @@ An operation failed and no more specific error information is available.
.\"
Any bugs which are found should be reported on the project website:
.br
\fIhttps://gitlab.freedesktop.org/pwithnall/malcontent/-/issues\fP
\fIhttps://support.endlessm.com/\fP
.\"
.SH AUTHOR
.IX Header "AUTHOR"

View File

@ -297,7 +297,6 @@ def command_check_app_filter(user, arg, quiet=False, interactive=True):
# when passing flatpak IDs as argument
is_maybe_content_type = not is_maybe_flatpak_id and is_valid_content_type(arg)
is_maybe_path = os.path.exists(arg)
is_maybe_desktop_file = arg.endswith('.desktop')
recognised_types = sum([is_maybe_flatpak_id, is_maybe_flatpak_ref,
is_maybe_content_type, is_maybe_path])
@ -321,11 +320,6 @@ def command_check_app_filter(user, arg, quiet=False, interactive=True):
# Content type
is_allowed = app_filter.is_content_type_allowed(arg)
noun = 'Content type'
elif is_maybe_path and is_maybe_desktop_file
path = os.path.abspath(arg)
app_info = Gio.DesktopAppInfo.new_from_filename(path)
is_allowed = app_filter.is_appinfo_allowed(app_info)
noun = 'Desktop file'
elif is_maybe_path:
path = os.path.abspath(arg)
is_allowed = app_filter.is_path_allowed(path)
@ -391,12 +385,12 @@ def command_set_app_filter(user, allow_user_installation=True,
file=sys.stderr)
raise SystemExit(EXIT_INVALID_OPTION)
elif is_maybe_flatpak_ref:
builder.blocklist_flatpak_ref(arg)
builder.blacklist_flatpak_ref(arg)
elif is_maybe_content_type:
builder.blocklist_content_type(arg)
builder.blacklist_content_type(arg)
elif is_maybe_path:
path = os.path.abspath(arg)
builder.blocklist_path(path)
builder.blacklist_path(path)
else:
raise AssertionError('code should not be reached')
@ -529,7 +523,7 @@ def main():
'flatpak repo')
parser_set_app_filter.add_argument('app_filter_args', nargs='*',
help='paths, content types or flatpak '
'refs to blocklist and OARS '
'refs to blacklist and OARS '
'section=value pairs to store')
parser_set_app_filter.set_defaults(allow_user_installation=True,
allow_system_installation=False)

View File

@ -27,7 +27,6 @@
#include <glib/gi18n-lib.h>
#include <gio/gio.h>
#include <gtk/gtk.h>
#include <adwaita.h>
#include <libmalcontent-ui/malcontent-ui.h>
#include <polkit/polkit.h>
@ -49,9 +48,6 @@ static void permission_notify_allowed_cb (GObject *obj,
gpointer user_data);
static void user_accounts_panel_button_clicked_cb (GtkButton *button,
gpointer user_data);
static void about_action_cb (GSimpleAction *action, GVariant *parameters, gpointer user_data);
static void help_action_cb (GSimpleAction *action, GVariant *parameters, gpointer user_data);
static void quit_action_cb (GSimpleAction *action, GVariant *parameters, gpointer user_data);
/**
@ -68,7 +64,6 @@ struct _MctApplication
GCancellable *cancellable; /* (owned) */
GDBusConnection *dbus_connection; /* (owned) */
ActUserManager *user_manager; /* (owned) */
GPermission *permission; /* (owned) */
@ -77,10 +72,10 @@ struct _MctApplication
MctUserSelector *user_selector;
MctUserControls *user_controls;
GtkStack *main_stack;
AdwStatusPage *error_page;
GtkLabel *error_title;
GtkLabel *error_message;
GtkLockButton *lock_button;
GtkButton *user_accounts_panel_button;
GtkLabel *help_label;
};
G_DEFINE_TYPE (MctApplication, mct_application, GTK_TYPE_APPLICATION)
@ -95,26 +90,9 @@ static void
mct_application_constructed (GObject *object)
{
GApplication *application = G_APPLICATION (object);
const GOptionEntry options[] =
{
{ "user", 'u', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, NULL,
/* Translators: This documents the --user command line option to malcontent-control: */
N_("User to select in the UI"),
/* Translators: This is a placeholder for a command line argument value: */
N_("USERNAME") },
{ NULL, },
};
g_application_set_application_id (application, "org.freedesktop.MalcontentControl");
g_application_add_main_option_entries (application, options);
g_application_set_flags (application, g_application_get_flags (application) | G_APPLICATION_HANDLES_COMMAND_LINE);
/* Translators: This is a summary of what the application does, displayed when
* its run with --help: */
g_application_set_option_context_parameter_string (application,
N_("— view and edit parental controls"));
/* Localisation */
bindtextdomain ("malcontent", PACKAGE_LOCALE_DIR);
bind_textdomain_codeset ("malcontent", "UTF-8");
@ -147,7 +125,6 @@ mct_application_dispose (GObject *object)
g_clear_object (&self->permission);
}
g_clear_object (&self->dbus_connection);
g_clear_error (&self->permission_error);
g_clear_object (&self->cancellable);
@ -184,20 +161,11 @@ mct_application_activate (GApplication *application)
builder = gtk_builder_new ();
g_assert (self->dbus_connection == NULL);
self->dbus_connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, self->cancellable, &local_error);
if (self->dbus_connection == NULL)
{
g_error ("Error getting system bus: %s", local_error->message);
return;
}
g_assert (self->user_manager == NULL);
self->user_manager = g_object_ref (act_user_manager_get_default ());
gtk_builder_set_translation_domain (builder, "malcontent");
gtk_builder_expose_object (builder, "user_manager", G_OBJECT (self->user_manager));
gtk_builder_expose_object (builder, "dbus_connection", G_OBJECT (self->dbus_connection));
gtk_builder_add_from_resource (builder, "/org/freedesktop/MalcontentControl/ui/main.ui", &local_error);
g_assert (local_error == NULL);
@ -209,7 +177,8 @@ mct_application_activate (GApplication *application)
self->main_stack = GTK_STACK (gtk_builder_get_object (builder, "main_stack"));
self->user_selector = MCT_USER_SELECTOR (gtk_builder_get_object (builder, "user_selector"));
self->user_controls = MCT_USER_CONTROLS (gtk_builder_get_object (builder, "user_controls"));
self->error_page = ADW_STATUS_PAGE (gtk_builder_get_object (builder, "error_page"));
self->error_title = GTK_LABEL (gtk_builder_get_object (builder, "error_title"));
self->error_message = GTK_LABEL (gtk_builder_get_object (builder, "error_message"));
self->lock_button = GTK_LOCK_BUTTON (gtk_builder_get_object (builder, "lock_button"));
self->user_accounts_panel_button = GTK_BUTTON (gtk_builder_get_object (builder, "user_accounts_panel_button"));
@ -228,56 +197,13 @@ mct_application_activate (GApplication *application)
user_selector_notify_user_cb (G_OBJECT (self->user_selector), NULL, self);
user_manager_notify_is_loaded_cb (G_OBJECT (self->user_manager), NULL, self);
gtk_window_present (GTK_WINDOW (window));
gtk_widget_show (GTK_WIDGET (window));
}
/* Bring the window to the front. */
gtk_window_present (window);
}
static void
mct_application_startup (GApplication *application)
{
const GActionEntry app_entries[] =
{
{ "about", about_action_cb, NULL, NULL, NULL, { 0, } },
{ "help", help_action_cb, NULL, NULL, NULL, { 0, } },
{ "quit", quit_action_cb, NULL, NULL, NULL, { 0, } },
};
/* Chain up. */
G_APPLICATION_CLASS (mct_application_parent_class)->startup (application);
adw_init ();
g_action_map_add_action_entries (G_ACTION_MAP (application), app_entries,
G_N_ELEMENTS (app_entries), application);
gtk_application_set_accels_for_action (GTK_APPLICATION (application),
"app.help", (const gchar * const[]) { "F1", NULL });
gtk_application_set_accels_for_action (GTK_APPLICATION (application),
"app.quit", (const gchar * const[]) { "<Primary>q", "<Primary>w", NULL });
}
static gint
mct_application_command_line (GApplication *application,
GApplicationCommandLine *command_line)
{
MctApplication *self = MCT_APPLICATION (application);
GVariantDict *options = g_application_command_line_get_options_dict (command_line);
const gchar *username;
/* Show the application. */
g_application_activate (application);
/* Select a user if requested. */
if (g_variant_dict_lookup (options, "user", "&s", &username) &&
!mct_user_selector_select_user_by_username (self->user_selector, username))
g_warning ("Failed to select user %s", username);
return 0; /* exit status */
}
static void
mct_application_class_init (MctApplicationClass *klass)
{
@ -288,81 +214,6 @@ mct_application_class_init (MctApplicationClass *klass)
object_class->dispose = mct_application_dispose;
application_class->activate = mct_application_activate;
application_class->startup = mct_application_startup;
application_class->command_line = mct_application_command_line;
}
static void
about_action_cb (GSimpleAction *action, GVariant *parameters, gpointer user_data)
{
MctApplication *self = MCT_APPLICATION (user_data);
const gchar *authors[] =
{
"Philip Withnall <withnall@endlessm.com>",
"Georges Basile Stavracas Neto <georges@endlessm.com>",
"Andre Moreira Magalhaes <andre@endlessm.com>",
NULL
};
gtk_show_about_dialog (mct_application_get_main_window (self),
"version", VERSION,
"copyright", _("Copyright © 2019, 2020 Endless Mobile, Inc."),
"authors", authors,
/* Translators: this should be "translated" to the
names of people who have translated Malcontent into
this language, one per line. */
"translator-credits", _("translator-credits"),
"logo-icon-name", "org.freedesktop.MalcontentControl",
"license-type", GTK_LICENSE_GPL_2_0,
"wrap-license", TRUE,
/* Translators: "Malcontent" is the brand name of this
project, so should not be translated. */
"website-label", _("Malcontent Website"),
"website", "https://gitlab.freedesktop.org/pwithnall/malcontent",
NULL);
}
static void
on_malcontent_help_shown_finished_cb (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
MctApplication *self = MCT_APPLICATION (user_data);
g_autoptr(GError) local_error = NULL;
if (!gtk_show_uri_full_finish (mct_application_get_main_window (self),
result,
&local_error))
{
GtkWidget *dialog = gtk_message_dialog_new (mct_application_get_main_window (self),
GTK_DIALOG_MODAL,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_OK,
_("The help contents could not be displayed"));
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", local_error->message);
gtk_window_present (GTK_WINDOW (dialog));
}
}
static void
help_action_cb (GSimpleAction *action, GVariant *parameters, gpointer user_data)
{
MctApplication *self = MCT_APPLICATION (user_data);
gtk_show_uri_full (mct_application_get_main_window (self),
"help:malcontent",
GDK_CURRENT_TIME,
NULL,
on_malcontent_help_shown_finished_cb,
self);
}
static void
quit_action_cb (GSimpleAction *action, GVariant *parameters, gpointer user_data)
{
MctApplication *self = MCT_APPLICATION (user_data);
g_application_quit (G_APPLICATION (self));
}
static void
@ -384,10 +235,10 @@ update_main_stack (MctApplication *self)
if ((is_user_manager_loaded && act_user_manager_no_service (self->user_manager)) ||
self->permission_error != NULL)
{
adw_status_page_set_title (self->error_page,
_("Failed to load user data from the system"));
adw_status_page_set_description (self->error_page,
_("Please make sure that the AccountsService is installed and enabled."));
gtk_label_set_label (self->error_title,
_("Failed to load user data from the system"));
gtk_label_set_label (self->error_message,
_("Please make sure that the AccountsService is installed and enabled."));
new_page_name = "error";
new_focus_widget = NULL;
@ -407,28 +258,10 @@ update_main_stack (MctApplication *self)
}
else if (is_permission_loaded && is_user_manager_loaded)
{
g_autofree gchar *help_label = NULL;
/* Translators: Replace the link to commonsensemedia.org with some
* localised guidance for parents/carers on how to set restrictions on
* their child/caree in a responsible way which is in keeping with the
* best practice and culture of the region. If no suitable localised
* guidance exists, and if the default commonsensemedia.org link is not
* suitable, please file an issue against malcontent so we can discuss
* further!
* https://gitlab.freedesktop.org/pwithnall/malcontent/-/issues/new
*/
help_label = g_strdup_printf (_("Its recommended that restrictions are "
"set as part of an ongoing conversation "
"with %s. <a href='https://www.commonsensemedia.org/privacy-and-internet-safety'>"
"Read guidance</a> on what to consider."),
act_user_get_real_name (selected_user));
mct_user_controls_set_description (self->user_controls, help_label);
mct_user_controls_set_user (self->user_controls, selected_user);
new_page_name = "controls";
new_focus_widget = GTK_WIDGET (self->user_controls);
new_focus_widget = GTK_WIDGET (self->user_selector);
}
else
{

View File

@ -18,7 +18,6 @@
*
* Authors:
* - Felipe Borges <felipeborges@gnome.org>
* - Georges Basile Stavracas Neto <georges@endlessos.org>
* - Philip Withnall <withnall@endlessm.com>
*/
@ -30,16 +29,13 @@
#define ARROW_SIZE 20
#define MCT_TYPE_CAROUSEL_LAYOUT (mct_carousel_layout_get_type ())
G_DECLARE_FINAL_TYPE (MctCarouselLayout, mct_carousel_layout, MCT, CAROUSEL_LAYOUT, GtkLayoutManager)
struct _MctCarouselItem {
GtkButton parent;
GtkRadioButton parent;
gint page;
};
G_DEFINE_TYPE (MctCarouselItem, mct_carousel_item, GTK_TYPE_BUTTON)
G_DEFINE_TYPE (MctCarouselItem, mct_carousel_item, GTK_TYPE_RADIO_BUTTON)
GtkWidget *
mct_carousel_item_new (void)
@ -47,36 +43,28 @@ mct_carousel_item_new (void)
return g_object_new (MCT_TYPE_CAROUSEL_ITEM, NULL);
}
void
mct_carousel_item_set_child (MctCarouselItem *self,
GtkWidget *child)
{
g_return_if_fail (MCT_IS_CAROUSEL_ITEM (self));
gtk_button_set_child (GTK_BUTTON (self), child);
}
static void
mct_carousel_item_class_init (MctCarouselItemClass *klass)
{
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (klass), "carousel-item");
}
static void
mct_carousel_item_init (MctCarouselItem *self)
{
gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (self), FALSE);
gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (self)),
"carousel-item");
}
struct _MctCarousel {
AdwBin parent;
GtkRevealer *revealer;
GtkRevealer parent;
GList *children;
gint visible_page;
MctCarouselItem *selected_item;
GtkWidget *last_box;
GtkWidget *arrow;
gint arrow_start_x;
/* Widgets */
GtkStack *stack;
@ -86,7 +74,7 @@ struct _MctCarousel {
GtkStyleProvider *provider;
};
G_DEFINE_TYPE (MctCarousel, mct_carousel, ADW_TYPE_BIN)
G_DEFINE_TYPE (MctCarousel, mct_carousel, GTK_TYPE_REVEALER)
enum {
ITEM_ACTIVATED,
@ -103,9 +91,9 @@ mct_carousel_item_get_x (MctCarouselItem *item,
{
GtkWidget *widget, *parent;
gint width;
gdouble dest_x;
gint dest_x;
parent = GTK_WIDGET (carousel->revealer);
parent = GTK_WIDGET (carousel->stack);
widget = GTK_WIDGET (item);
width = gtk_widget_get_allocated_width (widget);
@ -128,6 +116,8 @@ mct_carousel_move_arrow (MctCarousel *self)
GtkStyleContext *context;
gchar *css;
gint end_x;
GtkSettings *settings;
gboolean animations;
if (!self->selected_item)
return;
@ -139,9 +129,31 @@ mct_carousel_move_arrow (MctCarousel *self)
gtk_style_context_remove_provider (context, self->provider);
g_clear_object (&self->provider);
css = g_strdup_printf ("* { margin-left: %dpx; }", end_x);
settings = gtk_widget_get_settings (GTK_WIDGET (self));
g_object_get (settings, "gtk-enable-animations", &animations, NULL);
/* Animate the arrow movement if animations are enabled. Otherwise,
* jump the arrow to the right location instantly. */
if (animations)
{
css = g_strdup_printf ("@keyframes arrow_keyframes-%d-%d {\n"
" from { margin-left: %dpx; }\n"
" to { margin-left: %dpx; }\n"
"}\n"
"* {\n"
" animation-name: arrow_keyframes-%d-%d;\n"
"}\n",
self->arrow_start_x, end_x,
self->arrow_start_x, end_x,
self->arrow_start_x, end_x);
}
else
{
css = g_strdup_printf ("* { margin-left: %dpx }", end_x);
}
self->provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
gtk_css_provider_load_from_data (GTK_CSS_PROVIDER (self->provider), css, -1);
gtk_css_provider_load_from_data (GTK_CSS_PROVIDER (self->provider), css, -1, NULL);
gtk_style_context_add_provider (context, self->provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
g_free (css);
@ -166,7 +178,7 @@ update_buttons_visibility (MctCarousel *self)
/**
* mct_carousel_find_item:
* @carousel: an MctCarousel instance
* @data: user data passed to the comparison function
* @data: user data passed to the comparation function
* @func: the function to call for each element.
* It should return 0 when the desired element is found
*
@ -222,7 +234,10 @@ mct_carousel_select_item (MctCarousel *self,
}
if (self->selected_item != NULL)
page_changed = (self->selected_item->page != item->page);
{
page_changed = (self->selected_item->page != item->page);
self->arrow_start_x = mct_carousel_item_get_x (self->selected_item, self);
}
self->selected_item = item;
self->visible_page = item->page;
@ -285,44 +300,59 @@ mct_carousel_goto_next_page (GtkWidget *button,
mct_carousel_select_item_at_index (self, self->visible_page * ITEMS_PER_PAGE);
}
void
mct_carousel_add (MctCarousel *self,
MctCarouselItem *item)
static void
mct_carousel_add (GtkContainer *container,
GtkWidget *widget)
{
MctCarousel *self = MCT_CAROUSEL (container);
gboolean last_box_is_full;
g_return_if_fail (MCT_IS_CAROUSEL (self));
g_return_if_fail (MCT_IS_CAROUSEL_ITEM (item));
if (!MCT_IS_CAROUSEL_ITEM (widget))
{
GTK_CONTAINER_CLASS (mct_carousel_parent_class)->add (container, widget);
return;
}
self->children = g_list_append (self->children, item);
item->page = get_last_page_number (self);
g_signal_connect (item, "clicked", G_CALLBACK (on_item_toggled), self);
gtk_style_context_add_class (gtk_widget_get_style_context (widget), "menu");
gtk_button_set_relief (GTK_BUTTON (widget), GTK_RELIEF_NONE);
self->children = g_list_append (self->children, widget);
MCT_CAROUSEL_ITEM (widget)->page = get_last_page_number (self);
if (self->selected_item != NULL)
gtk_radio_button_join_group (GTK_RADIO_BUTTON (widget), GTK_RADIO_BUTTON (self->selected_item));
g_signal_connect (widget, "button-press-event", G_CALLBACK (on_item_toggled), self);
last_box_is_full = ((g_list_length (self->children) - 1) % ITEMS_PER_PAGE == 0);
if (last_box_is_full)
{
g_autofree gchar *page = NULL;
page = g_strdup_printf ("%d", item->page);
self->last_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 18);
gtk_widget_set_hexpand (self->last_box, TRUE);
page = g_strdup_printf ("%d", MCT_CAROUSEL_ITEM (widget)->page);
self->last_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_widget_show (self->last_box);
gtk_widget_set_valign (self->last_box, GTK_ALIGN_CENTER);
gtk_box_set_homogeneous (GTK_BOX (self->last_box), TRUE);
gtk_stack_add_named (self->stack, self->last_box, page);
}
gtk_box_append (GTK_BOX (self->last_box), GTK_WIDGET (item));
gtk_widget_show_all (widget);
gtk_box_pack_start (GTK_BOX (self->last_box), widget, TRUE, FALSE, 10);
update_buttons_visibility (self);
}
static void
destroy_widget_cb (GtkWidget *widget,
gpointer user_data)
{
gtk_widget_destroy (widget);
}
void
mct_carousel_purge_items (MctCarousel *self)
{
GtkWidget *child;
while ((child = gtk_widget_get_first_child (GTK_WIDGET (self->stack))) != NULL)
gtk_stack_remove (self->stack, child);
gtk_container_forall (GTK_CONTAINER (self->stack),
destroy_widget_cb,
NULL);
g_list_free (self->children);
self->children = NULL;
@ -356,6 +386,7 @@ mct_carousel_class_init (MctCarouselClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *wclass = GTK_WIDGET_CLASS (klass);
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
gtk_widget_class_set_template_from_resource (wclass,
"/org/freedesktop/MalcontentControl/ui/carousel.ui");
@ -364,15 +395,14 @@ mct_carousel_class_init (MctCarouselClass *klass)
gtk_widget_class_bind_template_child (wclass, MctCarousel, go_back_button);
gtk_widget_class_bind_template_child (wclass, MctCarousel, go_next_button);
gtk_widget_class_bind_template_child (wclass, MctCarousel, arrow);
gtk_widget_class_bind_template_child (wclass, MctCarousel, revealer);
gtk_widget_class_bind_template_callback (wclass, mct_carousel_goto_previous_page);
gtk_widget_class_bind_template_callback (wclass, mct_carousel_goto_next_page);
gtk_widget_class_set_layout_manager_type (wclass, MCT_TYPE_CAROUSEL_LAYOUT);
object_class->dispose = mct_carousel_dispose;
container_class->add = mct_carousel_add;
signals[ITEM_ACTIVATED] =
g_signal_new ("item-activated",
MCT_TYPE_CAROUSEL,
@ -384,6 +414,19 @@ mct_carousel_class_init (MctCarouselClass *klass)
MCT_TYPE_CAROUSEL_ITEM);
}
static void
on_size_allocate (MctCarousel *self)
{
if (self->selected_item == NULL)
return;
if (gtk_stack_get_transition_running (self->stack))
return;
self->arrow_start_x = mct_carousel_item_get_x (self->selected_item, self);
mct_carousel_move_arrow (self);
}
static void
on_transition_running (MctCarousel *self)
{
@ -402,12 +445,13 @@ mct_carousel_init (MctCarousel *self)
gtk_css_provider_load_from_resource (GTK_CSS_PROVIDER (provider),
"/org/freedesktop/MalcontentControl/ui/carousel.css");
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
provider,
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION - 1);
gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
provider,
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
g_object_unref (provider);
g_signal_connect_swapped (self->stack, "size-allocate", G_CALLBACK (on_size_allocate), self);
g_signal_connect_swapped (self->stack, "notify::transition-running", G_CALLBACK (on_transition_running), self);
}
@ -416,77 +460,3 @@ mct_carousel_get_item_count (MctCarousel *self)
{
return g_list_length (self->children);
}
void
mct_carousel_set_revealed (MctCarousel *self,
gboolean revealed)
{
g_return_if_fail (MCT_IS_CAROUSEL (self));
gtk_revealer_set_reveal_child (self->revealer, revealed);
}
struct _MctCarouselLayout {
GtkLayoutManager parent;
};
G_DEFINE_FINAL_TYPE (MctCarouselLayout, mct_carousel_layout, GTK_TYPE_LAYOUT_MANAGER)
static void
mct_carousel_layout_measure (GtkLayoutManager *layout_manager,
GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
MctCarousel *carousel;
g_assert (MCT_IS_CAROUSEL (widget));
carousel = MCT_CAROUSEL (widget);
gtk_widget_measure (GTK_WIDGET (carousel->revealer),
orientation, for_size,
minimum, natural,
minimum_baseline, natural_baseline);
}
static void
mct_carousel_layout_allocate (GtkLayoutManager *layout_manager,
GtkWidget *widget,
int width,
int height,
int baseline)
{
MctCarousel *carousel;
g_assert (MCT_IS_CAROUSEL (widget));
carousel = MCT_CAROUSEL (widget);
gtk_widget_allocate (GTK_WIDGET (carousel->revealer), width, height, baseline, NULL);
if (carousel->selected_item == NULL)
return;
if (gtk_stack_get_transition_running (carousel->stack))
return;
mct_carousel_move_arrow (carousel);
}
static void
mct_carousel_layout_class_init (MctCarouselLayoutClass *klass)
{
GtkLayoutManagerClass *layout_manager_class = GTK_LAYOUT_MANAGER_CLASS (klass);
layout_manager_class->measure = mct_carousel_layout_measure;
layout_manager_class->allocate = mct_carousel_layout_allocate;
}
static void
mct_carousel_layout_init (MctCarouselLayout *self)
{
}

View File

@ -22,18 +22,9 @@
margin-bottom: -2px;
}
carousel-item {
.carousel-item {
background: transparent;
box-shadow: none;
border: none;
color: @theme_fg_color;
}
carousel-item:focus:focus-visible avatar {
/* this should actually be $focus_border_color from
* gtk/theme/Default/_colors.scss, but we have to simplify the theming slightly */
outline-color: @theme_selected_bg_color;
outline-offset: -2px;
outline-width: 2px;
outline-style: solid;
}

View File

@ -18,28 +18,24 @@
*
* Authors:
* - Felipe Borges <felipeborges@gnome.org>
* - Georges Basile Stavracas Neto <georges@endlessos.org>
* - Philip Withnall <withnall@endlessm.com>
*/
#pragma once
#include <adwaita.h>
#include <gtk/gtk.h>
G_BEGIN_DECLS
#define MCT_TYPE_CAROUSEL_ITEM (mct_carousel_item_get_type ())
G_DECLARE_FINAL_TYPE (MctCarouselItem, mct_carousel_item, MCT, CAROUSEL_ITEM, GtkButton)
G_DECLARE_FINAL_TYPE (MctCarouselItem, mct_carousel_item, MCT, CAROUSEL_ITEM, GtkRadioButton)
#define MCT_TYPE_CAROUSEL (mct_carousel_get_type ())
G_DECLARE_FINAL_TYPE (MctCarousel, mct_carousel, MCT, CAROUSEL, AdwBin)
G_DECLARE_FINAL_TYPE (MctCarousel, mct_carousel, MCT, CAROUSEL, GtkRevealer)
GtkWidget *mct_carousel_item_new (void);
void mct_carousel_item_set_child (MctCarouselItem *self,
GtkWidget *child);
MctCarousel *mct_carousel_new (void);
void mct_carousel_purge_items (MctCarousel *self);
@ -53,10 +49,4 @@ void mct_carousel_select_item (MctCarousel *self,
guint mct_carousel_get_item_count (MctCarousel *self);
void mct_carousel_add (MctCarousel *self,
MctCarouselItem *item);
void mct_carousel_set_revealed (MctCarousel *self,
gboolean revealed);
G_END_DECLS

View File

@ -3,76 +3,100 @@
<!-- Copyright © 2020 Endless, Inc. -->
<interface>
<requires lib="gtk+" version="3.12"/>
<template class="MctCarousel" parent="AdwBin">
<template class="MctCarousel" parent="GtkRevealer">
<property name="transition_duration">400</property>
<property name="reveal-child">True</property>
<child>
<object class="GtkRevealer" id="revealer">
<property name="transition_duration">400</property>
<property name="reveal-child">True</property>
<object class="GtkOverlay">
<property name="visible">True</property>
<property name="hexpand">True</property>
<property name="border_width">16</property>
<child>
<object class="GtkStack" id="stack">
<property name="visible">True</property>
<property name="transition_duration">400</property>
<property name="transition_type">GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT_RIGHT</property>
<style>
<class name="location-bar"/>
</style>
</object>
</child>
<child type="overlay">
<object class="GtkOverlay">
<property name="hexpand">True</property>
<property name="visible">True</property>
<child>
<object class="GtkStack" id="stack">
<property name="margin-top">16</property>
<property name="margin-bottom">16</property>
<property name="margin-start">16</property>
<property name="margin-end">16</property>
<property name="transition_duration">400</property>
<property name="transition_type">GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT_RIGHT</property>
<style>
<class name="location-bar"/>
</style>
</object>
</child>
<child type="overlay">
<object class="GtkButton" id="go_back_button">
<property name="visible">False</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="margin-top">12</property>
<property name="margin-bottom">12</property>
<property name="margin-start">12</property>
<property name="margin-end">12</property>
<property name="icon_name">go-previous-symbolic</property>
<accessibility>
<property name="label" translatable="yes">Previous Page</property>
</accessibility>
<style>
<class name="circular"/>
</style>
<signal name="clicked" handler="mct_carousel_goto_previous_page" object="MctCarousel" swapped="no"/>
</object>
</child>
<child type="overlay">
<object class="GtkButton" id="go_next_button">
<property name="valign">center</property>
<property name="halign">end</property>
<property name="margin-top">12</property>
<property name="margin-bottom">12</property>
<property name="margin-start">12</property>
<property name="margin-end">12</property>
<property name="hexpand">True</property>
<property name="icon_name">go-next-symbolic</property>
<accessibility>
<property name="label" translatable="yes">Next Page</property>
</accessibility>
<style>
<class name="circular"/>
</style>
<signal name="clicked" handler="mct_carousel_goto_next_page" object="MctCarousel" swapped="no"/>
<object class="GtkBox">
<property name="visible">True</property>
<property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
<property name="border_width">12</property>
<child>
<object class="GtkButton" id="go_back_button">
<property name="visible">False</property>
<property name="can_focus">True</property>
<property name="valign">center</property>
<style>
<class name="circular"/>
</style>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon-size">4</property>
<property name="icon_name">go-previous-symbolic</property>
<child internal-child="accessible">
<object class="AtkObject">
<property name="accessible-name" translatable="yes">Previous Page</property>
</object>
</child>
</object>
</child>
<signal name="clicked" handler="mct_carousel_goto_previous_page" object="MctCarousel" swapped="no"/>
</object>
<packing>
<property name="pack_type">GTK_PACK_START</property>
</packing>
</child>
<child>
<object class="GtkButton" id="go_next_button">
<property name="can_focus">True</property>
<property name="valign">center</property>
<style>
<class name="circular"/>
</style>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon-size">4</property>
<property name="icon_name">go-next-symbolic</property>
<child internal-child="accessible">
<object class="AtkObject">
<property name="accessible-name" translatable="yes">Next Page</property>
</object>
</child>
</object>
</child>
<signal name="clicked" handler="mct_carousel_goto_next_page" object="MctCarousel" swapped="no"/>
</object>
<packing>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
</object>
</child>
<child type="overlay">
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="visible">True</property>
<property name="valign">GTK_ALIGN_END</property>
<style>
<class name="carousel-arrow-container"/>
</style>
<child>
<object class="GtkOverlay">
<property name="visible">True</property>
<child>
<object class="GtkBox" id="arrow">
<property name="visible">True</property>
<property name="halign">GTK_ALIGN_END</property>
<style>
<class name="carousel-arrow"/>
@ -81,6 +105,7 @@
</child>
<child type="overlay">
<object class="GtkBox">
<property name="visible">True</property>
<property name="halign">GTK_ALIGN_END</property>
<style>
<class name="carousel-inner-arrow"/>
@ -90,8 +115,14 @@
</object>
</child>
</object>
<packing>
<property name="pass-through">True</property>
</packing>
</child>
</object>
<packing>
<property name="pass-through">True</property>
</packing>
</child>
</object>
</child>

View File

@ -1,8 +0,0 @@
install_data(
join_paths('scalable', application_id + '.svg'),
install_dir: join_paths(get_option('datadir'), 'icons', 'hicolor', 'scalable', 'apps'),
)
install_data(
join_paths('symbolic', application_id + '-symbolic.svg'),
install_dir: join_paths(get_option('datadir'), 'icons', 'hicolor', 'symbolic', 'apps'),
)

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><clipPath id="a"><path d="M0 0h128v128H0z"/></clipPath><clipPath id="c"><path d="M0 0h128v128H0z"/></clipPath><clipPath id="i"><path d="M0 0h128v128H0z"/></clipPath><clipPath id="g"><path d="M0 0h128v128H0z"/></clipPath><g id="m" clip-path="url(#i)"><use xlink:href="#j" mask="url(#k)"/></g><g id="e" clip-path="url(#a)"><path d="M124 66c0 33.137-26.863 60-60 60S4 99.137 4 66 30.863 6 64 6s60 26.863 60 60zm0 0" fill="url(#b)"/><path d="M124 63c0 32.586-26.863 59-60 59S4 95.586 4 63 30.863 4 64 4s60 26.414 60 59zm0 0" fill="#f8e45c"/><path d="M52.785 24.977a9.317 9.317 0 000 18.632 9.317 9.317 0 000-18.632zm-5.543 22.277c-.988 0-1.937.39-2.637 1.09L28.25 65.19c-3.656 3.512 1.758 8.926 5.27 5.27l10.933-10.934-.937 1.09v36.196c-.07 5.039 7.464 5.039 7.394 0V78.867c0-2.906 3.738-2.906 3.738 0v17.945c-.07 5.04 7.485 5.04 7.414 0v-27.78l3.567 7.624c2.02 4.531 8.82 1.508 6.812-3.027L61.535 49.465a3.729 3.729 0 00-3.406-2.211zm0 0M84.848 61.16a7.46 7.46 0 017.46 7.461 7.464 7.464 0 01-14.926 0 7.464 7.464 0 017.466-7.46zm0 0" fill="#3d3846"/><path d="M71.707 75.426c-3.078-.059-3.953 4.183-1.105 5.351l7.18 2.84V97.91c-.052 3.762 5.613 3.762 5.562 0v-3.969c0-1.804 2.832-1.726 2.832 0v3.797c-.051 3.758 5.492 3.758 5.437 0v-8.156l1.207 2.09c1.852 3.21 6.668.43 4.813-2.781l-5.29-9.164a2.792 2.792 0 00-2.41-1.391H79.57l-6.785-2.672a2.708 2.708 0 00-1.078-.238zm0 0" fill="#3d3846"/><path d="M64 6.95C32.52 6.95 7 32.042 7 63c0 30.957 25.52 56.05 57 56.05S121 93.958 121 63c0-30.957-25.52-56.05-57-56.05zm0 3.706c29.398 0 53.23 23.434 53.23 52.344S93.398 115.344 64 115.344c-29.398 0-53.23-23.434-53.23-52.344S34.602 10.656 64 10.656zm0 0" fill="#3d3846"/></g><g id="f" clip-path="url(#c)" filter="url(#d)"><use xlink:href="#e"/></g><g id="j" clip-path="url(#g)"><path d="M128 80.64V128H0V80.64zm0 0" fill="url(#h)"/><path d="M13.309 80.64L60.664 128H81.88l-47.36-47.36zm42.421 0L103.094 128h21.215L76.945 80.64zm42.43 0L128 110.48V89.27l-8.629-8.63zM0 88.548v21.215L18.238 128h21.215zm0 0"/></g><linearGradient id="l" gradientUnits="userSpaceOnUse" x1="0" y1="269.463" x2="118.926" y2="269.463" gradientTransform="translate(0 -172)"><stop offset="0" stop-color="#e5a50a"/><stop offset=".414" stop-color="#fbdf9b"/><stop offset=".813" stop-color="#e5a50a"/><stop offset="1" stop-color="#f8ca5b"/></linearGradient><linearGradient id="h" gradientUnits="userSpaceOnUse" x1="300" y1="235" x2="428" y2="235" gradientTransform="matrix(0 .37 -.98462 0 295.385 -30.36)"><stop offset="0" stop-color="#f9f06b"/><stop offset="1" stop-color="#f5c211"/></linearGradient><linearGradient id="b" gradientUnits="userSpaceOnUse" x1="0" y1="269.463" x2="118.926" y2="269.463" gradientTransform="translate(0 -172)"><stop offset="0" stop-color="#e5a50a"/><stop offset=".414" stop-color="#fbdf9b"/><stop offset=".813" stop-color="#e5a50a"/><stop offset="1" stop-color="#f8ca5b"/></linearGradient><mask id="k"><g filter="url(#d)"><path fill-opacity=".8" d="M0 0h128v128H0z"/></g></mask><mask id="n"><use xlink:href="#f"/></mask><filter id="d" filterUnits="objectBoundingBox" x="0%" y="0%" width="100%" height="100%"><feColorMatrix in="SourceGraphic" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/></filter></defs><path d="M124 66c0 33.137-26.863 60-60 60S4 99.137 4 66 30.863 6 64 6s60 26.863 60 60zm0 0" fill="url(#l)"/><path d="M124 63c0 32.586-26.863 59-60 59S4 95.586 4 63 30.863 4 64 4s60 26.414 60 59zm0 0" fill="#f8e45c"/><path d="M52.785 24.977a9.317 9.317 0 000 18.632 9.317 9.317 0 000-18.632zm-5.543 22.277c-.988 0-1.937.39-2.637 1.09L28.25 65.19c-3.656 3.512 1.758 8.926 5.27 5.27l10.933-10.934-.937 1.09v36.196c-.07 5.039 7.464 5.039 7.394 0V78.867c0-2.906 3.738-2.906 3.738 0v17.945c-.07 5.04 7.485 5.04 7.414 0v-27.78l3.567 7.624c2.02 4.531 8.82 1.508 6.812-3.027L61.535 49.465a3.729 3.729 0 00-3.406-2.211zm0 0M84.848 61.16a7.46 7.46 0 017.46 7.461 7.464 7.464 0 01-14.926 0 7.464 7.464 0 017.466-7.46zm0 0" fill="#3d3846"/><path d="M71.707 75.426c-3.078-.059-3.953 4.183-1.105 5.351l7.18 2.84V97.91c-.052 3.762 5.613 3.762 5.562 0v-3.969c0-1.804 2.832-1.726 2.832 0v3.797c-.051 3.758 5.492 3.758 5.437 0v-8.156l1.207 2.09c1.852 3.21 6.668.43 4.813-2.781l-5.29-9.164a2.792 2.792 0 00-2.41-1.391H79.57l-6.785-2.672a2.708 2.708 0 00-1.078-.238zm0 0" fill="#3d3846"/><path d="M64 6.95C32.52 6.95 7 32.042 7 63c0 30.957 25.52 56.05 57 56.05S121 93.958 121 63c0-30.957-25.52-56.05-57-56.05zm0 3.706c29.398 0 53.23 23.434 53.23 52.344S93.398 115.344 64 115.344c-29.398 0-53.23-23.434-53.23-52.344S34.602 10.656 64 10.656zm0 0" fill="#3d3846"/><use xlink:href="#m" mask="url(#n)"/></svg>

Before

Width:  |  Height:  |  Size: 4.6 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128"><defs><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="0" y1="269.463" x2="118.926" y2="269.463" gradientTransform="translate(0 -172)"><stop offset="0" stop-color="#e5a50a"/><stop offset=".414" stop-color="#fbdf9b"/><stop offset=".813" stop-color="#e5a50a"/><stop offset="1" stop-color="#f8ca5b"/></linearGradient></defs><path d="M124 66c0 33.137-26.863 60-60 60S4 99.137 4 66 30.863 6 64 6s60 26.863 60 60zm0 0" fill="url(#a)"/><path d="M124 63c0 32.586-26.863 59-60 59S4 95.586 4 63 30.863 4 64 4s60 26.414 60 59zm0 0" fill="#f8e45c"/><path d="M52.785 24.977a9.317 9.317 0 000 18.632 9.317 9.317 0 000-18.632zm-5.543 22.277c-.988 0-1.937.39-2.637 1.09L28.25 65.19c-3.656 3.512 1.758 8.926 5.27 5.27l10.933-10.934-.937 1.09v36.196c-.07 5.039 7.464 5.039 7.394 0V78.867c0-2.906 3.738-2.906 3.738 0v17.945c-.07 5.04 7.485 5.04 7.414 0v-27.78l3.567 7.624c2.02 4.531 8.82 1.508 6.812-3.027L61.535 49.465a3.729 3.729 0 00-3.406-2.211zm0 0M84.848 61.16a7.46 7.46 0 017.46 7.461 7.464 7.464 0 01-14.926 0 7.464 7.464 0 017.466-7.46zm0 0" fill="#3d3846"/><path d="M71.707 75.426c-3.078-.059-3.953 4.183-1.105 5.351l7.18 2.84V97.91c-.052 3.762 5.613 3.762 5.562 0v-3.969c0-1.804 2.832-1.726 2.832 0v3.797c-.051 3.758 5.492 3.758 5.437 0v-8.156l1.207 2.09c1.852 3.21 6.668.43 4.813-2.781l-5.29-9.164a2.792 2.792 0 00-2.41-1.391H79.57l-6.785-2.672a2.708 2.708 0 00-1.078-.238zm0 0" fill="#3d3846"/><path d="M64 6.95C32.52 6.95 7 32.042 7 63c0 30.957 25.52 56.05 57 56.05S121 93.958 121 63c0-30.957-25.52-56.05-57-56.05zm0 3.706c29.398 0 53.23 23.434 53.23 52.344S93.398 115.344 64 115.344c-29.398 0-53.23-23.434-53.23-52.344S34.602 10.656 64 10.656zm0 0" fill="#3d3846"/></svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><g fill="#2e3436"><path d="M8 2.5C8 3.879 6.879 5 5.5 5A2.502 2.502 0 013 2.5C3 1.121 4.121 0 5.5 0S8 1.121 8 2.5zm0 0M12.5 5C13.879 5 15 6.121 15 7.5S13.879 10 12.5 10A2.502 2.502 0 0110 7.5C10 6.121 11.121 5 12.5 5zm0 0"/><path d="M10 11c-1.352-.02-1.352 2.02 0 2h1v2a.998.998 0 001.5.863A1 1 0 0014 15v-.137c.867.5 1.848-.437 1.387-1.324l-.95-1.812C14.087 11.117 13.845 11 13 11zm0 0" fill-rule="evenodd"/><path d="M4 6a1 1 0 00-.707.293l-3 3a.992.992 0 00-.273.973.99.99 0 00.714.714.992.992 0 00.973-.273L3.25 9.16 3 10.93V15c-.004.36.184.695.496.879.313.18.695.18 1.008 0 .312-.184.5-.52.496-.879v-2.5s0-.5.5-.5.5.5.5.5V15c-.004.36.184.695.496.879.313.18.695.18 1.008 0 .312-.184.5-.52.496-.879v-3.285l.086.191c.223.504.816.73 1.32.508.504-.223.73-.816.508-1.32l-2-4.5C7.754 6.234 7.394 6 7 6zm0 0" fill-rule="evenodd"/></g></svg>

Before

Width:  |  Height:  |  Size: 899 B

View File

@ -2,178 +2,233 @@
<!-- Copyright © 2019, 2020 Endless Mobile, Inc. -->
<interface>
<requires lib="gtk+" version="3.12"/>
<object class="AdwApplicationWindow" id="main_window">
<property name="default-width">540</property>
<property name="default-height">580</property>
<object class="GtkApplicationWindow" id="main_window">
<property name="default-width">500</property>
<property name="default-height">600</property>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<object class="GtkStack" id="main_stack">
<property name="visible">True</property>
<child>
<object class="GtkHeaderBar" id="header">
<property name="show-title-buttons">True</property>
<property name="title-widget">
<object class="AdwWindowTitle">
<!-- Translators: This is the title of the main window -->
<property name="title" translatable="yes">Parental Controls</property>
<object class="GtkBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="border_width">0</property>
<child>
<object class="MctUserSelector" id="user_selector">
<property name="visible">True</property>
<property name="user-manager">user_manager</property>
<property name="show-administrators">False</property>
<accessibility>
<relation target="user_controls" type="controller-for"/>
</accessibility>
</object>
</property>
<child type="end">
<object class="GtkMenuButton" id="primary_menu">
<property name="direction">none</property>
<property name="menu-model">primary-menu</property>
<style>
<class name="image-button"/>
</style>
<packing>
<property name="fill">False</property>
<property name="expand">False</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="hscrollbar-policy">never</property>
<property name="min-content-height">350</property>
<child>
<object class="GtkShortcutController">
<property name="scope">global</property>
<child>
<object class="GtkShortcut">
<property name="trigger">F10</property>
<property name="action">activate</property>
<object class="MctUserControls" id="user_controls">
<property name="visible">True</property>
<property name="margin">12</property>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
</packing>
</child>
</object>
<packing>
<property name="name">controls</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<child type="center">
<object class="GtkBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">12</property>
<property name="margin">18</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">Permission Required</property>
<attributes>
<attribute name="scale" value="1.4"/>
</attributes>
<child internal-child="accessible">
<object class="AtkObject">
<property name="AtkObject::accessible-role">static</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">Permission is required to view and change parental controls settings for other users.</property>
<property name="wrap">True</property>
<child internal-child="accessible">
<object class="AtkObject">
<property name="AtkObject::accessible-role">static</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkLockButton" id="lock_button">
<property name="visible">True</property>
<property name="halign">center</property>
<property name="can-default">True</property>
<property name="has-default">True</property>
<property name="can-focus">True</property>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="name">unlock</property>
</packing>
</child>
<child>
<object class="GtkStack" id="main_stack">
<child>
<object class="GtkStackPage">
<property name="name">controls</property>
<property name="child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="MctUserSelector" id="user_selector">
<property name="user-manager">user_manager</property>
<property name="show-administrators">False</property>
<accessibility>
<relation name="controls">user_controls</relation>
</accessibility>
</object>
</child>
<child>
<object class="AdwPreferencesPage">
<child>
<object class="AdwPreferencesGroup">
<child>
<object class="MctUserControls" id="user_controls">
<!-- Content is set in code; this string is just a placeholder -->
<property name="description">Its recommended that restrictions are set as part of an ongoing conversation with $name. Read guidance on what to consider.</property>
<property name="height-request">270</property>
<property name="dbus-connection">dbus_connection</property>
<property name="vexpand">True</property>
</object>
</child>
</object>
</child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<child type="center">
<object class="GtkBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">12</property>
<property name="margin">18</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">No Child Users Configured</property>
<attributes>
<attribute name="scale" value="1.4"/>
</attributes>
<child internal-child="accessible">
<object class="AtkObject">
<property name="AtkObject::accessible-role">static</property>
</object>
</child>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">unlock</property>
<property name="child">
<object class="AdwStatusPage">
<property name="title" translatable="yes">Permission Required</property>
<property name="description" translatable="yes">Permission is required to view and change user parental controls settings.</property>
<property name="icon-name">org.freedesktop.MalcontentControl</property>
<child>
<object class="GtkLockButton" id="lock_button">
<property name="halign">center</property>
<style>
<class name="suggested-action" />
<class name="pill" />
</style>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">No child users are currently set up on the system. Create one before setting up their parental controls.</property>
<property name="wrap">True</property>
<child internal-child="accessible">
<object class="AtkObject">
<property name="AtkObject::accessible-role">static</property>
</object>
</child>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">no-other-users</property>
<property name="child">
<object class="AdwStatusPage">
<property name="icon-name">system-users-symbolic</property>
<property name="title" translatable="yes">No Standard User Accounts</property>
<property name="description" translatable="yes">Parental controls can only be applied to standard user
accounts. These can be created in the user settings.</property>
<child>
<object class="GtkButton" id="user_accounts_panel_button">
<property name="label" translatable="yes">_User Settings</property>
<property name="halign">center</property>
<property name="use-underline">True</property>
<style>
<class name="suggested-action"/>
</style>
</object>
</child>
</child>
<child>
<object class="GtkButton" id="user_accounts_panel_button">
<property name="visible">True</property>
<property name="label" translatable="yes">Create _Child User</property>
<property name="halign">center</property>
<property name="can-default">True</property>
<property name="has-default">True</property>
<property name="use-underline">True</property>
<property name="can-focus">True</property>
<style>
<class name="suggested-action"/>
</style>
</object>
</property>
</child>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">loading</property>
<property name="child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<child type="center">
<object class="GtkLabel">
<property name="label" translatable="yes">Loading…</property>
<property name="vexpand">True</property>
<style>
<class name="title-1" />
</style>
</object>
</child>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">error</property>
<property name="child">
<object class="AdwStatusPage" id="error_page">
<property name="icon-name">dialog-error-symbolic</property>
</object>
</property>
</object>
</child>
</object>
<packing>
<property name="name">no-other-users</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<child type="center">
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">Loading…</property>
<attributes>
<attribute name="scale" value="1.4"/>
</attributes>
<child internal-child="accessible">
<object class="AtkObject">
<property name="AtkObject::accessible-role">static</property>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="name">loading</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<child type="center">
<object class="GtkBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">12</property>
<child>
<object class="GtkLabel" id="error_title">
<property name="visible">True</property>
<property name="label"></property>
<attributes>
<attribute name="scale" value="1.4"/>
</attributes>
</object>
</child>
<child>
<object class="GtkLabel" id="error_message">
<property name="visible">True</property>
<property name="label"></property>
</object>
</child>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject">
<property name="AtkObject::accessible-role">alert</property>
</object>
</child>
</object>
<packing>
<property name="name">error</property>
</packing>
</child>
</object>
</child>
</object>
<menu id="primary-menu">
<section>
<item>
<attribute name="action">app.help</attribute>
<attribute name="label" translatable="yes">_Help</attribute>
</item>
<item>
<attribute name="action">app.about</attribute>
<attribute name="label" translatable="yes">_About Parental Controls</attribute>
</item>
</section>
</menu>
</interface>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

View File

@ -7,7 +7,7 @@ endif
resources = gnome.compile_resources(
'resources',
'malcontent-control.gresource.xml',
source_dir: meson.current_source_dir(),
source_dir: meson.source_root(),
)
malcontent_control = executable('malcontent-control',
@ -27,9 +27,9 @@ malcontent_control = executable('malcontent-control',
dependency('gio-2.0', version: '>= 2.44'),
dependency('glib-2.0', version: '>= 2.54.2'),
dependency('gobject-2.0', version: '>= 2.54'),
gtk_dep,
dependency('gtk+-3.0'),
dependency('flatpak'),
dependency('polkit-gobject-1'),
libadwaita_dep,
libmalcontent_dep,
libmalcontent_ui_dep,
],
@ -37,11 +37,11 @@ malcontent_control = executable('malcontent-control',
install: true,
)
desktop_file = i18n.merge_file(
desktop_file = i18n.merge_file('desktop-file',
type: 'desktop',
input: '@0@.desktop.in'.format(application_id),
output: '@0@.desktop'.format(application_id),
po_dir: join_paths(meson.current_source_dir(), '..', 'po'),
po_dir: join_paths(meson.source_root(), 'po'),
install: true,
install_dir: join_paths(get_option('datadir'), 'applications'),
)
@ -58,10 +58,10 @@ if desktop_file_validate.found()
)
endif
appdata_file = i18n.merge_file(
appdata_file = i18n.merge_file('appdata-file',
input: '@0@.appdata.xml.in'.format(application_id),
output: '@0@.appdata.xml'.format(application_id),
po_dir: join_paths(meson.current_source_dir(), '..', 'po'),
po_dir: join_paths(meson.source_root(), 'po'),
install: true,
install_dir: join_paths(get_option('datadir'), 'metainfo'),
)
@ -79,12 +79,12 @@ endif
xmllint = find_program('xmllint', required: false)
if xmllint.found()
gtk_prefix = gtk_dep.get_variable(pkgconfig: 'prefix')
gtk_prefix = dependency('gtk+-3.0').get_pkgconfig_variable('prefix')
test(
'validate-ui', xmllint,
args: [
'--nonet', '--noblanks', '--noout',
'--relaxng', join_paths(gtk_prefix, 'share', 'gtk-4.0', 'gtk4builder.rng'),
'--relaxng', join_paths(gtk_prefix, 'share', 'gtk-3.0', 'gtkbuilder.rng'),
files(
'carousel.ui',
'main.ui',
@ -95,10 +95,10 @@ if xmllint.found()
)
endif
policy_file = i18n.merge_file(
policy_file = i18n.merge_file('policy-file',
input: '@0@.policy.in'.format(application_id),
output: '@0@.policy'.format(application_id),
po_dir: join_paths(meson.current_source_dir(), '..', 'po'),
po_dir: join_paths(meson.source_root(), 'po'),
install: true,
install_dir: join_paths(get_option('datadir'), 'polkit-1', 'actions'),
)
@ -113,6 +113,6 @@ if xmllint.found()
)
endif
# FIXME: Add tests
subdir('icons')
# FIXME: Add icons and tests
#subdir('icons')
#subdir('tests')

View File

@ -19,23 +19,22 @@
installed software they can run.
</p>
</description>
<!--
<screenshots>
<screenshot height="552" width="699" type="default">
<image>https://gitlab.freedesktop.org/pwithnall/malcontent/-/raw/HEAD/malcontent-control/malcontent-control.png</image>
<caption>Main window</caption>
<screenshot type="default" width="400" height="480">
<image>https://FIXME/malcontent-control.png</image>
</screenshot>
</screenshots>
-->
<provides>
<binary>malcontent-control</binary>
</provides>
<launchable type="desktop-id">org.freedesktop.MalcontentControl.desktop</launchable>
<url type="homepage">https://gitlab.freedesktop.org/pwithnall/malcontent</url>
<url type="bugtracker">https://gitlab.freedesktop.org/pwithnall/malcontent/issues</url>
<url type="donation">https://www.gnome.org/donate/</url>
<url type="vcs-browser">https://gitlab.freedesktop.org/pwithnall/malcontent</url>
<url type="donation">http://www.gnome.org/friends/</url>
<url type="translate">https://wiki.gnome.org/TranslationProject/LocalisationGuide</url>
<update_contact>philip_at_tecnocode.co.uk</update_contact>
<compulsory_for_desktop>GNOME</compulsory_for_desktop>
<project_group>GNOME</project_group>
<developer_name>The GNOME Project</developer_name>
<kudos>
@ -45,132 +44,8 @@
</kudos>
<translation type="gettext">malcontent</translation>
<releases>
<release version="0.11.1" date="2023-03-16" type="stable">
<description>
<p>This is a stable release with the following changes:</p>
<ul>
<li>Translation updates</li>
</ul>
</description>
</release>
<release version="0.11.0" date="2022-08-12" type="stable">
<description>
<p>This is a stable release with the following changes:</p>
<ul>
<li>Use libappstream instead of appstream-glib</li>
<li>Port to GTK4</li>
<li>Translation updates</li>
</ul>
</description>
</release>
<release version="0.10.5" date="2022-05-31" type="stable">
<description>
<p>This is a stable release with the following changes:</p>
<ul>
<li>German translation of the user help</li>
<li>Translation updates</li>
</ul>
</description>
</release>
<release version="0.10.4" date="2022-03-09" type="stable">
<description>
<p>This is a stable release with the following changes:</p>
<ul>
<li>Italian translation of the user help</li>
<li>Translation updates</li>
</ul>
</description>
</release>
<release version="0.10.3" date="2021-11-01" type="stable">
<description>
<p>This is a stable release with the following changes:</p>
<ul>
<li>Prevent malcontent-control from being uninstalled and removing core desktop components with it</li>
<li>Improve keyboard navigation of the interface</li>
<li>Translation updates</li>
</ul>
</description>
</release>
<release version="0.10.2" date="2021-09-17" type="stable">
<description>
<p>This is a stable release with the following changes:</p>
<ul>
<li>Hide the launcher for malcontent-control from gnome-shell if using the GNOME desktop; find it via gnome-control-center instead</li>
<li>Translation updates</li>
</ul>
</description>
</release>
<release version="0.10.1" date="2021-03-11" type="stable">
<description>
<p>This is a stable release with the following changes:</p>
<ul>
<li>Sort apps by displayed name when listing them</li>
<li>Translation updates</li>
</ul>
</description>
</release>
<release version="0.10.0" date="2020-12-09" type="stable">
<description>
<p>This is a stable release with the following changes:</p>
<ul>
<li>Reload the application list when apps are installed or removed</li>
<li>Fix some data loss consistency problems in the UI</li>
<li>Hide support for flatpak user repositories, as they are typically not configured</li>
<li>Minor improvements to parental controls application UI</li>
<li>Translation updates</li>
</ul>
</description>
</release>
<release version="0.9.0" date="2020-09-03" type="stable">
<description>
<p>This is a stable release with the following changes:</p>
<ul>
<li>Minor improvements to parental controls application UI</li>
<li>Choose rating system by territory rather than language</li>
<li>Translation updates</li>
</ul>
</description>
</release>
<release version="0.8.0" date="2020-04-28" type="stable">
<description>
<p>This is a stable release with the following changes:</p>
<ul>
<li>Minor improvements to parental controls application UI</li>
<li>Add a user manual</li>
<li>Translation updates</li>
</ul>
</description>
</release>
<release version="0.7.0" date="2020-03-24" type="stable">
<description>
<p>This is a stable release with the following changes:</p>
<ul>
<li>Minor improvements to parental controls application UI</li>
<li>Translations to Ukrainian and Polish</li>
</ul>
</description>
</release>
<release version="0.6.0" date="2020-02-26" type="stable">
<description>
<p>This is a stable release with the following changes:</p>
<ul>
<li>Improve parental controls application UI and add icon</li>
<li>Support for indicating which accounts are parent accounts</li>
</ul>
</description>
</release>
<release version="0.5.0" date="2020-02-14" type="stable">
<description>
<p>This is a stable release with the following changes:</p>
<ul>
<li>Initial release of basic parental controls application</li>
<li>Support for setting app installation and run restrictions on users</li>
</ul>
</description>
</release>
<release version="0.4.0" date="2019-07-17" type="stable">
<description>
<p>This is a stable release with the following changes:</p>
<ul>
<li>Maintenance release of underlying parental controls library</li>
</ul>

View File

@ -7,7 +7,6 @@ Icon=org.freedesktop.MalcontentControl
Terminal=false
Type=Application
Categories=GTK;GNOME;System;
NotShowIn=GNOME;
StartupNotify=true
# Translators: Search terms to find this application. Do NOT translate or localise the semicolons! The list MUST also end with a semicolon!
Keywords=parental controls;screen time;app restrictions;web browser restrictions;oars;usage;usage limit;kid;child;

View File

@ -13,6 +13,6 @@
<allow_inactive>no</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
<annotate key="org.freedesktop.policykit.imply">com.endlessm.ParentalControls.AppFilter.ReadAny com.endlessm.ParentalControls.AppFilter.ChangeAny com.endlessm.ParentalControls.AppFilter.ReadOwn com.endlessm.ParentalControls.AppFilter.ChangeOwn</annotate>
<annotate key="org.freedesktop.policykit.imply">com.endlessm.ParentalControls.AppFilter.ReadAny com.endlessm.ParentalControls.AppFilter.ChangeAny</annotate>
</action>
</policyconfig>

View File

@ -1,6 +1,5 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
* Copyright © 2022 Endless Mobile, Inc.
* Copyright © 2015 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or modify
@ -17,11 +16,10 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
* Authors:
* - Georges Basile Stavracas Neto <georges@endlessos.org>
* - Ondrej Holy <oholy@redhat.com>
*/
#include <adwaita.h>
#include <gtk/gtk.h>
#include <act/act.h>
#include <sys/stat.h>
@ -30,49 +28,108 @@
struct _MctUserImage
{
AdwBin parent_instance;
AdwAvatar *avatar;
GtkImage parent_instance;
ActUser *user;
};
G_DEFINE_TYPE (MctUserImage, mct_user_image, ADW_TYPE_BIN)
G_DEFINE_TYPE (MctUserImage, mct_user_image, GTK_TYPE_IMAGE)
static GdkTexture *
render_user_icon_texture (ActUser *user)
static GdkPixbuf *
round_image (GdkPixbuf *pixbuf)
{
g_autoptr(GdkTexture) texture = NULL;
g_autoptr(GError) error = NULL;
GdkPixbuf *dest = NULL;
cairo_surface_t *surface;
cairo_t *cr;
gint size;
size = gdk_pixbuf_get_width (pixbuf);
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, size, size);
cr = cairo_create (surface);
/* Clip a circle */
cairo_arc (cr, size / 2, size / 2, size / 2, 0, 2 * G_PI);
cairo_clip (cr);
cairo_new_path (cr);
gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
cairo_paint (cr);
dest = gdk_pixbuf_get_from_surface (surface, 0, 0, size, size);
cairo_surface_destroy (surface);
cairo_destroy (cr);
return dest;
}
static cairo_surface_t *
render_user_icon (ActUser *user,
gint icon_size,
gint scale)
{
g_autoptr(GdkPixbuf) source_pixbuf = NULL;
GdkPixbuf *pixbuf = NULL;
GError *error;
const gchar *icon_file;
cairo_surface_t *surface = NULL;
g_return_val_if_fail (ACT_IS_USER (user), NULL);
g_return_val_if_fail (icon_size > 12, NULL);
icon_file = act_user_get_icon_file (user);
if (icon_file == NULL)
return NULL;
texture = gdk_texture_new_from_filename (icon_file, &error);
if (error != NULL)
pixbuf = NULL;
if (icon_file)
{
g_warning ("Error loading user icon: %s", error->message);
return NULL;
source_pixbuf = gdk_pixbuf_new_from_file_at_size (icon_file,
icon_size * scale,
icon_size * scale,
NULL);
if (source_pixbuf)
pixbuf = round_image (source_pixbuf);
}
return g_steal_pointer (&texture);
if (pixbuf != NULL)
goto out;
error = NULL;
pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
"avatar-default",
icon_size * scale,
GTK_ICON_LOOKUP_FORCE_SIZE,
&error);
if (error)
{
g_warning ("%s", error->message);
g_error_free (error);
}
out:
if (pixbuf != NULL)
{
surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale, NULL);
g_object_unref (pixbuf);
}
return surface;
}
static void
render_image (MctUserImage *image)
{
g_autoptr(GdkTexture) texture = NULL;
cairo_surface_t *surface;
gint scale, pixel_size;
if (image->user == NULL)
return;
texture = render_user_icon_texture (image->user);
adw_avatar_set_custom_image (image->avatar, GDK_PAINTABLE (texture));
adw_avatar_set_text (image->avatar, act_user_get_real_name (image->user));
pixel_size = gtk_image_get_pixel_size (GTK_IMAGE (image));
scale = gtk_widget_get_scale_factor (GTK_WIDGET (image));
surface = render_user_icon (image->user,
pixel_size > 0 ? pixel_size : 48,
scale);
gtk_image_set_from_surface (GTK_IMAGE (image), surface);
cairo_surface_destroy (surface);
}
void
@ -106,8 +163,8 @@ mct_user_image_class_init (MctUserImageClass *class)
static void
mct_user_image_init (MctUserImage *image)
{
image->avatar = ADW_AVATAR (adw_avatar_new (48, NULL, TRUE));
adw_bin_set_child (ADW_BIN (image), GTK_WIDGET (image->avatar));
g_signal_connect_swapped (image, "notify::scale-factor", G_CALLBACK (render_image), image);
g_signal_connect_swapped (image, "notify::pixel-size", G_CALLBACK (render_image), image);
}
GtkWidget *

View File

@ -1,6 +1,5 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
* Copyright © 2022 Endless Mobile, Inc.
* Copyright © 2015 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or modify
@ -17,20 +16,19 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
* Authors:
* - Georges Basile Stavracas Neto <georges@endlessos.org>
* - Ondrej Holy <oholy@redhat.com>
*/
#pragma once
#include <adwaita.h>
#include <gtk/gtk.h>
#include <act/act.h>
G_BEGIN_DECLS
#define MCT_TYPE_USER_IMAGE (mct_user_image_get_type ())
G_DECLARE_FINAL_TYPE (MctUserImage, mct_user_image, MCT, USER_IMAGE, AdwBin)
G_DECLARE_FINAL_TYPE (MctUserImage, mct_user_image, MCT, USER_IMAGE, GtkImage)
GtkWidget *mct_user_image_new (void);
void mct_user_image_set_user (MctUserImage *image,

View File

@ -309,8 +309,8 @@ sort_users (gconstpointer a,
ActUser *ua, *ub;
gint result;
ua = ACT_USER ((gpointer) a);
ub = ACT_USER ((gpointer) b);
ua = ACT_USER (a);
ub = ACT_USER (b);
/* Make sure the current user is shown first */
if (act_user_get_uid (ua) == getuid ())
@ -344,7 +344,7 @@ user_compare (gconstpointer i,
gint result;
item = (MctCarouselItem *) i;
user = ACT_USER ((gpointer) u);
user = ACT_USER (u);
uid_a = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (item), "uid"));
uid_b = act_user_get_uid (user);
@ -370,11 +370,11 @@ reload_users (MctUserSelector *self,
g_object_get (settings, "gtk-enable-animations", &animations, NULL);
g_object_set (settings, "gtk-enable-animations", FALSE, NULL);
mct_carousel_purge_items (self->carousel);
list = act_user_manager_list_users (self->user_manager);
g_debug ("Got %u users", g_slist_length (list));
mct_carousel_purge_items (self->carousel);
list = g_slist_sort (list, (GCompareFunc) sort_users);
for (l = list; l; l = l->next)
{
@ -397,7 +397,7 @@ reload_users (MctUserSelector *self,
g_object_set (settings, "gtk-enable-animations", animations, NULL);
mct_carousel_set_revealed (self->carousel, TRUE);
gtk_revealer_set_reveal_child (GTK_REVEALER (self->carousel), TRUE);
}
static GtkWidget *
@ -411,7 +411,7 @@ create_carousel_entry (MctUserSelector *self,
widget = mct_user_image_new ();
mct_user_image_set_user (MCT_USER_IMAGE (widget), user);
gtk_box_append (GTK_BOX (box), widget);
gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 0);
label = g_strdup_printf ("<b>%s</b>",
get_real_or_user_name (user));
@ -419,7 +419,7 @@ create_carousel_entry (MctUserSelector *self,
gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
gtk_label_set_ellipsize (GTK_LABEL (widget), PANGO_ELLIPSIZE_END);
gtk_widget_set_margin_top (widget, 5);
gtk_box_append (GTK_BOX (box), widget);
gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 0);
g_free (label);
if (act_user_get_uid (user) == getuid ())
@ -431,7 +431,7 @@ create_carousel_entry (MctUserSelector *self,
gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
g_free (label);
gtk_box_append (GTK_BOX (box), widget);
gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 0);
gtk_style_context_add_class (gtk_widget_get_style_context (widget),
"dim-label");
@ -455,10 +455,10 @@ user_added_cb (ActUserManager *user_manager,
widget = create_carousel_entry (self, user);
item = mct_carousel_item_new ();
mct_carousel_item_set_child (MCT_CAROUSEL_ITEM (item), widget);
gtk_container_add (GTK_CONTAINER (item), widget);
g_object_set_data (G_OBJECT (item), "uid", GINT_TO_POINTER (act_user_get_uid (user)));
mct_carousel_add (self->carousel, MCT_CAROUSEL_ITEM (item));
gtk_container_add (GTK_CONTAINER (self->carousel), item);
}
static void
@ -506,38 +506,3 @@ mct_user_selector_get_user (MctUserSelector *self)
return self->user;
}
/**
* mct_user_selector_select_user_by_username:
* @self: an #MctUserSelector
* @username: username of the user to select
*
* Selects the given @username in the widget. This might fail if @username isnt
* a valid user, or if they arent listed in the selector due to being an
* administrator (see #MctUserSelector:show-administrators).
*
* Returns: %TRUE if the user was successfully selected, %FALSE otherwise
* Since: 0.10.0
*/
gboolean
mct_user_selector_select_user_by_username (MctUserSelector *self,
const gchar *username)
{
MctCarouselItem *item = NULL;
ActUser *user = NULL;
g_return_val_if_fail (MCT_IS_USER_SELECTOR (self), FALSE);
g_return_val_if_fail (username != NULL && *username != '\0', FALSE);
user = act_user_manager_get_user (self->user_manager, username);
if (user == NULL)
return FALSE;
item = mct_carousel_find_item (self->carousel, user, user_compare);
if (item == NULL)
return FALSE;
mct_carousel_select_item (self->carousel, item);
return TRUE;
}

View File

@ -34,7 +34,4 @@ MctUserSelector *mct_user_selector_new (ActUserManager *user_manager);
ActUser *mct_user_selector_get_user (MctUserSelector *self);
gboolean mct_user_selector_select_user_by_username (MctUserSelector *self,
const gchar *username);
G_END_DECLS

View File

@ -5,6 +5,7 @@
<template class="MctUserSelector" parent="GtkBox">
<child>
<object class="MctCarousel" id="carousel">
<property name="visible">True</property>
<property name="hexpand">True</property>
<signal name="item-activated" handler="carousel_item_activated"/>
</object>

View File

@ -1,6 +1,6 @@
<Project xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:foaf="http://xmlns.com/foaf/0.1/" xmlns="http://usefulinc.com/ns/doap#">
<name xml:lang="en">malcontent</name>
<shortdesc xml:lang="en">malcontent provides parental controls functionality on Linux systems</shortdesc>
<shortdesc xml:lang="en">malcontent provides restrictions for children on Linux systems</shortdesc>
<description xml:lang="en">malcontent implements support for restricting the abilities of non-administrator accounts on a Linux system.</description>
<homepage rdf:resource="https://gitlab.freedesktop.org/pwithnall/malcontent"/>
<license rdf:resource="http://usefulinc.com/doap/licenses/lgpl"/>

View File

@ -1,7 +1,7 @@
project('malcontent', 'c',
version : '0.12.0',
meson_version : '>= 0.59.0',
license: ['LGPL-2.1-or-later', 'GPL-2.0-or-later'],
version : '0.5.0',
meson_version : '>= 0.49.0',
license: 'LGPLv2.1+',
default_options : [
'buildtype=debugoptimized',
'warning_level=2',
@ -13,15 +13,14 @@ gnome = import('gnome')
i18n = import('i18n')
pkgconfig = import('pkgconfig')
meson_make_symlink = join_paths(meson.current_source_dir(), 'tools', 'meson-make-symlink.py')
po_dir = join_paths(meson.current_source_dir(), 'po')
meson_make_symlink = join_paths(meson.source_root(), 'tools', 'meson-make-symlink.py')
po_dir = join_paths(meson.source_root(), 'po')
prefix = get_option('prefix')
bindir = join_paths(prefix, get_option('bindir'))
datadir = join_paths(prefix, get_option('datadir'))
libdir = join_paths(prefix, get_option('libdir'))
libexecdir = join_paths(prefix, get_option('libexecdir'))
includedir = join_paths(prefix, get_option('includedir'))
# FIXME: This isnt exposed in accountsservice.pc
# See https://gitlab.freedesktop.org/accountsservice/accountsservice/merge_requests/16
@ -34,18 +33,22 @@ if pamlibdir == ''
endif
dbus = dependency('dbus-1')
dbusinterfacesdir = dbus.get_variable(pkgconfig: 'interfaces_dir',
pkgconfig_define: ['datadir', datadir])
dbusinterfacesdir = dbus.get_pkgconfig_variable('interfaces_dir',
define_variable: ['datadir', datadir])
polkit_gobject = dependency('polkit-gobject-1')
polkitpolicydir = polkit_gobject.get_variable(pkgconfig: 'policydir',
pkgconfig_define: ['prefix', prefix])
polkitpolicydir = polkit_gobject.get_pkgconfig_variable('policydir',
define_variable: ['prefix', prefix])
libglib_testing = subproject('libglib-testing')
libglib_testing_dep = dependency(
'libglib-testing',
fallback: ['libglib-testing', 'libglib_testing_dep'],
)
config_h = configuration_data()
config_h.set_quoted('GETTEXT_PACKAGE', 'malcontent')
config_h.set_quoted('PACKAGE_LOCALE_DIR', join_paths(get_option('prefix'), get_option('localedir')))
config_h.set_quoted('PAMLIBDIR', pamlibdir)
config_h.set_quoted('VERSION', meson.project_version())
config_h.set_quoted('GETTEXT_PACKAGE', meson.project_name())
config_h.set_quoted('PACKAGE_LOCALE_DIR', join_paths(get_option('localedir'), meson.project_name()))
configure_file(
output: 'config.h',
configuration: config_h,
@ -124,33 +127,9 @@ test_env = [
]
subdir('accounts-service')
subdir('help')
if not get_option('use_system_libmalcontent')
subdir('libmalcontent')
else
libmalcontent_api_version = '0'
libmalcontent_dep = dependency('malcontent-' + libmalcontent_api_version, version: meson.project_version())
libmalcontent_gir = ['Malcontent-' + libmalcontent_api_version,
'Malcontent-' + libmalcontent_api_version + '.typelib']
endif
if get_option('ui').enabled()
gtk_dep = dependency('gtk4', version: '>= 4.6')
libadwaita_dep = dependency(
'libadwaita-1',
version: '>= 1.1',
fallback: ['libadwaita', 'libadwaita_dep'],
default_options: ['examples=false', 'introspection=disabled', 'tests=false', 'vapi=false'],
)
subdir('libmalcontent-ui')
endif
subdir('libmalcontent')
subdir('libmalcontent-ui')
subdir('malcontent-client')
if get_option('ui').enabled()
subdir('malcontent-control')
gnome.post_install(
gtk_update_icon_cache: true,
update_desktop_database: true,
)
endif
subdir('malcontent-control')
subdir('pam')
subdir('po')

View File

@ -9,21 +9,3 @@ option(
type: 'string',
description: 'directory for PAM modules'
)
option(
'ui',
type: 'feature',
value: 'enabled',
description: 'enable UI library'
)
option(
'use_system_libmalcontent',
type: 'boolean',
value: false,
description: 'use installed libmalcontent rather than building it; used in distros to break a dependency cycle'
)
option(
'privileged_group',
type: 'string',
value: 'wheel',
description: 'name of group that has elevated permissions'
)

View File

@ -24,7 +24,6 @@
#include <glib.h>
#include <locale.h>
#include <stdlib.h>
#include "config.h"
/* Test that the `pam_malcontent.so` module can be loaded using dlopen() and
* that it exports the appropriate symbols for PAM to be able to use it. */
@ -38,13 +37,6 @@ test_pam_malcontent_dlopen (void)
module_path = g_test_build_filename (G_TEST_BUILT, "..", "pam_malcontent.so", NULL);
/* Installed tests version. */
if (!g_file_test (module_path, G_FILE_TEST_EXISTS))
{
g_free (module_path);
module_path = g_build_filename (PAMLIBDIR, "pam_malcontent.so", NULL);
}
/* Check the module can be loaded. */
handle = dlopen (module_path, RTLD_NOW);
g_assert_nonnull (handle);

View File

@ -1,51 +0,0 @@
af
ar
bg
bn
ca
ca@valencia
cs
da
de
el
eo
es
eu
fa
fi
fr
fur
gd
gl
he
hi
hr
hu
id
it
ka
kk
ko
lt
lv
ml
ms
nb
nl
oc
pa
pl
pt
pt_BR
ro
ru
sk
sl
sr
sr@latin
sv
th
tr
uk
vi
zh_TW

View File

@ -1,9 +1,8 @@
# List of source files containing translatable strings.
# Please keep this file sorted alphabetically.
accounts-service/com.endlessm.ParentalControls.policy.in
libmalcontent/app-filter.c
libmalcontent/manager.c
libmalcontent/session-limits.c
libmalcontent-ui/gs-content-rating.c
libmalcontent-ui/restrict-applications-dialog.c
libmalcontent-ui/restrict-applications-dialog.ui
libmalcontent-ui/restrict-applications-selector.c
@ -11,10 +10,8 @@ libmalcontent-ui/restrict-applications-selector.ui
libmalcontent-ui/user-controls.c
libmalcontent-ui/user-controls.ui
malcontent-control/application.c
malcontent-control/carousel.ui
malcontent-control/main.ui
malcontent-control/org.freedesktop.MalcontentControl.appdata.xml.in
malcontent-control/org.freedesktop.MalcontentControl.desktop.in
malcontent-control/org.freedesktop.MalcontentControl.policy.in
malcontent-control/user-selector.c
pam/pam_malcontent.c

757
po/af.po
View File

@ -1,757 +0,0 @@
# Afrikaans translations for malcontent package.
# Copyright (C) 2020 THE malcontent'S COPYRIGHT HOLDER
# This file is distributed under the same license as the malcontent package.
# Automatically generated, 2020.
#
msgid ""
msgstr ""
"Project-Id-Version: malcontent\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-06-10 12:04+0100\n"
"PO-Revision-Date: 2020-04-15 13:42+0100\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
"Language: af\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: accounts-service/com.endlessm.ParentalControls.policy.in:4
msgid "Change your own app filter"
msgstr ""
#: accounts-service/com.endlessm.ParentalControls.policy.in:5
msgid "Authentication is required to change your app filter."
msgstr ""
#: accounts-service/com.endlessm.ParentalControls.policy.in:14
msgid "Read your own app filter"
msgstr ""
#: accounts-service/com.endlessm.ParentalControls.policy.in:15
msgid "Authentication is required to read your app filter."
msgstr ""
#: accounts-service/com.endlessm.ParentalControls.policy.in:24
msgid "Change another users app filter"
msgstr ""
#: accounts-service/com.endlessm.ParentalControls.policy.in:25
msgid "Authentication is required to change another users app filter."
msgstr ""
#: accounts-service/com.endlessm.ParentalControls.policy.in:34
msgid "Read another users app filter"
msgstr ""
#: accounts-service/com.endlessm.ParentalControls.policy.in:35
msgid "Authentication is required to read another users app filter."
msgstr ""
#: accounts-service/com.endlessm.ParentalControls.policy.in:44
msgid "Change your own session limits"
msgstr ""
#: accounts-service/com.endlessm.ParentalControls.policy.in:45
msgid "Authentication is required to change your session limits."
msgstr ""
#: accounts-service/com.endlessm.ParentalControls.policy.in:54
msgid "Read your own session limits"
msgstr ""
#: accounts-service/com.endlessm.ParentalControls.policy.in:55
msgid "Authentication is required to read your session limits."
msgstr ""
#: accounts-service/com.endlessm.ParentalControls.policy.in:64
msgid "Change another users session limits"
msgstr ""
#: accounts-service/com.endlessm.ParentalControls.policy.in:65
msgid "Authentication is required to change another users session limits."
msgstr ""
#: accounts-service/com.endlessm.ParentalControls.policy.in:74
msgid "Read another users session limits"
msgstr ""
#: accounts-service/com.endlessm.ParentalControls.policy.in:75
msgid "Authentication is required to read another users session limits."
msgstr ""
#: accounts-service/com.endlessm.ParentalControls.policy.in:84
msgid "Change your own account info"
msgstr ""
#: accounts-service/com.endlessm.ParentalControls.policy.in:85
msgid "Authentication is required to change your account info."
msgstr ""
#: accounts-service/com.endlessm.ParentalControls.policy.in:94
msgid "Read your own account info"
msgstr ""
#: accounts-service/com.endlessm.ParentalControls.policy.in:95
msgid "Authentication is required to read your account info."
msgstr ""
#: accounts-service/com.endlessm.ParentalControls.policy.in:104
msgid "Change another users account info"
msgstr ""
#: accounts-service/com.endlessm.ParentalControls.policy.in:105
msgid "Authentication is required to change another users account info."
msgstr ""
#: accounts-service/com.endlessm.ParentalControls.policy.in:114
msgid "Read another users account info"
msgstr ""
#: accounts-service/com.endlessm.ParentalControls.policy.in:115
msgid "Authentication is required to read another users account info."
msgstr ""
#: libmalcontent/app-filter.c:694
#, c-format
msgid "App filter for user %u was in an unrecognized format"
msgstr ""
#: libmalcontent/app-filter.c:725
#, c-format
msgid "OARS filter for user %u has an unrecognized kind %s"
msgstr ""
#: libmalcontent/manager.c:283 libmalcontent/manager.c:412
#, c-format
msgid "Not allowed to query app filter data for user %u"
msgstr ""
#: libmalcontent/manager.c:288
#, c-format
msgid "User %u does not exist"
msgstr ""
#: libmalcontent/manager.c:394
msgid "App filtering is globally disabled"
msgstr ""
#: libmalcontent/manager.c:777
msgid "Session limits are globally disabled"
msgstr ""
#: libmalcontent/manager.c:795
#, c-format
msgid "Not allowed to query session limits data for user %u"
msgstr ""
#: libmalcontent/session-limits.c:306
#, c-format
msgid "Session limit for user %u was in an unrecognized format"
msgstr ""
#: libmalcontent/session-limits.c:328
#, c-format
msgid "Session limit for user %u has an unrecognized type %u"
msgstr ""
#: libmalcontent/session-limits.c:346
#, c-format
msgid "Session limit for user %u has invalid daily schedule %u%u"
msgstr ""
#. TRANSLATORS: This is the formatting of English and localized name
#. of the rating e.g. "Adults Only (solo adultos)"
#: libmalcontent-ui/gs-content-rating.c:75
#, c-format
msgid "%s (%s)"
msgstr ""
#: libmalcontent-ui/gs-content-rating.c:209
msgid "General"
msgstr ""
#: libmalcontent-ui/gs-content-rating.c:218
msgid "ALL"
msgstr ""
#: libmalcontent-ui/gs-content-rating.c:222
#: libmalcontent-ui/gs-content-rating.c:485
msgid "Adults Only"
msgstr ""
#: libmalcontent-ui/gs-content-rating.c:224
#: libmalcontent-ui/gs-content-rating.c:484
msgid "Mature"
msgstr ""
#: libmalcontent-ui/gs-content-rating.c:226
#: libmalcontent-ui/gs-content-rating.c:483
msgid "Teen"
msgstr ""
#: libmalcontent-ui/gs-content-rating.c:228
#: libmalcontent-ui/gs-content-rating.c:482
msgid "Everyone 10+"
msgstr ""
#: libmalcontent-ui/gs-content-rating.c:230
#: libmalcontent-ui/gs-content-rating.c:481
msgid "Everyone"
msgstr ""
#: libmalcontent-ui/gs-content-rating.c:232
#: libmalcontent-ui/gs-content-rating.c:480
msgid "Early Childhood"
msgstr ""
#. Translators: the placeholder is a users full name
#: libmalcontent-ui/restrict-applications-dialog.c:222
#, c-format
msgid "Restrict %s from using the following installed applications."
msgstr ""
#: libmalcontent-ui/restrict-applications-dialog.ui:6
#: libmalcontent-ui/restrict-applications-dialog.ui:12
msgid "Restrict Applications"
msgstr ""
#: libmalcontent-ui/restrict-applications-selector.ui:24
msgid "No applications found to restrict."
msgstr ""
#. Translators: this is the full name for an unknown user account.
#: libmalcontent-ui/user-controls.c:242 libmalcontent-ui/user-controls.c:253
msgid "unknown"
msgstr ""
#: libmalcontent-ui/user-controls.c:338 libmalcontent-ui/user-controls.c:425
#: libmalcontent-ui/user-controls.c:711
msgid "All Ages"
msgstr ""
#. Translators: The placeholder is a users display name.
#: libmalcontent-ui/user-controls.c:514
#, c-format
msgid ""
"Prevents %s from running web browsers. Limited web content may still be "
"available in other applications."
msgstr ""
#. Translators: The placeholder is a users display name.
#: libmalcontent-ui/user-controls.c:519
#, c-format
msgid "Prevents specified applications from being used by %s."
msgstr ""
#. Translators: The placeholder is a users display name.
#: libmalcontent-ui/user-controls.c:524
#, c-format
msgid "Prevents %s from installing applications."
msgstr ""
#. Translators: The placeholder is a users display name.
#: libmalcontent-ui/user-controls.c:529
#, c-format
msgid "Applications installed by %s will not appear for other users."
msgstr ""
#: libmalcontent-ui/user-controls.ui:17
msgid "Application Usage Restrictions"
msgstr ""
#: libmalcontent-ui/user-controls.ui:68
msgid "Restrict _Web Browsers"
msgstr ""
#: libmalcontent-ui/user-controls.ui:152
msgid "_Restrict Applications"
msgstr ""
#: libmalcontent-ui/user-controls.ui:231
msgid "Software Installation Restrictions"
msgstr ""
#: libmalcontent-ui/user-controls.ui:281
msgid "Restrict Application _Installation"
msgstr ""
#: libmalcontent-ui/user-controls.ui:366
msgid "Restrict Application Installation for _Others"
msgstr ""
#: libmalcontent-ui/user-controls.ui:451
msgid "Application _Suitability"
msgstr ""
#: libmalcontent-ui/user-controls.ui:473
msgid ""
"Restricts browsing or installation of applications to applications suitable "
"for certain ages or above."
msgstr ""
#. Translators: This is the title of the main window
#. Translators: the name of the application as it appears in a software center
#: malcontent-control/application.c:105 malcontent-control/main.ui:12
#: malcontent-control/org.freedesktop.MalcontentControl.appdata.xml.in:9
#: malcontent-control/org.freedesktop.MalcontentControl.desktop.in:3
msgid "Parental Controls"
msgstr ""
#: malcontent-control/application.c:270
msgid "Copyright © 2019, 2020 Endless Mobile, Inc."
msgstr ""
#. Translators: this should be "translated" to the
#. names of people who have translated Malcontent into
#. this language, one per line.
#: malcontent-control/application.c:275
msgid "translator-credits"
msgstr ""
#. Translators: "Malcontent" is the brand name of this
#. project, so should not be translated.
#: malcontent-control/application.c:281
msgid "Malcontent Website"
msgstr ""
#: malcontent-control/application.c:299
msgid "The help contents could not be displayed"
msgstr ""
#: malcontent-control/application.c:336
msgid "Failed to load user data from the system"
msgstr ""
#: malcontent-control/application.c:338
msgid "Please make sure that the AccountsService is installed and enabled."
msgstr ""
#: malcontent-control/carousel.ui:48
msgid "Previous Page"
msgstr ""
#: malcontent-control/carousel.ui:74
msgid "Next Page"
msgstr ""
#: malcontent-control/main.ui:93
msgid "Permission Required"
msgstr ""
#: malcontent-control/main.ui:107
msgid ""
"Permission is required to view and change user parental controls settings."
msgstr ""
#: malcontent-control/main.ui:148
msgid "No Child Users Configured"
msgstr ""
#: malcontent-control/main.ui:162
msgid ""
"No child users are currently set up on the system. Create one before setting "
"up their parental controls."
msgstr ""
#: malcontent-control/main.ui:174
msgid "Create _Child User"
msgstr ""
#: malcontent-control/main.ui:202
msgid "Loading…"
msgstr ""
#: malcontent-control/main.ui:265
msgid "_Help"
msgstr "_Hulp"
#: malcontent-control/main.ui:269
msgid "_About Parental Controls"
msgstr ""
#. Translators: the brief summary of the application as it appears in a software center.
#: malcontent-control/org.freedesktop.MalcontentControl.appdata.xml.in:12
#: malcontent-control/org.freedesktop.MalcontentControl.desktop.in:4
msgid "Set parental controls and monitor usage by users"
msgstr ""
#. Translators: These are the application description paragraphs in the AppData file.
#: malcontent-control/org.freedesktop.MalcontentControl.appdata.xml.in:16
msgid ""
"Manage users parental controls restrictions, controlling how long they can "
"use the computer for, what software they can install, and what installed "
"software they can run."
msgstr ""
#: malcontent-control/org.freedesktop.MalcontentControl.appdata.xml.in:39
msgid "The GNOME Project"
msgstr ""
#: malcontent-control/org.freedesktop.MalcontentControl.appdata.xml.in:50
#: malcontent-control/org.freedesktop.MalcontentControl.appdata.xml.in:59
msgid "Minor improvements to parental controls application UI"
msgstr ""
#: malcontent-control/org.freedesktop.MalcontentControl.appdata.xml.in:51
msgid "Add a user manual"
msgstr ""
#: malcontent-control/org.freedesktop.MalcontentControl.appdata.xml.in:52
msgid "Translation updates"
msgstr ""
#: malcontent-control/org.freedesktop.MalcontentControl.appdata.xml.in:60
msgid "Translations to Ukrainian and Polish"
msgstr ""
#: malcontent-control/org.freedesktop.MalcontentControl.appdata.xml.in:67
msgid "Improve parental controls application UI and add icon"
msgstr ""
#: malcontent-control/org.freedesktop.MalcontentControl.appdata.xml.in:68
msgid "Support for indicating which accounts are parent accounts"
msgstr ""
#: malcontent-control/org.freedesktop.MalcontentControl.appdata.xml.in:75
msgid "Initial release of basic parental controls application"
msgstr ""
#: malcontent-control/org.freedesktop.MalcontentControl.appdata.xml.in:76
msgid "Support for setting app installation and run restrictions on users"
msgstr ""
#: malcontent-control/org.freedesktop.MalcontentControl.appdata.xml.in:83
msgid "Maintenance release of underlying parental controls library"
msgstr ""
#. Translators: Do NOT translate or transliterate this text (this is an icon file name)!
#: malcontent-control/org.freedesktop.MalcontentControl.desktop.in:7
msgid "org.freedesktop.MalcontentControl"
msgstr ""
#. Translators: Search terms to find this application. Do NOT translate or localise the semicolons! The list MUST also end with a semicolon!
#: malcontent-control/org.freedesktop.MalcontentControl.desktop.in:13
msgid ""
"parental controls;screen time;app restrictions;web browser restrictions;oars;"
"usage;usage limit;kid;child;"
msgstr ""
#: malcontent-control/org.freedesktop.MalcontentControl.policy.in:9
msgid "Manage parental controls"
msgstr ""
#: malcontent-control/org.freedesktop.MalcontentControl.policy.in:10
msgid "Authentication is required to read and change user parental controls"
msgstr ""
#: malcontent-control/user-selector.c:426
msgid "Your account"
msgstr "Jou rekening"
#. Always allow root, to avoid a situation where this PAM module prevents
#. * all users logging in with no way of recovery.
#: pam/pam_malcontent.c:142 pam/pam_malcontent.c:188
#, c-format
msgid "User %s has no time limits enabled"
msgstr ""
#: pam/pam_malcontent.c:151 pam/pam_malcontent.c:172
#, c-format
msgid "Error getting session limits for user %s: %s"
msgstr ""
#: pam/pam_malcontent.c:182
#, c-format
msgid "User %s has no time remaining"
msgstr ""
#: pam/pam_malcontent.c:200
#, c-format
msgid "Error setting time limit on login session: %s"
msgstr ""
#~ msgid "No cartoon violence"
#~ msgstr "Geen animasie geweld nie"
#~ msgid "Cartoon characters in unsafe situations"
#~ msgstr "Animasiekarakters in onveilige situasies"
#~ msgid "Cartoon characters in aggressive conflict"
#~ msgstr "Animasiekarakters in aggressiewe konflik"
#~ msgid "Graphic violence involving cartoon characters"
#~ msgstr "Grafiese geweld met animasiekarakters"
#~ msgid "No fantasy violence"
#~ msgstr "Geen fantasie geweld nie"
#~ msgid "Characters in unsafe situations easily distinguishable from reality"
#~ msgstr ""
#~ "Karakters in onveilige situasies wat maklik onderskei kan word van die "
#~ "werklikheid"
#~ msgid ""
#~ "Characters in aggressive conflict easily distinguishable from reality"
#~ msgstr ""
#~ "Karakters in aggressiewe konflik wat maklik onderskei kan word van die "
#~ "werklikheid"
#~ msgid "Graphic violence easily distinguishable from reality"
#~ msgstr "Grafiese geweld wat maklik onderskei kan word van die werklikheid"
#~ msgid "No realistic violence"
#~ msgstr "Geen realistiese geweld nie"
#~ msgid "Mildly realistic characters in unsafe situations"
#~ msgstr "Effens realistiese karakters in onveilige situasies"
#~ msgid "Depictions of realistic characters in aggressive conflict"
#~ msgstr "Uitbeeldings van realistiese karakters in aggressiewe konflik"
#~ msgid "Graphic violence involving realistic characters"
#~ msgstr "Grafiese geweld met realistiese karakters"
#~ msgid "No bloodshed"
#~ msgstr "Geen bloedvergieting nie"
#~ msgid "Unrealistic bloodshed"
#~ msgstr "Onrealistiese bloedvergieting"
#~ msgid "Realistic bloodshed"
#~ msgstr "Realistiese bloedvergieting"
#~ msgid "Depictions of bloodshed and the mutilation of body parts"
#~ msgstr "Uitbeeldings van bloedvergieting en die verminking van liggaamsdele"
#~ msgid "No sexual violence"
#~ msgstr "Geen seksuele geweld nie"
#~ msgid "Rape or other violent sexual behavior"
#~ msgstr "Verkragting of ander gewelddadige seksuele gedrag"
#~ msgid "No references to alcohol"
#~ msgstr "Geen verwysings na alkohol nie"
#~ msgid "References to alcoholic beverages"
#~ msgstr "Verwysings na alkoholiese drankies"
#~ msgid "Use of alcoholic beverages"
#~ msgstr "Gebruik van alkoholiese drank"
#~ msgid "No references to illicit drugs"
#~ msgstr "Geen verwysings na onwettige dwelms"
#~ msgid "References to illicit drugs"
#~ msgstr "Verwysings na onwettige dwelms"
#~ msgid "Use of illicit drugs"
#~ msgstr "Gebruik van onwettige dwelms"
#~ msgid "References to tobacco products"
#~ msgstr "Verwysings na tabakprodukte"
#~ msgid "Use of tobacco products"
#~ msgstr "Gebruik van tabaksprodukte"
#~ msgid "No nudity of any sort"
#~ msgstr "Geen naaktheid van enige aard nie"
#~ msgid "Brief artistic nudity"
#~ msgstr "Kort kuns naaktheid"
#~ msgid "Prolonged nudity"
#~ msgstr "Langdurige naaktheid"
#~ msgid "No references or depictions of sexual nature"
#~ msgstr "Geen verwysings of uitbeeldings van 'n seksuele aard nie"
#~ msgid "Provocative references or depictions"
#~ msgstr "Aanloklike verwysings of afbeeldings"
#~ msgid "Sexual references or depictions"
#~ msgstr "Seksuele verwysings of afbeeldings"
#~ msgid "Graphic sexual behavior"
#~ msgstr "Grafiese seksuele gedrag"
#~ msgid "No profanity of any kind"
#~ msgstr "Geen vloek van enige aard nie"
#~ msgid "Mild or infrequent use of profanity"
#~ msgstr "Sagte of ongereelde gebruik van vloek"
#~ msgid "Moderate use of profanity"
#~ msgstr "Matige gebruik van vloek"
#~ msgid "Strong or frequent use of profanity"
#~ msgstr "Sterk of gereelde gebruik van vloek"
#~ msgid "No inappropriate humor"
#~ msgstr "Geen onvanpaste humor nie"
#~ msgid "Slapstick humor"
#~ msgstr "Slapstick humor"
#~ msgid "Vulgar or bathroom humor"
#~ msgstr "Onvanpaste of badkamer humor"
#~ msgid "Mature or sexual humor"
#~ msgstr "Volwasse of seksuele humor"
#~ msgid "No discriminatory language of any kind"
#~ msgstr "Geen diskriminerende taal van enige aard nie"
#~ msgid "Negativity towards a specific group of people"
#~ msgstr "Negatiwiteit teenoor 'n spesifieke groep mense"
#~ msgid "Discrimination designed to cause emotional harm"
#~ msgstr "Diskriminasie bedoel om emosionele skade te veroorsaak"
#~ msgid "Explicit discrimination based on gender, sexuality, race or religion"
#~ msgstr ""
#~ "Eksplisiete diskriminasie gebaseer op geslag, seksualiteit, ras of "
#~ "godsdiens"
#~ msgid "No advertising of any kind"
#~ msgstr "Geen advertensies van enige aard nie"
#~ msgid "Product placement"
#~ msgstr "Produk plasing"
#~ msgid "Explicit references to specific brands or trademarked products"
#~ msgstr "Verwysings na spesifieke handelsmerke"
#~ msgid "Users are encouraged to purchase specific real-world items"
#~ msgstr "Gebruikers word aangemoedig om spesifieke werklike items te koop"
#~ msgid "No gambling of any kind"
#~ msgstr "Geen dobbel van enige aard nie"
#~ msgid "Gambling on random events using tokens or credits"
#~ msgstr "Dobbel op sommige geleenthede deur gebruik te maak van krediete"
#~ msgid "Gambling using “play” money"
#~ msgstr "Dobbel met \"speel\" geld"
#~ msgid "Gambling using real money"
#~ msgstr "Dobbel met regte geld"
#~ msgid "No ability to spend money"
#~ msgstr "Geen vermoë om geld te spandeer nie"
#~ msgid "Users are encouraged to donate real money"
#~ msgstr "Spelers word aangemoedig om werklike geld te skenk"
#~ msgid "Ability to spend real money in-game"
#~ msgstr "Vermoë om geld te spandeer in die spel"
#~ msgid "No way to chat with other users"
#~ msgstr "Geen manier om met ander gebruikers te klets nie"
#~ msgid "Moderated chat functionality between users"
#~ msgstr "Gemodereerde kletsfunksie tussen gebruikers"
#~ msgid "Uncontrolled chat functionality between users"
#~ msgstr "Onbeheerde kletsfunksie tussen gebruikers"
#~ msgid "No way to talk with other users"
#~ msgstr "Geen manier om met ander gebruikers te praat nie"
#~ msgid "Uncontrolled audio or video chat functionality between users"
#~ msgstr "Onbeheerde klank- of videokletsfunksies tussen gebruikers"
#~ msgid "No sharing of social network usernames or email addresses"
#~ msgstr "Geen deel van sosiale netwerk gebruikersname of e-pos adresse nie"
#~ msgid "Sharing social network usernames or email addresses"
#~ msgstr "Deel van sosiale netwerk gebruikers name of e-pos adresse"
#~ msgid "No sharing of user information with 3rd parties"
#~ msgstr "Geen deel van gebruikersinligting met 3de partye nie"
#~ msgid "Checking for the latest application version"
#~ msgstr "Kyk tans vir die nuutste weergawe van die toepassing"
#~ msgid "Sharing diagnostic data that does not let others identify the user"
#~ msgstr "Deel anonieme diagnostiese data"
#~ msgid "Sharing information that lets others identify the user"
#~ msgstr ""
#~ "Deel inligting wat ander in staat sal kan stel om die gebruiker te "
#~ "identifiseer"
#~ msgid "No sharing of physical location to other users"
#~ msgstr "Geen deel van fisiese ligging aan ander gebruikers nie"
#~ msgid "Sharing physical location to other users"
#~ msgstr "Deel fisiese ligging aan ander gebruikers"
#~ msgid "No references to homosexuality"
#~ msgstr "Geen verwysings na homoseksualiteit"
#~ msgid "Indirect references to homosexuality"
#~ msgstr "Indirekte verwysings na homoseksualiteit"
#~ msgid "Kissing between people of the same gender"
#~ msgstr "Soen tussen mense van dieselfde geslag"
#~ msgid "Graphic sexual behavior between people of the same gender"
#~ msgstr "Grafiese seksuele gedrag tussen mense van dieselfde geslag"
#~ msgid "No references to prostitution"
#~ msgstr "Geen verwysings na prostitusie nie"
#~ msgid "Indirect references to prostitution"
#~ msgstr "Indirekte verwysings na prostitusie"
#~ msgid "Graphic depictions of the act of prostitution"
#~ msgstr "Grafiese uitbeeldings van die daad van prostitusie"
#~ msgid "No references to adultery"
#~ msgstr "Geen verwysings na owerspel nie"
#~ msgid "Indirect references to adultery"
#~ msgstr "Indirekte verwysings na owerspel"
#~ msgid "Graphic depictions of the act of adultery"
#~ msgstr "Grafiese uitbeeldings van die daad van owerspel"
#~ msgid "No sexualized characters"
#~ msgstr "Geen seksuele karakters nie"
#~ msgid "Scantily clad human characters"
#~ msgstr "Skraps geklede menslike karakters"
#~ msgid "Overtly sexualized human characters"
#~ msgstr "Uitermatige seksuele menslike karakters"
#~ msgid "No references to desecration"
#~ msgstr "Geen verwysings na ontheiliging nie"
#~ msgid "Depictions of modern-day human desecration"
#~ msgstr "Uitbeeldings van moderne menslike ontheiliging"
#~ msgid "Graphic depictions of modern-day desecration"
#~ msgstr "Grafiese uitbeeldings van moderne ontheiliging"
#~ msgid "No visible dead human remains"
#~ msgstr "Geen sigbare dooie menslike oorskot"
#~ msgid "Visible dead human remains"
#~ msgstr "Sigbare dooie menslike oorskot"
#~ msgid "Dead human remains that are exposed to the elements"
#~ msgstr "Dooie menslike oorskot wat aan die elemente blootgestel is"
#~ msgid "Graphic depictions of desecration of human bodies"
#~ msgstr "Grafiese uitbeeldings van die ontheiliging van menslike liggame"
#~ msgid "No references to slavery"
#~ msgstr "Geen verwysings na slawerny nie"
#~ msgid "Depictions of modern-day slavery"
#~ msgstr "Uitbeeldings van modererende slawerny"
#~ msgid "Graphic depictions of modern-day slavery"
#~ msgstr "Grafiese uitbeeldings van modererende slawerny"

Some files were not shown because too many files have changed in this diff Show More