~uriboni/webbrowser-app/tab-context-menu

« back to all changes in this revision

Viewing changes to src/app/webbrowser/NewTabViewWide.qml

  • Committer: CI Train Bot
  • Author(s): Arthur Mello, Ugo Riboni, Olivier Tilloy
  • Date: 2015-08-12 19:53:13 UTC
  • mfrom: (1126.1.5 wide-views-newtab-history)
  • Revision ID: ci-train-bot@canonical.com-20150812195313-u5v7kzrj8hfiacsj
Wide screen versions of the history view and new tab view, per design specification.
This adds a build dependency on qml-module-qt-labs-settings (for unit tests). Fixes: #1351157, #1481647

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2015 Canonical Ltd.
 
3
 *
 
4
 * This file is part of webbrowser-app.
 
5
 *
 
6
 * webbrowser-app is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation; version 3.
 
9
 *
 
10
 * webbrowser-app is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
17
 */
 
18
 
 
19
import QtQuick 2.4
 
20
import Qt.labs.settings 1.0
 
21
import Ubuntu.Components 1.3
 
22
import webbrowserapp.private 0.1
 
23
import ".."
 
24
 
 
25
FocusScope {
 
26
    id: newTabViewWide
 
27
 
 
28
    property QtObject bookmarksModel
 
29
    property alias historyModel: historyTimeframeModel.sourceModel
 
30
    property QtObject settingsObject
 
31
    property alias selectedIndex: sections.selectedIndex
 
32
    readonly property bool inBookmarksView: newTabViewWide.selectedIndex === 1
 
33
 
 
34
    signal bookmarkClicked(url url)
 
35
    signal bookmarkRemoved(url url)
 
36
    signal historyEntryClicked(url url)
 
37
    signal releasingKeyboardFocus()
 
38
 
 
39
    Keys.onTabPressed: selectedIndex = (selectedIndex + 1) % 2
 
40
    Keys.onBacktabPressed: selectedIndex = Math.abs((selectedIndex - 1) % 2)
 
41
    onActiveFocusChanged: {
 
42
        if (activeFocus) {
 
43
            if (inBookmarksView) {
 
44
                if (sections.lastFocusedBookmarksColumn === bookmarksList &&
 
45
                    bookmarksList.model.length === 0) {
 
46
                    sections.lastFocusedBookmarksColumn = folders
 
47
                }
 
48
                sections.lastFocusedBookmarksColumn.focus = true
 
49
            }
 
50
            else topSitesList.focus = true
 
51
        }
 
52
    }
 
53
 
 
54
    LimitProxyModel {
 
55
        id: topSitesModel
 
56
        limit: 10
 
57
        sourceModel: TopSitesModel {
 
58
            sourceModel: HistoryTimeframeModel {
 
59
                id: historyTimeframeModel
 
60
            }
 
61
        }
 
62
    }
 
63
 
 
64
    Rectangle {
 
65
        anchors.fill: parent
 
66
        color: "#fbfbfb"
 
67
    }
 
68
 
 
69
    ListView {
 
70
        id: folders
 
71
        objectName: "foldersList"
 
72
        visible: inBookmarksView
 
73
 
 
74
        Keys.onRightPressed: if (bookmarksList.model.length > 0) bookmarksList.focus = true
 
75
        Keys.onDownPressed: currentIndex = Math.min(currentIndex + 1, folders.model.count - 1)
 
76
        Keys.onUpPressed: {
 
77
            if (currentIndex > 0) currentIndex = Math.max(currentIndex - 1, 0)
 
78
            else newTabViewWide.releasingKeyboardFocus()
 
79
        }
 
80
        onActiveFocusChanged: {
 
81
            if (activeFocus) {
 
82
                sections.lastFocusedBookmarksColumn = folders
 
83
                if (currentIndex < 0) currentIndex = 0
 
84
            }
 
85
        }
 
86
 
 
87
        anchors {
 
88
            top: sectionsGroup.bottom
 
89
            bottom: parent.bottom
 
90
            left: parent.left
 
91
            topMargin: units.gu(2)
 
92
        }
 
93
        width: units.gu(25)
 
94
 
 
95
        currentIndex: 0
 
96
        model: BookmarksFolderListModel {
 
97
            sourceModel: newTabViewWide.bookmarksModel
 
98
        }
 
99
 
 
100
        delegate: ListItem {
 
101
            id: folderItem
 
102
            objectName: "folderItem"
 
103
            property var model: entries
 
104
            property bool isActiveFolder: ListView.isCurrentItem
 
105
            property bool isCurrentItem: ListView.isCurrentItem
 
106
            property bool isAllBookmarksFolder: folder.length === 0
 
107
            property alias name: dropArea.folderName
 
108
            divider.visible: false
 
109
 
 
110
            property bool isCurrentDropTarget: dropArea.containsDrag && dropArea.drag.source.folder !== folder
 
111
            color: isCurrentDropTarget ? "green" :
 
112
                   ((folders.activeFocus && isActiveFolder) ? Qt.rgba(0, 0, 0, 0.05) : "transparent")
 
113
 
 
114
            Label {
 
115
                anchors.verticalCenter: parent.verticalCenter
 
116
                anchors.left: parent.left
 
117
                anchors.right: parent.right
 
118
                anchors.leftMargin: units.gu(2)
 
119
                anchors.rightMargin: units.gu(2)
 
120
 
 
121
                fontSize: isAllBookmarksFolder ? "medium" : "small"
 
122
                text: isAllBookmarksFolder ? i18n.tr("All Bookmarks") : folderItem.name
 
123
                color: isActiveFolder ? UbuntuColors.orange : UbuntuColors.darkGrey
 
124
            }
 
125
 
 
126
            onClicked: folders.currentIndex = index
 
127
 
 
128
            DropArea {
 
129
                id: dropArea
 
130
                anchors.fill: parent
 
131
                property string folderName: folder
 
132
            }
 
133
        }
 
134
    }
 
135
 
 
136
    Scrollbar {
 
137
        flickableItem: folders
 
138
    }
 
139
 
 
140
    ListView {
 
141
        id: bookmarksList
 
142
        objectName: "bookmarksList"
 
143
        anchors {
 
144
            top: sectionsGroup.bottom
 
145
            bottom: parent.bottom
 
146
            left: folders.right
 
147
            right: parent.right
 
148
            topMargin: units.gu(2)
 
149
        }
 
150
        visible: inBookmarksView
 
151
        onActiveFocusChanged: if (activeFocus) sections.lastFocusedBookmarksColumn = bookmarksList
 
152
 
 
153
        // Build a temporary model for the bookmarks list that includes, when
 
154
        // necessary, the homepage bookmark as a fixed first item in the list
 
155
        model: {
 
156
            if (!folders.currentItem) return null
 
157
 
 
158
            var items = []
 
159
            if (folders.currentItem.isAllBookmarksFolder) items.push({
 
160
                title: i18n.tr("Homepage"),
 
161
                url: newTabViewWide.settingsObject.homepage,
 
162
                folder: ""
 
163
            })
 
164
 
 
165
            if (!folders.currentItem.model) return null
 
166
            for (var i = 0; i < folders.currentItem.model.count; i++) {
 
167
                items.push(folders.currentItem.model.get(i))
 
168
            }
 
169
            return items
 
170
        }
 
171
 
 
172
        currentIndex: 0
 
173
 
 
174
        delegate: DraggableUrlDelegateWide {
 
175
            objectName: "bookmarkItem"
 
176
            clip: true
 
177
 
 
178
            title: modelData.title
 
179
            icon: modelData.icon ? modelData.icon : ""
 
180
            url: modelData.url
 
181
 
 
182
            property string folder: modelData.folder
 
183
            property bool isHomeBookmark: folder === "" && index === 0
 
184
 
 
185
            removable: !isHomeBookmark
 
186
            draggable: !isHomeBookmark && contentItem.x === 0
 
187
            highlighted: bookmarksList.activeFocus && ListView.isCurrentItem
 
188
 
 
189
            onClicked: newTabViewWide.bookmarkClicked(url)
 
190
            onRemoved: newTabViewWide.bookmarkRemoved(url)
 
191
 
 
192
            // Larger margin to prevent interference from Scrollbar hovering area
 
193
            gripMargin: units.gu(4)
 
194
            onDragStarted: {
 
195
                // Remove interactivity to prevent the list from scrolling
 
196
                // while dragging near its margins. This ensures we can correctly
 
197
                // return the item to its original position on a failed drop.
 
198
                bookmarksList.interactive = false
 
199
 
 
200
                // Relinquish focus as the presses and releases that compose the
 
201
                // drag will move the keyboard focus in a location unexpected
 
202
                // for the user. This way it will go back to the address bar and
 
203
                // the user can predictably resume keyboard interaction from there.
 
204
                newTabViewWide.releasingKeyboardFocus()
 
205
            }
 
206
            onDragEnded: {
 
207
                bookmarksList.interactive = true
 
208
 
 
209
                if (dragAndDrop.target && dragAndDrop.target.folderName !== folder) {
 
210
                    bookmarksModel.update(modelData.url, modelData.title,
 
211
                                          dragAndDrop.target.folderName)
 
212
                    dragAndDrop.success = true
 
213
                }
 
214
            }
 
215
        }
 
216
 
 
217
        Keys.onReturnPressed: newTabViewWide.bookmarkClicked(currentItem.url)
 
218
        Keys.onDeletePressed: {
 
219
            if (currentItem.removable) {
 
220
                newTabViewWide.bookmarkRemoved(currentItem.url)
 
221
                if (bookmarksList.model.length === 0) folders.focus = true
 
222
            }
 
223
        }
 
224
        Keys.onLeftPressed: folders.focus = true
 
225
        Keys.onDownPressed: currentIndex = Math.min(currentIndex + 1, model.length - 1)
 
226
        Keys.onUpPressed: {
 
227
            if (currentIndex > 0) currentIndex = Math.max(currentIndex - 1, 0)
 
228
            else newTabViewWide.releasingKeyboardFocus()
 
229
        }
 
230
    }
 
231
 
 
232
    Scrollbar {
 
233
        flickableItem: bookmarksList
 
234
    }
 
235
 
 
236
    ListView {
 
237
        id: topSitesList
 
238
        objectName: "topSitesList"
 
239
        anchors {
 
240
            top: sectionsGroup.bottom
 
241
            bottom: parent.bottom
 
242
            left: parent.left
 
243
            right: parent.right
 
244
            topMargin: units.gu(2)
 
245
        }
 
246
 
 
247
        visible: !inBookmarksView
 
248
        currentIndex: 0
 
249
 
 
250
        model: topSitesModel
 
251
        delegate: UrlDelegateWide {
 
252
            objectName: "topSiteItem"
 
253
            clip: true
 
254
 
 
255
            title: model.title
 
256
            icon: model.icon
 
257
            url: model.url
 
258
            highlighted: topSitesList.activeFocus && ListView.isCurrentItem
 
259
 
 
260
            onClicked: newTabViewWide.historyEntryClicked(url)
 
261
            onRemoved: newTabViewWide.historyModel.hide(url)
 
262
        }
 
263
 
 
264
        Keys.onReturnPressed: newTabViewWide.historyEntryClicked(currentItem.url)
 
265
        Keys.onDeletePressed: {
 
266
            newTabViewWide.historyModel.hide(currentItem.url)
 
267
            if (topSitesList.model.count === 0) newTabViewWide.releasingKeyboardFocus()
 
268
        }
 
269
        Keys.onDownPressed: currentIndex = Math.min(currentIndex + 1, model.count - 1)
 
270
        Keys.onUpPressed: {
 
271
            if (currentIndex > 0) currentIndex = Math.max(currentIndex - 1, 0)
 
272
            else newTabViewWide.releasingKeyboardFocus()
 
273
        }
 
274
    }
 
275
 
 
276
    Scrollbar {
 
277
        flickableItem: topSitesList
 
278
    }
 
279
 
 
280
    Rectangle {
 
281
        id: sectionsGroup
 
282
        anchors {
 
283
            top: parent.top
 
284
            left: parent.left
 
285
            right: parent.right
 
286
        }
 
287
        color: "#dedede"
 
288
        height: sections.height
 
289
 
 
290
        Sections {
 
291
            id: sections
 
292
            objectName: "sections"
 
293
            anchors {
 
294
                left: parent.left
 
295
                top: parent.top
 
296
                leftMargin: units.gu(1)
 
297
            }
 
298
 
 
299
            selectedIndex: settingsObject.newTabDefaultSection
 
300
            onSelectedIndexChanged: {
 
301
                settingsObject.newTabDefaultSection = selectedIndex
 
302
                if (selectedIndex === 0) topSitesList.focus = true
 
303
                else {
 
304
                    if (lastFocusedBookmarksColumn) lastFocusedBookmarksColumn.focus = true
 
305
                    else folders.focus = true
 
306
                }
 
307
 
 
308
            }
 
309
            property var lastFocusedBookmarksColumn: folders
 
310
 
 
311
            actions: [
 
312
                Action { text: i18n.tr("Top sites") },
 
313
                Action { text: i18n.tr("Bookmarks") }
 
314
            ]
 
315
        }
 
316
    }
 
317
}