import QtQuick 2.0
import QtQml.Models 2.1
import QtQuick.Layouts 1.3
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtGraphicalEffects 1
import QtQuick.Window 2
import Qt.labs.settings 1.0
import QtQuick.Dialogs 1.1
Rectangle {
id: box
//width: 1000 * Screen.devicePixelRatio; height: 650 * Screen.devicePixelRatio
property alias view: view
//: For Right to Left language, set this string to RTL, else keep it untranslated
property var direction: qsTr("LTR")
LayoutMirroring.enabled: (direction == "LTR" ? false : true)
// for tests
//LayoutMirroring.enabled: true
// TO-DO GridLayout RowLayout are not sensible to mirroring, change to other layout tools
LayoutMirroring.childrenInherit: true
Settings {
property alias width: box.width
property alias height: box.height
}
Component {
id: slidebackground
LinearGradient {
start: Qt.point(0, 0)
end: Qt.point(0, box.height)
gradient: Gradient {
GradientStop { position: 1.0; color: "#2397D4" }
GradientStop { position: 0.0; color: "#262F45" }
}
}
}
Rectangle {
id: banner
opacity: 0.95
layer.enabled: true
width: parent.width;height: 120
LinearGradient {
anchors.fill: parent
start: Qt.point(0, 0)
end: Qt.point(0, 400)
gradient: Gradient {
GradientStop { position: 0.0; color: "lightgray" }
GradientStop { position: 1.0; color: "white" }
}
}
Image {
anchors.fill: parent
anchors.bottomMargin: 10
anchors.topMargin: 10
source: "img/mageia-2013-black-alpha.png"
fillMode: Image.PreserveAspectFit
}
}
Rectangle {
id: slideshow
property Item displayItem: null
anchors {left: parent.left; top: buttonbox.bottom; bottom: parent.bottom; right: parent.right}
color: "#2397D4"
width: parent.width
ObjectModel {
id: itemModel
// Welcome page
Welcome {}
// Configure source page
Sources {}
// Update page
Updates {}
// MCC Page
Mcc {}
// Install software page
InstallSoftware {}
// Applications page
function update_list(group) {
appListDM.items.remove(0,appListDM.count );
var rowCount = appList.count;
for( var i = 0;i < rowCount;i++ )
{
var entry = appList.get(i);
var pattern = new RegExp(group, "g");
if(pattern.test(entry.group) && !pyinstallable.other(entry.name, entry.repo)) {
appListDM.items.insert(entry, "group");
}
}
for(var child in applicationsListView.contentItem.children) {
if (applicationsListView.contentItem.children[child].naturalwidth > softListRect.installwidth ) {
softListRect.installwidth = applicationsListView.contentItem.children[child].naturalwidth
}
}
appListDM.filterOnGroup = "items";
}
Rectangle {
property var title: qsTr("Applications")
width: view.width; height: view.height
Loader { sourceComponent: slidebackground ;
anchors.fill: parent}
Column {
Rectangle {
// warning banner
id: warning
width: view.width
height: warnText.height
color: "gold"
Label {
id: warnText
width: view.width
horizontalAlignment: TextInput.AlignHCenter
font.pixelSize: Qt.application.font.pixelSize * .9
text: qsTr("Here is a small selection of popular applications - any of which may be installed or launched at this point.")+"
"+qsTr("Ensure that you have enabled the Media sources.")
textFormat: Text.RichText
wrapMode: Text.WordWrap
color: "black"
font.weight: Font.DemiBold
}
}
Item {
width: row.width
height: 200
Row {
id: row
// Under the warning
// Software categories
Component { //The hightlight
id: catHighlight
Rectangle {
width: categoriesList.width
height: Qt.application.font.pixelSize + 16
color: "#262F45"
y: categoriesList.currentItem.y;
}
}
ListView {
id:categoriesList
width: 190
highlight: catHighlight
highlightFollowsCurrentItem: false
focus: true
model: [{'name': qsTr("Featured"), 'group': "featured"},
{'name': qsTr("Games"),'group': "games"},
{'name':qsTr("Internet"),'group': "internet"},
{'name':qsTr("Video"),'group': "video"},
{'name':qsTr("Audio"),'group': "audio"},
{'name':qsTr("Office"),'group': "office"},
{'name':qsTr("Graphics"),'group': "graphics"},
{'name':qsTr("System"),'group': "system"},
{'name':qsTr("Programming"),'group': "programming"}]
height: (Qt.application.font.pixelSize + 16) * 9
delegate: Rectangle{
property variant myGroup: modelData.group
width: parent.width
height: Qt.application.font.pixelSize + 16
color:"#20FFFFFF"
Label {id: catLabel;
anchors.horizontalCenter: parent.horizontalCenter
text: modelData.name ;
padding: 7
color: "white"
}
MouseArea {
anchors.centerIn: parent
width: parent.width
height: 25
onClicked: {
categoriesList.currentIndex = index;
itemModel.update_list(modelData.group);
}
}
}
}
Rectangle {
// Software list
id: softListRect
height: view.height
width: view.width - categoriesList.width
color: "transparent"
// the width of install and Launch button will be calculated then updated. We give here a minimal size
property real installwidth: Qt.application.font.pixelSize * 2
DelegateModel {
id: appListDM
model: AppList {id: appList}
groups: [
DelegateModelGroup {
includeByDefault: false
name: "group"
}
]
filterOnGroup: "group"
Component.onCompleted: {
var rowCount = appList.count;
items.remove(0,rowCount);
for( var i = 0;i < rowCount;i++ )
{
var entry = appList.get(i);
var pattern = /featured/g;
if(pattern.test(entry.group) && !pyinstallable.other(entry.name, entry.repo) ) {
items.insert(entry, "group");
}
}
// The lsit has to be painted first for buttons width evaluation
applicationsListView.forceLayout()
for(var child in applicationsListView.contentItem.children) {
if (applicationsListView.contentItem.children[child].naturalwidth > softListRect.installwidth ) {
softListRect.installwidth = applicationsListView.contentItem.children[child].naturalwidth
}
}
console.log("Screen: ", Screen.devicePixelRatio, Screen.pixelDensity)
}
delegate: Row {
spacing: 10
property int naturalwidth : optButton.item.implicitWidth
Image {
source: icon
width: 32
height: 32
}
//CheckBox{ enabled: installable
//}
Column{
Label {
text: title
font.weight: Font.DemiBold
color: "white"
}
Label {
text: description
font.italic: true
font.pixelSize: Qt.application.font.pixelSize * .9
width: view.width - (190 + 44 +38 + softListRect.installwidth + tag.width )
wrapMode: Text.WordWrap
color: "white"
}
}
Loader {
id: optButton
Component { id: button;
Button {
width: softListRect.installwidth;
height: Qt.application.font.pixelSize * 1.3
objectName: "launch"
onClicked: {
launch.install([name,repo,])}
style: ButtonStyle {
label: Label {
horizontalAlignment: TextInput.AlignHCenter
verticalAlignment: TextInput.AlignVCenter
text: qsTr("Install");
font.pixelSize: Qt.application.font.pixelSize * .8
color: "black"
}
}
}
}
Component { id: launcher;
Button {
width: softListRect.installwidth;
height: Qt.application.font.pixelSize * 1.3
objectName: "launch"
onClicked: {
launch.command([command,])}
style: ButtonStyle {
label: Label {
horizontalAlignment: TextInput.AlignHCenter
verticalAlignment: TextInput.AlignVCenter
text: qsTr("Launch");
font.pixelSize: Qt.application.font.pixelSize * .8
color: "black"
}
}
}
}
Component { id: dummy;Label {text: qsTr("Installed")
padding: 2
horizontalAlignment: TextInput.AlignHCenter
font.pixelSize: Qt.application.font.pixelSize * .8
width: softListRect.installwidth
color: "white"
}
}
sourceComponent: ( pyinstallable.installable(name, repo)) ? button : (command === "" ? dummy : launcher)
}
Loader {
id: tag
Component {
id: repotag
Rectangle {
color: "#FF4C4C"
radius: 3
width: Qt.application.font.pixelSize * 3.5; height: Qt.application.font.pixelSize * 1.3
Label {
anchors.centerIn: parent
text: repo
font.pixelSize: Qt.application.font.pixelSize * .8
color: "white"
}
}
}
Component { id: dumm;
Label {
width: Qt.application.font.pixelSize * 3.5;
text: " "}}
sourceComponent: repo == "" ? dumm : repotag
}
}
}
Rectangle {
height: view.height-warning.height
width: view.width-200
color: "transparent"
ListView {
id: applicationsListView
anchors.fill: parent
clip: true
model: appListDM
spacing: 5
}
}
}
}
}
}
}
// Configuration summary Page
Configuration {}
// Links page
Links {}
}
ObjectModel {
id: itemModelLive
// Welcome page
Welcome {}
// Live mode
Live {}
// MCC Page
Mcc {}
// Install software page
InstallSoftware {}
// Install on HD
Install {}
// Documentation links
Links {}
}
ListView {
id: view
z: 1
anchors.rightMargin: 0
anchors.leftMargin: 0
anchors.topMargin: 0
anchors { fill: parent; bottomMargin: startCB.implicitHeight +10 }
model: (user == 'live' ? itemModelLive : itemModel)
preferredHighlightBegin: 0; preferredHighlightEnd: view.width
highlightRangeMode: ListView.StrictlyEnforceRange
orientation: ListView.Horizontal
snapMode: ListView.SnapOneItem; flickDeceleration: 2000
highlightFollowsCurrentItem: true
highlightMoveDuration: 800
cacheBuffer: 200
}
}
MouseArea {
id: nextMA
anchors {right: parent.right; verticalCenter: slideshow.verticalCenter }
width: 60
height: 60
hoverEnabled: true
onEntered: { rightArrow.state='Hovering'}
onExited: { rightArrow.state=''}
onClicked: {if (view.currentIndex < view.model.count - 1)
view.currentIndex = view.currentIndex + 1}
Rectangle {
id: rightArrow
anchors.fill: parent
color: "#80262F45"
visible: false
Text {
anchors.centerIn: parent
text: (direction == "LTR" ? ">" : "<")
font.pointSize: 30
}
states: [
State {
name: "Hovering"
PropertyChanges {
target: rightArrow
visible: view.currentIndex == view.model.count - 1 ? false : true
}
}
]
}
}
MouseArea {
id: previousMA
anchors {left: parent.left; verticalCenter: slideshow.verticalCenter }
width: 60
height: 60
hoverEnabled: true
onEntered: { leftArrow.state='Hovering'}
onExited: { leftArrow.state=''}
onClicked: {if (view.currentIndex > 0)
view.currentIndex = view.currentIndex - 1}
Rectangle {
id: leftArrow
anchors.fill: parent
color: "#80262F45"
visible: false
Text {
anchors.centerIn: parent
text: (direction == "LTR" ? "<" : ">")
font.pointSize: 30
}
states: [
State {
name: "Hovering"
PropertyChanges {
target: leftArrow
visible: view.currentIndex == 0 ? false : true
}
}
]
}
}
Rectangle {
id: buttonbox
width: banner.width; height: buttonRow.height
anchors { top: banner.bottom; }
color: "#262F45"
RowLayout {
id: buttonRow
Rectangle {
Layout.preferredWidth: 8
Layout.preferredHeight: buttonbox.height
color: buttonbox.color
}
Repeater {
model: (user == 'live' ? itemModelLive.count : itemModel.count)
Button {
Layout.fillHeight: true
Layout.preferredWidth: (buttonbox.width - 8)/(user == 'live' ? itemModelLive.count : itemModel.count) - 9;
Layout.topMargin: 6
Layout.bottomMargin: 6
style: ButtonStyle {
background: Rectangle {
radius: 5
color: view.currentIndex == index ? "#2397D4" : "white"
}
label: Label{
text: (user == 'live' ? itemModelLive.get(index).title : itemModel.get(index).title)
font.pointSize: 9
color: view.currentIndex == index ? "white" : "#262F45"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
wrapMode : Text.WordWrap
}
}
onClicked: view.currentIndex = index
}
}
Rectangle {
Layout.preferredWidth: 8
Layout.preferredHeight: buttonbox.height
color: buttonbox.color
}
}
}
Row {
anchors.right: box.right
anchors.bottom: box.bottom
anchors.margins: 6
CheckBox {
id:startCB
text: qsTr("Show this window at startup")
checked: startupcheck
onClicked: norun.setRunAtLaunch(checked)
}
}
MessageDialog {
id: no_tainted
icon: StandardIcon.Warning
title: qsTr("Application installation")
//: %1 will be replaced with the 'Media sources' translation
text: qsTr("Tainted repositories are not enabled. See the '%1' tab.").arg(qsTr("Media sources"))
standardButtons: StandardButton.Close
}
MessageDialog {
id: no_core
icon: StandardIcon.Warning
title: qsTr("Application installation")
//: %1 will be replaced with the 'Media sources' translation
text: qsTr("Core repositories are not enabled. See the '%1' tab.").arg(qsTr("Media sources"))
standardButtons: StandardButton.Close
}
MessageDialog {
id: no_nonfree
icon: StandardIcon.Warning
title: qsTr("Application installation")
//: %1 will be replaced with the 'Media sources' translation
text: qsTr("Nonfree repositories are not enabled. See the '%1' tab.").arg(qsTr("Media sources"))
standardButtons: StandardButton.Close
}
MessageDialog {
id: no_program
icon: StandardIcon.Warning
title: qsTr("Launching command")
text: qsTr("This command is not installed")
standardButtons: StandardButton.Close
}
MessageDialog {
id: no_steam
icon: StandardIcon.Warning
title: qsTr("Application installation")
//: %1 will be replaced with the 'Media sources' translation
text: qsTr("Steam needs that Nonfree and Core 32bit repositories are enabled. See the '%1' tab.").arg(qsTr("Media sources"))
standardButtons: StandardButton.Close
}
Connections {
target: launch
function onInstalled() {
// get the signal to reload the applist
console.log("Reload applications list")
itemModel.update_list(categoriesList.currentItem.myGroup)
}
function onRepo() {
// get the signal that core repo is not enabled
console.log("Core repository is not enabled")
no_core.visible = true
}
function onNeeded(repo) {
// get the signal that tainted repo is not enabled
console.log("%1 is not enabled".arg(repo))
if (repo == "non-free") {
no_nonfree.visible = true
}
if (repo == "tainted") {
no_tainted.visible = true
}
if (repo == "steam") {
no_steam.visible = true
}
}
function onNoprogram() {
// get the signal that the command doesn't exist'
console.log("The program is not installed")
no_program.visible = true
}
}
}