...
 
Commits (3)
{
"phabricator.uri": "https://phabricator.kde.org"
}
project(Koko)
cmake_minimum_required(VERSION 2.8.12)
find_package(ECM 0.0.9 REQUIRED NO_MODULE)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${ECM_MODULE_PATH})
find_package(Qt5 REQUIRED NO_MODULE COMPONENTS Qml Quick Widgets Test Sql Positioning)
find_package(KF5 5.5 REQUIRED COMPONENTS I18n Declarative Config DBusAddons KIO GuiAddons CoreAddons Notifications IconThemes)
find_package(Exiv2 0.21 REQUIRED)
include(FeatureSummary)
include(ECMAddTests)
include(KDEInstallDirs)
include(KDECMakeSettings)
include(KDECompilerSettings)
include(GenerateExportHeader)
include(ECMInstallIcons)
include_directories(
${CMAKE_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/src
${CMAKE_BINARY_DIR}/src
${EXIV2_INCLUDE_DIR}
)
kde_enable_exceptions()
add_subdirectory(src)
add_subdirectory(autotests)
add_subdirectory(qml)
add_subdirectory(icons)
install(FILES org.kde.koko.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR})
feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
This diff is collapsed.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This diff is collapsed.
ecm_add_test(reversegeocodertest.cpp ../src/reversegeocoder.cpp ../src/kdtree.c
TEST_NAME "reversegeocodertest"
LINK_LIBRARIES Qt5::Test
)
/*
* Copyright (C) 2015 Vishesh Handa <vhanda@kde.org>
*
* 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
*
*/
#include <QTest>
#include <QSignalSpy>
#include <QDebug>
#include <QCoreApplication>
#include <QTime>
#include "reversegeocoder.h"
class ReverseGeoCoderTest : public QObject
{
Q_OBJECT
private slots:
void testSimple();
};
using namespace Koko;
void ReverseGeoCoderTest::testSimple()
{
QCoreApplication::instance()->setApplicationName("koko");
ReverseGeoCoder coder;
QCOMPARE(coder.initialized(), false);
coder.init();
QCOMPARE(coder.initialized(), true);
double lat = 52.54877605;
double lon = -1.81627023283164;
QVariantMap data = coder.lookup(lat, lon);
QCOMPARE(data.value("country").toString(), QString("United Kingdom"));
QCOMPARE(data.value("admin1").toString(), QString("England"));
QCOMPARE(data.value("admin2").toString(), QString("City and Borough of Birmingham"));
}
QTEST_MAIN(ReverseGeoCoderTest)
#include "reversegeocodertest.moc"
# - Try to find the Exiv2 library
#
# EXIV2_MIN_VERSION - You can set this variable to the minimum version you need
# before doing FIND_PACKAGE(Exiv2). The default is 0.12.
#
# Once done this will define
#
# EXIV2_FOUND - system has libexiv2
# EXIV2_INCLUDE_DIR - the libexiv2 include directory
# EXIV2_LIBRARIES - Link these to use libexiv2
# EXIV2_DEFINITIONS - Compiler switches required for using libexiv2
#
# The minimum required version of Exiv2 can be specified using the
# standard syntax, e.g. find_package(Exiv2 0.17)
#
# For compatibility, also the variable EXIV2_MIN_VERSION can be set to the minimum version
# you need before doing FIND_PACKAGE(Exiv2). The default is 0.12.
# Copyright (c) 2010, Alexander Neundorf, <neundorf@kde.org>
# Copyright (c) 2008, Gilles Caulier, <caulier.gilles@gmail.com>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
# Support EXIV2_MIN_VERSION for compatibility:
if(NOT Exiv2_FIND_VERSION)
set(Exiv2_FIND_VERSION "${EXIV2_MIN_VERSION}")
endif(NOT Exiv2_FIND_VERSION)
# the minimum version of exiv2 we require
if(NOT Exiv2_FIND_VERSION)
set(Exiv2_FIND_VERSION "0.12")
endif(NOT Exiv2_FIND_VERSION)
if (NOT WIN32)
# use pkg-config to get the directories and then use these values
# in the FIND_PATH() and FIND_LIBRARY() calls
find_package(PkgConfig)
pkg_check_modules(PC_EXIV2 QUIET exiv2)
set(EXIV2_DEFINITIONS ${PC_EXIV2_CFLAGS_OTHER})
endif (NOT WIN32)
find_path(EXIV2_INCLUDE_DIR NAMES exiv2/exif.hpp
HINTS
${PC_EXIV2_INCLUDEDIR}
${PC_EXIV2_INCLUDE_DIRS}
)
find_library(EXIV2_LIBRARY NAMES exiv2 libexiv2
HINTS
${PC_EXIV2_LIBDIR}
${PC_EXIV2_LIBRARY_DIRS}
)
# Get the version number from exiv2/version.hpp and store it in the cache:
if(EXIV2_INCLUDE_DIR AND NOT EXIV2_VERSION)
file(READ ${EXIV2_INCLUDE_DIR}/exiv2/version.hpp EXIV2_VERSION_CONTENT)
string(REGEX MATCH "#define EXIV2_MAJOR_VERSION +\\( *([0-9]+) *\\)" _dummy "${EXIV2_VERSION_CONTENT}")
set(EXIV2_VERSION_MAJOR "${CMAKE_MATCH_1}")
string(REGEX MATCH "#define EXIV2_MINOR_VERSION +\\( *([0-9]+) *\\)" _dummy "${EXIV2_VERSION_CONTENT}")
set(EXIV2_VERSION_MINOR "${CMAKE_MATCH_1}")
string(REGEX MATCH "#define EXIV2_PATCH_VERSION +\\( *([0-9]+) *\\)" _dummy "${EXIV2_VERSION_CONTENT}")
set(EXIV2_VERSION_PATCH "${CMAKE_MATCH_1}")
set(EXIV2_VERSION "${EXIV2_VERSION_MAJOR}.${EXIV2_VERSION_MINOR}.${EXIV2_VERSION_PATCH}" CACHE STRING "Version number of Exiv2" FORCE)
endif(EXIV2_INCLUDE_DIR AND NOT EXIV2_VERSION)
set(EXIV2_LIBRARIES "${EXIV2_LIBRARY}")
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Exiv2 REQUIRED_VARS EXIV2_LIBRARY EXIV2_INCLUDE_DIR
VERSION_VAR EXIV2_VERSION)
mark_as_advanced(EXIV2_INCLUDE_DIR EXIV2_LIBRARY)
koko (0.0+git20190126-1) UNRELEASED; urgency=medium
koko (0.0+git20190126-1~36.gbp7bae88) UNRELEASED; urgency=medium
** SNAPSHOT build @7bae882c5cd6cc92349b3044bf068dcd32bfd618 **
[ Harald Sitter ]
* Initial release.
......@@ -6,4 +8,7 @@ koko (0.0+git20190126-1) UNRELEASED; urgency=medium
[ Jonah Brüchert ]
* New snapshot.
-- Jonah Brüchert <jbb@kaidan.im> Sat, 26 Jan 2019 19:06:14 +0100
[ Jenkins ]
* New upstream version 0.0+git20190126
-- Jenkins <jenkins@arm01.puri.sm> Fri, 08 Feb 2019 10:19:30 -0800
ecm_install_icons(ICONS hi128-apps-koko.png DESTINATION ${ICON_INSTALL_DIR})
<?xml version="1.0" encoding="utf-8"?>
<component type="desktop">
<id>org.kde.koko.desktop</id>
<metadata_license>CC0-1.0</metadata_license>
<project_license>GPL-2.0+</project_license>
<name>Koko</name>
<name xml:lang="ca">Koko</name>
<name xml:lang="ca-valencia">Koko</name>
<name xml:lang="cs">Koko</name>
<name xml:lang="de">Koko</name>
<name xml:lang="en-GB">Koko</name>
<name xml:lang="es">Koko</name>
<name xml:lang="fr">Koko</name>
<name xml:lang="gl">Koko</name>
<name xml:lang="id">Koko</name>
<name xml:lang="it">Koko</name>
<name xml:lang="nl">Koko</name>
<name xml:lang="pt">Koko</name>
<name xml:lang="pt-BR">Koko</name>
<name xml:lang="sk">Koko</name>
<name xml:lang="sv">Koko</name>
<name xml:lang="uk">Koko</name>
<name xml:lang="x-test">xxKokoxx</name>
<name xml:lang="zh-CN">Koko</name>
<name xml:lang="zh-TW">Koko</name>
<summary>Image Gallery</summary>
<summary xml:lang="ca">Galeria d'imatges</summary>
<summary xml:lang="ca-valencia">Galeria d'imatges</summary>
<summary xml:lang="cs">Galerie obrázků</summary>
<summary xml:lang="de">Bildergalerie</summary>
<summary xml:lang="en-GB">Image Gallery</summary>
<summary xml:lang="es">Galería de imágenes</summary>
<summary xml:lang="fr">Galerie d'images</summary>
<summary xml:lang="gl">Galería de imaxes</summary>
<summary xml:lang="id">Galeri Image</summary>
<summary xml:lang="it">Galleria di immagini</summary>
<summary xml:lang="nl">Galerij van afbeeldingen</summary>
<summary xml:lang="pt">Galeria de Imagens</summary>
<summary xml:lang="pt-BR">Galeria de imagens</summary>
<summary xml:lang="sk">Galéria obrázkov</summary>
<summary xml:lang="sv">Bildgalleri</summary>
<summary xml:lang="uk">Галерея зображень</summary>
<summary xml:lang="x-test">xxImage Galleryxx</summary>
<summary xml:lang="zh-CN">图片库</summary>
<summary xml:lang="zh-TW">圖片庫</summary>
<description>
<p>An Image gallery application</p>
<p xml:lang="ca">Una aplicació de galeria d'imatges</p>
<p xml:lang="ca-valencia">Una aplicació de galeria d'imatges</p>
<p xml:lang="cs">Aplikace s galerií obrázků</p>
<p xml:lang="de">Ein Bildergalerie-Programm</p>
<p xml:lang="en-GB">An Image gallery application</p>
<p xml:lang="es">Aplicación para galerías de imágenes</p>
<p xml:lang="fr">Une application de galerie d'images</p>
<p xml:lang="gl">Aplicativo de galería de imaxes.</p>
<p xml:lang="id">Sebuah aplikasi galeri Image</p>
<p xml:lang="it">Un'applicazione per gallerie di immagini</p>
<p xml:lang="nl">Toepassing voor afbeeldingsgalerij</p>
<p xml:lang="pt">Uma aplicação de galeria de imagens</p>
<p xml:lang="pt-BR">Aplicativo de galeria de imagens</p>
<p xml:lang="sk">Aplikácia na galériu obrázkov</p>
<p xml:lang="sv">Ett bildgalleriprogram</p>
<p xml:lang="uk">Програма для роботи з галереями зображень</p>
<p xml:lang="x-test">xxAn Image gallery applicationxx</p>
<p xml:lang="zh-CN">一个图片库应用程序</p>
<p xml:lang="zh-TW">提供圖片庫功能的應用程式</p>
</description>
<screenshots>
<screenshot type="default">
<image>https://userbase.kde.org/images.userbase/thumb/6/69/Koko-normal.png/380px-Koko-normal.png</image>
</screenshot>
</screenshots>
<url type="homepage">https://userbase.kde.org/Koko</url>
<url type="bugtracker">https://bugs.kde.org/enter_bug.cgi?format=guided&amp;product=koko</url>
<url type="help">https://docs.kde.org/?application=koko</url>
<url type="donation">https://www.kde.org/donate.php?app=org.kde.koko</url>
<project_group>KDE</project_group>
<provides>
<binary>koko</binary>
</provides>
</component>
/*
* Copyright (C) 2017 Atul Sharma <atulsharma406@gmail.com>
*
* 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) version 3, or any
* later version accepted by the membership of KDE e.V. (or its
* successor approved by the membership of KDE e.V.), which shall
* act as a proxy defined in Section 6 of version 3 of the license.
*
* 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, see <http://www.gnu.org/licenses/>.
*
*/
import QtQuick 2.7
import QtQuick.Controls 2.1 as Controls
import org.kde.kquickcontrolsaddons 2.0 as KQA
import org.kde.kirigami 2.1 as Kirigami
import org.kde.koko 0.1 as Koko
Item {
id: albumDelegate
width: gridView.cellWidth
height: gridView.cellHeight
Rectangle {
anchors {
fill: image
margins: -1
}
radius: 2
color: Kirigami.Theme.textColor
opacity: 0.2
visible: model.itemType != Koko.Types.Folder
}
KQA.QImageItem {
id: image
anchors.centerIn: parent
width: kokoConfig.iconSize
height: width
smooth: true
image: model.thumbnail
fillMode: KQA.QImageItem.PreserveAspectCrop
}
Rectangle {
anchors {
top: image.top
left: image.left
right: image.right
}
visible: textLabel.visible
width: image.width
height: textLabel.contentHeight + (Kirigami.Units.smallSpacing * 2)
color: Kirigami.Theme.viewBackgroundColor
opacity: 0.8
}
Controls.Label {
id: textLabel
anchors {
left: image.left
right: image.right
top: image.top
bottom: countRect.visible ? countRect.top : image.bottom
}
visible: model.itemType == Koko.Types.Folder || model.itemType == Koko.Types.Album
verticalAlignment: Text.AlignTop
padding: Kirigami.Units.smallSpacing
elide: Text.ElideRight
maximumLineCount: 4
wrapMode: Text.WordWrap
color: Kirigami.Theme.textColor
text: model.display
}
Rectangle {
id: countRect
anchors {
bottom: image.bottom
left: image.left
right: image.right
}
visible: model.fileCount && model.itemType == Koko.Types.Folder || model.itemType == Koko.Types.Album
height: countLabel.contentHeight + (Kirigami.Units.smallSpacing * 2)
color: Kirigami.Theme.viewBackgroundColor
opacity: 0.8
Controls.Label {
id: countLabel
padding: Kirigami.Units.smallSpacing
elide: Text.ElideRight
maximumLineCount: 4
wrapMode: Text.WordWrap
color: Kirigami.Theme.textColor
text: i18np("1 Image", "%1 Images", model.fileCount)
}
}
SelectionButton {
id: selectionButton
opacity: ( albumThumbnailMouseArea.containsMouse || iconMouseArea.containsMouse || page.state == "selecting") && !(model.itemType == Koko.Types.Folder || model.itemType == Koko.Types.Album)
Behavior on opacity {
OpacityAnimator {
duration: Kirigami.Units.longDuration
easing.type: Easing.InOutQuad
}
}
}
SelectionDelegateHighlight {
id: selectionHighlight
visible: model.selected
}
MouseArea {
id: albumThumbnailMouseArea
anchors.fill: parent
hoverEnabled: true
onPressAndHold: {
gridView.model.toggleSelected(model.index)
}
onClicked: {
if (page.state == "selecting" || (mouse.modifiers & Qt.ControlModifier ) && (model.itemType == Koko.Types.Image)) {
gridView.model.toggleSelected(model.index)
} else {
activate();
}
}
}
Keys.onPressed: {
switch (event.key) {
case Qt.Key_Enter:
case Qt.Key_Return:
case Qt.Key_Space:
activate();
break;
default:
break;
}
}
function activate( ) {
gridView.model.clearSelections()
gridView.currentIndex = model.index;
switch( model.itemType) {
case Koko.Types.Album: {
imageListModel.query = imageListModel.queryForIndex( model.sourceIndex)
sortedListModel.sourceModel = imageListModel
collectionSelected( sortedListModel, model.display)
break;
}
case Koko.Types.Folder: {
imageFolderModel.url = model.imageurl
sortedListModel.sourceModel = imageFolderModel
folderSelected( sortedListModel, model.display)
break;
}
case Koko.Types.Image: {
imageSelected( model.sourceIndex)
break;
}
default: {
console.log("Unknown")
break;
}
}
}
}
/*
* Copyright (C) 2017 Atul Sharma <atulsharma406@gmail.com>
*
* 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) version 3, or any
* later version accepted by the membership of KDE e.V. (or its
* successor approved by the membership of KDE e.V.), which shall
* act as a proxy defined in Section 6 of version 3 of the license.
*
* 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, see <http://www.gnu.org/licenses/>.
*
*/
import QtQuick 2.7
import QtQuick.Controls 2.1 as Controls
import org.kde.kirigami 2.1 as Kirigami
import org.kde.koko 0.1 as Koko
Kirigami.ScrollablePage {
id: page
property alias model: gridView.model
signal collectionSelected(QtObject selectedModel, string cover)
signal imageSelected(int currentIndex)
signal folderSelected(QtObject selectedModel, string cover)
keyboardNavigationEnabled: true
focus: true
states: [
State {
name: "browsing"
when: !model.hasSelectedImages
},
State {
name: "selecting"
when: model.hasSelectedImages && Kirigami.Settings.tabletMode
}
]
actions {
main: Kirigami.Action {
iconName: "edit-select-none"
text: i18n("Deselect All")
tooltip: i18n("De-selects all the selected images")
enabled: model.hasSelectedImages
visible: model.hasSelectedImages && Kirigami.Settings.tabletMode
onTriggered: model.clearSelections()
}
contextualActions: [
Kirigami.Action {
iconName: "edit-select-all"
text: i18n("Select All")
tooltip: i18n("Selects all the images in the current view")
enabled: model.containImages
onTriggered: model.selectAll()
},
Kirigami.Action {
iconName: "edit-select-none"
text: i18n("Deselect All")
tooltip: i18n("De-selects all the selected images")
enabled: model.hasSelectedImages
onTriggered: model.clearSelections()
},
Kirigami.Action {
iconName: "emblem-shared-symbolic"
text: i18n("Share")
tooltip: i18n("Share the selected images")
enabled: model.hasSelectedImages
onTriggered: {
shareMenu.open();
shareMenu.inputData = {
"urls": model.selectedImages(),
"mimeType": "image/"
}
}
},
Kirigami.Action {
iconName: "group-delete"
text: i18n("Delete Selection")
tooltip: i18n("Move selected items to trash")
enabled: model.hasSelectedImages
onTriggered: model.deleteSelection()
}
]
}
background: Rectangle {
color: Kirigami.Theme.viewBackgroundColor
}
Keys.onPressed: {
switch (event.key) {
case Qt.Key_Escape:
gridView.model.clearSelections()
break;
default:
break;
}
}
ShareDialog {
id: shareMenu
inputData: {
"urls": [],
"mimeType": ["image/"]
}
onFinished: {
if (error==0 && output.url !== "") {
console.assert(output.url !== undefined);
var resultUrl = output.url;
console.log("Received", resultUrl)
notificationManager.showNotification( true, resultUrl);
clipboard.content = resultUrl;
} else {
notificationManager.showNotification( false);
}
}
}
GridView {
id: gridView
//FIXME: right now if those two objects are out of this, the whole page breaks
Koko.SortModel {
id: sortedListModel
}
Koko.ImageFolderModel {
id: imageFolderModel
}
keyNavigationEnabled: true
property real widthToApproximate: (applicationWindow().wideScreen ? applicationWindow().pageStack.defaultColumnWidth : page.width) - (1||Kirigami.Settings.tabletMode ? Kirigami.Units.gridUnit : 0)
cellWidth: Math.floor(width/Math.floor(width/(kokoConfig.iconSize + Kirigami.Units.largeSpacing * 2)))
cellHeight: kokoConfig.iconSize + Kirigami.Units.largeSpacing * 2
highlightMoveDuration: 0
highlight: Item {
Rectangle {
anchors.centerIn: parent
width: Math.min(parent.width, parent.height)
height: width
color: Qt.rgba(Kirigami.Theme.highlightColor.r, Kirigami.Theme.highlightColor.g, Kirigami.Theme.highlightColor.b, 0.3)
border.color: Kirigami.Theme.highlightColor
radius: 2
}
}
delegate: AlbumDelegate {}
Controls.Label {
anchors.centerIn: parent
text: i18n("No Images Found")
visible: gridView.count == 0
font.pixelSize: Kirigami.Units.gridUnit * 1
}
}
onCollectionSelected: pageStack.push( Qt.resolvedUrl("AlbumView.qml"), { "model": selectedModel, "title": i18n(cover)})
onFolderSelected: pageStack.push( Qt.resolvedUrl("AlbumView.qml"), { "model": selectedModel, "title": i18n(cover)})
onImageSelected: {
currentImage.model = model.sourceModel
currentImage.index = currentIndex
applicationWindow().pageStack.layers.push(imageViewerComponent);
}
}
install(DIRECTORY ./ DESTINATION ${DATA_INSTALL_DIR}/koko/ui PATTERN "*.qml")
/*
* Copyright 2017 by Atul Sharma <atulsharma406@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details
*
* You should have received a copy of the GNU Library 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.
*/
import QtQuick 2.7
import QtQuick.Controls 2.1 as Controls
import org.kde.kirigami 2.0 as Kirigami
import org.kde.kquickcontrolsaddons 2.0 as KQA
import org.kde.koko 0.1 as Koko
Kirigami.Page {
id: rootEditorView
title: i18n("Edit")
leftPadding: 0
rightPadding: 0
property string imagePath
Koko.ImageDocument {
id: imageDoc
path: imagePath
}
contentItem: Flickable {
width: rootEditorView.width
height: rootEditorView.height
KQA.QImageItem {
id: editImage
width: rootEditorView.width
height: rootEditorView.height
image: imageDoc.visualImage
}
}
}
/*
* Copyright 2017 by Atul Sharma <atulsharma406@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details
*
* You should have received a copy of the GNU Library 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.
*/
import QtQuick 2.7
import org.kde.koko 0.1 as Koko
AlbumView {
property alias sourceUrl: albumViewFolderModel.url
model: Koko.SortModel {
sourceModel: Koko.ImageFolderModel {
id: albumViewFolderModel
onRowsInserted: {
if (indexForUrl(imagePathArgument[imagePathArgument.length - 1]) != -1) {
currentImage.model = this
currentImage.index = indexForUrl(imagePathArgument[imagePathArgument.length - 1])
}
}
}
}
}
This diff is collapsed.
/*
* Copyright (C) 2017 Atul Sharma <atulsharma406@gmail.com>
*
* 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) version 3, or any
* later version accepted by the membership of KDE e.V. (or its
* successor approved by the membership of KDE e.V.), which shall
* act as a proxy defined in Section 6 of version 3 of the license.
*
* 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, see <http://www.gnu.org/licenses/>.
*
*/
import QtQuick 2.1
import QtQuick.Controls 2.0 as Controls
import org.kde.kirigami 2.5 as Kirigami
import org.kde.kquickcontrolsaddons 2.0 as KQA
import org.kde.koko 0.1 as Koko
Kirigami.ApplicationWindow {
id: root
/*
* currentImage now stores the information related to the source model
*/
QtObject {
id: currentImage
property int index
property var model
property GridView view : pageStack.currentItem.flickable
onIndexChanged: {
view.currentIndex = view.model.proxyIndex(currentImage.index)
}
}
pageStack.initialPage: AlbumView {
id: albumView
model: imageFolderModel
title: i18n("Folders")
}
pageStack.layers.onDepthChanged: {
sideBar.enabled = pageStack.layers.depth < 2;
sideBar.drawerOpen = !Kirigami.Settings.isMobile && pageStack.layers.depth < 2;
}
globalDrawer: Sidebar {
id: sideBar
onFilterBy: {
pageStack.pop(albumView)
albumView.title = i18n(value)
previouslySelectedAction.checked = false
switch( value){
case "Countries": {
albumView.model = imageLocationModelCountry;
imageListModel.locationGroup = Koko.Types.Country;
break;
}
case "States": {
albumView.model = imageLocationModelState;
imageListModel.locationGroup = Koko.Types.State;
break;
}
case "Cities": {
albumView.model = imageLocationModelCity;
imageListModel.locationGroup = Koko.Types.City;
break;
}
case "Years": {
albumView.model = imageTimeModelYear;
imageListModel.timeGroup = Koko.Types.Year;
break;
}
case "Months": {
albumView.model = imageTimeModelMonth;
imageListModel.timeGroup = Koko.Types.Month;
break;
}
case "Weeks": {
albumView.model = imageTimeModelWeek;
imageListModel.timeGroup = Koko.Types.Week;
break;
}
case "Days": {
albumView.model = imageTimeModelDay;
imageListModel.timeGroup = Koko.Types.Day;
break;
}
case "Folders": {
albumView.model = imageFolderModel;
imageListModel.locationGroup = -1;
imageListModel.timeGroup = -1;
break;
}
}
}
}
Koko.SortModel {
id: imageFolderModel
sourceModel: Koko.ImageFolderModel {
/**
* imagePathArgument[0] sets the column 0 of the pageStack to reflect either a foreign path or ~/Pictures
*/
url: imagePathArgument == "" ? "" : imagePathArgument[0]
/**
* makes sure that operation only occurs after the model is populated
*/
onRowsInserted: {
for( var i = 1; i < imagePathArgument.length -1 ; i++) {
pageStack.push( Qt.resolvedUrl("ImageFolderAlbumView.qml"), { "sourceUrl": imagePathArgument[i] })
}
/**
* To set the currentImage when no folder is pushed
*/
if ( (currentImage.view.model.sourceModel == this) && (indexForUrl(imagePathArgument[imagePathArgument.length - 1]) != -1) ) {
currentImage.model = this
currentImage.index = indexForUrl(imagePathArgument[imagePathArgument.length - 1])
}
}
}
/*
* filterRole is an Item property exposed by the QSortFilterProxyModel
*/
filterRole: Koko.Roles.MimeTypeRole
}
Koko.SortModel {
id: imageTimeModelYear
sourceModel: Koko.ImageTimeModel {
group: Koko.Types.Year
}
sortRoleName: "date"
}
Koko.SortModel {
id: imageTimeModelMonth
sourceModel: Koko.ImageTimeModel {
group: Koko.Types.Month
}
sortRoleName: "date"
}
Koko.SortModel {
id: imageTimeModelWeek
sourceModel: Koko.ImageTimeModel {
group: Koko.Types.Week
}
sortRoleName: "date"
}
Koko.SortModel {
id: imageTimeModelDay
sourceModel: Koko.ImageTimeModel {
group: Koko.Types.Day
}
sortRoleName: "date"
}
Koko.SortModel {
id: imageLocationModelCountry
sourceModel: Koko.ImageLocationModel {
group: Koko.Types.Country
}
}
Koko.SortModel {
id: imageLocationModelState
sourceModel: Koko.ImageLocationModel {
group: Koko.Types.State
}
}
Koko.SortModel {
id: imageLocationModelCity
sourceModel: Koko.ImageLocationModel {
group: Koko.Types.City
}
}
Koko.ImageListModel {
id: imageListModel
}
Component {
id: imageViewerComponent
ImageViewer {
id: imageViewer
indexValue: currentImage.index
sourceModel: currentImage.model
imageWidth: root.width
imageHeight: root.height
}
}
Component.onCompleted: {
if (imagePathArgument != "") {
pageStack.layers.push(imageViewerComponent);
}
}
Koko.NotificationManager {
id: notificationManager
}
KQA.Clipboard {
id: clipboard
}
}
/*
* Copyright (C) 2017 Atul Sharma <atulsharma406@gmail.com>
*
* 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) version 3, or any
* later version accepted by the membership of KDE e.V. (or its
* successor approved by the membership of KDE e.V.), which shall
* act as a proxy defined in Section 6 of version 3 of the license.
*
* 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, see <http://www.gnu.org/licenses/>.
*
*/
import QtQuick 2.7
import org.kde.kirigami 2.1 as Kirigami
import org.kde.koko 0.1 as Koko
Kirigami.Icon {
id: iconArea
property QtObject iconMouseArea: iconMouseArea
width: Kirigami.Units.iconSizes.smallMedium
height: width
z: gridView.z + 2
anchors.top: image.top
anchors.left: image.left
MouseArea {
id: iconMouseArea
anchors.fill: parent
state: "add"
onClicked: {
if(iconMouseArea.state == "add") {
gridView.model.setSelected(model.index)
currentImage.view.currentIndex = model.index
} else {
gridView.model.toggleSelected(model.index)
currentImage.view.currentIndex = model.index
}
}
states: [
State {
name: "add"
when: !model.selected
PropertyChanges {
target: iconArea
source: "emblem-added"
}
},
State {
name: "remove"
when: model.selected
PropertyChanges {
target: iconArea
source: "emblem-remove"
}
}
]
}
}
/*
* Copyright (C) 2017 Atul Sharma <atulsharma406@gmail.com>
*
* 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) version 3, or any
* later version accepted by the membership of KDE e.V. (or its
* successor approved by the membership of KDE e.V.), which shall
* act as a proxy defined in Section 6 of version 3 of the license.
*
* 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, see <http://www.gnu.org/licenses/>.
*
*/
import QtQuick 2.7
import org.kde.kirigami 2.1 as Kirigami
Rectangle {
anchors.fill: parent
z: gridView.z + 1
color: Kirigami.Theme.highlightColor
opacity: 0.5
}
/*
* Copyright 2017 by Atul Sharma <atulsharma406@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details
*
* You should have received a copy of the GNU Library 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.
*/
import QtQuick 2.7
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.0 as Controls
import org.kde.purpose 1.0 as Purpose
import org.kde.kirigami 2.1 as Kirigami
Kirigami.OverlaySheet {
id: window
// focus: true
property alias inputData: view.inputData
property bool running: false
signal finished(var output, int error, string message)
leftPadding: 0
rightPadding: 0
Controls.BusyIndicator {
visible: window.running
anchors.fill: parent
}
header: Kirigami.Heading {
text: i18n("Share")
}
Purpose.AlternativesView {
id: view
clip: true
pluginType: "Export"
implicitWidth: Kirigami.Units.gridUnit * 20
implicitHeight: Math.max(Kirigami.Units.gridUnit * 10, initialItem.contentHeight)
delegate: Kirigami.BasicListItem {
label: model.display
icon: "arrow-right"
onClicked: view.createJob (model.index)
Keys.onReturnPressed: view.createJob (model.index)
Keys.onEnterPressed: view.createJob (model.index)
}
onRunningChanged: window.running = running
onFinished: {
window.finished(output, error, message)
}
}
}
/*
* Copyright (C) 2017 Atul Sharma <atulsharma406@gmail.com>
*
* 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) version 3, or any
* later version accepted by the membership of KDE e.V. (or its
* successor approved by the membership of KDE e.V.), which shall
* act as a proxy defined in Section 6 of version 3 of the license.
*
* 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, see <http://www.gnu.org/licenses/>.
*
*/
import QtQuick 2.1
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.1 as Controls
import org.kde.kirigami 2.5 as Kirigami
Kirigami.GlobalDrawer {
signal filterBy(string value)
property Kirigami.Action previouslySelectedAction
contentItem.implicitWidth: Kirigami.Units.gridUnit * 10
modal: Kirigami.Settings.isMobile
collapsible: true
collapsed: true
actions: [
Kirigami.Action {
text: i18n("Locations")
iconName: "tag-places"
expandible: true
Kirigami.Action {
id: countryAction
text: i18n("By Country")
checkable: true
onTriggered: {
filterBy("Countries")
previouslySelectedAction = countryAction
}
}
Kirigami.Action {
id: stateAction
text: i18n("By State")
checkable: true
onTriggered: {
filterBy("States")
previouslySelectedAction = stateAction
}
}
Kirigami.Action {
id: cityAction
text: i18n("By City")
checkable: true
onTriggered: {
filterBy("Cities")
previouslySelectedAction = cityAction
}
}
},
Kirigami.Action {
text: i18n("Time")
expandible: true
iconName: "view-calendar"
Kirigami.Action {
id: yearAction
text: i18n("By Year")
checkable: true
onTriggered: {
filterBy("Years")
previouslySelectedAction = yearAction
}
}
Kirigami.Action {
id: monthAction
text: i18n("By month")
checkable: true
onTriggered: {
filterBy("Months")
previouslySelectedAction = monthAction
}
}
Kirigami.Action {
id: weekAction
text: i18n("By Week")
checkable: true
onTriggered: {
filterBy("Weeks")
previouslySelectedAction = weekAction
}
}
Kirigami.Action {
id: "dayAction"
text: i18n("By Day")
checkable: true
onTriggered: {
filterBy("Days")
previouslySelectedAction = dayAction
}
}
},
Kirigami.Action {
text: i18n("Path")
expandible: true
iconName: "folder-symbolic"
Kirigami.Action {
id: folderAction
text: i18n("By Folder")
checkable: true
onTriggered: {
filterBy("Folders")
previouslySelectedAction = folderAction
}
}
}
]
Controls.Label {
text: i18n("Thumbnails size:")
}
Controls.Slider {
Layout.fillWidth: true
from: Kirigami.Units.iconSizes.medium
to: Kirigami.Units.iconSizes.enormous
value: kokoConfig.iconSize
onMoved: kokoConfig.iconSize = value;
}
Component.onCompleted: {
folderAction.checked = true
previouslySelectedAction = folderAction
}
}
/*
* Copyright (C) 2017 Atul Sharma <atulsharma406@gmail.com>
* Copyright (C) 2017 Marco Martin <mart@kde.org>
*
* 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) version 3, or any
* later version accepted by the membership of KDE e.V. (or its
* successor approved by the membership of KDE e.V.), which shall
* act as a proxy defined in Section 6 of version 3 of the license.
*
* 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, see <http://www.gnu.org/licenses/>.
*
*/
import QtQuick 2.1
import org.kde.kirigami 2.0 as Kirigami
Main {
}
/*
* Copyright (C) 2017 Atul Sharma <atulsharma406@gmail.com>
* Copyright (C) 2017 Marco Martin <mart@kde.org>
*
* 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) version 3, or any
* later version accepted by the membership of KDE e.V. (or its
* successor approved by the membership of KDE e.V.), which shall
* act as a proxy defined in Section 6 of version 3 of the license.
*
* 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, see <http://www.gnu.org/licenses/>.
*
*/
import QtQuick 2.1
import org.kde.kirigami 2.0 as Kirigami
Main {
contextDrawer: Kirigami.ContextDrawer {}
}
#
# Common Library
#
set(LIB_SRCS
imagestorage.cpp
filesystemimagefetcher.cpp
${LIB_SRCS}
)
add_library(kokocommon SHARED ${LIB_SRCS})
target_link_libraries(kokocommon
Qt5::Core
Qt5::Positioning
Qt5::Sql
KF5::CoreAddons
)
generate_export_header(kokocommon BASE_NAME KOKO EXPORT_FILE_NAME koko_export.h)
install(TARGETS kokocommon EXPORT KokoLibraryTargets ${INSTALL_TARGETS_DEFAULT_ARGS})
#
# Application
#
add_executable(koko
main.cpp
reversegeocoder.cpp
filesystemtracker.cpp
processor.cpp
committimer.cpp
imageprocessorrunnable.cpp
exiv2extractor.cpp
kokoconfig.cpp
kdtree.c
)
target_link_libraries(koko
Qt5::Quick
Qt5::Widgets
Qt5::Qml
Qt5::Positioning
KF5::ConfigCore
KF5::DBusAddons
KF5::I18n
KF5::CoreAddons
KF5::KIOCore
KF5::IconThemes
kokocommon
${EXIV2_LIBRARIES}
)
install(TARGETS koko ${INSTALL_TARGETS_DEFAULT_ARGS})
#
# QML Plugin
#
set (qml_plugin_SRCS
qmlplugins.cpp
tagmodel.cpp
imagelocationmodel.cpp
imagetimemodel.cpp
imagefoldermodel.cpp
sortmodel.cpp
allimagesmodel.cpp
imagelistmodel.cpp
notificationmanager.cpp
types.cpp
roles.cpp
imagedocument.cpp
)
add_library (kokoqmlplugin SHARED ${qml_plugin_SRCS})
target_link_libraries (kokoqmlplugin
Qt5::Qml
KF5::KIOCore
KF5::KIOFileWidgets
KF5::KIOWidgets
KF5::GuiAddons
KF5::I18n
KF5::Notifications
kokocommon
)
install (TARGETS kokoqmlplugin DESTINATION ${QML_INSTALL_DIR}/org/kde/koko)
install (FILES qmldir DESTINATION ${QML_INSTALL_DIR}/org/kde/koko)
install (FILES org.kde.koko.desktop DESTINATION ${XDG_APPS_INSTALL_DIR})
#
# Reverse GeoLookup Data
#
# Packagers can download the file and put it in the tarball
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/cities1000.zip)
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/cities1000.zip DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
endif()
if (NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/cities1000.zip)
file (DOWNLOAD "http://download.geonames.org/export/dump/cities1000.zip"
${CMAKE_CURRENT_BINARY_DIR}/cities1000.zip
SHOW_PROGRESS
)
endif()
execute_process(
COMMAND ${CMAKE_COMMAND} -E tar -xzf ${CMAKE_CURRENT_BINARY_DIR}/cities1000.zip
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/admin1CodesASCII.txt)
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/admin1CodesASCII.txt DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
endif()
if (NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/admin1CodesASCII.txt)
file (DOWNLOAD "http://download.geonames.org/export/dump/admin1CodesASCII.txt"
${CMAKE_CURRENT_BINARY_DIR}/admin1CodesASCII.txt
SHOW_PROGRESS
)
endif()
file(RENAME ${CMAKE_CURRENT_BINARY_DIR}/admin1CodesASCII.txt ${CMAKE_CURRENT_BINARY_DIR}/admin1Codes.txt)
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/admin2Codes.txt)
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/admin2Codes.txt DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
endif()
if (NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/admin2Codes.txt)
file (DOWNLOAD "http://download.geonames.org/export/dump/admin2Codes.txt"
${CMAKE_CURRENT_BINARY_DIR}/admin2Codes.txt
SHOW_PROGRESS
)
endif()
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/cities1000.txt DESTINATION ${DATA_INSTALL_DIR}/koko)
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/admin1Codes.txt DESTINATION ${DATA_INSTALL_DIR}/koko)
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/admin2Codes.txt DESTINATION ${DATA_INSTALL_DIR}/koko)
install (FILES countries.csv DESTINATION ${DATA_INSTALL_DIR}/koko)
install (FILES koko.notifyrc DESTINATION ${KNOTIFYRC_INSTALL_DIR})
/*
* Copyright (C) 2015 Vishesh Handa <vhanda@kde.org>
*
* 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
*
*/
#include "allimagesmodel.h"
#include "imagestorage.h"
AllImagesModel::AllImagesModel(QObject* parent)
: QAbstractListModel(parent)
{
m_images = ImageStorage::instance()->allImages();
connect(ImageStorage::instance(), SIGNAL(storageModified()), this, SLOT(slotPopulate()));
}
void AllImagesModel::slotPopulate()
{
beginResetModel();
m_images = ImageStorage::instance()->allImages();
endResetModel();
}
QHash<int, QByteArray> AllImagesModel::roleNames() const
{
auto hash = QAbstractItemModel::roleNames();
hash.insert(FilePathRole, "filePath");
hash.insert(FilePathRole, "modelData");
return hash;
}
QVariant AllImagesModel::data(const QModelIndex& index, int role) const
{
if (!index.isValid()) {
return QVariant();
}
QString filePath = m_images.at(index.row());
switch (role) {
case Qt::DisplayRole: {
QString fileName = filePath.mid(filePath.lastIndexOf('/') + 1);
return fileName;
}
case FilePathRole:
return filePath;
}
return QVariant();
}
int AllImagesModel::rowCount(const QModelIndex& parent) const
{
if (parent.isValid()) {
return 0;
}
return m_images.size();