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 } } }