Commit 57c78a51 authored by Linus Jahn's avatar Linus Jahn

Add minimal functionality for adding a contact

parent 7af9604e
......@@ -29,7 +29,7 @@ include(KDECompilerSettings NO_POLICY_SCOPE)
################# Find dependencies #################
find_package(Qt5 ${QT_MIN_VERSION} REQUIRED NO_MODULE COMPONENTS Core Quick Test Gui Svg QuickControls2)
find_package(KF5Kirigami2 ${KF5_MIN_VERSION})
find_package(KF5 COMPONENTS Kirigami2 Contacts ${KF5_MIN_VERSION})
################# Enable C++11 features for clang and gcc #################
......
set(plasma-phonebook_SRCS
main.cpp
phonebook.cpp
)
qt5_add_resources(RESOURCES resources.qrc)
add_executable(plasma-phonebook ${plasma-phonebook_SRCS} ${RESOURCES})
target_link_libraries(plasma-phonebook Qt5::Core Qt5::Qml Qt5::Quick Qt5::Svg)
target_link_libraries(plasma-phonebook
Qt5::Core Qt5::Qml Qt5::Quick Qt5::Svg
KF5::Contacts
)
install(TARGETS plasma-phonebook ${KF5_INSTALL_TARGETS_DEFAULT_ARGS})
/*
* Copyright 2015 Martin Klapetek <mklapetek@kde.org>
* Copyright 2019 Linus Jahn <lnj@kaidan.im>
*
* 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) 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 14 of version 3 of the license.
*
* 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, see <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.0
import QtQuick.Controls 1.3
import QtQuick.Layouts 1.1
import org.kde.kirigami 2.0 as Kirigami
import org.kde.people 1.0 as KPeople
import org.kde.kquickcontrolsaddons 2.0 as ExtraComponents
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.plasma.extras 2.0 as PlasmaExtras
import org.kde.plasma.private.kpeoplehelper 1.0
Kirigami.Page {
title: i18n("Contacts")
actions {
main: Kirigami.Action {
icon.name: "contact-new"
onTriggered: {
phonebook.addContact("Dummy User", "+00123396640")
}
}
}
PlasmaComponents.Label {
anchors.centerIn: parent
text: i18n("No contacts")
visible: contactsModel.count == 0
}
ColumnLayout {
anchors.fill: parent
//visible: contactsModel.count > 0
PlasmaComponents.ToolBar {
Layout.fillWidth: true
tools: RowLayout {
id: toolBarLayout
PlasmaComponents.TextField {
id: searchField
clearButtonShown: true
Layout.fillWidth: true
Layout.fillHeight: true
placeholderText: i18n("Search...")
}
}
}
PlasmaExtras.ScrollArea {
Layout.fillWidth: true
Layout.fillHeight: true
verticalScrollBarPolicy: Qt.ScrollBarAlwaysOff
contentItem: ListView {
id: contactsList
property bool delegateSelected: false
property string numberToCall
section.property: "display"
section.criteria: ViewSection.FirstCharacter
clip: true
model:PlasmaCore.SortFilterModel {
sourceModel: KPeople.PersonsSortFilterProxyModel {
sourceModel: KPeopleHelper {
id: contactsModel
}
requiredProperties: "phoneNumber"
}
sortRole: "display"
filterRole: "display"
filterRegExp: ".*"+searchField.text+".*"
sortOrder: Qt.AscendingOrder
}
// PlasmaCore.SortFilterModel {
// sortRole: "display"
// sourceModel:
// }
boundsBehavior: Flickable.StopAtBounds
highlight: PlasmaComponents.Highlight {
hover: contactsList.focus
}
highlightMoveDuration: 0
delegate: PlasmaComponents.ListItem {
height: units.gridUnit * 6
enabled: true
clip: true
opacity: contactsList.delegateSelected && contactsList.currentIndex != index ? 0.4 : 1
onClicked: {
if (contactsList.delegateSelected) {
contactsList.currentIndex = -1;
contactsList.delegateSelected = false;
contactsList.numberToCall = "";
} else {
contactsList.currentIndex = index;
contactsList.delegateSelected = true;
contactsList.numberToCall = model.phoneNumber;
}
contactsList.toggleOverlayButtons(contactsList.delegateSelected);
}
RowLayout {
id: mainLayout
anchors.fill: parent
ExtraComponents.QPixmapItem {
id: avatarLabel
Layout.maximumWidth: parent.height
Layout.minimumWidth: parent.height
Layout.fillHeight: true
pixmap: model.decoration
fillMode: ExtraComponents.QPixmapItem.PreserveAspectFit
smooth: true
}
ColumnLayout {
Layout.fillHeight: true
Layout.fillWidth: true
Label {
id: nickLabel
Layout.fillWidth: true
text: model.display
elide: Text.ElideRight
}
Label {
id: dataLabel
Layout.fillWidth: true
text: model.phoneNumber
elide: Text.ElideRight
visible: dataLabel.text != nickLabel.text
}
}
}
}
function toggleOverlayButtons(show) {
if (show) {
settingsRect.parent = contactsList.currentItem
settingsRect.visible = true;
callRect.parent = contactsList.currentItem
callRect.visible = true;
} else {
settingsRect.visible = false;
callRect.visible = false;
}
}
Rectangle {
id: settingsRect
height: units.gridUnit * 6
width: height + units.gridUnit * 2
radius: height
z: 100
visible: false
color: "lightblue"
anchors {
left: parent.left
leftMargin: -width/2
verticalCenter: parent.verticalCenter
}
PlasmaCore.IconItem {
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: parent.height / 4
source: "configure-shortcuts"
}
}
Rectangle {
id: callRect
height: settingsRect.height
width: settingsRect.width
radius: height
z: 100
visible: false
color: "lightgreen"
anchors {
right: parent.right
rightMargin: -width/2
verticalCenter: parent.verticalCenter
}
PlasmaCore.IconItem {
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: parent.height / 4
source: "call-start"
}
MouseArea {
anchors.fill: parent
//TODO: needs the proper number
onClicked: call(contactsList.numberToCall)
}
}
// CustomSectionScroller {
// listView: contactsList
// }
}
}
}
}
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Components project.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
** the names of its contributors may be used to endorse or promote
** products derived from this software without specific prior written
** permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.1
import QtQuick.Layouts 1.1
//import "private/SectionScroller.js" as Sections
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.extras 2.0 as PlasmaExtras
import org.kde.plasma.components 2.0 as PlasmaComponents
/**
* Similar to a ScrollBar or a ScrollDecorator.
*
* It's interactive and works on ListViews that have section.property set, so
* its contents are categorized.
*
* An indicator will say to what category the user scrolled to. Useful for
* things like address books or things sorted by date. Don't use with models
* too big (thousands of items) because it implies loading all the items to
* memory, as well loses precision.
*
* @inherit QtQuick.Item
*/
Item {
id: root
/**
* The listview the sectionScroller will operate on. This component doesn't
* work with Flickable or GridView.
*/
property ListView listView
onListViewChanged: {
if (listView && listView.model)
internal.initDirtyObserver();
}
Connections {
target: listView
onModelChanged: {
if (listView && listView.model) {
internal.initDirtyObserver()
}
}
}
implicitWidth: scrollBar.implicitWidth
Behavior on opacity {
NumberAnimation {
duration: units.longDuration
}
}
anchors {
right: listView.right
top: listView.top
bottom: listView.bottom
}
PlasmaComponents.RangeModel {
id: range
minimumValue: 0
maximumValue: Math.max(0, listView.contentHeight - listView.height)
stepSize: 0
//inverted: true
positionAtMinimum: root.width*2
positionAtMaximum: root.height - root.width*2
value: listView.contentY
onPositionChanged: {
var section = Sections.closestSection(position/listView.height);
if (section) {
if (listView.section.criteria == ViewSection.FirstCharacter) {
sectionLabel.text = section[0];
} else {
sectionLabel.text = section;
}
}
}
}
PlasmaComponents.ScrollBar {
id: scrollBar
flickableItem: listView
anchors.fill: parent
interactive: true
}
PlasmaCore.FrameSvgItem {
id: tooltip
imagePath: "widgets/background"
width: units.gridUnit * 5 + margins.left + margins.right
height: sectionLabel.height + /*subtitle.height +*/ margins.top + margins.bottom
ColumnLayout {
anchors.centerIn: parent
PlasmaExtras.Title {
id: sectionLabel
Layout.fillWidth: true
Layout.fillHeight: true
horizontalAlignment: Text.AlignHCenter
}
// PlasmaComponents.Label {
// id: subtitle
// Layout.fillWidth: true
// horizontalAlignment: Text.AlignHCenter
// visible: text.length > 0
// text: "Thursday, 7th"
// }
}
y: 0
x: -listView.width/2 - width/2
opacity: sectionLabel.text && scrollBar.pressed ? 1 : 0
Behavior on opacity {
NumberAnimation {
duration: units.longDuration
}
}
}
Timer {
id: dirtyTimer
interval: 250
onTriggered: {
Sections.initSectionData(listView);
internal.modelDirty = false;
tooltip.visible = Sections._sections.length > 1
}
}
QtObject {
id: internal
property bool modelDirty: false
function initDirtyObserver() {
Sections.initSectionData(listView);
tooltip.visible = Sections._sections.length > 1
function dirtyObserver() {
if (!internal.modelDirty) {
internal.modelDirty = true;
dirtyTimer.running = true;
}
}
if (listView.model.countChanged)
listView.model.countChanged.connect(dirtyObserver);
if (listView.model.itemsChanged)
listView.model.itemsChanged.connect(dirtyObserver);
if (listView.model.itemsInserted)
listView.model.itemsInserted.connect(dirtyObserver);
if (listView.model.itemsMoved)
listView.model.itemsMoved.connect(dirtyObserver);
if (listView.model.itemsRemoved)
listView.model.itemsRemoved.connect(dirtyObserver);
}
}
Accessible.role: Accessible.ScrollBar
}
/*
* Copyright 2019 Linus Jahn <lnj@kaidan.im>
*
* 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) 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 14 of version 3 of the license.
*
* 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, see <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.1
import org.kde.kirigami 2.4 as Kirigami
import QtQuick.Controls 2.0 as Controls
......@@ -7,24 +27,7 @@ Kirigami.ApplicationWindow {
title: "Hello"
pageStack.initialPage: mainPageComponent
Component {
id: mainPageComponent
Kirigami.Page {
title: "Hello"
pageStack.initialPage: contactsPage
Rectangle {
color: "black"
anchors.fill: parent
Controls.Label {
text: qsTr("Hello Kirigami")
color: "white"
anchors.centerIn: parent
}
}
}
}
Component { id: contactsPage; ContactsPage {}}
}
/*
* Copyright 2019 Linus Jahn <lnj@kaidan.im>
*
* 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) 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 14 of version 3 of the license.
*
* 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, see <http://www.gnu.org/licenses/>.
*/
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QtQml>
#include <QUrl>
#include "phonebook.h"
Q_DECL_EXPORT int main(int argc, char *argv[])
{
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
......@@ -11,8 +33,12 @@ Q_DECL_EXPORT int main(int argc, char *argv[])
QCoreApplication::setOrganizationDomain("kde.org");
QCoreApplication::setApplicationName("plasma-phonebook");
// back-end
PhoneBook phonebook;
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("phonebook", &phonebook);
engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
if (engine.rootObjects().isEmpty()) {
......
/*
* Copyright 2019 Linus Jahn <lnj@kaidan.im>
*
* 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) 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 14 of version 3 of the license.
*
* 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, see <http://www.gnu.org/licenses/>.
*/
#include "phonebook.h"
#include <QDebug>
#include <QFile>
#include <QStandardPaths>
#include <QCryptographicHash>
#include <KContacts/Addressee>
#include <KContacts/VCardConverter>
using namespace KContacts;
PhoneBook::PhoneBook(QObject *parent) : QObject(parent)
{
}
void PhoneBook::addContact(QString name, QString tel)
{
// addresses
Addressee adr;
adr.setName(name);
PhoneNumber::List phoneNums;
PhoneNumber phoneNum;
phoneNum.setNumber(tel);
phoneNum.setType(PhoneNumber::Cell);
phoneNums.append(phoneNum);
adr.setPhoneNumbers(phoneNums);
// create vcard
VCardConverter converter;
QByteArray vcard = converter.createVCard(adr);
qDebug() << vcard;
// save vcard
QString path = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)
+ ("/kpeoplevcard");
QCryptographicHash hash(QCryptographicHash::Sha1);
hash.addData(name.toUtf8());
QFile file(path + "/" + hash.result().toHex() + ".vcf");
if (!file.open(QFile::WriteOnly)) {
qWarning() << "Couldn't save vCard: Couldn't open file for writing.";
return;
}
file.write(vcard.data(), vcard.length());
file.close();
}
/*
* Copyright 2019 Linus Jahn <lnj@kaidan.im>
*
* 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) 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 14 of version 3 of the license.
*
* 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, see <http://www.gnu.org/licenses/>.
*/
#ifndef PHONEBOOK_H
#define PHONEBOOK_H
#include <QObject>
class PhoneBook : public QObject
{
Q_OBJECT
public:
explicit PhoneBook(QObject *parent = nullptr);
signals:
public slots:
void addContact(QString name, QString tel);
};
#endif // PHONEBOOK_H
<RCC>
<qresource prefix="/">
<file alias="main.qml">contents/ui/main.qml</file>
<file alias="ContactsPage.qml">contents/ui/ContactsPage.qml</file>
<file alias="CustomSectionScroller.qml">contents/ui/CustomSectionScroller.qml</file>
</qresource>
</RCC>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment