1 /****************************************************************************
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
6 ** This file is part of the QtBrowser project.
8 ** $QT_BEGIN_LICENSE:GPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
17 ** GNU General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU
19 ** General Public License version 2 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.GPLv2 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU General Public License version 2 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 3.0 as published by the Free Software
28 ** Foundation and appearing in the file LICENSE.GPL included in the
29 ** packaging of this file. Please review the following information to
30 ** ensure the GNU General Public License version 3.0 requirements will be
31 ** met: http://www.gnu.org/copyleft/gpl.html.
36 ****************************************************************************/
45 property int padding: 60
46 property int cellSize: width / 5 - padding
47 property alias messageBox: messageBox
48 property alias count: gridView.count
49 property alias currentIndex: gridView.currentIndex
52 var p = (i - i % gridViewPageItemCount) / gridViewPageItemCount
53 gridView.contentX = p * gridView.page
58 if (state == "enabled" && !gridView.count)
59 messageBox.state = "empty"
62 signal add(string title, string url, string iconUrl, string fallbackColor)
64 if (listModel.count === gridViewMaxBookmarks) {
66 messageBox.state = "full"
68 homeScreen.forceActiveFocus()
71 var icon = url.indexOf("qt.io") != -1 ? "assets/icons/qt.png" : iconUrl
72 var element = { "title": title, "url": url, "iconUrl": icon, "fallbackColor": fallbackColor }
73 listModel.append(element)
74 set(listModel.count - 1)
77 signal remove(string url, int idx)
79 var index = idx < 0 ? contains(url) : idx
83 listModel.remove(index)
84 gridView.forceLayout()
87 messageBox.state = "empty"
91 return listModel.get(index)
94 function contains(url) {
95 for (var idx = 0; idx < listModel.count; ++idx) {
96 if (listModel.get(idx).url === url)
107 anchors.top: navigation.bottom
114 anchors.top: homeScreen.parent.bottom
122 transitions: Transition {
123 AnchorAnimation { duration: animationDuration; easing.type : Easing.InSine }
128 property string defaultBookmarks: "[{\"fallbackColor\":\"#46a2da\",\"iconUrl\":\"assets/icons/qt.png\",\"title\":\"Qt - Home\",\"url\":\"http://www.qt.io/\"},{\"fallbackColor\":\"#18394c\",\"iconUrl\":\"http://www.topgear.com/sites/all/themes/custom/tg/apple-touch-icon-144x144.png\",\"title\":\"Top Gear\",\"url\":\"http://www.topgear.com/\"},{\"fallbackColor\":\"#46a2da\",\"iconUrl\":\"https://duckduckgo.com/assets/icons/meta/DDG-iOS-icon_152x152.png\",\"title\":\"DuckDuckGo\",\"url\":\"https://duckduckgo.com/\"},{\"fallbackColor\":\"#ff8c0a\",\"iconUrl\":\"http://www.blogsmithmedia.com/www.engadget.com/media/favicon-160x160.png\",\"title\":\"Engadget | Technology News, Advice and Features\",\"url\":\"http://www.engadget.com/\"},{\"fallbackColor\":\"#ff8c0a\",\"iconUrl\":\"https://www.openstreetmap.org/assets/favicon-194x194-32cdac24b02b88e09f0639bb92c760b2.png\",\"title\":\"OpenStreetMap\",\"url\":\"https://www.openstreetmap.org/\"},{\"fallbackColor\":\"#5caa15\",\"iconUrl\":\"http://www.redditstatic.com/icon.png\",\"title\":\"reddit: the front page of the internet\",\"url\":\"http://www.reddit.com/\"}]"
130 Component.onCompleted: {
132 var string = WebEngine.restoreSetting("bookmarks", defaultBookmarks)
135 var list = JSON.parse(string)
136 for (var i = 0; i < list.length; ++i) {
137 listModel.append(list[i])
141 Component.onDestruction: {
143 for (var i = 0; i < listModel.count; ++i) {
144 list[i] = listModel.get(i)
146 WebEngine.saveSetting("bookmarks", JSON.stringify(list))
155 messageBox.state = "empty"
157 messageBox.state = "disabled"
160 property real dragStart: 0
161 property real page: 4 * cellWidth
165 cellWidth: homeScreen.cellSize + homeScreen.padding
166 cellHeight: cellWidth
167 flow: GridView.FlowTopToBottom
168 boundsBehavior: Flickable.StopAtBounds
169 maximumFlickVelocity: 0
170 contentHeight: parent.height
174 enabled: homeScreen.state == "edit"
176 onClicked: homeScreen.state = "enabled"
180 var margin = (parent.width - 4 * gridView.cellWidth - homeScreen.padding) / 2
181 var padding = gridView.page - Math.round(gridView.count % gridViewPageItemCount / 2) * gridView.cellWidth
183 if (padding == gridView.page)
186 return margin + padding
190 topMargin: toolBarSize
191 leftMargin: (parent.width - 4 * gridView.cellWidth + homeScreen.padding) / 2
194 Behavior on contentX {
195 NumberAnimation { duration: 1.5 * animationDuration; easing.type : Easing.InSine}
198 function snapToPage() {
203 if (dragStart == 2 * page && contentX < 2 * page) {
207 if (dragStart == page) {
208 if (contentX < page) {
212 if (page < contentX) {
217 if (dragStart == 0 && 0 < contentX) {
224 onDraggingChanged: snapToPage()
225 delegate: Rectangle {
227 property string iconColor: "#f6f6f6"
228 width: homeScreen.cellSize
230 border.color: iconStrokeColor
236 horizontalCenter: parent.horizontalCenter
241 width: square.width - 2
273 horizontalCenter: parent.horizontalCenter
274 topMargin: width < bg.width ? 15 : 0
277 if (!icon.sourceSize.width)
279 if (icon.sourceSize.width < 100)
291 bg.state = "fallback"
300 function cleanup(string) {
301 var t = string.replace("-", " ")
302 .replace("|", " ").replace(",", " ")
303 .replace(/\s\s+/g, "\n")
307 visible: icon.width != bg.width
309 font.family: defaultFontFamily
311 color: bg.state == "fallback" ? "white" : "black"
314 bottom: parent.bottom
322 elide: Text.ElideRight
324 verticalAlignment: Text.AlignVCenter
325 horizontalAlignment: Text.AlignHCenter
331 visible: opacity != 0.0
333 color: iconOverlayColor
335 if (iconMouse.pressed) {
336 if (homeScreen.state != "edit")
340 if (homeScreen.state == "edit")
349 if (homeScreen.state == "edit") {
350 homeScreen.state = "enabled"
353 homeScreen.state = "edit"
356 if (homeScreen.state == "edit") {
357 homeScreen.state = "enabled"
364 enabled: homeScreen.state == "edit"
365 opacity: enabled ? 1.0 : 0.0
366 width: image.sourceSize.width
367 height: image.sourceSize.height - 2
369 color: iconOverlayColor
371 horizontalCenter: parent.right
372 verticalCenter: parent.top
377 if (deleteButton.pressed)
385 source: "assets/icons/Btn_Delete.png"
390 mouse.accepted = true
395 Behavior on opacity {
396 NumberAnimation { duration: animationDuration }
402 width: homeScreen.cellSize - homeScreen.padding / 2 - 10
406 bottom: parent.bottom
409 enabled: homeScreen.state == "edit"
411 onClicked: homeScreen.state = "enabled"
415 width: homeScreen.cellSize - homeScreen.padding / 2 - 10
419 bottom: parent.bottom
422 enabled: homeScreen.state == "edit"
424 onClicked: homeScreen.state = "enabled"
432 bottom: parent.bottom
433 horizontalCenter: parent.horizontalCenter
437 var c = gridView.count % gridViewPageItemCount
440 return Math.floor(gridView.count / gridViewPageItemCount) + c
442 delegate: Rectangle {
443 property bool active: index * gridView.page <= gridView.contentX && gridView.contentX < (index + 1) * gridView.page
447 color: !active ? inactivePagerColor : uiColor
448 anchors.verticalCenter: parent.verticalCenter
451 onClicked: gridView.contentX = index * gridView.page
464 visible: messageBox.state != "empty"
465 height: childrenRect.height
474 source: "assets/icons/Error_Icon.png"
476 horizontalCenter: parent.horizontalCenter
483 top: errorIcon.bottom
484 horizontalCenter: parent.horizontalCenter
486 font.family: defaultFontFamily
487 font.pixelSize: message.font.pixelSize
489 color: iconOverlayColor
497 horizontalCenter: parent.horizontalCenter
499 color: iconOverlayColor
500 font.family: defaultFontFamily
502 verticalAlignment: Text.AlignTop
503 horizontalAlignment: Text.AlignHCenter
510 bottom: parent.bottom
520 visible: messageBox.state != "empty"
522 horizontalCenter: parent.horizontalCenter
523 bottom: parent.bottom
526 if (messageBox.state == "tabsfull") {
527 homeScreen.state = "disabled"
528 tabView.viewState = "list"
531 if (messageBox.state == "full") {
532 messageBox.state = "disabled"
533 homeScreen.state = "edit"
554 text: qsTr("No bookmarks have been saved so far.")
558 color: emptyBackgroundColor
563 anchors.topMargin: 30
574 text: qsTr("24 bookmarks is the maximum limit.\nTo bookmark a new page you must delete a bookmark first.")
589 text: qsTr("10 open tabs is the maximum limit.\nTo open a new tab you must close another one first.")