Merge lp:~artmello/webbrowser-app/webbrowser-app-multi_window into lp:webbrowser-app
- webbrowser-app-multi_window
- Merge into trunk
Status: | Rejected |
---|---|
Rejected by: | Olivier Tilloy |
Proposed branch: | lp:~artmello/webbrowser-app/webbrowser-app-multi_window |
Merge into: | lp:webbrowser-app |
Diff against target: |
772 lines (+440/-91) 13 files modified
src/app/BrowserView.qml (+4/-0) src/app/actions/NewPrivateWindow.qml (+28/-0) src/app/actions/NewWindow.qml (+28/-0) src/app/actions/OpenLinkInNewPrivateWindow.qml (+23/-0) src/app/actions/OpenLinkInNewWindow.qml (+23/-0) src/app/webbrowser/BookmarksModel.qml (+0/-24) src/app/webbrowser/Browser.qml (+118/-33) src/app/webbrowser/CMakeLists.txt (+1/-0) src/app/webbrowser/HistoryModel.qml (+0/-24) src/app/webbrowser/webbrowser-app.cpp (+40/-9) src/app/webbrowser/webbrowser-app.qml (+9/-1) src/app/webbrowser/windows-model.cpp (+106/-0) src/app/webbrowser/windows-model.h (+60/-0) |
To merge this branch: | bzr merge lp:~artmello/webbrowser-app/webbrowser-app-multi_window |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Olivier Tilloy | Disapprove | ||
system-apps-ci-bot | continuous-integration | Needs Fixing | |
PS Jenkins bot | continuous-integration | Needs Fixing | |
Review via email: mp+272681@code.launchpad.net |
Commit message
Description of the change
*DO NOT MERGE/REVIEW*
Initial prototype of Multi Window using QML approach
PS Jenkins bot (ps-jenkins) wrote : | # |
- 1207. By Arthur Mello
-
Undo changes on the models
- 1208. By Arthur Mello
-
Make HistoryModel and BookmarksModel to be singletons
- 1209. By Arthur Mello
-
Open new window with startuo url wn nothing is set
- 1210. By Arthur Mello
-
Add support to open new windows in private mode
- 1211. By Arthur Mello
-
Add initial support to storing all opened windows
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1211
http://
Executed test runs:
UNSTABLE: http://
FAILURE: http://
SUCCESS: http://
deb: http://
FAILURE: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 1212. By Arthur Mello
-
Expand session storage support
- 1213. By Arthur Mello
-
Merge with trunk
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1213
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
FAILURE: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 1214. By Arthur Mello
-
Make sure that only a single instance of webbrowser is running
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1214
http://
Executed test runs:
UNSTABLE: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
system-apps-ci-bot (system-apps-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:1214
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unmerged revisions
- 1214. By Arthur Mello
-
Make sure that only a single instance of webbrowser is running
- 1213. By Arthur Mello
-
Merge with trunk
- 1212. By Arthur Mello
-
Expand session storage support
- 1211. By Arthur Mello
-
Add initial support to storing all opened windows
- 1210. By Arthur Mello
-
Add support to open new windows in private mode
- 1209. By Arthur Mello
-
Open new window with startuo url wn nothing is set
- 1208. By Arthur Mello
-
Make HistoryModel and BookmarksModel to be singletons
- 1207. By Arthur Mello
-
Undo changes on the models
- 1206. By Arthur Mello
-
Initial prototype of Multi Window using QML approach
Preview Diff
1 | === modified file 'src/app/BrowserView.qml' |
2 | --- src/app/BrowserView.qml 2015-08-10 15:22:00 +0000 |
3 | +++ src/app/BrowserView.qml 2015-10-07 00:51:42 +0000 |
4 | @@ -37,11 +37,15 @@ |
5 | |
6 | focus: true |
7 | |
8 | + /* FIXME: Error when opening new windows |
9 | + * Reason: An object is already exported for the interface org.gtk.Actions at /com/canonical/unity/actions |
10 | + |
11 | property QtObject actionManager: UnityActions.ActionManager { |
12 | id: unityActionManager |
13 | onQuit: Qt.quit() |
14 | } |
15 | property alias actions: unityActionManager.actions |
16 | + */ |
17 | |
18 | default property alias contents: contentsItem.data |
19 | property alias automaticOrientation: contentsItem.automaticOrientation |
20 | |
21 | === added file 'src/app/actions/NewPrivateWindow.qml' |
22 | --- src/app/actions/NewPrivateWindow.qml 1970-01-01 00:00:00 +0000 |
23 | +++ src/app/actions/NewPrivateWindow.qml 2015-10-07 00:51:42 +0000 |
24 | @@ -0,0 +1,28 @@ |
25 | +/* |
26 | + * Copyright 2015 Canonical Ltd. |
27 | + * |
28 | + * This file is part of webbrowser-app. |
29 | + * |
30 | + * webbrowser-app is free software; you can redistribute it and/or modify |
31 | + * it under the terms of the GNU General Public License as published by |
32 | + * the Free Software Foundation; version 3. |
33 | + * |
34 | + * webbrowser-app is distributed in the hope that it will be useful, |
35 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
36 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
37 | + * GNU General Public License for more details. |
38 | + * |
39 | + * You should have received a copy of the GNU General Public License |
40 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
41 | + */ |
42 | + |
43 | +import Ubuntu.Components 1.3 |
44 | +import Ubuntu.Unity.Action 1.1 as UnityActions |
45 | + |
46 | +UnityActions.Action { |
47 | + text: i18n.tr("New Private Window") |
48 | + // TRANSLATORS: This is a free-form list of keywords associated to the 'New Private Window' action. |
49 | + // Keywords may actually be sentences, and must be separated by semi-colons. |
50 | + keywords: i18n.tr("Open a New Private Window") |
51 | +} |
52 | + |
53 | |
54 | === added file 'src/app/actions/NewWindow.qml' |
55 | --- src/app/actions/NewWindow.qml 1970-01-01 00:00:00 +0000 |
56 | +++ src/app/actions/NewWindow.qml 2015-10-07 00:51:42 +0000 |
57 | @@ -0,0 +1,28 @@ |
58 | +/* |
59 | + * Copyright 2015 Canonical Ltd. |
60 | + * |
61 | + * This file is part of webbrowser-app. |
62 | + * |
63 | + * webbrowser-app is free software; you can redistribute it and/or modify |
64 | + * it under the terms of the GNU General Public License as published by |
65 | + * the Free Software Foundation; version 3. |
66 | + * |
67 | + * webbrowser-app is distributed in the hope that it will be useful, |
68 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
69 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
70 | + * GNU General Public License for more details. |
71 | + * |
72 | + * You should have received a copy of the GNU General Public License |
73 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
74 | + */ |
75 | + |
76 | +import Ubuntu.Components 1.3 |
77 | +import Ubuntu.Unity.Action 1.1 as UnityActions |
78 | + |
79 | +UnityActions.Action { |
80 | + text: i18n.tr("New Window") |
81 | + // TRANSLATORS: This is a free-form list of keywords associated to the 'New Window' action. |
82 | + // Keywords may actually be sentences, and must be separated by semi-colons. |
83 | + keywords: i18n.tr("Open a New Window") |
84 | +} |
85 | + |
86 | |
87 | === added file 'src/app/actions/OpenLinkInNewPrivateWindow.qml' |
88 | --- src/app/actions/OpenLinkInNewPrivateWindow.qml 1970-01-01 00:00:00 +0000 |
89 | +++ src/app/actions/OpenLinkInNewPrivateWindow.qml 2015-10-07 00:51:42 +0000 |
90 | @@ -0,0 +1,23 @@ |
91 | +/* |
92 | + * Copyright 2015 Canonical Ltd. |
93 | + * |
94 | + * This file is part of webbrowser-app. |
95 | + * |
96 | + * webbrowser-app is free software; you can redistribute it and/or modify |
97 | + * it under the terms of the GNU General Public License as published by |
98 | + * the Free Software Foundation; version 3. |
99 | + * |
100 | + * webbrowser-app is distributed in the hope that it will be useful, |
101 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
102 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
103 | + * GNU General Public License for more details. |
104 | + * |
105 | + * You should have received a copy of the GNU General Public License |
106 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
107 | + */ |
108 | + |
109 | +import Ubuntu.Components 1.3 |
110 | + |
111 | +Action { |
112 | + text: i18n.tr("Open link in new private window") |
113 | +} |
114 | |
115 | === added file 'src/app/actions/OpenLinkInNewWindow.qml' |
116 | --- src/app/actions/OpenLinkInNewWindow.qml 1970-01-01 00:00:00 +0000 |
117 | +++ src/app/actions/OpenLinkInNewWindow.qml 2015-10-07 00:51:42 +0000 |
118 | @@ -0,0 +1,23 @@ |
119 | +/* |
120 | + * Copyright 2015 Canonical Ltd. |
121 | + * |
122 | + * This file is part of webbrowser-app. |
123 | + * |
124 | + * webbrowser-app is free software; you can redistribute it and/or modify |
125 | + * it under the terms of the GNU General Public License as published by |
126 | + * the Free Software Foundation; version 3. |
127 | + * |
128 | + * webbrowser-app is distributed in the hope that it will be useful, |
129 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
130 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
131 | + * GNU General Public License for more details. |
132 | + * |
133 | + * You should have received a copy of the GNU General Public License |
134 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
135 | + */ |
136 | + |
137 | +import Ubuntu.Components 1.3 |
138 | + |
139 | +Action { |
140 | + text: i18n.tr("Open link in new window") |
141 | +} |
142 | |
143 | === removed file 'src/app/webbrowser/BookmarksModel.qml' |
144 | --- src/app/webbrowser/BookmarksModel.qml 2015-08-10 15:22:00 +0000 |
145 | +++ src/app/webbrowser/BookmarksModel.qml 1970-01-01 00:00:00 +0000 |
146 | @@ -1,24 +0,0 @@ |
147 | -/* |
148 | - * Copyright 2014-2015 Canonical Ltd. |
149 | - * |
150 | - * This file is part of webbrowser-app. |
151 | - * |
152 | - * webbrowser-app is free software; you can redistribute it and/or modify |
153 | - * it under the terms of the GNU General Public License as published by |
154 | - * the Free Software Foundation; version 3. |
155 | - * |
156 | - * webbrowser-app is distributed in the hope that it will be useful, |
157 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
158 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
159 | - * GNU General Public License for more details. |
160 | - * |
161 | - * You should have received a copy of the GNU General Public License |
162 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
163 | - */ |
164 | - |
165 | -import QtQuick 2.4 |
166 | -import webbrowserapp.private 0.1 |
167 | - |
168 | -BookmarksModel { |
169 | - databasePath: dataLocation + "/bookmarks.sqlite" |
170 | -} |
171 | |
172 | === modified file 'src/app/webbrowser/Browser.qml' |
173 | --- src/app/webbrowser/Browser.qml 2015-09-28 08:15:10 +0000 |
174 | +++ src/app/webbrowser/Browser.qml 2015-10-07 00:51:42 +0000 |
175 | @@ -31,13 +31,15 @@ |
176 | BrowserView { |
177 | id: browser |
178 | |
179 | + signal closingWindow() |
180 | + |
181 | // Should be true when the containing window is fullscreen. |
182 | property bool fullscreen: false |
183 | |
184 | currentWebview: tabsModel && tabsModel.currentTab ? tabsModel.currentTab.webview : null |
185 | |
186 | - property var historyModel: (historyModelLoader.status == Loader.Ready) ? historyModelLoader.item : null |
187 | - property var bookmarksModel: (bookmarksModelLoader.status == Loader.Ready) ? bookmarksModelLoader.item : null |
188 | + property var historyModel: HistoryModel |
189 | + property var bookmarksModel: BookmarksModel |
190 | |
191 | property bool newSession: false |
192 | |
193 | @@ -54,6 +56,21 @@ |
194 | // tab objects (see http://pad.lv/1376433). |
195 | readonly property int maxTabsToRestore: 10 |
196 | |
197 | + property alias tabContainer: tabContainer |
198 | + property alias currentTabIndex: publicTabsModel.currentIndex |
199 | + |
200 | + Component.onCompleted: { |
201 | + WindowsModel.add(browser) |
202 | + HistoryModel.databasePath = dataLocation + "/history.sqlite" |
203 | + BookmarksModel.databasePath = dataLocation + "/bookmarks.sqlite" |
204 | + } |
205 | + |
206 | + Component.onDestruction: closingWindow() |
207 | + |
208 | + onClosingWindow: { |
209 | + WindowsModel.remove(browser) |
210 | + } |
211 | + |
212 | onTabsModelChanged: { |
213 | if (incognito && privateTabsModelLoader.item) { |
214 | browser.openUrlInNewTab("", true) |
215 | @@ -75,6 +92,7 @@ |
216 | } |
217 | } |
218 | |
219 | + /* |
220 | actions: [ |
221 | Actions.GoTo { |
222 | onTriggered: currentWebview.url = value |
223 | @@ -98,6 +116,12 @@ |
224 | Actions.NewTab { |
225 | onTriggered: browser.openUrlInNewTab("", true) |
226 | }, |
227 | + Actions.NewWindow { |
228 | + onTriggered: browser.openUrlInNewWindow("") |
229 | + }, |
230 | + Actions.NewPrivateWindow { |
231 | + onTriggered: browser.openUrlInNewWindow("", true) |
232 | + }, |
233 | Actions.ClearHistory { |
234 | enabled: browser.historyModel |
235 | onTriggered: browser.historyModel.clearAll() |
236 | @@ -110,6 +134,7 @@ |
237 | } |
238 | } |
239 | ] |
240 | + */ |
241 | |
242 | Settings { |
243 | id: settings |
244 | @@ -335,7 +360,7 @@ |
245 | y: webview ? webview.locationBarController.offset : 0 |
246 | |
247 | function isCurrentUrlBookmarked() { |
248 | - return ((webview && browser.bookmarksModel) ? browser.bookmarksModel.contains(webview.url) : false) |
249 | + return ((webview && BookmarksModel) ? BookmarksModel.contains(webview.url) : false) |
250 | } |
251 | bookmarked: isCurrentUrlBookmarked() |
252 | onToggleBookmark: { |
253 | @@ -348,7 +373,7 @@ |
254 | onUrlChanged: chrome.bookmarked = chrome.isCurrentUrlBookmarked() |
255 | } |
256 | Connections { |
257 | - target: browser.bookmarksModel |
258 | + target: BookmarksModel |
259 | onAdded: if (!chrome.bookmarked && (url === chrome.webview.url)) chrome.bookmarked = true |
260 | onRemoved: if (chrome.bookmarked && (url === chrome.webview.url)) chrome.bookmarked = false |
261 | } |
262 | @@ -395,6 +420,20 @@ |
263 | onTriggered: browser.openUrlInNewTab("", true) |
264 | }, |
265 | Action { |
266 | + objectName: "newwindow" |
267 | + text: i18n.tr("New window") |
268 | + iconName: "note-new" |
269 | + visible: (formFactor === "desktop") |
270 | + onTriggered: browser.openUrlInNewWindow("") |
271 | + }, |
272 | + Action { |
273 | + objectName: "newprivatewindow" |
274 | + text: i18n.tr("New private window") |
275 | + iconName: "note-new" |
276 | + visible: (formFactor === "desktop") |
277 | + onTriggered: browser.openUrlInNewWindow("", true) |
278 | + }, |
279 | + Action { |
280 | objectName: "findinpage" |
281 | text: i18n.tr("Find in page") |
282 | iconName: "search" |
283 | @@ -899,19 +938,7 @@ |
284 | } |
285 | } |
286 | } |
287 | - |
288 | - Loader { |
289 | - id: historyModelLoader |
290 | - source: "HistoryModel.qml" |
291 | - asynchronous: true |
292 | - } |
293 | - |
294 | - Loader { |
295 | - id: bookmarksModelLoader |
296 | - source: "BookmarksModel.qml" |
297 | - asynchronous: true |
298 | - } |
299 | - |
300 | + |
301 | Component { |
302 | id: tabComponent |
303 | |
304 | @@ -961,6 +988,16 @@ |
305 | (formFactor === "desktop"))) |
306 | onTriggered: browser.openUrlInNewTab(contextModel.linkUrl, false) |
307 | } |
308 | + Actions.OpenLinkInNewWindow { |
309 | + objectName: "openLinkInNewWindowContextualAction" |
310 | + enabled: contextModel && contextModel.linkUrl.toString() && formFactor === "desktop" |
311 | + onTriggered: browser.openUrlInNewWindow(contextModel.linkUrl) |
312 | + } |
313 | + Actions.OpenLinkInNewPrivateWindow { |
314 | + objectName: "OpenLinkInNewPrivateWindowContextualAction" |
315 | + enabled: contextModel && contextModel.linkUrl.toString() && formFactor === "desktop" |
316 | + onTriggered: browser.openUrlInNewWindow(contextModel.linkUrl, true) |
317 | + } |
318 | Actions.BookmarkLink { |
319 | objectName: "BookmarkLinkContextualAction" |
320 | enabled: contextModel && contextModel.linkUrl.toString() && |
321 | @@ -1364,6 +1401,27 @@ |
322 | } |
323 | } |
324 | |
325 | + function openUrlInNewWindow(url, incognito) { |
326 | + incognito = typeof incognito !== 'undefined' ? incognito : false |
327 | + |
328 | + var component = Qt.createComponent("./webbrowser-app.qml") |
329 | + if (component.status == Component.Ready) { |
330 | + var newWindow = component.createObject() |
331 | + |
332 | + newWindow.incognito = incognito |
333 | + |
334 | + if (url.toString()) { |
335 | + newWindow.urls = [url] |
336 | + } |
337 | + newWindow.show() |
338 | + return newWindow |
339 | + } |
340 | + } |
341 | + |
342 | + function restoreTab(tab, setCurrent) { |
343 | + internal.addTab(tab, setCurrent) |
344 | + } |
345 | + |
346 | SessionStorage { |
347 | id: session |
348 | |
349 | @@ -1373,12 +1431,27 @@ |
350 | if (!locked) { |
351 | return |
352 | } |
353 | - var tabs = [] |
354 | - for (var i = 0; i < publicTabsModel.count; ++i) { |
355 | - var tab = publicTabsModel.get(i) |
356 | - tabs.push(serializeTabState(tab)) |
357 | - } |
358 | - store(JSON.stringify({tabs: tabs, currentIndex: publicTabsModel.currentIndex})) |
359 | + |
360 | + var session = { |
361 | + 'windows': [] |
362 | + } |
363 | + |
364 | + for (var i = 0; i < WindowsModel.count; ++i) { |
365 | + var window = WindowsModel.get(i) |
366 | + var tabs = window.tabsModel |
367 | + var sessionWindow = { |
368 | + 'tabs': [], |
369 | + 'currentIndex': tabsModel.currentIndex |
370 | + } |
371 | + |
372 | + for (var j = 0; j < tabsModel.count; ++j) { |
373 | + var tab = tabs.get(j) |
374 | + sessionWindow.tabs.push(serializeTabState(tab)) |
375 | + } |
376 | + |
377 | + session.windows.push(sessionWindow) |
378 | + } |
379 | + store(JSON.stringify(session)) |
380 | } |
381 | |
382 | function restore() { |
383 | @@ -1392,16 +1465,28 @@ |
384 | return |
385 | } |
386 | if (state) { |
387 | - var tabs = state.tabs |
388 | - if (tabs) { |
389 | - for (var i = 0; i < Math.min(tabs.length, browser.maxTabsToRestore); ++i) { |
390 | - var tab = createTabFromState(tabs[i]) |
391 | - internal.addTab(tab, i == 0) |
392 | + var windows = state.windows |
393 | + if (windows) { |
394 | + for (var w = 0; w < windows.length; ++w) { |
395 | + var windowBrowser = browser |
396 | + if (w > 0) { |
397 | + var newWindow = browser.openUrlInNewWindow("") |
398 | + windowBrowser = newWindow.browser |
399 | + } |
400 | + |
401 | + var tabs = windows[w].tabs |
402 | + if (tabs) { |
403 | + for (var t = 0; t < Math.min(tabs.length, windowBrowser.maxTabsToRestore); ++t) { |
404 | + var tab = createTabFromState(tabs[t], windowBrowser.tabContainer) |
405 | + windowBrowser.restoreTab(tab, t == 0) |
406 | + } |
407 | + } |
408 | + |
409 | + if ('currentIndex' in windows[w]) { |
410 | + windowBrowser.currentTabIndex = windows[w].currentIndex |
411 | + } |
412 | } |
413 | } |
414 | - if ('currentIndex' in state) { |
415 | - publicTabsModel.currentIndex = state.currentIndex |
416 | - } |
417 | } |
418 | } |
419 | |
420 | @@ -1417,7 +1502,7 @@ |
421 | return state |
422 | } |
423 | |
424 | - function createTabFromState(state) { |
425 | + function createTabFromState(state, container) { |
426 | var properties = {'initialUrl': state.url, 'initialTitle': state.title} |
427 | if ('uniqueId' in state) { |
428 | properties["uniqueId"] = state.uniqueId |
429 | @@ -1432,7 +1517,7 @@ |
430 | properties['restoreState'] = state.savedState |
431 | properties['restoreType'] = Oxide.WebView.RestoreLastSessionExitedCleanly |
432 | } |
433 | - return tabComponent.createObject(tabContainer, properties) |
434 | + return tabComponent.createObject(container, properties) |
435 | } |
436 | } |
437 | Timer { |
438 | |
439 | === modified file 'src/app/webbrowser/CMakeLists.txt' |
440 | --- src/app/webbrowser/CMakeLists.txt 2015-09-22 01:27:19 +0000 |
441 | +++ src/app/webbrowser/CMakeLists.txt 2015-10-07 00:51:42 +0000 |
442 | @@ -24,6 +24,7 @@ |
443 | tabs-model.cpp |
444 | text-search-filter-model.cpp |
445 | top-sites-model.cpp |
446 | + windows-model.cpp |
447 | ) |
448 | |
449 | set(WEBBROWSER_APP_MODELS webbrowser-app-models) |
450 | |
451 | === removed file 'src/app/webbrowser/HistoryModel.qml' |
452 | --- src/app/webbrowser/HistoryModel.qml 2015-08-10 15:22:00 +0000 |
453 | +++ src/app/webbrowser/HistoryModel.qml 1970-01-01 00:00:00 +0000 |
454 | @@ -1,24 +0,0 @@ |
455 | -/* |
456 | - * Copyright 2014-2015 Canonical Ltd. |
457 | - * |
458 | - * This file is part of webbrowser-app. |
459 | - * |
460 | - * webbrowser-app is free software; you can redistribute it and/or modify |
461 | - * it under the terms of the GNU General Public License as published by |
462 | - * the Free Software Foundation; version 3. |
463 | - * |
464 | - * webbrowser-app is distributed in the hope that it will be useful, |
465 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
466 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
467 | - * GNU General Public License for more details. |
468 | - * |
469 | - * You should have received a copy of the GNU General Public License |
470 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
471 | - */ |
472 | - |
473 | -import QtQuick 2.4 |
474 | -import webbrowserapp.private 0.1 |
475 | - |
476 | -HistoryModel { |
477 | - databasePath: dataLocation + "/history.sqlite" |
478 | -} |
479 | |
480 | === modified file 'src/app/webbrowser/webbrowser-app.cpp' |
481 | --- src/app/webbrowser/webbrowser-app.cpp 2015-08-19 13:16:06 +0000 |
482 | +++ src/app/webbrowser/webbrowser-app.cpp 2015-10-07 00:51:42 +0000 |
483 | @@ -32,6 +32,7 @@ |
484 | #include "text-search-filter-model.h" |
485 | #include "tabs-model.h" |
486 | #include "top-sites-model.h" |
487 | +#include "windows-model.h" |
488 | #include "webbrowser-app.h" |
489 | |
490 | // Qt |
491 | @@ -64,24 +65,46 @@ |
492 | return new CacheDeleter(); |
493 | } |
494 | |
495 | +static QObject* HistoryModel_singleton_factory(QQmlEngine* engine, QJSEngine* scriptEngine) |
496 | +{ |
497 | + Q_UNUSED(engine); |
498 | + Q_UNUSED(scriptEngine); |
499 | + return new HistoryModel(); |
500 | +} |
501 | + |
502 | +static QObject* BookmarksModel_singleton_factory(QQmlEngine* engine, QJSEngine* scriptEngine) |
503 | +{ |
504 | + Q_UNUSED(engine); |
505 | + Q_UNUSED(scriptEngine); |
506 | + return new BookmarksModel(); |
507 | +} |
508 | + |
509 | +static QObject* WindowsModel_singleton_factory(QQmlEngine* engine, QJSEngine* scriptEngine) |
510 | +{ |
511 | + Q_UNUSED(engine); |
512 | + Q_UNUSED(scriptEngine); |
513 | + return new WindowsModel(); |
514 | +} |
515 | + |
516 | bool WebbrowserApp::initialize() |
517 | { |
518 | const char* uri = "webbrowserapp.private"; |
519 | - qmlRegisterType<HistoryModel>(uri, 0, 1, "HistoryModel"); |
520 | - qmlRegisterType<HistoryTimeframeModel>(uri, 0, 1, "HistoryTimeframeModel"); |
521 | - qmlRegisterType<TopSitesModel>(uri, 0 , 1, "TopSitesModel"); |
522 | + qmlRegisterSingletonType<BookmarksModel>(uri, 0, 1, "BookmarksModel", BookmarksModel_singleton_factory); |
523 | + qmlRegisterSingletonType<CacheDeleter>(uri, 0, 1, "CacheDeleter", CacheDeleter_singleton_factory); |
524 | + qmlRegisterSingletonType<FileOperations>(uri, 0, 1, "FileOperations", FileOperations_singleton_factory); |
525 | + qmlRegisterSingletonType<HistoryModel>(uri, 0, 1, "HistoryModel", HistoryModel_singleton_factory); |
526 | + qmlRegisterSingletonType<WindowsModel>(uri, 0, 1, "WindowsModel", WindowsModel_singleton_factory); |
527 | + qmlRegisterType<BookmarksFolderListModel>(uri, 0, 1, "BookmarksFolderListModel"); |
528 | + qmlRegisterType<HistoryDomainListChronologicalModel>(uri, 0, 1, "HistoryDomainListChronologicalModel"); |
529 | qmlRegisterType<HistoryDomainListModel>(uri, 0, 1, "HistoryDomainListModel"); |
530 | - qmlRegisterType<HistoryDomainListChronologicalModel>(uri, 0, 1, "HistoryDomainListChronologicalModel"); |
531 | qmlRegisterType<HistoryLastVisitDateListModel>(uri, 0, 1, "HistoryLastVisitDateListModel"); |
532 | qmlRegisterType<HistoryLastVisitDateModel>(uri, 0, 1, "HistoryLastVisitDateModel"); |
533 | + qmlRegisterType<HistoryTimeframeModel>(uri, 0, 1, "HistoryTimeframeModel"); |
534 | qmlRegisterType<LimitProxyModel>(uri, 0 , 1, "LimitProxyModel"); |
535 | + qmlRegisterType<SearchEngine>(uri, 0, 1, "SearchEngine"); |
536 | qmlRegisterType<TabsModel>(uri, 0, 1, "TabsModel"); |
537 | - qmlRegisterType<BookmarksModel>(uri, 0, 1, "BookmarksModel"); |
538 | - qmlRegisterType<BookmarksFolderListModel>(uri, 0, 1, "BookmarksFolderListModel"); |
539 | - qmlRegisterSingletonType<FileOperations>(uri, 0, 1, "FileOperations", FileOperations_singleton_factory); |
540 | - qmlRegisterType<SearchEngine>(uri, 0, 1, "SearchEngine"); |
541 | - qmlRegisterSingletonType<CacheDeleter>(uri, 0, 1, "CacheDeleter", CacheDeleter_singleton_factory); |
542 | qmlRegisterType<TextSearchFilterModel>(uri, 0, 1, "TextSearchFilterModel"); |
543 | + qmlRegisterType<TopSitesModel>(uri, 0 , 1, "TopSitesModel"); |
544 | |
545 | if (BrowserApplication::initialize("webbrowser/webbrowser-app.qml")) { |
546 | QStringList searchEnginesSearchPaths; |
547 | @@ -122,6 +145,14 @@ |
548 | int main(int argc, char** argv) |
549 | { |
550 | QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); |
551 | + |
552 | + // Make sure that only a single instance of webbrowser is running |
553 | + const char *sharedMemKey = "webbrowser-app"; |
554 | + QSharedMemory sharedMem(sharedMemKey); |
555 | + if (!sharedMem.create(1, QSharedMemory::ReadOnly)) { |
556 | + return 0; |
557 | + } |
558 | + |
559 | WebbrowserApp app(argc, argv); |
560 | if (app.initialize()) { |
561 | return app.run(); |
562 | |
563 | === modified file 'src/app/webbrowser/webbrowser-app.qml' |
564 | --- src/app/webbrowser/webbrowser-app.qml 2015-08-10 15:33:43 +0000 |
565 | +++ src/app/webbrowser/webbrowser-app.qml 2015-10-07 00:51:42 +0000 |
566 | @@ -24,11 +24,15 @@ |
567 | BrowserWindow { |
568 | id: window |
569 | |
570 | + property bool incognito: false |
571 | property alias urls: browser.initialUrls |
572 | property alias newSession: browser.newSession |
573 | + property alias browser: browser |
574 | |
575 | currentWebview: browser.currentWebview |
576 | |
577 | + onClosing: browser.closingWindow() |
578 | + |
579 | title: { |
580 | if (browser.title) { |
581 | // TRANSLATORS: %1 refers to the current page’s title |
582 | @@ -44,9 +48,13 @@ |
583 | webbrowserWindow: webbrowserWindowProxy |
584 | developerExtrasEnabled: window.developerExtrasEnabled |
585 | |
586 | + incognito: window.incognito |
587 | + |
588 | fullscreen: window.visibility === Window.FullScreen |
589 | |
590 | - Component.onCompleted: i18n.domain = "webbrowser-app" |
591 | + Component.onCompleted: { |
592 | + i18n.domain = "webbrowser-app" |
593 | + } |
594 | |
595 | Keys.onPressed: { |
596 | if ((event.key === Qt.Key_F11) && (event.modifiers === Qt.NoModifier)) { |
597 | |
598 | === added file 'src/app/webbrowser/windows-model.cpp' |
599 | --- src/app/webbrowser/windows-model.cpp 1970-01-01 00:00:00 +0000 |
600 | +++ src/app/webbrowser/windows-model.cpp 2015-10-07 00:51:42 +0000 |
601 | @@ -0,0 +1,106 @@ |
602 | +/* |
603 | + * Copyright 2015 Canonical Ltd. |
604 | + * |
605 | + * This file is part of webbrowser-app. |
606 | + * |
607 | + * webbrowser-app is free software; you can redistribute it and/or modify |
608 | + * it under the terms of the GNU General Public License as published by |
609 | + * the Free Software Foundation; version 3. |
610 | + * |
611 | + * webbrowser-app is distributed in the hope that it will be useful, |
612 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
613 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
614 | + * GNU General Public License for more details. |
615 | + * |
616 | + * You should have received a copy of the GNU General Public License |
617 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
618 | + */ |
619 | + |
620 | +#include "windows-model.h" |
621 | + |
622 | +// Qt |
623 | +#include <QtCore/QDebug> |
624 | +#include <QtCore/QObject> |
625 | + |
626 | +/*! |
627 | + \class WindowsModel |
628 | + \brief List model that stores the list of currently open windows. |
629 | + |
630 | + WindowsModel is a list model that stores the list of currently open windowss. |
631 | + Each window holds a pointer to a Window and associated metadata (id). |
632 | + |
633 | + The model doesn’t own the Window, so it is the responsibility of whoever |
634 | + adds a window to instantiate the corresponding Window, and to destroy it after |
635 | + it’s removed from the model. |
636 | +*/ |
637 | +WindowsModel::WindowsModel(QObject* parent) |
638 | + : QAbstractListModel(parent) |
639 | +{ |
640 | +} |
641 | + |
642 | +WindowsModel::~WindowsModel() |
643 | +{ |
644 | +} |
645 | + |
646 | +QHash<int, QByteArray> WindowsModel::roleNames() const |
647 | +{ |
648 | + static QHash<int, QByteArray> roles; |
649 | + if (roles.isEmpty()) { |
650 | + roles[TabsModel] = "tabsModel"; |
651 | + } |
652 | + return roles; |
653 | +} |
654 | + |
655 | +int WindowsModel::rowCount(const QModelIndex& parent) const |
656 | +{ |
657 | + Q_UNUSED(parent); |
658 | + return m_windows.count(); |
659 | +} |
660 | + |
661 | +QVariant WindowsModel::data(const QModelIndex& index, int role) const |
662 | +{ |
663 | + if (!index.isValid()) { |
664 | + return QVariant(); |
665 | + } |
666 | + QObject* window = m_windows.at(index.row()); |
667 | + switch (role) { |
668 | + case TabsModel: |
669 | + return window->property("urls"); |
670 | + default: |
671 | + return QVariant(); |
672 | + } |
673 | +} |
674 | + |
675 | +void WindowsModel::add(QObject* window) |
676 | +{ |
677 | + if (window == nullptr) { |
678 | + qWarning() << "Invalid Window"; |
679 | + return; |
680 | + } |
681 | + int index = m_windows.count(); |
682 | + beginInsertRows(QModelIndex(), index, index); |
683 | + m_windows.append(window); |
684 | + endInsertRows(); |
685 | + Q_EMIT countChanged(); |
686 | +} |
687 | + |
688 | +void WindowsModel::remove(QObject* window) |
689 | +{ |
690 | + int index = m_windows.indexOf(window); |
691 | + if (index < 0) { |
692 | + return; |
693 | + } |
694 | + beginRemoveRows(QModelIndex(), index, index); |
695 | + m_windows.removeAt(index); |
696 | + endRemoveRows(); |
697 | + Q_EMIT countChanged(); |
698 | +} |
699 | + |
700 | +QObject* WindowsModel::get(int index) const |
701 | +{ |
702 | + if ((index < 0) || (index >= m_windows.count())) { |
703 | + qWarning() << "Invalid window index:" << index; |
704 | + return nullptr; |
705 | + } |
706 | + return m_windows.at(index); |
707 | +} |
708 | |
709 | === added file 'src/app/webbrowser/windows-model.h' |
710 | --- src/app/webbrowser/windows-model.h 1970-01-01 00:00:00 +0000 |
711 | +++ src/app/webbrowser/windows-model.h 2015-10-07 00:51:42 +0000 |
712 | @@ -0,0 +1,60 @@ |
713 | +/* |
714 | + * Copyright 2015 Canonical Ltd. |
715 | + * |
716 | + * This file is part of webbrowser-app. |
717 | + * |
718 | + * webbrowser-app is free software; you can redistribute it and/or modify |
719 | + * it under the terms of the GNU General Public License as published by |
720 | + * the Free Software Foundation; version 3. |
721 | + * |
722 | + * webbrowser-app is distributed in the hope that it will be useful, |
723 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
724 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
725 | + * GNU General Public License for more details. |
726 | + * |
727 | + * You should have received a copy of the GNU General Public License |
728 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
729 | + */ |
730 | + |
731 | +#ifndef __WINDOWS_MODEL_H__ |
732 | +#define __WINDOWS_MODEL_H__ |
733 | + |
734 | +// Qt |
735 | +#include <QtCore/QAbstractListModel> |
736 | +#include <QtCore/QList> |
737 | + |
738 | +class QObject; |
739 | + |
740 | +class WindowsModel : public QAbstractListModel |
741 | +{ |
742 | + Q_OBJECT |
743 | + |
744 | + Q_ENUMS(Roles) |
745 | + |
746 | + Q_PROPERTY(int count READ rowCount NOTIFY countChanged) |
747 | + |
748 | +public: |
749 | + WindowsModel(QObject* parent=0); |
750 | + ~WindowsModel(); |
751 | + |
752 | + enum Roles { |
753 | + TabsModel = Qt::UserRole + 1, |
754 | + }; |
755 | + |
756 | + // reimplemented from QAbstractListModel |
757 | + QHash<int, QByteArray> roleNames() const; |
758 | + int rowCount(const QModelIndex& parent=QModelIndex()) const; |
759 | + QVariant data(const QModelIndex& index, int role) const; |
760 | + |
761 | + Q_INVOKABLE void add(QObject* window); |
762 | + Q_INVOKABLE void remove(QObject* window); |
763 | + Q_INVOKABLE QObject* get(int index) const; |
764 | + |
765 | +Q_SIGNALS: |
766 | + void countChanged() const; |
767 | + |
768 | +private: |
769 | + QList<QObject*> m_windows; |
770 | +}; |
771 | + |
772 | +#endif // __WINDOWS_MODEL_H__ |
FAILED: Continuous integration, rev:1206 jenkins. qa.ubuntu. com/job/ webbrowser- app-ci/ 2292/ jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- vivid-touch/ 4392 jenkins. qa.ubuntu. com/job/ webbrowser- app-vivid- amd64-ci/ 1046 jenkins. qa.ubuntu. com/job/ webbrowser- app-vivid- armhf-ci/ 1046 jenkins. qa.ubuntu. com/job/ webbrowser- app-vivid- armhf-ci/ 1046/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ webbrowser- app-vivid- i386-ci/ 1046/console jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- runner- vivid-mako/ 3575 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 4389 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 4389/artifact/ work/output/ *zip*/output. zip s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 23730
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
FAILURE: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/webbrowser- app-ci/ 2292/rebuild
http://