diff --git a/plugins/welcomepage/qml/Develop.qml b/plugins/welcomepage/qml/Develop.qml index 9c485ec7a4..75fb438331 100644 --- a/plugins/welcomepage/qml/Develop.qml +++ b/plugins/welcomepage/qml/Develop.qml @@ -1,140 +1,144 @@ /* KDevelop * * Copyright 2011 Aleix Pol * Copyright 2016 Kevin Funk * * 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. */ -import QtQuick 2.0 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 1.3 +import QtQuick 2.7 +import QtQuick.Layouts 1.6 +import QtQuick.Controls 2.0 +import QtQuick.Controls 1.4 as QQC1 import org.kdevelop.welcomepage 4.3 StandardPage { id: root ColumnLayout { anchors.fill: parent anchors.margins: 20 spacing: 20 RowLayout { id: toolBar width: parent.width - Button { + QQC1.Button { iconName: "project-development-new-template" text: i18n("New Project") onClicked: kdev.retrieveMenuAction("project/project_new").trigger() } - Button { + QQC1.Button { text: i18n("Open Project") iconName: "project-open" onClicked: ICore.projectController.openProject() } - Button { + QQC1.Button { text: i18n("Fetch Project") iconName: "edit-download" onClicked: kdev.retrieveMenuAction("project/project_fetch").trigger() } - Button { + QQC1.Button { iconName: "document-open-recent" text: i18n("Recent Projects") onClicked: kdev.showMenu("project/project_open_recent") } Item { Layout.fillWidth: true } } Label { id: greetingLabel visible: !sessionsView.visible Layout.fillWidth: true Layout.fillHeight: true text: i18n("

Welcome to KDevelop!

\n" + "

You can start working on a project by opening an existing or creating a new one via the above buttons.

\n" + "

If you need help, please check out the User Manual.

") + (Qt.platform.os === "windows" ? i18n("
\n" + "

Note for Windows users

\n" + "

Note that KDevelop does NOT ship a C/C++ compiler on Windows!

\n" + "

You need to install either GCC via MinGW or install a recent version of the Microsoft Visual Studio IDE and make sure the environment is setup correctly before starting KDevelop.

\n" + "

If you need further assistance, please check out the KDevelop under Windows instructions.

") : "") wrapMode: Text.WordWrap onLinkActivated: Qt.openUrlExternally(link) MouseArea { anchors.fill: parent acceptedButtons: Qt.NoButton // we don't want to eat clicks on the Text cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor } } - ScrollView { + ListView { + id: sessionsView + Layout.fillHeight: true Layout.fillWidth: true visible: sessionsView.count > 1 // we always have at least one active session + clip: true + boundsBehavior: Flickable.StopAtBounds - ListView { - id: sessionsView + ScrollBar.vertical: ScrollBar { id: verticalScrollBar } - anchors.fill: parent + delegate: Label { + readonly property string projectNamesString: projectNames.join(", ").replace(/.kdev4/g, "") - delegate: MouseArea { - width: sessionsView.width - height: visible ? 30 : 0 + width: sessionsView.width - verticalScrollBar.width + height: visible ? 30 : 0 - visible: projects.length > 0 - hoverEnabled: true - cursorShape: Qt.PointingHandCursor + visible: projects.length > 0 - onClicked: sessionsModel.loadSession(uuid) + text: display == "" ? projectNamesString : i18n("%1: %2", display, projectNamesString) + elide: Text.ElideRight + opacity: labelMouseArea.containsMouse ? 0.8 : 1 - Label { - readonly property string projectNamesString: projectNames.join(", ").replace(/.kdev4/g, "") + MouseArea { + id: labelMouseArea - width: parent.width + anchors.fill: parent - text: display == "" ? projectNamesString : i18n("%1: %2", display, projectNamesString) - elide: Text.ElideRight - opacity: parent.containsMouse ? 0.8 : 1 - } + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + + onClicked: sessionsModel.loadSession(uuid) } + } - model: SessionsModel { id: sessionsModel } + model: SessionsModel { id: sessionsModel } - header: Heading { - text: i18n("Sessions") - } + header: Heading { + text: i18n("Sessions") } } } } diff --git a/plugins/welcomepage/qml/Heading.qml b/plugins/welcomepage/qml/Heading.qml index 96e5caaa5a..b7f4a7b477 100644 --- a/plugins/welcomepage/qml/Heading.qml +++ b/plugins/welcomepage/qml/Heading.qml @@ -1,29 +1,31 @@ /* KDevelop * * Copyright 2011 Aleix Pol * * 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. */ -import QtQuick.Controls 1.3 +import QtQuick 2.7 + +import QtQuick.Controls 2.0 Label { Label { id: instance } property real scale: 1.4 height: 2 * implicitHeight font.pointSize: instance.font.pointSize * scale } diff --git a/plugins/welcomepage/qml/Link.qml b/plugins/welcomepage/qml/Link.qml index 7730116602..37b67b29cf 100644 --- a/plugins/welcomepage/qml/Link.qml +++ b/plugins/welcomepage/qml/Link.qml @@ -1,44 +1,43 @@ /* KDevelop * * Copyright 2011 Aleix Pol * * 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. */ -import QtQuick 2.1 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 1.3 -import QtQuick.Controls.Styles 1.3 +import QtQuick 2.7 +import QtQuick.Layouts 1.6 +import QtQuick.Controls 2.0 Label { id: root signal clicked elide: Text.ElideRight opacity: mouseArea.containsMouse ? 0.8 : 1 MouseArea { id: mouseArea anchors.fill: parent cursorShape: Qt.PointingHandCursor hoverEnabled: true onClicked: root.clicked() } } diff --git a/plugins/welcomepage/qml/NewsFeed.qml b/plugins/welcomepage/qml/NewsFeed.qml index 8bd8a8c574..33f867dc81 100644 --- a/plugins/welcomepage/qml/NewsFeed.qml +++ b/plugins/welcomepage/qml/NewsFeed.qml @@ -1,209 +1,209 @@ /* KDevelop * * Copyright 2017 Kevin Funk * * 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. */ -import QtQuick 2.0 -import QtQuick.Controls 1.3 -import QtQuick.Layouts 1.2 -import QtQuick.XmlListModel 2.0 +import QtQuick 2.7 +import QtQuick.Controls 2.0 +import QtQuick.Layouts 1.6 +import QtQuick.XmlListModel 2.7 import org.kde.kdevplatform 1.0 import "storage.js" as Storage ListView { id: root /// Update interval (in seconds) in which the news feed is polled property int updateInterval: 24 * 3600 // 24 hours /// Max age (in seconds) of a news entry so it is shown in the list view /// TODO: Implement me property int maxNewsAge: 3 * 30 * 24 * 3600 // 3 months /// Max age (in seconds) of a news entry so it is considered 'new' (thus highlighted with a bold font) property int maxHighlightedNewsAge: 30 * 24 * 3600 // a month readonly property string feedUrl: "https://www.kdevelop.org/news/feed" readonly property bool loading: newsFeedSyncModel.status === XmlListModel.Loading /// Returns a date parsed from the pubDate function parsePubDate(pubDate) { // We need to modify the pubDate read from the RSS feed // so the JavaScript Date object can interpret it var d = pubDate.replace(',','').split(' '); if (d.length != 6) return new Date(NaN); return new Date([d[0], d[2], d[1], d[3], d[4], 'GMT' + d[5]].join(' ')); } // there's no builtin function for this(?) function toMap(obj) { var map = {}; for (var k in obj) { map[k] = obj[k]; } return map; } function secondsSince(date) { return !isNaN(date) ? Math.floor(Number((new Date() - date)) / 1000) : -1; } function loadEntriesFromCache() { newsFeedOfflineModel.clear() var data = Storage.get("newsFeedOfflineModelData", null); if (data) { var newsEntries = JSON.parse(data); for (var i = 0; i < newsEntries.length; ++i) { newsFeedOfflineModel.append(newsEntries[i]); } } root.positionViewAtBeginning() } function saveEntriesToCache() { var newsEntries = []; for (var i = 0; i < newsFeedSyncModel.count; ++i) { var entry = newsFeedSyncModel.get(i); newsEntries.push(toMap(entry)); } Storage.set("newsFeedOfflineModelData", JSON.stringify(newsEntries)); } spacing: 10 // Note: this model is *not* attached to the view -- it's merely used for fetching the RSS feed XmlListModel { id: newsFeedSyncModel property bool active: false source: active ? feedUrl : "" query: "/rss/channel/item" XmlRole { name: "title"; query: "title/string()" } XmlRole { name: "link"; query: "link/string()" } XmlRole { name: "pubDate"; query: "pubDate/string()" } onStatusChanged: { if (status == XmlListModel.Ready) { saveEntriesToCache(); loadEntriesFromCache(); Storage.set("newsFeedLastFetchDate", JSON.stringify(new Date())); } else if (status == XmlListModel.Error) { Logger.log("Failed to fetch news feed: " + errorString()); } } } ListModel { id: newsFeedOfflineModel } // detach from model while fetching feed to make space for the busy indicator model: root.loading ? undefined : newsFeedOfflineModel delegate: Column { id: feedDelegate readonly property date publicationDate: parsePubDate(model.pubDate) /// in seconds readonly property int age: secondsSince(publicationDate) readonly property bool isNew: age != -1 && age < maxHighlightedNewsAge readonly property string dateString: isNaN(publicationDate.getDate()) ? model.pubDate : publicationDate.toLocaleDateString() x: 10 width: parent.width - 2*x Link { width: parent.width text: model.title onClicked: Qt.openUrlExternally(model.link) } Label { width: parent.width font.bold: isNew font.pointSize: 8 color: disabledPalette.windowText text: isNew ? i18nc("Example: Tue, 03 Jan 2017 10:00:00 (new)", "%1 (new)", dateString) : dateString } } Label { id: placeHolderLabel x: 10 width: parent.width - 2*x text: root.loading ? i18n("Fetching feeds...") : i18n("No recent news") color: disabledPalette.windowText visible: root.count === 0 Behavior on opacity { NumberAnimation {} } } SystemPalette { id: disabledPalette colorGroup: SystemPalette.Disabled } function fetchFeed() { Logger.log("Fetching news feed") newsFeedSyncModel.active = true newsFeedSyncModel.reload() } Timer { id: delayedStartupTimer // delay loading a bit so it has no effect on the KDevelop startup interval: 3000 running: true onTriggered: { // only fetch feed if items are out of date var lastFetchDate = new Date(JSON.parse(Storage.get("newsFeedLastFetchDate", null))); Logger.log("Last fetch of news feed was on " + lastFetchDate); if (secondsSince(lastFetchDate) > root.updateInterval) { root.fetchFeed(); } } } Timer { id: reloadFeedTimer interval: root.updateInterval * 1000 running: true repeat: true onTriggered: root.fetchFeed() } Component.onCompleted: loadEntriesFromCache() } diff --git a/plugins/welcomepage/qml/StandardBackground.qml b/plugins/welcomepage/qml/StandardBackground.qml index d397426929..30eebca17c 100644 --- a/plugins/welcomepage/qml/StandardBackground.qml +++ b/plugins/welcomepage/qml/StandardBackground.qml @@ -1,59 +1,59 @@ /* KDevelop * * Copyright 2011 Aleix Pol * * 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. */ -import QtQuick 2.0 -import QtQuick.Controls 1.3 -import QtQuick.Layouts 1.2 +import QtQuick 2.7 +import QtQuick.Controls 2.0 +import QtQuick.Layouts 1.6 GroupBox { id: bg property alias tools: toolsLoader.sourceComponent property string pageIcon readonly property real marginLeft: toolsLoader.x + toolsLoader.width property real margins: 5 Loader { id: toolsLoader width: bg.width/4 anchors { top: parent.top topMargin: 15 left: parent.left leftMargin: 15 bottom: parent.bottom bottomMargin: 15 } } Image { id: theIcon anchors { bottom: parent.bottom left: parent.left margins: bg.margins } source: bg.pageIcon !== "" ? "image://icon/" + bg.pageIcon : "" width: 64 height: width } } diff --git a/plugins/welcomepage/qml/StandardPage.qml b/plugins/welcomepage/qml/StandardPage.qml index 1347f83c0d..d13460a102 100644 --- a/plugins/welcomepage/qml/StandardPage.qml +++ b/plugins/welcomepage/qml/StandardPage.qml @@ -1,32 +1,31 @@ /* KDevelop * * Copyright 2011 Aleix Pol * * 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. */ -import QtQuick 2.1 -import QtQuick.Controls 1.3 -import QtQuick.Layouts 1.2 +import QtQuick 2.7 +import QtQuick.Layouts 1.6 Rectangle { id: root SystemPalette { id: pal } color: pal.base border.color: pal.mid } diff --git a/plugins/welcomepage/qml/area_code.qml b/plugins/welcomepage/qml/area_code.qml index b1788780b1..81a56a8c76 100644 --- a/plugins/welcomepage/qml/area_code.qml +++ b/plugins/welcomepage/qml/area_code.qml @@ -1,125 +1,125 @@ /* KDevelop * * Copyright 2011 Aleix Pol * * 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. */ -import QtQuick 2.0 -import QtQuick.Controls 1.3 -import QtQuick.Layouts 1.2 +import QtQuick 2.7 +import QtQuick.Controls 2.0 +import QtQuick.Layouts 1.6 StandardBackground { id: root state: "develop" tools: ColumnLayout { spacing: 10 Row { Layout.fillWidth: true spacing: 5 Image { id: icon horizontalAlignment: Image.AlignHCenter verticalAlignment: Image.AlignVCenter source: "image://icon/kdevelop" smooth: true fillMode: Image.PreserveAspectFit } Label { verticalAlignment: Text.AlignVCenter height: icon.height text: "KDevelop" font { pointSize: 20 weight: Font.ExtraLight } } } Item { Layout.fillWidth: true Layout.fillHeight: true } Heading { id: newsHeading Layout.fillWidth: true text: i18n("News") } NewsFeed { id: newsFeed readonly property int maxEntries: 3 Layout.fillWidth: true Layout.minimumHeight: !loading ? (Math.min(count, maxEntries) * 40) : 40 Behavior on Layout.minimumHeight { PropertyAnimation {} } } // add some spacing Item { Layout.fillWidth: true height: 10 } Heading { text: i18n("Need Help?") } Column { spacing: 10 Link { x: 10 text: i18n("KDevelop.org") onClicked: { Qt.openUrlExternally("https://kdevelop.org") } } Link { x: 10 text: i18n("Learn about KDevelop") onClicked: Qt.openUrlExternally("https://userbase.kde.org/KDevelop") } Link { x: 10 text: i18n("Join KDevelop's team!") onClicked: Qt.openUrlExternally("https://kdevelop.org/contribute-kdevelop") } Link { x: 10 text: i18n("Handbook") onClicked: kdev.retrieveMenuAction("help/help_contents").trigger() } } } Develop { anchors { fill: parent leftMargin: root.marginLeft+root.margins } } } diff --git a/plugins/welcomepage/qml/main.qml b/plugins/welcomepage/qml/main.qml index 752d99ee8e..774e68bd8d 100644 --- a/plugins/welcomepage/qml/main.qml +++ b/plugins/welcomepage/qml/main.qml @@ -1,48 +1,48 @@ /* KDevelop * * Copyright 2011 Aleix Pol * * 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. */ -import QtQuick 2.2 +import QtQuick 2.7 Rectangle { id: root SystemPalette { id: myPalette } color: myPalette.window Loader { id: loader anchors.fill: parent // non-code areas are broken ATM, so just go blank for them // old: source: "qrc:///qml/area_"+area+".qml" source: area === "code" ? "qrc:///qml/area_code.qml" : "" asynchronous: true opacity: status === Loader.Ready Behavior on opacity { PropertyAnimation {} } } }