Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Moving files deleted from my last commit.

  • Loading branch information...
commit 8772087ef4c7ecaf3d7e75897b6f4d5b6e914f71 1 parent 8e907e8
Daker authored
Showing with 2,489 additions and 0 deletions.
  1. +3 −0  comics-reader
  2. +8 −0 comics-reader.desktop
  3. +5 −0 debian/changelog
  4. +70 −0 debian/comics-reader/DEBIAN/control
  5. +30 −0 debian/comics-reader/DEBIAN/md5sums
  6. +18 −0 debian/comics-reader/opt/comics-reader/BusyIndicator.qml
  7. +76 −0 debian/comics-reader/opt/comics-reader/Button.qml
  8. +33 −0 debian/comics-reader/opt/comics-reader/ComicCanvas.qml
  9. +76 −0 debian/comics-reader/opt/comics-reader/ComicDelegate.qml
  10. +12 −0 debian/comics-reader/opt/comics-reader/ComicFeedModel.qml
  11. +16 −0 debian/comics-reader/opt/comics-reader/ExpandButton.qml
  12. +55 −0 debian/comics-reader/opt/comics-reader/FeedDelegate.qml
  13. +106 −0 debian/comics-reader/opt/comics-reader/Feeds.qml
  14. +97 −0 debian/comics-reader/opt/comics-reader/FullscreenView.qml
  15. +76 −0 debian/comics-reader/opt/comics-reader/FullscreenView2.qml
  16. +34 −0 debian/comics-reader/opt/comics-reader/Icon.qml
  17. +16 −0 debian/comics-reader/opt/comics-reader/Label.qml
  18. +111 −0 debian/comics-reader/opt/comics-reader/Settings.qml
  19. +170 −0 debian/comics-reader/opt/comics-reader/baseDesktop.qml
  20. +170 −0 debian/comics-reader/opt/comics-reader/baseN900.qml
  21. BIN  debian/comics-reader/opt/comics-reader/images/background.png
  22. BIN  debian/comics-reader/opt/comics-reader/images/bt-normal.png
  23. BIN  debian/comics-reader/opt/comics-reader/images/bt-pressed.png
  24. BIN  debian/comics-reader/opt/comics-reader/images/bt-radio-orange.png
  25. BIN  debian/comics-reader/opt/comics-reader/images/bt-radio-white.png
  26. BIN  debian/comics-reader/opt/comics-reader/images/bt-trash.png
  27. BIN  debian/comics-reader/opt/comics-reader/images/busy.png
  28. BIN  debian/comics-reader/opt/comics-reader/images/expand.png
  29. BIN  debian/comics-reader/opt/comics-reader/images/left.png
  30. BIN  debian/comics-reader/opt/comics-reader/images/logo.png
  31. BIN  debian/comics-reader/opt/comics-reader/images/random.png
  32. BIN  debian/comics-reader/opt/comics-reader/images/right.png
  33. +3 −0  debian/comics-reader/usr/bin/comics-reader
  34. +8 −0 debian/comics-reader/usr/share/applications/hildon/comics-reader.desktop
  35. BIN  debian/comics-reader/usr/share/icons/hicolor/64x64/hildon/comics-reader.png
  36. +1 −0  debian/compat
  37. +76 −0 debian/control
  38. +1 −0  debian/files
  39. +46 −0 debian/rules
  40. BIN  icons/hicolor/26x26/hildon/comics-reader.png
  41. BIN  icons/hicolor/48x48/hildon/comics-reader.png
  42. BIN  icons/hicolor/64x64/hildon/comics-reader.png
  43. +18 −0 ui/BusyIndicator.qml
  44. +76 −0 ui/Button.qml
  45. +33 −0 ui/ComicCanvas.qml
  46. +76 −0 ui/ComicDelegate.qml
  47. +12 −0 ui/ComicFeedModel.qml
  48. +16 −0 ui/ExpandButton.qml
  49. +55 −0 ui/FeedDelegate.qml
  50. +106 −0 ui/Feeds.qml
  51. +97 −0 ui/FullscreenView.qml
  52. +76 −0 ui/FullscreenView2.qml
  53. +34 −0 ui/Icon.qml
  54. +16 −0 ui/Label.qml
  55. +111 −0 ui/Settings.qml
  56. +170 −0 ui/baseDesktop.qml
  57. +170 −0 ui/baseN900.qml
  58. +13 −0 ui/example_feeds.txt
  59. +75 −0 ui/feed.js
  60. BIN  ui/images/background.png
  61. BIN  ui/images/bt-normal.png
  62. BIN  ui/images/bt-pressed.png
  63. BIN  ui/images/bt-radio-orange.png
  64. BIN  ui/images/bt-radio-white.png
  65. BIN  ui/images/bt-trash.png
  66. BIN  ui/images/busy.png
  67. BIN  ui/images/expand.png
  68. BIN  ui/images/left.png
  69. BIN  ui/images/logo.png
  70. BIN  ui/images/random.png
  71. BIN  ui/images/right.png
  72. +18 −0 ui/ui.qmlproject
