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 ****************************************************************************/
44 property int padding: 60
45 property int cellSize: width / 5 - padding
46 property alias messageBox: messageBox
47 property alias count: gridView.count
48 property alias currentIndex: gridView.currentIndex
51 var p = (i - i % gridViewPageItemCount) / gridViewPageItemCount
52 gridView.contentX = p * gridView.page
57 signal add(string title, string url, string iconUrl, string fallbackColor)
59 if (listModel.count === gridViewMaxBookmarks) {
61 messageBox.state = "full"
65 var element = { "title": title, "url": url, "iconUrl": iconUrl, "fallbackColor": fallbackColor }
66 listModel.append(element)
67 set(listModel.count - 1)
70 signal remove(string url, int idx)
72 var index = idx < 0 ? contains(url) : idx
76 listModel.remove(index)
77 gridView.forceLayout()
82 return listModel.get(index)
85 function contains(url) {
86 for (var idx = 0; idx < listModel.count; ++idx) {
87 if (listModel.get(idx).url === url)
98 anchors.top: navigation.bottom
105 anchors.top: homeScreen.parent.bottom
113 transitions: Transition {
114 AnchorAnimation { duration: animationDuration; easing.type : Easing.InSine }
119 Component.onCompleted: {
121 var string = engine.restoreSetting("bookmarks")
124 var list = JSON.parse(string)
125 for (var i = 0; i < list.length; ++i) {
126 listModel.append(list[i])
130 Component.onDestruction: {
132 for (var i = 0; i < listModel.count; ++i) {
133 list[i] = listModel.get(i)
137 engine.saveSetting("bookmarks", JSON.stringify(list))
146 messageBox.state = "empty"
148 messageBox.state = "disabled"
151 property real dragStart: 0
152 property real page: 4 * cellWidth
156 cellWidth: homeScreen.cellSize + homeScreen.padding
157 cellHeight: cellWidth
158 flow: GridView.FlowTopToBottom
159 boundsBehavior: Flickable.StopAtBounds
160 maximumFlickVelocity: 0
161 contentHeight: parent.height
165 enabled: homeScreen.state == "edit"
167 onClicked: homeScreen.state = "enabled"
171 var margin = (parent.width - 4 * gridView.cellWidth - homeScreen.padding) / 2
172 var padding = gridView.page - Math.round(gridView.count % gridViewPageItemCount / 2) * gridView.cellWidth
174 if (padding == gridView.page)
177 return margin + padding
181 topMargin: toolBarSize
182 leftMargin: (parent.width - 4 * gridView.cellWidth + homeScreen.padding) / 2
185 Behavior on contentX {
186 NumberAnimation { duration: 1.5 * animationDuration; easing.type : Easing.InSine}
189 function snapToPage() {
194 if (dragStart == 2 * page && contentX < 2 * page) {
198 if (dragStart == page) {
199 if (contentX < page) {
203 if (page < contentX) {
208 if (dragStart == 0 && 0 < contentX) {
215 onDraggingChanged: snapToPage()
216 delegate: Rectangle {
218 property string iconColor: "#f6f6f6"
219 width: homeScreen.cellSize
221 border.color: iconStrokeColor
227 horizontalCenter: parent.horizontalCenter
232 width: square.width - 2
264 horizontalCenter: parent.horizontalCenter
265 topMargin: width < bg.width ? 15 : 0
268 if (!icon.sourceSize.width)
270 if (icon.sourceSize.width < 100)
282 bg.state = "fallback"
291 function cleanup(string) {
292 var t = string.replace("-", " ")
293 .replace("|", " ").replace(",", " ")
294 .replace(/\s\s+/g, "\n")
298 visible: icon.width != bg.width
300 font.family: defaultFontFamily
302 color: bg.state == "fallback" ? "white" : "black"
305 bottom: parent.bottom
313 elide: Text.ElideRight
315 verticalAlignment: Text.AlignVCenter
316 horizontalAlignment: Text.AlignHCenter
322 visible: opacity != 0.0
324 color: iconOverlayColor
326 if (iconMouse.pressed) {
327 if (homeScreen.state != "edit")
331 if (homeScreen.state == "edit")
340 if (homeScreen.state == "edit") {
341 homeScreen.state = "enabled"
344 homeScreen.state = "edit"
347 if (homeScreen.state == "edit") {
348 homeScreen.state = "enabled"
355 enabled: homeScreen.state == "edit"
356 opacity: enabled ? 1.0 : 0.0
357 width: image.sourceSize.width
358 height: image.sourceSize.height - 2
360 color: iconOverlayColor
362 horizontalCenter: parent.right
363 verticalCenter: parent.top
368 if (deleteButton.pressed)
376 source: "qrc:///delete"
381 mouse.accepted = true
386 Behavior on opacity {
387 NumberAnimation { duration: animationDuration }
393 width: homeScreen.cellSize - homeScreen.padding / 2 - 10
397 bottom: parent.bottom
400 enabled: homeScreen.state == "edit"
402 onClicked: homeScreen.state = "enabled"
406 width: homeScreen.cellSize - homeScreen.padding / 2 - 10
410 bottom: parent.bottom
413 enabled: homeScreen.state == "edit"
415 onClicked: homeScreen.state = "enabled"
423 bottom: parent.bottom
424 horizontalCenter: parent.horizontalCenter
428 var c = gridView.count % gridViewPageItemCount
431 return Math.floor(gridView.count / gridViewPageItemCount) + c
433 delegate: Rectangle {
434 property bool active: index * gridView.page <= gridView.contentX && gridView.contentX < (index + 1) * gridView.page
438 color: !active ? inactivePagerColor : uiColor
439 anchors.verticalCenter: parent.verticalCenter
442 onClicked: gridView.contentX = index * gridView.page
455 visible: messageBox.state != "empty"
461 height: homeScreen.height / 2
464 source: "qrc:///error"
465 anchors.centerIn: parent
470 top: errorIcon.bottom
471 horizontalCenter: parent.horizontalCenter
473 font.family: defaultFontFamily
474 font.pixelSize: message.font.pixelSize
476 color: iconOverlayColor
484 horizontalCenter: parent.horizontalCenter
486 color: iconOverlayColor
487 font.family: defaultFontFamily
489 verticalAlignment: Text.AlignVCenter
490 horizontalAlignment: Text.AlignHCenter
494 height: 2 * toolBarSize
496 bottom: parent.bottom
506 visible: messageBox.state != "empty"
508 horizontalCenter: parent.horizontalCenter
509 bottom: parent.bottom
513 anchors.centerIn: parent
515 font.family: defaultFontFamily
519 if (messageBox.state == "tabsfull") {
520 homeScreen.state = "disabled"
521 tabView.viewState = "list"
524 if (messageBox.state == "full") {
525 messageBox.state = "disabled"
526 homeScreen.state = "edit"
547 text: qsTr("No bookmarks have been saved so far.")
563 text: qsTr("24 bookmarks is the maximum limit.\nTo bookmark a new page you must delete a bookmark first.")
578 text: qsTr("10 open tabs is the maximum limit.\nTo open a new tab you must close another one first.")