diff --git a/package/contents/config/config.qml b/package/contents/config/config.qml
index 52f1d4f..d268134 100644
--- a/package/contents/config/config.qml
+++ b/package/contents/config/config.qml
@@ -1,35 +1,35 @@
import QtQuick 2.2
import org.kde.plasma.configuration 2.0
ConfigModel {
ConfigCategory {
name: i18n("Layout")
icon: "preferences-desktop-color"
source: "config/ConfigLayout.qml"
}
ConfigCategory {
name: i18n("Behaviour")
icon: "preferences-desktop"
source: "config/ConfigBehaviour.qml"
}
ConfigCategory {
name: i18n("Title and Icon")
- icon: "preferences-desktop-color"
+ icon: "preferences-system-windows"
source: "config/ConfigTitleAndIcon.qml"
}
ConfigCategory {
name: i18n("Buttons")
icon: "preferences-activities"
source: "config/ConfigButtons.qml"
}
ConfigCategory {
name: i18n("Application Menu")
icon: "application-menu"
source: "config/ConfigAppMenu.qml"
}
ConfigCategory {
name: i18n("Mouse Control")
icon: "preferences-desktop-mouse"
source: "config/ConfigMouseControl.qml"
}
}
diff --git a/package/contents/config/main.xml b/package/contents/config/main.xml
index 3963f5b..99fed7c 100644
--- a/package/contents/config/main.xml
+++ b/package/contents/config/main.xml
@@ -1,228 +1,228 @@
icon|title|menu|buttons
5.0
0
true
false
1
0
true
true
0
0
true
true
0
0
false
false
1
0
false
false
0.2
0.0
-
- true
-
+
+
+
0
0
0
false
^(.*)\s*[—–\-:]\s*(Mozilla )?([^—–\-:]+)$
$3 — $1
Plasma Desktop :: %activity%
false
1000
0
-
+
-
- 1
+
+ 1.0
false
false
false
false
close|maximize|minimize|pin
false
10
0.5
0
true
false
1
true
1.0
true
0
0
false
0
diff --git a/package/contents/ui/WindowTitle.qml b/package/contents/ui/WindowTitle.qml
index 3170b34..885b39b 100644
--- a/package/contents/ui/WindowTitle.qml
+++ b/package/contents/ui/WindowTitle.qml
@@ -1,76 +1,76 @@
import QtQuick 2.2
import QtGraphicalEffects 1.0
import QtQuick.Layouts 1.1
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
PlasmaComponents.Label {
id: titleItem
property double properHeight: parent.height
property int fontBold: plasmoid.configuration.textFontBold
- property string fontFamily: plasmoid.configuration.fontFamily
+ property string textFontFamily: plasmoid.configuration.textFontFamily
property int fitText: plasmoid.configuration.fitText
property bool noElide: fitText === 2 || (fitText === 1 && mainMouseArea.containsMouse)
property int allowFontSizeChange: 3
property int minimumPixelSize: 8
property bool limitTextWidth: plasmoid.configuration.limitTextWidth
property int textWidthLimit: plasmoid.configuration.textWidthLimit
property double recommendedMaxWidth
property bool useUpPossibleWidth: main.useUpWidthItem === 0
property bool doNotRestrictWidth: useUpPossibleWidth && autoFillWidth
signal contentChanged()
onRecommendedMaxWidthChanged: {
var maxWidth = limitTextWidth ? Math.min(textWidthLimit, recommendedMaxWidth) : recommendedMaxWidth
width = undefined
if (useUpPossibleWidth || (implicitWidth > maxWidth)) {
width = maxWidth
}
print('title: width set to ' + width)
}
onUseUpPossibleWidthChanged: recommendedMaxWidthChanged()
onDoNotRestrictWidthChanged: {
if (doNotRestrictWidth) {
width = undefined
} else {
recommendedMaxWidthChanged()
}
}
verticalAlignment: Text.AlignVCenter
horizontalAlignment: plasmoid.configuration.controlPartTitleHorizontalAlignment === 0 ? Text.AlignLeft : Text.AlignRight
text: plasmoid.configuration.noWindowText
wrapMode: Text.Wrap
height: properHeight
elide: noElide ? Text.ElideNone : Text.ElideRight
font.pixelSize: fontPixelSize
font.pointSize: -1
font.weight: fontBold === 1 || (fontBold === 2 && menuItem.showItem) ? Font.Bold : theme.defaultFont.weight
- font.family: fontFamily || theme.defaultFont.family
+ font.family: textFontFamily || theme.defaultFont.family
onTextChanged: {
font.pixelSize = fontPixelSize
allowFontSizeChange = 3
recommendedMaxWidthChanged()
contentChanged()
}
onNoElideChanged: {
font.pixelSize = fontPixelSize
allowFontSizeChange = 3
}
onPaintedHeightChanged: {
if (allowFontSizeChange > 0 && noElide && paintedHeight > properHeight) {
var newPixelSize = (properHeight / paintedHeight) * fontPixelSize
font.pixelSize = newPixelSize < minimumPixelSize ? minimumPixelSize : newPixelSize
}
allowFontSizeChange--
}
}
\ No newline at end of file
diff --git a/package/contents/ui/code/profiles.js b/package/contents/ui/code/profiles.js
new file mode 100644
index 0000000..e8dbc0f
--- /dev/null
+++ b/package/contents/ui/code/profiles.js
@@ -0,0 +1,122 @@
+var ITEMS = [
+ {
+ "title": "Unity",
+ "configuration": {
+ "horizontalScreenWidthPercent": 0.25,
+
+ "controlPartOrder": "icon|title|buttons|menu",
+ "controlPartSpacing": 5.0,
+ "controlPartButtonsShowOnMouseIn": true,
+ "controlPartButtonsShowOnMouseOut": false,
+ "controlPartButtonsPosition": 1,
+ "controlPartButtonsHorizontalAlignment": 0,
+ "controlPartIconShowOnMouseIn": false,
+ "controlPartIconShowOnMouseOut": true,
+ "controlPartIconPosition": 0,
+ "controlPartIconHorizontalAlignment": 0,
+ "controlPartTitleShowOnMouseIn": false,
+ "controlPartTitleShowOnMouseOut": true,
+ "controlPartTitlePosition": 0,
+ "controlPartTitleHorizontalAlignment": 0,
+ "controlPartMenuShowOnMouseIn": true,
+ "controlPartMenuShowOnMouseOut": false,
+ "controlPartMenuPosition": 1,
+ "controlPartMenuHorizontalAlignment": 0,
+
+ "textFontBold": 1,
+
+ "buttonOrder": "close|maximize|minimize|alldesktops",
+ "showMaximize": true,
+ "showMinimize": true,
+ "showPinToAllDesktops": false,
+ "showButtonOnlyWhenMaximized": false,
+ "controlButtonsSpacing": 0,
+ "buttonSize": 1,
+ "buttonsVerticalPosition": 1,
+
+ "appmenuFontBold": false,
+ "appmenuSeparatorEnabled": false,
+ "appmenuVerticalPosition": 1
+ }
+ },
+ {
+ "title": "One Liner",
+ "configuration": {
+ "horizontalScreenWidthPercent": 0.33,
+
+ "controlPartOrder": "buttons|icon|title|menu",
+ "controlPartSpacing": 5.0,
+ "controlPartButtonsShowOnMouseIn": true,
+ "controlPartButtonsShowOnMouseOut": true,
+ "controlPartButtonsPosition": 0,
+ "controlPartButtonsHorizontalAlignment": 0,
+ "controlPartIconShowOnMouseIn": true,
+ "controlPartIconShowOnMouseOut": true,
+ "controlPartIconPosition": 0,
+ "controlPartIconHorizontalAlignment": 0,
+ "controlPartTitleShowOnMouseIn": true,
+ "controlPartTitleShowOnMouseOut": true,
+ "controlPartTitlePosition": 0,
+ "controlPartTitleHorizontalAlignment": 0,
+ "controlPartMenuShowOnMouseIn": true,
+ "controlPartMenuShowOnMouseOut": true,
+ "controlPartMenuPosition": 0,
+ "controlPartMenuHorizontalAlignment": 0,
+
+ "textFontBold": 0,
+
+ "buttonOrder": "close|maximize|minimize|alldesktops",
+ "showMaximize": true,
+ "showMinimize": true,
+ "showPinToAllDesktops": false,
+ "showButtonOnlyWhenMaximized": false,
+ "controlButtonsSpacing": 0,
+ "buttonSize": 1,
+ "buttonsVerticalPosition": 1,
+
+ "appmenuFontBold": false,
+ "appmenuSeparatorEnabled": true,
+ "appmenuVerticalPosition": 1
+ }
+ },
+ {
+ "title": "Thick Panel",
+ "configuration": {
+ "horizontalScreenWidthPercent": 0.20,
+
+ "controlPartOrder": "icon|title|menu|buttons",
+ "controlPartSpacing": 5.0,
+ "controlPartButtonsShowOnMouseIn": true,
+ "controlPartButtonsShowOnMouseOut": false,
+ "controlPartButtonsPosition": 2,
+ "controlPartButtonsHorizontalAlignment": 0,
+ "controlPartIconShowOnMouseIn": false,
+ "controlPartIconShowOnMouseOut": true,
+ "controlPartIconPosition": 0,
+ "controlPartIconHorizontalAlignment": 0,
+ "controlPartTitleShowOnMouseIn": false,
+ "controlPartTitleShowOnMouseOut": true,
+ "controlPartTitlePosition": 0,
+ "controlPartTitleHorizontalAlignment": 0,
+ "controlPartMenuShowOnMouseIn": true,
+ "controlPartMenuShowOnMouseOut": false,
+ "controlPartMenuPosition": 2,
+ "controlPartMenuHorizontalAlignment": 0,
+
+ "textFontBold": 0,
+
+ "buttonOrder": "close|maximize|minimize|alldesktops",
+ "showMaximize": true,
+ "showMinimize": true,
+ "showPinToAllDesktops": false,
+ "showButtonOnlyWhenMaximized": false,
+ "controlButtonsSpacing": 5,
+ "buttonSize": 0.4,
+ "buttonsVerticalPosition": 0,
+
+ "appmenuFontBold": false,
+ "appmenuSeparatorEnabled": false,
+ "appmenuVerticalPosition": 2
+ }
+ }
+]
\ No newline at end of file
diff --git a/package/contents/ui/config/ConfigLayout.qml b/package/contents/ui/config/ConfigLayout.qml
index 98c8121..4db5232 100644
--- a/package/contents/ui/config/ConfigLayout.qml
+++ b/package/contents/ui/config/ConfigLayout.qml
@@ -1,433 +1,480 @@
import QtQuick 2.2
import QtQuick.Controls 1.3
import QtQuick.Layouts 1.1
import QtQml.Models 2.1
+import "../code/profiles.js" as Profiles
Item {
id: configLayout
property string cfg_controlPartOrder
property alias cfg_controlPartSpacing: controlPartSpacing.value
property alias cfg_useUpWidthItem: useUpWidthItem.currentIndex
// GENERATED config (start)
property alias cfg_controlPartIconShowOnMouseIn: controlPartIconShowOnMouseIn.checked
property alias cfg_controlPartIconShowOnMouseOut: controlPartIconShowOnMouseOut.checked
property alias cfg_controlPartIconPosition: controlPartIconPosition.currentIndex
property alias cfg_controlPartIconHorizontalAlignment: controlPartIconHorizontalAlignment.currentIndex
property alias cfg_controlPartTitleShowOnMouseIn: controlPartTitleShowOnMouseIn.checked
property alias cfg_controlPartTitleShowOnMouseOut: controlPartTitleShowOnMouseOut.checked
property alias cfg_controlPartTitlePosition: controlPartTitlePosition.currentIndex
property alias cfg_controlPartTitleHorizontalAlignment: controlPartTitleHorizontalAlignment.currentIndex
property alias cfg_controlPartButtonsShowOnMouseIn: controlPartButtonsShowOnMouseIn.checked
property alias cfg_controlPartButtonsShowOnMouseOut: controlPartButtonsShowOnMouseOut.checked
property alias cfg_controlPartButtonsPosition: controlPartButtonsPosition.currentIndex
property alias cfg_controlPartButtonsHorizontalAlignment: controlPartButtonsHorizontalAlignment.currentIndex
property alias cfg_controlPartMenuShowOnMouseIn: controlPartMenuShowOnMouseIn.checked
property alias cfg_controlPartMenuShowOnMouseOut: controlPartMenuShowOnMouseOut.checked
property alias cfg_controlPartMenuPosition: controlPartMenuPosition.currentIndex
property alias cfg_controlPartMenuHorizontalAlignment: controlPartMenuHorizontalAlignment.currentIndex
// GENERATED config (end)
property alias cfg_controlPartMouseAreaRestrictedToWidget: controlPartMouseAreaRestrictedToWidget.checked
property alias cfg_autoFillWidth: autoFillWidth.checked
property alias cfg_horizontalScreenWidthPercent: horizontalScreenWidthPercent.value
property alias cfg_widthFineTuning: widthFineTuning.value
+ // properties from other config pages
+ // we need them here to be able to apply profiles from this config page
+ property bool cfg_textFontBold
+ property string cfg_buttonOrder
+ property bool cfg_showMaximize
+ property bool cfg_showMinimize
+ property bool cfg_showPinToAllDesktops
+ property bool cfg_showButtonOnlyWhenMaximized
+ property double cfg_controlButtonsSpacing
+ property double cfg_buttonSize
+ property int cfg_buttonsVerticalPosition
+ property bool cfg_appmenuFontBold
+ property bool cfg_appmenuSeparatorEnabled
+ property int cfg_appmenuVerticalPosition
+
ListModel {
id: partsToSpend
ListElement {
name: 'icon'
text: 'Icon'
}
ListElement {
name: 'title'
text: 'Title'
}
ListElement {
name: 'buttons'
text: 'Buttons'
}
ListElement {
name: 'menu'
text: 'Menu'
}
}
function sortPartOrder() {
buttonOrder.model.clear()
cfg_controlPartOrder.split('|').forEach(function (itemId, index) {
var partIndex = -1
print('adding ' + itemId);
if (itemId === 'icon') {
partIndex = 0
} else if (itemId === 'title') {
partIndex = 1
} else if (itemId === 'buttons') {
partIndex = 2
} else if (itemId === 'menu') {
partIndex = 3
}
if (partIndex >= 0) {
buttonOrder.model.append(partsToSpend.get(partIndex));
}
});
print('model count: ' + buttonOrder.model.count)
}
+ onCfg_controlPartOrderChanged: sortPartOrder()
+
GridLayout {
columns: 3
Label {
text: i18n('Plasmoid version: ') + '1.8.0-git'
Layout.alignment: Qt.AlignRight
Layout.columnSpan: 3
}
+ Label {
+ text: i18n('Profiles:')
+ Layout.alignment: Qt.AlignLeft
+ }
+ ComboBox {
+ id: profilesCombo
+ model: []
+ onCurrentIndexChanged: {
+ if (currentIndex < 1) {
+ return
+ }
+ var item = Profiles.ITEMS[currentIndex - 1]
+ print('setting profile: ' + item.title)
+ var config = item.configuration
+ for (var key in config) {
+ var configPropName = 'cfg_' + key
+ if (configPropName in configLayout) {
+ configLayout[configPropName] = config[key]
+ }
+ }
+ }
+ }
+
Item {
width: 2
height: units.largeSpacing
Layout.columnSpan: 3
}
Label {
text: i18n("Item order:")
}
OrderableListView {
id: buttonOrder
Layout.columnSpan: 2
itemHeight: units.gridUnit * 2
itemWidth: units.gridUnit * 4
height: itemHeight
width: itemWidth * 4
model: ListModel {
// will be filled initially by sortButtonOrder() method
}
orientation: ListView.Horizontal
onModelOrderChanged: {
var orderStr = '';
for (var i = 0; i < model.count; i++) {
var item = model.get(i)
if (orderStr.length > 0) {
orderStr += '|';
}
orderStr += item.name;
}
cfg_controlPartOrder = orderStr;
print('written: ' + cfg_controlPartOrder);
}
}
Label {
text: i18n("Item spacing:")
}
SpinBox {
id: controlPartSpacing
decimals: 1
stepSize: 0.5
minimumValue: 0.5
maximumValue: 300
Layout.columnSpan: 2
}
Label {
text: i18n('Item to use up remaining width:')
}
ComboBox {
id: useUpWidthItem
model: [i18n('Title'), i18n('Menu'), i18n('None')]
Layout.columnSpan: 2
}
// GENERATED controls (start)
GridLayout {
columns: 2
Item {
width: 2
height: units.largeSpacing
Layout.columnSpan: 2
}
Label {
text: i18n('Icon')
font.bold: true
Layout.columnSpan: 2
}
Label {
text: i18n('Show:')
Layout.alignment: Qt.AlignRight
}
CheckBox {
id: controlPartIconShowOnMouseIn
text: i18n('On mouse in')
}
Item {
width: 2
height: 2
}
CheckBox {
id: controlPartIconShowOnMouseOut
text: i18n('On mouse out')
}
Label {
text: i18n('Position:')
Layout.alignment: Qt.AlignRight
enabled: controlPartIconPosition.enabled
}
ComboBox {
id: controlPartIconPosition
model: [i18n('Occupy'), i18n('Floating layer'), i18n('Absolute')]
enabled: controlPartIconShowOnMouseIn.checked || controlPartIconShowOnMouseOut.checked
}
Label {
text: i18n('Align:')
Layout.alignment: Qt.AlignRight
enabled: controlPartIconPosition.enabled
}
ComboBox {
id: controlPartIconHorizontalAlignment
model: [i18n('Left'), i18n('Right')]
enabled: controlPartIconPosition.enabled
}
Item {
width: 2
height: units.largeSpacing
Layout.columnSpan: 2
}
Label {
text: i18n('Buttons')
font.bold: true
Layout.columnSpan: 2
}
Label {
text: i18n('Show:')
Layout.alignment: Qt.AlignRight
}
CheckBox {
id: controlPartButtonsShowOnMouseIn
text: i18n('On mouse in')
}
Item {
width: 2
height: 2
}
CheckBox {
id: controlPartButtonsShowOnMouseOut
text: i18n('On mouse out')
}
Label {
text: i18n('Position:')
Layout.alignment: Qt.AlignRight
enabled: controlPartButtonsPosition.enabled
}
ComboBox {
id: controlPartButtonsPosition
model: [i18n('Occupy'), i18n('Floating layer'), i18n('Absolute')]
enabled: controlPartButtonsShowOnMouseIn.checked || controlPartButtonsShowOnMouseOut.checked
}
Label {
text: i18n('Align:')
Layout.alignment: Qt.AlignRight
enabled: controlPartButtonsPosition.enabled
}
ComboBox {
id: controlPartButtonsHorizontalAlignment
model: [i18n('Left'), i18n('Right')]
enabled: controlPartButtonsPosition.enabled
}
}
Item {
width: units.largeSpacing
height: units.largeSpacing
}
GridLayout {
columns: 2
Item {
width: 2
height: units.largeSpacing
Layout.columnSpan: 2
}
Label {
text: i18n('Title')
font.bold: true
Layout.columnSpan: 2
}
Label {
text: i18n('Show:')
Layout.alignment: Qt.AlignRight
}
CheckBox {
id: controlPartTitleShowOnMouseIn
text: i18n('On mouse in')
}
Item {
width: 2
height: 2
}
CheckBox {
id: controlPartTitleShowOnMouseOut
text: i18n('On mouse out')
}
Label {
text: i18n('Position:')
Layout.alignment: Qt.AlignRight
enabled: controlPartTitlePosition.enabled
}
ComboBox {
id: controlPartTitlePosition
model: [i18n('Occupy'), i18n('Floating layer'), i18n('Absolute')]
enabled: controlPartTitleShowOnMouseIn.checked || controlPartTitleShowOnMouseOut.checked
}
Label {
text: i18n('Align:')
Layout.alignment: Qt.AlignRight
enabled: controlPartTitlePosition.enabled
}
ComboBox {
id: controlPartTitleHorizontalAlignment
model: [i18n('Left'), i18n('Right')]
enabled: controlPartTitlePosition.enabled
}
Item {
width: 2
height: units.largeSpacing
Layout.columnSpan: 2
}
Label {
text: i18n('Menu')
font.bold: true
Layout.columnSpan: 2
}
Label {
text: i18n('Show:')
Layout.alignment: Qt.AlignRight
}
CheckBox {
id: controlPartMenuShowOnMouseIn
text: i18n('On mouse in')
}
Item {
width: 2
height: 2
}
CheckBox {
id: controlPartMenuShowOnMouseOut
text: i18n('On mouse out')
}
Label {
text: i18n('Position:')
Layout.alignment: Qt.AlignRight
enabled: controlPartMenuPosition.enabled
}
ComboBox {
id: controlPartMenuPosition
model: [i18n('Occupy'), i18n('Floating layer'), i18n('Absolute')]
enabled: controlPartMenuShowOnMouseIn.checked || controlPartMenuShowOnMouseOut.checked
}
Label {
text: i18n('Align:')
Layout.alignment: Qt.AlignRight
enabled: controlPartMenuPosition.enabled
}
ComboBox {
id: controlPartMenuHorizontalAlignment
model: [i18n('Left'), i18n('Right')]
enabled: controlPartMenuPosition.enabled
}
}
// GENERATED controls (end)
Item {
width: units.largeSpacing
height: units.largeSpacing
Layout.columnSpan: 3
}
CheckBox {
id: controlPartMouseAreaRestrictedToWidget
text: i18n('Restrict mouse area to widget')
Layout.columnSpan: 3
}
Item {
width: units.largeSpacing
height: units.largeSpacing
Layout.columnSpan: 3
}
Label {
text: i18n("Width in horizontal panel:")
font.bold: true
Layout.alignment: Qt.AlignLeft
Layout.columnSpan: 3
}
CheckBox {
id: autoFillWidth
text: i18n("Fill width")
Layout.columnSpan: 3
}
GridLayout {
columns: 2
Layout.columnSpan: 3
enabled: !autoFillWidth.checked
Slider {
id: horizontalScreenWidthPercent
stepSize: 0.001
minimumValue: 0.001
maximumValue: 1
Layout.preferredWidth: configLayout.width
Layout.columnSpan: 2
}
Label {
text: i18n("Fine tuning:")
Layout.alignment: Qt.AlignRight
}
SpinBox {
id: widthFineTuning
decimals: 1
stepSize: 0.5
minimumValue: -100
maximumValue: 100
}
}
}
Component.onCompleted: {
sortPartOrder()
+ var profileNames = ['Default']
+ Profiles.ITEMS.forEach(function (item) {
+ print('profile: ' + item.title)
+ profileNames.push(item.title)
+ })
+ profilesCombo.model = profileNames
}
}
diff --git a/package/contents/ui/config/ConfigTitleAndIcon.qml b/package/contents/ui/config/ConfigTitleAndIcon.qml
index 45b6d7f..9993351 100644
--- a/package/contents/ui/config/ConfigTitleAndIcon.qml
+++ b/package/contents/ui/config/ConfigTitleAndIcon.qml
@@ -1,233 +1,233 @@
import QtQuick 2.2
import QtQuick.Controls 1.3
import QtQuick.Layouts 1.1
import org.kde.plasma.core 2.0 as PlasmaCore
Item {
property alias cfg_textType: textTypeCombo.currentIndex
property alias cfg_fitText: fitTextCombo.currentIndex
property alias cfg_tooltipTextType: tooltipTextTypeCombo.currentIndex
property alias cfg_useWindowTitleReplace: useWindowTitleReplace.checked
property alias cfg_replaceTextRegex: replaceTextRegex.text
property alias cfg_replaceTextReplacement: replaceTextReplacement.text
property alias cfg_noWindowText: noWindowText.text
property string cfg_noWindowIcon: plasmoid.configuration.noWindowIcon
property alias cfg_limitTextWidth: limitTextWidth.checked
property alias cfg_textWidthLimit: textWidthLimit.value
property alias cfg_textFontBold: textFontBoldCombo.currentIndex
- property string cfg_fontFamily
- property alias cfg_fontSizeScale: fontSizeScale.value
+ property string cfg_textFontFamily
+ property alias cfg_textFontSizeScale: textFontSizeScale.value
/* copied from /usr/share/plasma/plasmoids/org.kde.plasma.digitalclock/contents/ui/configAppearance.qml */
- onCfg_fontFamilyChanged: {
+ onCfg_textFontFamilyChanged: {
// HACK by the time we populate our model and/or the ComboBox is finished the value is still undefined
- if (cfg_fontFamily) {
+ if (cfg_textFontFamily) {
for (var i = 0, j = fontsModel.count; i < j; ++i) {
- if (fontsModel.get(i).value == cfg_fontFamily) {
- fontFamilyComboBox.currentIndex = i
+ if (fontsModel.get(i).value == cfg_textFontFamily) {
+ textFontFamilyComboBox.currentIndex = i
break
}
}
}
}
ListModel {
id: fontsModel
Component.onCompleted: {
var arr = [ {text: i18nc("Use default font", "Default"), value: ""} ]
Qt.fontFamilies().forEach(function (font) {
arr.push({text: font, value: font})
})
append(arr)
- cfg_fontFamilyChanged();
+ cfg_textFontFamilyChanged();
}
}
GridLayout {
columns: 2
Label {
text: i18n('Title')
Layout.alignment: Qt.AlignLeft
font.bold: true
Layout.columnSpan: 2
}
Label {
text: i18n('Text type:')
Layout.alignment: Qt.AlignRight
}
ComboBox {
id: textTypeCombo
model: [i18n('Window title'), i18n('Application name')]
}
Label {
text: i18n('Fit text:')
Layout.alignment: Qt.AlignRight
}
ComboBox {
id: fitTextCombo
model: [i18n('Just elide'), i18n('Fit on hover'), i18n('Always fit')]
}
Label {
text: i18n('Tooltip text:')
Layout.alignment: Qt.AlignRight
}
ComboBox {
id: tooltipTextTypeCombo
model: [i18n('No tooltip'), i18n('Window title'), i18n('Application name')]
}
Item {
width: 2
height: units.largeSpacing
Layout.columnSpan: 2
}
Label {
text: i18n('Bold text:')
Layout.alignment: Qt.AlignRight
}
ComboBox {
id: textFontBoldCombo
// ComboBox's sizing is just utterly broken
Layout.minimumWidth: units.gridUnit * 10
model: [i18n('Never'), i18n('Always'), i18n('When appmenu is displayed')]
}
Label {
text: i18n('Text font:')
Layout.alignment: Qt.AlignRight
}
ComboBox {
- id: fontFamilyComboBox
+ id: textFontFamilyComboBox
// ComboBox's sizing is just utterly broken
Layout.minimumWidth: units.gridUnit * 10
model: fontsModel
// doesn't autodeduce from model because we manually populate it
textRole: "text"
onCurrentIndexChanged: {
var current = model.get(currentIndex)
if (current) {
- cfg_fontFamily = current.value
+ cfg_textFontFamily = current.value
//appearancePage.configurationChanged()
- console.log('change: ' + cfg_fontFamily)
+ console.log('change: ' + cfg_textFontFamily)
}
}
}
Label {
text: i18n("Font size scale:")
Layout.alignment: Qt.AlignVCenter|Qt.AlignRight
}
SpinBox {
- id: fontSizeScale
+ id: textFontSizeScale
decimals: 2
stepSize: 0.05
minimumValue: 0
maximumValue: 3
}
CheckBox {
id: limitTextWidth
text: i18n('Limit text width')
Layout.alignment: Qt.AlignRight
}
SpinBox {
id: textWidthLimit
decimals: 0
stepSize: 10
minimumValue: 0
maximumValue: 10000
enabled: limitTextWidth.checked
suffix: i18nc('Abbreviation for pixels', 'px')
}
Item {
width: 2
height: units.largeSpacing
Layout.columnSpan: 2
}
CheckBox {
id: useWindowTitleReplace
text: '"' + i18n('Window title') + '".replace(/'
Layout.alignment: Qt.AlignRight
}
GridLayout {
columns: 4
TextField {
id: replaceTextRegex
placeholderText: '^(.*)\\s+[—–\\-:]\\s+([^—–\\-:]+)$'
Layout.preferredWidth: 270
onTextChanged: cfg_replaceTextRegex = text
enabled: useWindowTitleReplace.checked
}
Label {
text: '/, "'
}
TextField {
id: replaceTextReplacement
placeholderText: '$2 — $1'
Layout.preferredWidth: 100
onTextChanged: cfg_replaceTextReplacement = text
enabled: useWindowTitleReplace.checked
}
Label {
text: '");'
}
}
Label {
text: i18n('No window text:')
Layout.alignment: Qt.AlignRight
}
GridLayout {
columns: 2
TextField {
id: noWindowText
placeholderText: 'Plasma Desktop :: %activity%'
onTextChanged: cfg_noWindowText = text
Layout.preferredWidth: 270
}
Label {
text: i18n('Use %activity% placeholder to show current activity name.')
Layout.preferredWidth: 150
wrapMode: Text.Wrap
}
}
Item {
width: 2
height: units.largeSpacing
Layout.columnSpan: 2
}
Label {
text: i18n('Icon')
Layout.alignment: Qt.AlignLeft
font.bold: true
Layout.columnSpan: 2
}
Label {
text: i18n("No window icon:")
Layout.alignment: Qt.AlignRight
}
IconPicker {
currentIcon: cfg_noWindowIcon
defaultIcon: ''
onIconChanged: cfg_noWindowIcon = iconName
}
}
}
diff --git a/package/contents/ui/main.qml b/package/contents/ui/main.qml
index b3f29f1..fa2b574 100644
--- a/package/contents/ui/main.qml
+++ b/package/contents/ui/main.qml
@@ -1,619 +1,619 @@
/*
* Copyright 2015 Martin Kotelnik
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
import QtQuick 2.2
import QtGraphicalEffects 1.0
import QtQuick.Layouts 1.1
import QtQuick.Window 2.2
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.taskmanager 0.1 as TaskManager
import org.kde.activities 0.1 as Activities
Item {
id: main
property bool vertical: (plasmoid.formFactor == PlasmaCore.Types.Vertical)
property double horizontalScreenWidthPercent: plasmoid.configuration.horizontalScreenWidthPercent
property bool autoFillWidth: plasmoid.configuration.autoFillWidth
property double widthForHorizontalPanel: (Screen.width * horizontalScreenWidthPercent + plasmoid.configuration.widthFineTuning)
property int useUpWidthItem: plasmoid.configuration.useUpWidthItem
property int textType: plasmoid.configuration.textType
property int tooltipTextType: plasmoid.configuration.tooltipTextType
property string tooltipText: ''
- property double fontPixelSize: theme.defaultFont.pixelSize * plasmoid.configuration.fontSizeScale
+ property double fontPixelSize: theme.defaultFont.pixelSize * plasmoid.configuration.textFontSizeScale
property bool noWindowActive: true
property bool currentWindowMaximized: false
property bool doubleClickMaximizes: plasmoid.configuration.doubleClickMaximizes
property int leftClickAction: plasmoid.configuration.leftClickAction
property string chosenLeftClickSource: leftClickAction === 1 ? shortcutDS.presentWindows : leftClickAction === 2 ? shortcutDS.presentWindowsAll : leftClickAction === 3 ? shortcutDS.presentWindowsClass : ''
property bool middleClickClose: plasmoid.configuration.middleClickAction === 1
property bool middleClickFullscreen: plasmoid.configuration.middleClickAction === 2
property bool wheelUpMaximizes: plasmoid.configuration.wheelUpMaximizes
property bool wheelDownMinimizes: plasmoid.configuration.wheelDownAction === 1
property bool wheelDownUnmaximizes: plasmoid.configuration.wheelDownAction === 2
property bool textColorLight: ((theme.textColor.r + theme.textColor.g + theme.textColor.b) / 3) > 0.5
property bool isActiveWindowPinned: false
property bool isActiveWindowMaximized: false
property bool controlPartMouseAreaRestrictedToWidget: plasmoid.configuration.controlPartMouseAreaRestrictedToWidget
property var activeTaskLocal: null
property int activityActionCount: 0
property var itemPartOrder: []
property bool mouseInWidget: mainMouseArea.containsMouse || buttonsItem.mouseInWidget || menuItem.mouseInWidget
anchors.fill: parent
Layout.fillWidth: autoFillWidth
Layout.preferredWidth: autoFillWidth ? -1 : (vertical ? parent.width : (widthForHorizontalPanel > 0 ? widthForHorizontalPanel : 0.0001))
Layout.minimumWidth: Layout.preferredWidth
Layout.maximumWidth: Layout.preferredWidth
Layout.preferredHeight: parent === null ? 0 : vertical ? Math.min(theme.defaultFont.pointSize * 4, parent.width) : parent.height
Layout.minimumHeight: Layout.preferredHeight
Layout.maximumHeight: Layout.preferredHeight
Plasmoid.preferredRepresentation: Plasmoid.fullRepresentation
Plasmoid.status: {
if (menuItem.appmenuOpened) {
return PlasmaCore.Types.NeedsAttentionStatus;
} else if (!menuItem.appmenuOpened && menuItem.appmenuEnabledAndNonEmpty){
return PlasmaCore.Types.ActiveStatus;
} else {
return PlasmaCore.Types.PassiveStatus;
}
}
//
// MODEL
//
TaskManager.TasksModel {
id: tasksModel
sortMode: TaskManager.TasksModel.SortVirtualDesktop
groupMode: TaskManager.TasksModel.GroupDisabled
screenGeometry: plasmoid.screenGeometry
filterByScreen: plasmoid.configuration.showForCurrentScreenOnly
onActiveTaskChanged: {
updateActiveWindowInfo()
}
onDataChanged: {
updateActiveWindowInfo()
}
onCountChanged: {
updateActiveWindowInfo()
}
}
TaskManager.ActivityInfo {
id: activityInfo
onCurrentActivityChanged: {
if (noWindowActive) {
updateActiveWindowInfo();
}
reAddActivityActions()
}
onNumberOfRunningActivitiesChanged: {
reAddActivityActions()
}
}
Activities.ActivityModel {
id: activityModel
}
function activeTask() {
return activeTaskLocal
}
function activeTaskExists() {
return activeTaskLocal.display !== undefined
}
function updateTooltip() {
if (tooltipTextType === 1) {
tooltipText = replaceTitle(activeTask().display || '')
} else if (tooltipTextType === 2) {
tooltipText = activeTask().AppName || ''
} else {
tooltipText = ''
}
}
onTooltipTextTypeChanged: updateTooltip()
function composeNoWindowText() {
return plasmoid.configuration.noWindowText.replace('%activity%', activityInfo.activityName(activityInfo.currentActivity))
}
function updateActiveWindowInfo() {
var activeTaskIndex = tasksModel.activeTask
// fallback for Plasma 5.8
var abstractTasksModel = TaskManager.AbstractTasksModel || {}
var isActive = abstractTasksModel.IsActive || 271
var appName = abstractTasksModel.AppName || 258
var isMaximized = abstractTasksModel.IsMaximized || 276
var virtualDesktop = abstractTasksModel.VirtualDesktop || 286
activeTaskLocal = {}
if (tasksModel.data(activeTaskIndex, isActive)) {
activeTaskLocal = {
display: tasksModel.data(activeTaskIndex, Qt.DisplayRole),
decoration: tasksModel.data(activeTaskIndex, Qt.DecorationRole),
AppName: tasksModel.data(activeTaskIndex, appName),
IsMaximized: tasksModel.data(activeTaskIndex, isMaximized),
VirtualDesktop: tasksModel.data(activeTaskIndex, virtualDesktop)
}
}
var actTask = activeTask()
noWindowActive = !activeTaskExists()
currentWindowMaximized = !noWindowActive && actTask.IsMaximized === true
isActiveWindowPinned = actTask.VirtualDesktop === -1;
if (noWindowActive) {
titleItem.text = composeNoWindowText()
iconItem.source = plasmoid.configuration.noWindowIcon
} else {
titleItem.text = (textType === 1 ? actTask.AppName : null) || replaceTitle(actTask.display)
iconItem.source = actTask.decoration
}
updateTooltip()
}
function toggleMaximized() {
tasksModel.requestToggleMaximized(tasksModel.activeTask);
}
function toggleMinimized() {
tasksModel.requestToggleMinimized(tasksModel.activeTask);
}
function toggleClose() {
tasksModel.requestClose(tasksModel.activeTask);
}
function toggleFullscreen() {
tasksModel.requestToggleFullScreen(tasksModel.activeTask);
}
function togglePinToAllDesktops() {
tasksModel.requestVirtualDesktop(tasksModel.activeTask, 0);
}
function setMaximized(maximized) {
if ((maximized && !activeTask().IsMaximized)
|| (!maximized && activeTask().IsMaximized)) {
print('toggle maximized')
toggleMaximized()
}
}
function setMinimized() {
if (!activeTask().IsMinimized) {
toggleMinimized()
}
}
function getConfigName(itemName) {
return itemName.substring(0, 1).toUpperCase() + itemName.substring(1)
}
/*
* Position can be:
* 0 ... occupy
* 1 ... floating layer (second occupy)
* 2 ... absolute
*/
function getPosition(itemName) {
var configName = getConfigName(itemName)
return plasmoid.configuration['controlPart' + configName + 'Position']
}
/*
* Alignment can be:
* 0 ... left
* 1 ... right
*/
function getAlignment(itemName) {
var configName = getConfigName(itemName)
return plasmoid.configuration['controlPart' + configName + 'HorizontalAlignment']
}
function isRelevant(itemName) {
var configName = getConfigName(itemName)
var mouseInConfigName = 'controlPart' + configName + 'ShowOnMouseIn'
var mouseOutConfigName = 'controlPart' + configName + 'ShowOnMouseOut'
return plasmoid.configuration[mouseInConfigName] || plasmoid.configuration[mouseOutConfigName]
}
function getItem(itemName) {
if (itemName === 'icon') {
return iconItem
}
if (itemName === 'title') {
return titleItem
}
if (itemName === 'menu') {
return menuItem
}
if (itemName === 'buttons') {
return buttonsItem
}
return null
}
function getItemWidth(itemName) {
if (itemName === 'title') {
return Math.min(titleItem.implicitWidth, titleItem.recommendedMaxWidth)
}
if (itemName === 'menu') {
return Math.min(menuItem.innerItemWidth, menuItem.recommendedMaxWidth)
}
if (itemName === 'icon' && noWindowActive && !iconItem.source) {
return 0
}
return getItem(itemName).width
}
function getLeftMargin(itemName) {
var itemPosition = getPosition(itemName)
var itemAlignment = getAlignment(itemName)
print('position of ' + itemName + ' is ' + itemPosition)
if (itemPosition === 2) {
return 0
}
var anchorSize = 0
var itemPartOrderArray = itemAlignment === 0 ? itemPartOrder : itemPartOrder.slice().reverse()
itemPartOrderArray.some(function (iName, index) {
print('iterating: ' + iName)
if (iName === itemName) {
return true
}
if (getPosition(iName) === itemPosition && getAlignment(iName) === itemAlignment && isRelevant(iName)) {
var currentItemWidth = getItemWidth(iName)
print('width of ' + iName + ' is ' + currentItemWidth)
anchorSize += currentItemWidth
anchorSize += plasmoid.configuration.controlPartSpacing
}
});
if (itemAlignment === 1) {
var computedWidth = autoFillWidth ? main.width : widthForHorizontalPanel
anchorSize = computedWidth - anchorSize - getItemWidth(itemName)
}
print('leftMargin of ' + itemName + ' is ' + anchorSize)
return anchorSize
}
function getMaxWidth(itemName) {
var itemPosition = getPosition(itemName)
print('getMaxWidth(): position of ' + itemName + ' is ' + itemPosition)
if (itemPosition === 2) {
return 0
}
var computedWidth = autoFillWidth ? main.width : widthForHorizontalPanel
print('available width is ' + computedWidth)
var minWidth = main.height
itemPartOrder.forEach(function (iName, index) {
print('iterating: ' + iName)
if (iName === itemName) {
return;
}
if (getPosition(iName) === itemPosition && isRelevant(iName)) {
var currentItemWidth = getItemWidth(iName)
print('width of ' + iName + ' is ' + currentItemWidth)
computedWidth -= currentItemWidth
computedWidth -= plasmoid.configuration.controlPartSpacing
}
});
print('computedWidth of ' + itemName + ' is ' + computedWidth)
if (computedWidth < minWidth) {
print('computedWidth changed to minWidth: ' + minWidth)
return minWidth
}
return computedWidth
}
function refreshItemPosition() {
if (menuItem.useUpPossibleWidth) {
titleItem.recommendedMaxWidth = getMaxWidth('title')
menuItem.recommendedMaxWidth = getMaxWidth('menu')
} else {
menuItem.recommendedMaxWidth = getMaxWidth('menu')
titleItem.recommendedMaxWidth = getMaxWidth('title')
}
iconItem.x = getLeftMargin('icon')
titleItem.x = getLeftMargin('title')
menuItem.x = getLeftMargin('menu')
buttonsItem.x = getLeftMargin('buttons')
textSeparator.x = getLeftMargin('menu')// - (plasmoid.configuration.controlPartSpacing / 2)
}
function replaceTitle(title) {
if (!plasmoid.configuration.useWindowTitleReplace) {
return title
}
return title.replace(new RegExp(plasmoid.configuration.replaceTextRegex), plasmoid.configuration.replaceTextReplacement);
}
onWidthChanged: {
if (autoFillWidth) {
refreshItemPosition();
}
}
onWidthForHorizontalPanelChanged: refreshItemPosition()
MouseArea {
id: mainMouseArea
anchors.fill: parent
hoverEnabled: true
acceptedButtons: Qt.LeftButton | Qt.MiddleButton
onWheel: {
if (wheel.angleDelta.y > 0) {
if (wheelUpMaximizes) {
setMaximized(true)
}
} else {
if (wheelDownMinimizes) {
setMinimized()
} else if (wheelDownUnmaximizes) {
setMaximized(false)
}
}
}
onDoubleClicked: {
if (doubleClickMaximizes && mouse.button == Qt.LeftButton) {
toggleMaximized()
}
}
onClicked: {
if (chosenLeftClickSource !== '' && !doubleClickMaximizes && mouse.button == Qt.LeftButton) {
shortcutDS.connectedSources.push(chosenLeftClickSource)
buttonsItem.mouseInWidget = false
return
}
if (mouse.button == Qt.MiddleButton) {
if (middleClickFullscreen) {
toggleFullscreen()
} else if (middleClickClose) {
toggleClose()
}
}
}
PlasmaCore.ToolTipArea {
anchors.fill: parent
active: tooltipTextType > 0 && tooltipText !== ''
interactive: true
location: plasmoid.location
mainItem: Row {
spacing: 0
Layout.minimumWidth: fullText.width + units.largeSpacing
Layout.minimumHeight: childrenRect.height
Layout.maximumWidth: Layout.minimumWidth
Layout.maximumHeight: Layout.minimumHeight
Item {
width: units.largeSpacing / 2
height: 2
}
PlasmaComponents.Label {
id: fullText
text: tooltipText
}
}
}
}
ListModel {
id: controlButtonsModel
}
WindowIcon {
id: iconItem
visible: ((mouseInWidget && plasmoid.configuration.controlPartIconShowOnMouseIn)
|| (!mouseInWidget && plasmoid.configuration.controlPartIconShowOnMouseOut))
onWidthChanged: refreshItemPosition()
onSourceChanged: {
if (!source) {
refreshItemPosition()
}
}
}
WindowTitle {
id: titleItem
visible: ((mouseInWidget && plasmoid.configuration.controlPartTitleShowOnMouseIn)
|| (!mouseInWidget && plasmoid.configuration.controlPartTitleShowOnMouseOut))
onContentChanged: {
print('onContentChanged - TITLE')
refreshItemPosition()
}
onUseUpPossibleWidthChanged: refreshItemPosition()
}
AppMenu {
id: menuItem
property bool mouseIn: controlPartMouseAreaRestrictedToWidget ? menuItem.mouseInWidget : main.mouseInWidget
height: main.height
showItem: !noWindowActive && ((mouseIn && plasmoid.configuration.controlPartMenuShowOnMouseIn)
|| (!mouseIn && plasmoid.configuration.controlPartMenuShowOnMouseOut))
onContentChanged: {
print('onContentChanged - MENU')
refreshItemPosition()
}
onUseUpPossibleWidthChanged: refreshItemPosition()
}
ControlButtons {
id: buttonsItem
property bool mouseIn: controlPartMouseAreaRestrictedToWidget ? buttonsItem.mouseInWidget : main.mouseInWidget
showItem: !noWindowActive && ((mouseIn && plasmoid.configuration.controlPartButtonsShowOnMouseIn)
|| (!mouseIn && plasmoid.configuration.controlPartButtonsShowOnMouseOut))
onWidthChanged: refreshItemPosition()
}
Rectangle {
id: textSeparator
x: 0
anchors.verticalCenter: main.verticalCenter
height: 0.8 * parent.height
width: 1
visible: plasmoid.configuration.appmenuSeparatorEnabled && menuItem.showItem
color: theme.textColor
opacity: 0.4
}
function action_close() {
toggleClose()
}
function action_maximise() {
toggleMaximized()
}
function action_minimise() {
toggleMinimized()
}
function action_pinToAllDesktops() {
togglePinToAllDesktops()
}
function action_reloadTheme() {
plasmoid.nativeInterface.refreshAuroraeTheme();
}
function actionTriggered(actionName) {
if (actionName.indexOf("switchToActivity_") == 0) {
var activityIndex = actionName.replace("switchToActivity_", "")
var activityId = activityInfo.runningActivities()[activityIndex]
activityModel.setCurrentActivity(activityId, function() {});
}
}
function reAddActivityActions() {
plasmoid.removeAction("separator1")
for (var i = 0; i < activityActionCount; i++) {
plasmoid.removeAction('switchToActivity_' + i)
}
plasmoid.removeAction("separator2")
var runningActivities = activityInfo.runningActivities()
activityActionCount = runningActivities.length
if (activityActionCount === 0) {
return
}
plasmoid.setActionSeparator("separator1")
activityInfo.runningActivities().forEach(function (activityId, index) {
if (activityId === activityInfo.currentActivity) {
return;
}
var activityName = activityInfo.activityName(activityId)
plasmoid.setAction('switchToActivity_' + index, i18n('Switch to activity: %1', activityName), 'preferences-activities')
})
plasmoid.setActionSeparator("separator2")
}
property string controlPartOrder: plasmoid.configuration.controlPartOrder
onControlPartOrderChanged: refreshControlPartOrder()
onUseUpWidthItemChanged: refreshControlPartOrder()
function refreshControlPartOrder() {
itemPartOrder.length = 0
plasmoid.configuration.controlPartOrder.split('|').forEach(function (itemName, index) {
print('itemOrder: ' + itemName)
itemPartOrder.push(itemName)
print('itemZ: ' + index)
getItem(itemName).z = index
});
print('itemPartOrder initialized: ' + itemPartOrder)
refreshItemPosition()
}
Component.onCompleted: {
refreshControlPartOrder()
refreshItemPosition()
updateActiveWindowInfo()
// actions
plasmoid.setAction('close', i18n('Close'), 'window-close');
plasmoid.setAction('maximise', i18n('Toggle Maximise'), 'arrow-up-double');
plasmoid.setAction('minimise', i18n('Minimise'), 'draw-arrow-down');
plasmoid.setAction('pinToAllDesktops', i18n('Toggle Pin To All Desktops'), 'window-pin');
plasmoid.setActionSeparator("separator0")
plasmoid.setAction('reloadTheme', i18n('Reload Theme'), 'system-reboot');
reAddActivityActions()
}
PlasmaCore.DataSource {
id: shortcutDS
engine: 'executable'
property string presentWindows: 'qdbus org.kde.kglobalaccel /component/kwin invokeShortcut "Expose"'
property string presentWindowsAll: 'qdbus org.kde.kglobalaccel /component/kwin invokeShortcut "ExposeAll"'
property string presentWindowsClass: 'qdbus org.kde.kglobalaccel /component/kwin invokeShortcut "ExposeClass"'
connectedSources: []
onNewData: {
connectedSources.length = 0
}
}
}