3  comics-reader
View
@@ -0,0 +1,3 @@
+#!/bin/sh
+# run qml app with qml viewer
+/opt/qt4-maemo5/bin/qmlviewer /opt/comics-reader/baseN900.qml
8 comics-reader.desktop
View
@@ -0,0 +1,8 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=0.6.1
+Type=Application
+Name=ComicsReader
+Exec=/usr/bin/comics-reader
+Icon=comics-reader
+X-Window-Icon=comics-reader
5 debian/changelog
View
@@ -0,0 +1,5 @@
+comics-reader (1.0.0-0) experimental; urgency=low
+
+ * First release of comics-reader package.
+
+ -- Daker Fernandes Pinheiro <daker.pinheiro@openbossa.org> Wed, 18 Aug 2010 12:00:00 -3000
70 debian/comics-reader/DEBIAN/control
View
@@ -0,0 +1,70 @@
+Package: comics-reader
+Version: 1.0.0-0
+Section: user/multimedia
+Priority: optional
+Architecture: i386
+Depends: qt4-experimental-declarative-qmlviewer, libqt4-experimental-declarative
+Installed-Size: 212
+Maintainer: Daker Fernandes <daker.pinheiro@openbossa.org>
+Description: A feed viewer of web comics strips.
+ With the fullscreen mode you can zoom the comic.
+ You can also add any web comic feed you like.
+Bugtracker: https://garage.maemo.org/tracker/?atid=6294&group_id=1803&func=browse
+Maemo-Icon-26:
+ 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
+ 5l7y6xMAAAAASUVORK5CYII=
30 debian/comics-reader/DEBIAN/md5sums
View
@@ -0,0 +1,30 @@
+5e8a3674a60472703265a9c3fcdfeab9 opt/comics-reader/baseDesktop.qml
+a91f799ca31e4c83b28927f46e23dc86 opt/comics-reader/FeedDelegate.qml
+197b7b6b41f1f97684d03f8c34d04f68 opt/comics-reader/ComicDelegate.qml
+aef62f99954e1a541d39352a1b4ba4e3 opt/comics-reader/Settings.qml
+e9bedd583a91e57b80c957c6738d8386 opt/comics-reader/images/random.png
+5685dd68287555d4d8f10ba0d41c0977 opt/comics-reader/images/background.png
+bca07867557d941ade6189742e861b40 opt/comics-reader/images/right.png
+92b82ec03fa5b6a6fc81dc4406c73d23 opt/comics-reader/images/left.png
+6a9afb638b3d7c67e8cd3b0feff0370c opt/comics-reader/images/bt-radio-white.png
+7c084661bffec1b8ff06fd5f555d2201 opt/comics-reader/images/busy.png
+5df646d7243dda446e545afd7755c698 opt/comics-reader/images/logo.png
+9d8e9cc9cf101dc153a3413305b9a3c5 opt/comics-reader/images/expand.png
+87de8296d62cf7dd1500b604af264cb4 opt/comics-reader/images/bt-normal.png
+c009549390e3e67136b3756a1b7b6920 opt/comics-reader/images/bt-pressed.png
+92d33e0d25d7b9d452b7184a998ef235 opt/comics-reader/images/bt-radio-orange.png
+b35bfc50b43969e8500c6d999650c170 opt/comics-reader/images/bt-trash.png
+340a2d5369779164dd15005151a61a9c opt/comics-reader/Button.qml
+c3cdfb5e147245bdb529f408b6c397fd opt/comics-reader/ExpandButton.qml
+831bd059ea122d1e0ad497f7dd470477 opt/comics-reader/ComicCanvas.qml
+b866f5be3846db09f7bae06ab3ab1130 opt/comics-reader/ComicFeedModel.qml
+865ad52e77929407089891327b98874b opt/comics-reader/FullscreenView2.qml
+58b61ad55456fdba3826c51b248ba059 opt/comics-reader/baseN900.qml
+14886ea99f2be47acce8510445f941ec opt/comics-reader/Feeds.qml
+10c04590b8ffb467b9a35230414dfe9a opt/comics-reader/FullscreenView.qml
+b1dc3b4febcd2c49e0ad001fbb2646cb opt/comics-reader/BusyIndicator.qml
+cbfc98a7f782134c867b622283edac28 opt/comics-reader/Icon.qml
+e3063760f2193205081865882370db5e opt/comics-reader/Label.qml
+fae59c51a802efb0a9db7520bcf8131d usr/share/applications/hildon/comics-reader.desktop
+fb6f5a8f810e08efd799cad202cc5736 usr/share/icons/hicolor/64x64/hildon/comics-reader.png
+602fa55b31767130d0bfbf75038b35de usr/bin/comics-reader
18 debian/comics-reader/opt/comics-reader/BusyIndicator.qml
View
@@ -0,0 +1,18 @@
+import Qt 4.7
+
+Image {
+ id: indicator
+
+ property bool on: false
+
+ source: "images/busy.png"
+ visible: indicator.on
+ width: 40; height: 40
+
+ NumberAnimation on rotation {
+ running: indicator.on
+ from: 0; to: 360
+ loops: Animation.Infinite
+ duration: 1200
+ }
+}
76 debian/comics-reader/opt/comics-reader/Button.qml
View
@@ -0,0 +1,76 @@
+import Qt 4.7
+
+Item {
+ id: button
+
+ width: 104; height: 52;
+
+ property alias iconPressed: icon.sourcePressed
+ property alias iconUnpressed: icon.sourceUnpressed
+ property alias label: label.text
+ property alias enabled: mouseArea.enabled
+ property bool pressed: false
+ signal clicked
+
+ Image {
+ id: background
+
+ source: "images/bt-normal.png"
+
+ states: [
+ State {
+ name: "disabled"
+ when: button.enabled == false
+ PropertyChanges {
+ target: icon
+ opacity: 0.3
+ }
+ PropertyChanges {
+ target: label
+ opacity: 0.3
+ }
+ },
+ State {
+ name: "unpressed"
+ when: button.pressed == false
+ PropertyChanges {
+ target: background
+ source: "images/bt-normal.png"
+ }
+ },
+ State {
+ name: "pressed"
+ when: button.pressed == true
+ PropertyChanges {
+ target: background
+ source: "images/bt-pressed.png"
+ }
+ }
+ ]
+ }
+
+ Label { id: label }
+ Icon { id: icon }
+
+ Connections {
+ target: mouseArea
+ onPressed: {
+ button.pressed = true
+ }
+ onReleased: {
+ button.pressed = false
+ }
+ }
+
+ onPressedChanged: {
+ label.pressed = pressed
+ icon.pressed = pressed
+ }
+
+ MouseArea {
+ id: mouseArea
+ anchors.fill: parent
+ onClicked:
+ button.clicked()
+ }
+}
33 debian/comics-reader/opt/comics-reader/ComicCanvas.qml
View
@@ -0,0 +1,33 @@
+import Qt 4.7
+import "feed.js" as Feed
+
+ListView {
+ id: comic
+ spacing: 10
+ highlightMoveSpeed: 1200
+ highlightRangeMode: ListView.StrictlyEnforceRange
+ clip: true
+ flickableDirection: Flickable.HorizontalFlick
+ snapMode: ListView.SnapToItem
+ orientation: ListView.Horizontal
+
+ property alias feed: rssModel.source
+ property real scale: 1
+ property bool firstComic: comic.currentIndex == 0
+ property bool lastComic: comic.currentIndex >= comic.count - 1
+ signal fullscreen
+
+ model: ComicFeedModel {id: rssModel}
+ delegate: ComicDelegate {
+ scale: comic.scale
+ onExpand: {
+ comic.currentIndex = index
+ fullscreen(index)
+ }
+ }
+
+ BusyIndicator {
+ anchors.centerIn: parent
+ on: comic.model.status == XmlListModel.Loading
+ }
+}
76 debian/comics-reader/opt/comics-reader/ComicDelegate.qml
View
@@ -0,0 +1,76 @@
+import Qt 4.7
+import "feed.js" as Feed
+
+Item {
+ id: delegate
+ width: parent.parent.width
+ height: parent.parent.height
+
+ property string image: Feed.getImage(model)
+ property string alt: Feed.getAlt(model)
+ property string title: model.comicTitle
+ property bool isValidComic: image != ""
+ property real scale: 1
+ signal expand
+
+ Text {
+ id: title
+ text: (isValidComic) ? comicTitle : ""
+ anchors {
+ left: parent.left
+ }
+ width: parent.width
+ elide: Text.ElideRight
+ color: "white"
+ font {
+ family: "Arial"
+ bold: true
+ pointSize: 20
+ }
+ }
+
+ Item {
+ anchors {
+ top: title.bottom
+ left: delegate.left
+ right: delegate.right
+ bottom: delegate.bottom
+ topMargin: 20
+ }
+ Image {
+ id: strip
+ fillMode: Image.PreserveAspectFit
+ source: image
+ width: Math.min(strip.sourceSize.width, delegate.width)
+ height: Math.min(strip.sourceSize.height,
+ delegate.height - title.height - 20)
+ anchors {
+ verticalCenter: parent.verticalCenter
+ left: parent.left
+ }
+ MouseArea {
+ anchors.fill: parent
+ onDoubleClicked:
+ expand()
+ }
+ }
+ }
+
+ BusyIndicator {
+ anchors.centerIn: parent
+ on: strip.status != Image.Ready
+ }
+
+ ExpandButton {
+ id: btExpand
+ scale: delegate.scale
+ onClicked:
+ expand()
+ anchors {
+ right: parent.right
+ rightMargin: 20
+ bottom: parent.bottom
+ bottomMargin: 20
+ }
+ }
+}
12 debian/comics-reader/opt/comics-reader/ComicFeedModel.qml
View
@@ -0,0 +1,12 @@
+import Qt 4.7
+
+XmlListModel { // TODO put the javascript in a .js module
+ id: rssModel
+
+ source: ""
+ query: "/rss/channel/item"
+
+ XmlRole { name: "comicTitle"; query: "title/string()" }
+ XmlRole { name: "comicContent"; query: "description/string()" }
+ XmlRole { name: "comicLink"; query: "link/string()" }
+}
16 debian/comics-reader/opt/comics-reader/ExpandButton.qml
View
@@ -0,0 +1,16 @@
+import Qt 4.7
+
+Image {
+ id: btExpand
+ signal clicked
+ property real scale: 1
+
+ source: "images/expand.png"
+ width: (visible) ? 32 * scale : 0; height: 31 * scale;
+
+ MouseArea {
+ id: expandMouseArea
+ anchors.fill: parent
+ onClicked: { btExpand.clicked() }
+ }
+}
55 debian/comics-reader/opt/comics-reader/FeedDelegate.qml
View
@@ -0,0 +1,55 @@
+import Qt 4.7
+
+Item {
+ width: parent.width
+ height: 50
+
+ signal deletedFeed(int index)
+ signal selectedFeed(int index)
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: selectedFeed(index)
+ }
+
+ Text {
+ text: model.title
+ color: "white"
+ anchors {
+ left: parent.left
+ leftMargin: 10
+ right: button.left
+ rightMargin: 10
+ verticalCenter: parent.verticalCenter
+ }
+ font {
+ pointSize: 12
+ family: "Arial"
+ bold: true
+ }
+ }
+
+ Image {
+ id: button
+ signal deletedFeed
+ source: "images/bt-trash.png"
+ width: 32; height: 32
+ anchors {
+ verticalCenter: parent.verticalCenter
+ right: parent.right
+ rightMargin: 10
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked:
+ deletedFeed(index)
+ }
+ }
+
+ Rectangle {
+ color: "white"
+ opacity: 0.1
+ anchors.fill: parent
+ }
+}
106 debian/comics-reader/opt/comics-reader/Feeds.qml
View
@@ -0,0 +1,106 @@
+import Qt 4.7
+
+import "feed.js" as Feed
+
+ListModel {
+ id: feeds
+ signal invalidFeed(string url);
+
+ Component.onCompleted: {
+ var db = openDatabaseSync("feed", "1.0",
+ "Comics Feeds SQL", 1000000, "QSQLITE");
+
+ db.transaction(function(tx) {
+ tx.executeSql("CREATE TABLE IF NOT EXISTS \
+ Feeds(url STRING PRIMARY KEY, \
+ title STRING, description STRING)")
+
+ tx.executeSql("INSERT OR IGNORE INTO \
+ Feeds (url, title, description) \
+ VALUES ('http://xkcd.com/rss.xml','xkcd.com',\
+ 'xkcd.com: A webcomic of romance and math humor.')");
+
+ var resultSet = tx.executeSql(
+ "SELECT url, title, description FROM Feeds");
+
+ for(var i = 0; i < resultSet.rows.length; i++){
+ var result = resultSet.rows.item(i)
+ var url = result.url;
+ var title = result.title;
+ var description = result.description;
+ feeds.append({'url': url,
+ 'title': title, 'description': description });
+ }
+ })
+ }
+
+ function _getRssInfo(feedSample) {
+
+ var channel = null
+ for(var i = 0; i < feedSample.childNodes.length; i++) {
+ if(feedSample.childNodes[i].nodeName == "channel")
+ channel = feedSample.childNodes[i]
+ }
+ var title = ""
+ var description = ""
+ // TODO find out a better way to do this
+ for(var i = 0; i < channel.childNodes.length; i++) {
+ if(channel.childNodes[i].nodeName == "title")
+ title = channel.childNodes[i].firstChild.nodeValue
+ else if(channel.childNodes[i].nodeName == "description")
+ description = channel.childNodes[i].firstChild.nodeValue
+ }
+ return {'title': title, 'description': description}
+ }
+
+ function _validateFeed(url, onValidated, onInvalidFeed) {
+ var doc = new XMLHttpRequest()
+ doc.onreadystatechange = function() {
+ if (doc.readyState == XMLHttpRequest.DONE) {
+ if (doc.responseXML == null) {
+ onInvalidFeed(url)
+ return;
+ }
+ var feedSample = doc.responseXML.documentElement
+ if (feedSample.tagName.toString() == "rss") {
+ var feedInfo = feeds._getRssInfo(
+ doc.responseXML.documentElement)
+ feedInfo['url'] = url
+ onValidated(feedInfo)
+ } else {
+ onInvalidFeed(url)
+ }
+ }
+ }
+ doc.open("GET", url)
+ doc.send()
+ }
+
+ function addFeed(url) {
+ var db = openDatabaseSync("feed", "1.0", "Comics Feeds SQL",
+ 1000000, "QSQLITE")
+
+ function _addFeed(feedInfo) {
+ var title = feedInfo['title']
+ var url = feedInfo['url']
+ var description = feedInfo['description']
+ db.transaction(function(tx) {
+ tx.executeSql("INSERT OR IGNORE INTO Feeds \
+ (title, url, description) VALUES (?,?,?)",
+ [title,url,description] );
+ })
+ feeds.append(feedInfo)
+ }
+ feeds._validateFeed(url, _addFeed, invalidFeed);
+ }
+
+ function deleteFeed(index) {
+ var db = openDatabaseSync("feed", "1.0", "Comics Feeds SQL",
+ 1000000, "QSQLITE")
+ db.transaction(function(tx) {
+ var url = feeds.get(index).url
+ tx.executeSql("DELETE FROM Feeds WHERE url = ?", [url])
+ feeds.remove(index)
+ })
+ }
+}
97 debian/comics-reader/opt/comics-reader/FullscreenView.qml
View
@@ -0,0 +1,97 @@
+import Qt 4.7
+
+Item{
+ id: comicView
+
+ property string currentImage
+ property string currentAlt
+ property real scale: 1
+ property int borderSize: 60 * scale
+ signal exitFullscreen
+
+ anchors.fill: parent
+
+ Rectangle {
+ id: blackout
+ color: "black"
+ anchors.fill: parent
+ }
+ Flickable {
+ anchors.fill: parent
+ contentWidth: container.width
+ contentHeight: container.height
+
+ Item {
+ id: container
+ width: image.width + borderSize * 2
+ height: image.height + imageLabel.height + borderSize * 2
+ x: {
+ if ( comicView.width > image.width + borderSize)
+ return (comicView.width - container.width)/2 +
+ borderSize
+ else
+ return borderSize
+ }
+ y: {
+ if ( comicView.height > image.height + borderSize)
+ return (comicView.height - container.height)/2 +
+ borderSize
+ else
+ return borderSize
+ }
+
+ Image {
+ id: image
+ source: currentImage
+ width: sourceSize.width * comicView.scale
+ height: sourceSize.height * comicView.scale
+ MouseArea {
+ id: mouseArea
+ anchors.fill: parent
+ onDoubleClicked: { comicView.exitFullscreen() }
+ }
+ }
+
+ Text {
+ id: imageLabel
+
+ color: "white"
+ text: comicView.currentAlt
+ wrapMode: Text.WordWrap
+ anchors {
+ top: image.bottom
+ topMargin: 20
+ left: image.left
+ right: image.right
+ }
+ font {
+ family: "Arial"
+ pointSize: 12 * comicView.scale
+ bold: true
+ }
+ }
+
+ BusyIndicator {
+ anchors.centerIn: parent
+ on: { image.status == XmlListModel.Loading }
+ }
+
+ ExpandButton {
+ scale: comicView.scale
+ anchors {
+ bottom: image.top
+ right: imageLabel.left
+ }
+ onClicked: { comicView.exitFullscreen() }
+ }
+ ExpandButton {
+ scale: comicView.scale
+ anchors {
+ bottom: imageLabel.bottom
+ left: imageLabel.right
+ }
+ onClicked: { comicView.exitFullscreen() }
+ }
+ }
+ }
+}
76 debian/comics-reader/opt/comics-reader/FullscreenView2.qml
View
@@ -0,0 +1,76 @@
+import Qt 4.7
+
+Item{
+ id: comicView
+
+ property string currentImage
+ property string currentAlt
+ property real scale: 1
+ property int borderSize: 60 * scale
+ signal exitFullscreen
+
+ anchors.fill: parent
+
+ Rectangle {
+ id: blackout
+ color: "white"
+ anchors.fill: parent
+ }
+
+ Flickable {
+ anchors.fill: parent
+ contentWidth: container.width
+ contentHeight: container.height
+
+ Item {
+ id: container
+ width: image.width
+ height: image.height + imageLabel.height + 20
+
+ Image {
+ id: image
+ source: currentImage
+ width: sourceSize.width * comicView.scale
+ height: sourceSize.height * comicView.scale
+ MouseArea {
+ id: mouseArea
+ anchors.fill: parent
+ onDoubleClicked: { comicView.exitFullscreen() }
+ }
+ }
+
+ Text {
+ id: imageLabel
+
+ color: "black"
+ text: comicView.currentAlt
+ wrapMode: Text.WordWrap
+ anchors {
+ top: image.bottom
+ topMargin: 20
+ left: image.left
+ right: image.right
+ }
+ font {
+ family: "Arial"
+ pointSize: 12 * comicView.scale
+ bold: true
+ }
+ }
+
+ BusyIndicator {
+ anchors.centerIn: parent
+ on: { image.status == XmlListModel.Loading }
+ }
+ }
+ }
+ ExpandButton {
+ scale: 2
+ anchors {
+ bottom: parent.bottom
+ right: parent.right
+ }
+ onClicked:
+ exitFullscreen()
+ }
+}
34 debian/comics-reader/opt/comics-reader/Icon.qml
View
@@ -0,0 +1,34 @@
+import Qt 4.7
+
+Image {
+ id: icon
+
+ property string sourcePressed
+ property string sourceUnpressed
+ property bool pressed: false
+
+ width: 22; height: 22;
+ x: 38; y: 12;
+ fillMode: Image.PreserveAspectFit
+ source: sourceUnpressed
+
+ states: [
+ State {
+ name: "pressed"
+ when: pressed == true
+ PropertyChanges {
+ target: icon
+ source: sourcePressed
+ }
+ },
+
+ State {
+ name: "unpressed"
+ when: pressed == false
+ PropertyChanges {
+ target: icon
+ source: sourceUnpressed
+ }
+ }
+ ]
+}
16 debian/comics-reader/opt/comics-reader/Label.qml
View
@@ -0,0 +1,16 @@
+import Qt 4.7
+
+Text {
+ id: label
+
+ property bool pressed: false
+
+ color: "black"
+ font { bold: true; pointSize: 8 }
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ horizontalCenterOffset: -1
+ verticalCenter: parent.verticalCenter
+ verticalCenterOffset: -1
+ }
+}
111 debian/comics-reader/opt/comics-reader/Settings.qml
View
@@ -0,0 +1,111 @@
+import Qt 4.7
+
+Item {
+ id: settings
+
+ property string currentFeed: feedModel.get(0).url
+
+ Text {
+ id: title
+ text: "Settings"
+ color: "white"
+ anchors {
+ left: parent.left
+ right: parent.righth
+ }
+ font {
+ family: "Trebuchet MS"
+ bold: true
+ pointSize: 20
+ }
+ }
+
+ Feeds {
+ id: feedModel
+ onInvalidFeed:
+ input.text = url
+ }
+
+ Item {
+ id: feedInput
+ property alias text: input.text
+ height: 60
+ anchors {
+ top: title.bottom
+ topMargin: 25
+ right: parent.right
+ rightMargin: 10
+ left: parent.left
+ leftMargin: 10
+ bottomMargin: 10
+ }
+
+ TextInput {
+ id: input
+ color: "white"
+ anchors {
+ left: parent.left
+ right: btAddFeed.left
+ rightMargin: 10
+ verticalCenter: parent.verticalCenter
+ verticalCenterOffset: -5
+ }
+ font {
+ pointSize: 18
+ family: "Arial"
+ bold: true
+ }
+ Rectangle {
+ color: "white"
+ opacity: 0.2
+ anchors.fill: parent
+ }
+ }
+
+ Button {
+ id: btAddFeed
+ label: "add"
+ enabled: input.text.match(/(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/) != null
+ anchors {
+ top: parent.top
+ right: parent.right
+ }
+
+ onClicked: {
+ feedModel.addFeed(feedInput.text)
+ input.text = ""
+ }
+ }
+ }
+
+ ListView {
+ id: feedView
+ clip: true
+ model: feedModel
+ delegate: FeedDelegate {
+ onDeletedFeed:
+ feedModel.deleteFeed(index)
+ onSelectedFeed:
+ feedView.currentIndex = index
+ }
+ spacing: 5
+ focus: true
+ anchors {
+ top: feedInput.bottom
+ left: parent.left
+ bottom: parent.bottom
+ bottomMargin: 10
+ right: parent.right
+ }
+ highlightFollowsCurrentItem: true
+ highlight: Rectangle {
+ color: "lightsteelblue";
+ width: parent.width
+ opacity: 0.3
+ }
+ onCurrentItemChanged: {
+ var index = feedView.currentIndex
+ settings.currentFeed = feedModel.get(index).url
+ }
+ }
+}
170 debian/comics-reader/opt/comics-reader/baseDesktop.qml
View
@@ -0,0 +1,170 @@
+import Qt 4.7
+import "feed.js" as Feed
+
+Item {
+ id: window
+ width: 800; height: 480
+
+ property bool loading: canvas.delegate.status == XmlListModel.Loading
+ property int lastComicId
+ property real scale: 1 // Scales items
+
+ Image {
+ id: background
+
+ source: "images/background.png"
+ anchors.fill: parent
+ }
+
+ Image {
+ id: logo
+
+ source: "images/logo.png"
+ anchors {
+ right: parent.right
+ rightMargin: 20
+ top: parent.top
+ topMargin: 15
+ }
+ }
+
+ Column {
+ id: controls
+
+ width: 95
+ anchors {
+ right: parent.right
+ rightMargin: 20
+ verticalCenter: parent.verticalCenter
+ }
+
+ Button {
+ id: btFeeds
+
+ label: "feeds"
+ anchors.horizontalCenter: parent.horizontalCenter
+
+ onClicked: {
+ if (window.state != "settings") {
+ window.state = "settings"
+ } else {
+ window.state = "normalView"
+ }
+ }
+ }
+
+ Button {
+ id: btRandom
+
+ anchors.horizontalCenter: parent.horizontalCenter
+ iconPressed: "images/random.png"
+ iconUnpressed: "images/random.png"
+
+ onClicked: {
+ /* Real random xkcd feed
+ Feed.randomXkcdFeed(function (src, alt) {
+ fullscreen.currentImage = src
+ fullscreen.currentAlt = alt
+ window.state = "fullscreen"
+ })
+ */
+ canvas.highlightMoveDuration = 1
+ canvas.currentIndex = Math.floor(
+ Math.random() * canvas.count)
+ canvas.highlightMoveDuration = -1
+ }
+ }
+
+ Button {
+ id: btLeft
+
+ anchors.horizontalCenter: parent.horizontalCenter
+ enabled: !canvas.firstComic
+ iconPressed: "images/left.png"
+ iconUnpressed: "images/left.png"
+ onClicked: { canvas.decrementCurrentIndex() }
+ }
+
+ Button {
+ id: btRight
+
+ anchors.horizontalCenter: parent.horizontalCenter
+ enabled: !canvas.lastComic
+ iconPressed: "images/right.png"
+ iconUnpressed: "images/right.png"
+ onClicked: { canvas.incrementCurrentIndex() }
+ }
+ }
+
+ /* Canvas to place comics images */
+ ComicCanvas {
+ id: canvas
+ scale: window.scale
+ feed: settings.currentFeed
+ opacity: 1
+ anchors {
+ topMargin: 15
+ top: parent.top
+ leftMargin: 15
+ left: parent.left
+ bottomMargin: 20
+ bottom: parent.bottom
+ rightMargin: 15
+ right: controls.left
+ }
+
+ onFullscreen: {
+ fullscreen.currentImage = canvas.currentItem.image
+ fullscreen.currentAlt = canvas.currentItem.alt
+ window.state = "fullscreen"
+ }
+ }
+
+ FullscreenView {
+ id: fullscreen
+ scale: window.scale
+ opacity: 0
+ onExitFullscreen: { window.state = "normalView" }
+ }
+
+ Settings {
+ id: settings
+
+ opacity: 0
+ anchors {
+ topMargin: 15
+ top: parent.top
+ leftMargin: 15
+ left: parent.left
+ bottomMargin: 20
+ bottom: parent.bottom
+ rightMargin: 15
+ right: controls.left
+ }
+ }
+
+ states: [
+ State {
+ name: "fullscreen"
+ PropertyChanges { target: fullscreen; opacity: 1 }
+ PropertyChanges { target: canvas; opacity: 0 }
+ PropertyChanges { target: controls; opacity: 0 }
+ },
+ State {
+ name: "normalView"
+ PropertyChanges { target: canvas; opacity: 1 }
+ PropertyChanges { target: controls; opacity: 1 }
+ PropertyChanges { target: fullscreen; opacity: 0 }
+ },
+ State {
+ name: "settings"
+ PropertyChanges { target: canvas; opacity: 0.05 }
+ PropertyChanges { target: controls; opacity: 1 }
+ PropertyChanges { target: settings; opacity: 1 }
+ PropertyChanges { target: btFeeds; label: "ok" }
+ PropertyChanges { target: btRandom; enabled: false }
+ PropertyChanges { target: btLeft; enabled: false }
+ PropertyChanges { target: btRight; enabled: false }
+ }
+ ]
+}
170 debian/comics-reader/opt/comics-reader/baseN900.qml
View
@@ -0,0 +1,170 @@
+import Qt 4.7
+import "feed.js" as Feed
+
+Item {
+ id: window
+ width: 800; height: 480
+
+ property bool loading: canvas.delegate.status == XmlListModel.Loading
+ property int lastComicId
+ property real scale: 2 // Scales items
+
+ Image {
+ id: background
+
+ source: "images/background.png"
+ anchors.fill: parent
+ }
+
+ Image {
+ id: logo
+
+ source: "images/logo.png"
+ anchors {
+ right: parent.right
+ rightMargin: 20
+ top: parent.top
+ topMargin: 15
+ }
+ }
+
+ Column {
+ id: controls
+
+ width: 95
+ anchors {
+ right: parent.right
+ rightMargin: 20
+ verticalCenter: parent.verticalCenter
+ }
+
+ Button {
+ id: btFeeds
+
+ label: "feeds"
+ anchors.horizontalCenter: parent.horizontalCenter
+
+ onClicked: {
+ if (window.state != "settings") {
+ window.state = "settings"
+ } else {
+ window.state = "normalView"
+ }
+ }
+ }
+
+ Button {
+ id: btRandom
+
+ anchors.horizontalCenter: parent.horizontalCenter
+ iconPressed: "images/random.png"
+ iconUnpressed: "images/random.png"
+
+ onClicked: {
+ /* Real random xkcd feed
+ Feed.randomXkcdFeed(function (src, alt) {
+ fullscreen.currentImage = src
+ fullscreen.currentAlt = alt
+ window.state = "fullscreen"
+ })
+ */
+ canvas.highlightMoveDuration = 1
+ canvas.currentIndex = Math.floor(
+ Math.random() * canvas.count)
+ canvas.highlightMoveDuration = -1
+ }
+ }
+
+ Button {
+ id: btLeft
+
+ anchors.horizontalCenter: parent.horizontalCenter
+ enabled: !canvas.firstComic
+ iconPressed: "images/left.png"
+ iconUnpressed: "images/left.png"
+ onClicked: { canvas.decrementCurrentIndex() }
+ }
+
+ Button {
+ id: btRight
+
+ anchors.horizontalCenter: parent.horizontalCenter
+ enabled: !canvas.lastComic
+ iconPressed: "images/right.png"
+ iconUnpressed: "images/right.png"
+ onClicked: { canvas.incrementCurrentIndex() }
+ }
+ }
+
+ /* Canvas to place comics images */
+ ComicCanvas {
+ id: canvas
+ scale: window.scale
+ feed: settings.currentFeed
+ opacity: 1
+ anchors {
+ topMargin: 15
+ top: parent.top
+ leftMargin: 15
+ left: parent.left
+ bottomMargin: 20
+ bottom: parent.bottom
+ rightMargin: 15
+ right: controls.left
+ }
+
+ onFullscreen: {
+ fullscreen.currentImage = canvas.currentItem.image
+ fullscreen.currentAlt = canvas.currentItem.alt
+ window.state = "fullscreen"
+ }
+ }
+
+ FullscreenView2 { // FullscreenView {
+ id: fullscreen
+ scale: window.scale
+ opacity: 0
+ onExitFullscreen: { window.state = "normalView" }
+ }
+
+ Settings {
+ id: settings
+
+ opacity: 0
+ anchors {
+ topMargin: 15
+ top: parent.top
+ leftMargin: 15
+ left: parent.left
+ bottomMargin: 20
+ bottom: parent.bottom
+ rightMargin: 15
+ right: controls.left
+ }
+ }
+
+ states: [
+ State {
+ name: "fullscreen"
+ PropertyChanges { target: fullscreen; opacity: 1 }
+ PropertyChanges { target: canvas; opacity: 0 }
+ PropertyChanges { target: controls; opacity: 0 }
+ },
+ State {
+ name: "normalView"
+ PropertyChanges { target: canvas; opacity: 1 }
+ PropertyChanges { target: controls; opacity: 1 }
+ PropertyChanges { target: fullscreen; opacity: 0 }
+ },
+ State {
+ name: "settings"
+ PropertyChanges { target: canvas; opacity: 0.05 }
+ PropertyChanges { target: controls; opacity: 1 }
+ PropertyChanges { target: settings; opacity: 1 }
+ PropertyChanges { target: btFeeds; label: "ok" }
+ PropertyChanges { target: btRandom; enabled: false }
+ PropertyChanges { target: btLeft; enabled: false }
+ PropertyChanges { target: btRight; enabled: false }
+ }
+ ]
+}
BIN  debian/comics-reader/opt/comics-reader/images/background.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  debian/comics-reader/opt/comics-reader/images/bt-normal.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  debian/comics-reader/opt/comics-reader/images/bt-pressed.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  debian/comics-reader/opt/comics-reader/images/bt-radio-orange.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  debian/comics-reader/opt/comics-reader/images/bt-radio-white.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  debian/comics-reader/opt/comics-reader/images/bt-trash.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  debian/comics-reader/opt/comics-reader/images/busy.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  debian/comics-reader/opt/comics-reader/images/expand.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  debian/comics-reader/opt/comics-reader/images/left.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  debian/comics-reader/opt/comics-reader/images/logo.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  debian/comics-reader/opt/comics-reader/images/random.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  debian/comics-reader/opt/comics-reader/images/right.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3  debian/comics-reader/usr/bin/comics-reader
View
@@ -0,0 +1,3 @@
+#!/bin/sh
+# run qml app with qml viewer
+/opt/qt4-maemo5/bin/qmlviewer /opt/comics-reader/baseN900.qml
8 debian/comics-reader/usr/share/applications/hildon/comics-reader.desktop
View
@@ -0,0 +1,8 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=0.6.1
+Type=Application
+Name=ComicsReader
+Exec=/usr/bin/comics-reader
+Icon=comics-reader
+X-Window-Icon=comics-reader
BIN  debian/comics-reader/usr/share/icons/hicolor/64x64/hildon/comics-reader.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1  debian/compat
View
@@ -0,0 +1 @@
+5
76 debian/control
View
@@ -0,0 +1,76 @@
+Source: comics-reader
+Section: user/multimedia
+Maintainer: Daker Fernandes <daker.pinheiro@openbossa.org>
+Build-Depends: debhelper (>= 4)
+Standards-Version: 3.8.1
+
+Package: comics-reader
+Architecture: any
+Maintainer: Daker Fernandes <daker.pinheiro@openbossa.org>
+Depends: qt4-experimental-declarative-qmlviewer, libqt4-experimental-declarative
+Section: user/multimedia
+Priority: optional
+Description: A feed viewer of web comics strips.
+ With the fullscreen mode you can zoom the comic.
+ You can also add any web comic feed you like.
+XSBC-Bugtracker: https://garage.maemo.org/tracker/?atid=6294&group_id=1803&func=browse
+Maemo-Display-Name: Comics Reader
+XB-Maemo-Icon-26:
+ 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
+ 5l7y6xMAAAAASUVORK5CYII=
+
1  debian/files
View
@@ -0,0 +1 @@
+comics-reader_1.0.0-0_i386.deb user/multimedia optional
46 debian/rules
View
@@ -0,0 +1,46 @@
+#!/usr/bin/make -f
+
+configure:
+ dh_testdir
+
+build: build-stamp
+
+build-stamp: configure
+ dh_testdir
+
+clean:
+ dh_testdir
+ dh_testroot
+ dh_clean
+
+install: build
+ dh_testdir
+ dh_testroot
+ dh_clean -k
+ dh_installdirs
+
+ install -D -m 755 $(CURDIR)/comics-reader $(CURDIR)/debian/comics-reader/usr/bin/comics-reader
+ install -D -m 644 $(CURDIR)/comics-reader.desktop $(CURDIR)/debian/comics-reader/usr/share/applications/hildon/comics-reader.desktop
+ install -D -m 644 $(CURDIR)/icons/hicolor/64x64/hildon/comics-reader.png $(CURDIR)/debian/comics-reader/usr/share/icons/hicolor/64x64/hildon/comics-reader.png
+ install -d $(CURDIR)/debian/comics-reader/opt/comics-reader/
+ install -d $(CURDIR)/debian/comics-reader/opt/comics-reader/images
+ install -D -m 644 $(CURDIR)/ui/*.qml $(CURDIR)/debian/comics-reader/opt/comics-reader/
+ install -D -m 644 $(CURDIR)/ui/images/* $(CURDIR)/debian/comics-reader/opt/comics-reader/images/
+
+binary-indep:
+
+binary-arch: build install
+ dh_testdir
+ dh_testroot
+ dh_installmenu
+ dh_link
+ dh_compress
+ dh_fixperms
+ dh_installdeb
+ dh_shlibdeps
+ dh_gencontrol
+ dh_md5sums
+ dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure
BIN  icons/hicolor/26x26/hildon/comics-reader.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  icons/hicolor/48x48/hildon/comics-reader.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  icons/hicolor/64x64/hildon/comics-reader.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 ui/BusyIndicator.qml
View
@@ -0,0 +1,18 @@
+import Qt 4.7
+
+Image {
+ id: indicator
+
+ property bool on: false
+
+ source: "images/busy.png"
+ visible: indicator.on
+ width: 40; height: 40
+
+ NumberAnimation on rotation {
+ running: indicator.on
+ from: 0; to: 360
+ loops: Animation.Infinite
+ duration: 1200
+ }
+}
76 ui/Button.qml
View
@@ -0,0 +1,76 @@
+import Qt 4.7
+
+Item {
+ id: button
+
+ width: 104; height: 52;
+
+ property alias iconPressed: icon.sourcePressed
+ property alias iconUnpressed: icon.sourceUnpressed
+ property alias label: label.text
+ property alias enabled: mouseArea.enabled
+ property bool pressed: false
+ signal clicked
+
+ Image {
+ id: background
+
+ source: "images/bt-normal.png"
+
+ states: [
+ State {
+ name: "disabled"
+ when: button.enabled == false
+ PropertyChanges {
+ target: icon
+ opacity: 0.3
+ }
+ PropertyChanges {
+ target: label
+ opacity: 0.3
+ }
+ },
+ State {
+ name: "unpressed"
+ when: button.pressed == false
+ PropertyChanges {
+ target: background
+ source: "images/bt-normal.png"
+ }
+ },
+ State {
+ name: "pressed"
+ when: button.pressed == true
+ PropertyChanges {
+ target: background
+ source: "images/bt-pressed.png"
+ }
+ }
+ ]
+ }
+
+ Label { id: label }
+ Icon { id: icon }
+
+ Connections {
+ target: mouseArea
+ onPressed: {
+ button.pressed = true
+ }
+ onReleased: {
+ button.pressed = false
+ }
+ }
+
+ onPressedChanged: {
+ label.pressed = pressed
+ icon.pressed = pressed
+ }
+
+ MouseArea {
+ id: mouseArea
+ anchors.fill: parent
+ onClicked:
+ button.clicked()
+ }
+}
33 ui/ComicCanvas.qml
View
@@ -0,0 +1,33 @@
+import Qt 4.7
+import "feed.js" as Feed
+
+ListView {
+ id: comic
+ spacing: 10
+ highlightMoveSpeed: 1200
+ highlightRangeMode: ListView.StrictlyEnforceRange
+ clip: true
+ flickableDirection: Flickable.HorizontalFlick
+ snapMode: ListView.SnapToItem
+ orientation: ListView.Horizontal
+
+ property alias feed: rssModel.source
+ property real scale: 1
+ property bool firstComic: comic.currentIndex == 0
+ property bool lastComic: comic.currentIndex >= comic.count - 1
+ signal fullscreen
+
+ model: ComicFeedModel {id: rssModel}
+ delegate: ComicDelegate {
+ scale: comic.scale
+ onExpand: {
+ comic.currentIndex = index
+ fullscreen(index)
+ }
+ }
+
+ BusyIndicator {
+ anchors.centerIn: parent
+ on: comic.model.status == XmlListModel.Loading
+ }
+}
76 ui/ComicDelegate.qml
View
@@ -0,0 +1,76 @@
+import Qt 4.7
+import "feed.js" as Feed
+
+Item {
+ id: delegate
+ width: parent.parent.width
+ height: parent.parent.height
+
+ property string image: Feed.getImage(model)
+ property string alt: Feed.getAlt(model)
+ property string title: model.comicTitle
+ property bool isValidComic: image != ""
+ property real scale: 1
+ signal expand
+
+ Text {
+ id: title
+ text: (isValidComic) ? comicTitle : ""
+ anchors {
+ left: parent.left
+ }
+ width: parent.width
+ elide: Text.ElideRight
+ color: "white"
+ font {
+ family: "Arial"
+ bold: true
+ pointSize: 20
+ }
+ }
+
+ Item {
+ anchors {
+ top: title.bottom
+ left: delegate.left
+ right: delegate.right
+ bottom: delegate.bottom
+ topMargin: 20
+ }
+ Image {
+ id: strip
+ fillMode: Image.PreserveAspectFit
+ source: image
+ width: Math.min(strip.sourceSize.width, delegate.width)
+ height: Math.min(strip.sourceSize.height,
+ delegate.height - title.height - 20)
+ anchors {
+ verticalCenter: parent.verticalCenter
+ left: parent.left
+ }
+ MouseArea {
+ anchors.fill: parent
+ onDoubleClicked:
+ expand()
+ }
+ }
+ }
+
+ BusyIndicator {
+ anchors.centerIn: parent
+ on: strip.status != Image.Ready
+ }
+
+ ExpandButton {
+ id: btExpand
+ scale: delegate.scale
+ onClicked:
+ expand()
+ anchors {
+ right: parent.right
+ rightMargin: 20
+ bottom: parent.bottom
+ bottomMargin: 20
+ }
+ }
+}
12 ui/ComicFeedModel.qml
View
@@ -0,0 +1,12 @@
+import Qt 4.7
+
+XmlListModel { // TODO put the javascript in a .js module
+ id: rssModel
+
+ source: ""
+ query: "/rss/channel/item"
+
+ XmlRole { name: "comicTitle"; query: "title/string()" }
+ XmlRole { name: "comicContent"; query: "description/string()" }
+ XmlRole { name: "comicLink"; query: "link/string()" }
+}
16 ui/ExpandButton.qml
View
@@ -0,0 +1,16 @@
+import Qt 4.7
+
+Image {
+ id: btExpand
+ signal clicked
+ property real scale: 1
+
+ source: "images/expand.png"
+ width: (visible) ? 32 * scale : 0; height: 31 * scale;
+
+ MouseArea {
+ id: expandMouseArea
+ anchors.fill: parent
+ onClicked: { btExpand.clicked() }
+ }
+}
55 ui/FeedDelegate.qml
View
@@ -0,0 +1,55 @@
+import Qt 4.7
+
+Item {
+ width: parent.width
+ height: 50
+
+ signal deletedFeed(int index)
+ signal selectedFeed(int index)
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: selectedFeed(index)
+ }
+
+ Text {
+ text: model.title
+ color: "white"
+ anchors {
+ left: parent.left
+ leftMargin: 10
+ right: button.left
+ rightMargin: 10
+ verticalCenter: parent.verticalCenter
+ }
+ font {
+ pointSize: 12
+ family: "Arial"
+ bold: true
+ }
+ }
+
+ Image {
+ id: button
+ signal deletedFeed
+ source: "images/bt-trash.png"
+ width: 32; height: 32
+ anchors {
+ verticalCenter: parent.verticalCenter
+ right: parent.right
+ rightMargin: 10
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked:
+ deletedFeed(index)
+ }
+ }
+
+ Rectangle {
+ color: "white"
+ opacity: 0.1
+ anchors.fill: parent
+ }
+}
106 ui/Feeds.qml
View
@@ -0,0 +1,106 @@
+import Qt 4.7
+
+import "feed.js" as Feed
+
+ListModel {
+ id: feeds
+ signal invalidFeed(string url);
+
+ Component.onCompleted: {
+ var db = openDatabaseSync("feed", "1.0",
+ "Comics Feeds SQL", 1000000, "QSQLITE");
+
+ db.transaction(function(tx) {
+ tx.executeSql("CREATE TABLE IF NOT EXISTS \
+ Feeds(url STRING PRIMARY KEY, \
+ title STRING, description STRING)")
+
+ tx.executeSql("INSERT OR IGNORE INTO \
+ Feeds (url, title, description) \
+ VALUES ('http://xkcd.com/rss.xml','xkcd.com',\
+ 'xkcd.com: A webcomic of romance and math humor.')");
+
+ var resultSet = tx.executeSql(
+ "SELECT url, title, description FROM Feeds");
+
+ for(var i = 0; i < resultSet.rows.length; i++){
+ var result = resultSet.rows.item(i)
+ var url = result.url;
+ var title = result.title;
+ var description = result.description;
+ feeds.append({'url': url,
+ 'title': title, 'description': description });
+ }
+ })
+ }
+
+ function _getRssInfo(feedSample) {
+
+ var channel = null
+ for(var i = 0; i < feedSample.childNodes.length; i++) {
+ if(feedSample.childNodes[i].nodeName == "channel")
+ channel = feedSample.childNodes[i]
+ }
+ var title = ""
+ var description = ""
+ // TODO find out a better way to do this
+ for(var i = 0; i < channel.childNodes.length; i++) {
+ if(channel.childNodes[i].nodeName == "title")
+ title = channel.childNodes[i].firstChild.nodeValue
+ else if(channel.childNodes[i].nodeName == "description")
+ description = channel.childNodes[i].firstChild.nodeValue
+ }
+ return {'title': title, 'description': description}
+ }
+
+ function _validateFeed(url, onValidated, onInvalidFeed) {
+ var doc = new XMLHttpRequest()
+ doc.onreadystatechange = function() {
+ if (doc.readyState == XMLHttpRequest.DONE) {
+ if (doc.responseXML == null) {
+ onInvalidFeed(url)
+ return;
+ }
+ var feedSample = doc.responseXML.documentElement
+ if (feedSample.tagName.toString() == "rss") {
+ var feedInfo = feeds._getRssInfo(
+ doc.responseXML.documentElement)
+ feedInfo['url'] = url
+ onValidated(feedInfo)
+ } else {
+ onInvalidFeed(url)
+ }
+ }
+ }
+ doc.open("GET", url)
+ doc.send()
+ }
+
+ function addFeed(url) {
+ var db = openDatabaseSync("feed", "1.0", "Comics Feeds SQL",
+ 1000000, "QSQLITE")
+
+ function _addFeed(feedInfo) {
+ var title = feedInfo['title']
+ var url = feedInfo['url']
+ var description = feedInfo['description']
+ db.transaction(function(tx) {
+ tx.executeSql("INSERT OR IGNORE INTO Feeds \
+ (title, url, description) VALUES (?,?,?)",
+ [title,url,description] );
+ })
+ feeds.append(feedInfo)
+ }
+ feeds._validateFeed(url, _addFeed, invalidFeed);
+ }
+
+ function deleteFeed(index) {
+ var db = openDatabaseSync("feed", "1.0", "Comics Feeds SQL",
+ 1000000, "QSQLITE")
+ db.transaction(function(tx) {
+ var url = feeds.get(index).url
+ tx.executeSql("DELETE FROM Feeds WHERE url = ?", [url])
+ feeds.remove(index)
+ })
+ }
+}
97 ui/FullscreenView.qml
View
@@ -0,0 +1,97 @@
+import Qt 4.7
+
+Item{
+ id: comicView
+
+ property string currentImage
+ property string currentAlt
+ property real scale: 1
+ property int borderSize: 60 * scale
+ signal exitFullscreen
+
+ anchors.fill: parent
+
+ Rectangle {
+ id: blackout
+ color: "black"
+ anchors.fill: parent
+ }
+ Flickable {
+ anchors.fill: parent
+ contentWidth: container.width
+ contentHeight: container.height
+
+ Item {
+ id: container
+ width: image.width + borderSize * 2
+ height: image.height + imageLabel.height + borderSize * 2
+ x: {
+ if ( comicView.width > image.width + borderSize)
+ return (comicView.width - container.width)/2 +
+ borderSize
+ else
+ return borderSize
+ }
+ y: {
+ if ( comicView.height > image.height + borderSize)
+ return (comicView.height - container.height)/2 +
+ borderSize
+ else
+ return borderSize
+ }
+
+ Image {
+ id: image
+ source: currentImage
+ width: sourceSize.width * comicView.scale
+ height: sourceSize.height * comicView.scale
+ MouseArea {
+ id: mouseArea
+ anchors.fill: parent
+ onDoubleClicked: { comicView.exitFullscreen() }
+ }
+ }
+
+ Text {
+ id: imageLabel
+
+ color: "white"
+ text: comicView.currentAlt
+ wrapMode: Text.WordWrap
+ anchors {
+ top: image.bottom
+ topMargin: 20
+ left: image.left
+ right: image.right
+ }
+ font {
+ family: "Arial"
+ pointSize: 12 * comicView.scale
+ bold: true
+ }
+ }
+
+ BusyIndicator {
+ anchors.centerIn: parent
+ on: { image.status == XmlListModel.Loading }
+ }
+
+ ExpandButton {
+ scale: comicView.scale
+ anchors {
+ bottom: image.top
+ right: imageLabel.left
+ }
+ onClicked: { comicView.exitFullscreen() }
+ }
+ ExpandButton {
+ scale: comicView.scale
+ anchors {
+ bottom: imageLabel.bottom
+ left: imageLabel.right
+ }
+ onClicked: { comicView.exitFullscreen() }
+ }
+ }
+ }
+}
76 ui/FullscreenView2.qml
View
@@ -0,0 +1,76 @@
+import Qt 4.7
+
+Item{
+ id: comicView
+
+ property string currentImage
+ property string currentAlt
+ property real scale: 1
+ property int borderSize: 60 * scale
+ signal exitFullscreen
+
+ anchors.fill: parent
+
+ Rectangle {
+ id: blackout
+ color: "white"
+ anchors.fill: parent
+ }
+
+ Flickable {
+ anchors.fill: parent
+ contentWidth: container.width
+ contentHeight: container.height
+
+ Item {
+ id: container
+ width: image.width
+ height: image.height + imageLabel.height + 20
+
+ Image {
+ id: image
+ source: currentImage
+ width: sourceSize.width * comicView.scale
+ height: sourceSize.height * comicView.scale
+ MouseArea {
+ id: mouseArea
+ anchors.fill: parent
+ onDoubleClicked: { comicView.exitFullscreen() }
+ }
+ }
+
+ Text {
+ id: imageLabel
+
+ color: "black"
+ text: comicView.currentAlt
+ wrapMode: Text.WordWrap
+ anchors {
+ top: image.bottom
+ topMargin: 20
+ left: image.left
+ right: image.right
+ }
+ font {
+ family: "Arial"
+ pointSize: 12 * comicView.scale
+ bold: true
+ }
+ }
+
+ BusyIndicator {
+ anchors.centerIn: parent
+ on: { image.status == XmlListModel.Loading }
+ }
+ }
+ }
+ ExpandButton {
+ scale: 2
+ anchors {
+ bottom: parent.bottom
+ right: parent.right
+ }
+ onClicked:
+ exitFullscreen()
+ }
+}
34 ui/Icon.qml
View
@@ -0,0 +1,34 @@
+import Qt 4.7
+
+Image {
+ id: icon
+
+ property string sourcePressed
+ property string sourceUnpressed
+ property bool pressed: false
+
+ width: 22; height: 22;
+ x: 38; y: 12;
+ fillMode: Image.PreserveAspectFit
+ source: sourceUnpressed
+
+ states: [
+ State {
+ name: "pressed"
+ when: pressed == true
+ PropertyChanges {
+ target: icon
+ source: sourcePressed
+ }
+ },
+
+ State {
+ name: "unpressed"
+ when: pressed == false
+ PropertyChanges {
+ target: icon
+ source: sourceUnpressed
+ }
+ }
+ ]
+}
16 ui/Label.qml
View
@@ -0,0 +1,16 @@
+import Qt 4.7
+
+Text {
+ id: label
+
+ property bool pressed: false
+
+ color: "black"
+ font { bold: true; pointSize: 8 }
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ horizontalCenterOffset: -1
+ verticalCenter: parent.verticalCenter
+ verticalCenterOffset: -1
+ }
+}
111 ui/Settings.qml
View
@@ -0,0 +1,111 @@
+import Qt 4.7
+
+Item {
+ id: settings
+
+ property string currentFeed: feedModel.get(0).url
+
+ Text {
+ id: title
+ text: "Settings"
+ color: "white"
+ anchors {
+ left: parent.left
+ right: parent.righth
+ }
+ font {
+ family: "Trebuchet MS"
+ bold: true
+ pointSize: 20
+ }
+ }
+
+ Feeds {
+ id: feedModel
+ onInvalidFeed:
+ input.text = url
+ }
+
+ Item {
+ id: feedInput
+ property alias text: input.text
+ height: 60
+ anchors {
+ top: title.bottom
+ topMargin: 25
+ right: parent.right
+ rightMargin: 10
+ left: parent.left
+ leftMargin: 10
+ bottomMargin: 10
+ }
+
+ TextInput {
+ id: input
+ color: "white"
+ anchors {
+ left: parent.left
+ right: btAddFeed.left
+ rightMargin: 10
+ verticalCenter: parent.verticalCenter
+ verticalCenterOffset: -5
+ }
+ font {
+ pointSize: 18
+ family: "Arial"
+ bold: true
+ }
+ Rectangle {
+ color: "white"
+ opacity: 0.2
+ anchors.fill: parent
+ }
+ }
+
+ Button {
+ id: btAddFeed
+ label: "add"
+ enabled: input.text.match(/(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/) != null
+ anchors {
+ top: parent.top
+ right: parent.right
+ }
+
+ onClicked: {
+ feedModel.addFeed(feedInput.text)
+ input.text = ""
+ }
+ }
+ }
+
+ ListView {
+ id: feedView
+ clip: true
+ model: feedModel
+ delegate: FeedDelegate {
+ onDeletedFeed:
+ feedModel.deleteFeed(index)
+ onSelectedFeed:
+ feedView.currentIndex = index
+ }
+ spacing: 5
+ focus: true
+ anchors {
+ top: feedInput.bottom
+ left: parent.left
+ bottom: parent.bottom
+ bottomMargin: 10
+ right: parent.right
+ }
+ highlightFollowsCurrentItem: true
+ highlight: Rectangle {
+ color: "lightsteelblue";
+ width: parent.width
+ opacity: 0.3
+ }
+ onCurrentItemChanged: {
+ var index = feedView.currentIndex
+ settings.currentFeed = feedModel.get(index).url
+ }
+ }
+}
170 ui/baseDesktop.qml
View
@@ -0,0 +1,170 @@
+import Qt 4.7
+import "feed.js" as Feed
+
+Item {
+ id: window
+ width: 800; height: 480
+
+ property bool loading: canvas.delegate.status == XmlListModel.Loading
+ property int lastComicId
+ property real scale: 1 // Scales items
+
+ Image {
+ id: background
+
+ source: "images/background.png"
+ anchors.fill: parent
+ }
+
+ Image {
+ id: logo
+
+ source: "images/logo.png"
+ anchors {
+ right: parent.right
+ rightMargin: 20
+ top: parent.top
+ topMargin: 15
+ }
+ }
+
+ Column {
+ id: controls
+
+ width: 95
+ anchors {
+ right: parent.right
+ rightMargin: 20
+ verticalCenter: parent.verticalCenter
+ }
+
+ Button {
+ id: btFeeds
+
+ label: "feeds"
+ anchors.horizontalCenter: parent.horizontalCenter
+
+ onClicked: {
+ if (window.state != "settings") {
+ window.state = "settings"
+ } else {
+ window.state = "normalView"
+ }
+ }
+ }
+
+ Button {
+ id: btRandom
+
+ anchors.horizontalCenter: parent.horizontalCenter
+ iconPressed: "images/random.png"
+ iconUnpressed: "images/random.png"
+
+ onClicked: {
+ /* Real random xkcd feed
+ Feed.randomXkcdFeed(function (src, alt) {
+ fullscreen.currentImage = src
+ fullscreen.currentAlt = alt
+ window.state = "fullscreen"
+ })
+ */
+ canvas.highlightMoveDuration = 1
+ canvas.currentIndex = Math.floor(
+ Math.random() * canvas.count)
+ canvas.highlightMoveDuration = -1
+ }
+ }
+
+ Button {
+ id: btLeft
+
+ anchors.horizontalCenter: parent.horizontalCenter
+ enabled: !canvas.firstComic
+ iconPressed: "images/left.png"
+ iconUnpressed: "images/left.png"
+ onClicked: { canvas.decrementCurrentIndex() }
+ }
+
+ Button {
+ id: btRight
+
+ anchors.horizontalCenter: parent.horizontalCenter
+ enabled: !canvas.lastComic
+ iconPressed: "images/right.png"
+ iconUnpressed: "images/right.png"
+ onClicked: { canvas.incrementCurrentIndex() }
+ }
+ }
+
+ /* Canvas to place comics images */
+ ComicCanvas {
+ id: canvas
+ scale: window.scale
+ feed: settings.currentFeed
+ opacity: 1
+ anchors {
+ topMargin: 15
+ top: parent.top
+ leftMargin: 15
+ left: parent.left
+ bottomMargin: 20
+ bottom: parent.bottom
+ rightMargin: 15
+ right: controls.left
+ }
+
+ onFullscreen: {
+ fullscreen.currentImage = canvas.currentItem.image
+ fullscreen.currentAlt = canvas.currentItem.alt
+ window.state = "fullscreen"
+ }
+ }
+
+ FullscreenView {
+ id: fullscreen
+ scale: window.scale
+ opacity: 0
+ onExitFullscreen: { window.state = "normalView" }
+ }
+
+ Settings {
+ id: settings
+
+ opacity: 0
+ anchors {
+ topMargin: 15
+ top: parent.top
+ leftMargin: 15
+ left: parent.left
+ bottomMargin: 20
+ bottom: parent.bottom
+ rightMargin: 15
+ right: controls.left
+ }
+ }
+
+ states: [
+ State {
+ name: "fullscreen"
+ PropertyChanges { target: fullscreen; opacity: 1 }
+ PropertyChanges { target: canvas; opacity: 0 }
+ PropertyChanges { target: controls; opacity: 0 }
+ },
+ State {
+ name: "normalView"
+ PropertyChanges { target: canvas; opacity: 1 }
+ PropertyChanges { target: controls; opacity: 1 }
+ PropertyChanges { target: fullscreen; opacity: 0 }
+ },
+ State {
+ name: "settings"
+ PropertyChanges { target: canvas; opacity: 0.05 }
+ PropertyChanges { target: controls; opacity: 1 }
+ PropertyChanges { target: settings; opacity: 1 }
+ PropertyChanges { target: btFeeds; label: "ok" }
+ Property