Warning, /plasma/kdeplasma-addons/applets/calculator/package/contents/ui/main.qml is written in an unsupported language. File is not indexed.
0001 /* 0002 * SPDX-FileCopyrightText: 2015 Bernhard Friedreich <friesoft@gmail.com> 0003 * SPDX-FileCopyrightText: 2014 Martin Yrjölä <martin.yrjola@gmail.com> 0004 * SPDX-FileCopyrightText: 2012, 2014 Davide Bettio <davide.bettio@kdemail.net> 0005 * SPDX-FileCopyrightText: 2012, 2014 David Edmundson <davidedmundson@kde.org> 0006 * SPDX-FileCopyrightText: 2012 Luiz Romário Santana Rios <luizromario@gmail.com> 0007 * SPDX-FileCopyrightText: 2007 Henry Stanaland <stanaland@gmail.com> 0008 * SPDX-FileCopyrightText: 2008 Laurent Montel <montel@kde.org> 0009 * 0010 * SPDX-License-Identifier: GPL-2.0-or-later 0011 */ 0012 0013 import QtQuick 2.5 0014 import QtQuick.Layouts 1.3 0015 import QtQuick.Controls 2.5 as QQC2 0016 import org.kde.kirigami 2.20 as Kirigami 0017 import org.kde.ksvg 1.0 as KSvg 0018 import org.kde.plasma.plasma5support 2.0 as P5Support 0019 import org.kde.plasma.components 3.0 as PlasmaComponents 0020 import org.kde.plasma.plasmoid 0021 0022 PlasmoidItem { 0023 id: main; 0024 0025 switchWidth: Kirigami.Units.gridUnit * 7 0026 switchHeight: Math.round(Kirigami.Units.gridUnit * 10.5) 0027 0028 // Make the buttons' text labels scale with the widget's size 0029 // This is propagated down to all child controls with text 0030 0031 property real result: 0; 0032 property bool hasResult: false; 0033 property bool showingInput: true; 0034 property bool showingResult: false; 0035 property string operator 0036 property real operand: 0; 0037 property bool commaPressed: false; 0038 property int decimals: 0; 0039 property int inputSize: 0; 0040 property TextEdit display 0041 0042 readonly property int maxInputLength: 18; // More than that and the number notation 0043 // turns scientific (i.e.: 1.32324e+12). 0044 // When calculating 1/3 the answer is 0045 // 18 characters long. 0046 0047 function digitClicked(digit) { 0048 if (showingResult) { 0049 allClearClicked(); 0050 } 0051 0052 if (commaPressed) { 0053 ++decimals; 0054 var tenToTheDecimals = Math.pow(10, decimals); 0055 operand = (operand * tenToTheDecimals + digit) / tenToTheDecimals; 0056 } else { 0057 operand = operand * 10 + digit; 0058 } 0059 showingInput = true; 0060 displayNumber(operand); 0061 ++inputSize; 0062 } 0063 0064 function deleteDigit() { 0065 if (showingResult) { 0066 allClearClicked(); 0067 } 0068 0069 if (showingInput) { 0070 if (commaPressed) { 0071 if (decimals === 0) { 0072 commaPressed = false; 0073 } else if (decimals > 0) { 0074 operand -= operand % Math.pow(10, 1 - decimals); 0075 --decimals; 0076 --inputSize; 0077 } 0078 } else if (inputSize > 0) { 0079 operand = (operand - (operand % 10)) / 10; 0080 --inputSize; 0081 } 0082 } 0083 displayNumber(operand); 0084 } 0085 0086 function decimalClicked() { 0087 if (showingResult) { 0088 allClearClicked(); 0089 } 0090 0091 commaPressed = true; 0092 showingInput = true; 0093 displayNumber(operand); 0094 } 0095 0096 function doOperation() { 0097 switch (operator) { 0098 case "+": 0099 result += operand; 0100 break; 0101 case "-": 0102 result -= operand; 0103 break; 0104 case "*": 0105 result *= operand; 0106 break; 0107 case "/": 0108 if (operand === 0) { 0109 divisionByZero(); 0110 return; 0111 } 0112 result /= operand; 0113 break; 0114 default: 0115 return; 0116 } 0117 0118 showingInput = false; 0119 displayNumber(result); 0120 } 0121 0122 function clearOperand() { 0123 operand = 0; 0124 commaPressed = false; 0125 decimals = 0; 0126 inputSize = 0; 0127 } 0128 0129 function setOperator(op) { 0130 if (!hasResult) { 0131 result = operand; 0132 hasResult = true; 0133 } else if (showingInput) { 0134 doOperation(); 0135 } 0136 0137 clearOperand(); 0138 operator = op; 0139 showingResult = false; 0140 } 0141 0142 function equalsClicked() { 0143 showingResult = true; 0144 doOperation(); 0145 } 0146 0147 function clearClicked() { 0148 clearOperand(); 0149 operator = ""; 0150 displayNumber(operand); 0151 showingInput = true; 0152 showingResult = false; 0153 } 0154 0155 function allClearClicked() { 0156 clearClicked(); 0157 result = 0; 0158 hasResult = false; 0159 } 0160 0161 function algarismCount(number) { 0162 return number == 0? 1 : 0163 Math.floor(Math.log(Math.abs(number))/Math.log(10)) + 1; 0164 } 0165 0166 // use the clipboard datasource for being able to inspect the clipboard content before pasting it 0167 P5Support.DataSource { 0168 id: clipboardSource 0169 property bool editing: false; 0170 engine: "org.kde.plasma.clipboard" 0171 connectedSources: "clipboard" 0172 } 0173 0174 function copyToClipboard() { 0175 display.selectAll(); 0176 display.copy(); 0177 display.deselect(); 0178 } 0179 0180 function pasteFromClipboard() { 0181 var content = clipboardSource.data["clipboard"]["current"]; 0182 if (content != "") { 0183 content = content.trim(); 0184 } 0185 0186 // check if the clipboard content as a whole is a valid number (without sign, no operators, ...) 0187 if (isValidClipboardInput(content)) { 0188 var digitRegex = new RegExp('^[0-9]$'); 0189 var decimalRegex = new RegExp('^[\.,]$'); 0190 0191 for (var i = 0; i < content.length; i++) { 0192 if (digitRegex.test(content[i])) { 0193 digitClicked(parseInt(content[i])); 0194 } else if (decimalRegex.test(content[i])) { 0195 decimalClicked(); 0196 } 0197 } 0198 } 0199 } 0200 0201 function isValidClipboardInput(input) { 0202 return new RegExp('^[0-9]*[\.,]?[0-9]+$').test(input); 0203 } 0204 0205 function displayNumber(number) { 0206 var text = number.toLocaleString(Qt.locale(), "g", 14); 0207 0208 // Show all decimals including zeroes and show decimalPoint 0209 if (showingInput && commaPressed) { 0210 text = number.toLocaleString(Qt.locale(), "f", decimals); 0211 if (decimals === 0) { 0212 text += Qt.locale().decimalPoint; 0213 } 0214 } 0215 display.text = text; 0216 0217 var decimalsToShow = 9; 0218 // Decrease precision until the text fits to the display. 0219 while (display.contentWidth > display.width && decimalsToShow > 0) { 0220 display.text = number.toLocaleString(Qt.locale(), "g", decimalsToShow--); 0221 } 0222 } 0223 0224 function divisionByZero() { 0225 showingInput = false; 0226 showingResult = true; 0227 display.text = i18nc("Abbreviation for result (undefined) of division by zero, max. six to nine characters.", "undef"); 0228 } 0229 0230 fullRepresentation: QQC2.Control { 0231 // Make the buttons' text labels scale with the widget's size 0232 // This is propagated down to all child controls with text 0233 font.pixelSize: Math.round(width/12) 0234 padding: 0 0235 Layout.minimumWidth: main.switchWidth 0236 Layout.minimumHeight: main.switchHeight 0237 Layout.preferredWidth: main.switchWidth * 2 0238 Layout.preferredHeight: main.switchHeight * 2 0239 0240 contentItem: ColumnLayout { 0241 id: mainLayout 0242 anchors.fill: parent 0243 anchors.margins: 4 0244 0245 focus: true; 0246 spacing: 4; 0247 0248 Keys.onDigit0Pressed: { digitClicked(0); zeroButton.forceActiveFocus(Qt.TabFocusReason); } 0249 Keys.onDigit1Pressed: { digitClicked(1); oneButton.forceActiveFocus(Qt.TabFocusReason); } 0250 Keys.onDigit2Pressed: { digitClicked(2); twoButton.forceActiveFocus(Qt.TabFocusReason); } 0251 Keys.onDigit3Pressed: { digitClicked(3); threeButton.forceActiveFocus(Qt.TabFocusReason); } 0252 Keys.onDigit4Pressed: { digitClicked(4); fourButton.forceActiveFocus(Qt.TabFocusReason); } 0253 Keys.onDigit5Pressed: { digitClicked(5); fiveButton.forceActiveFocus(Qt.TabFocusReason); } 0254 Keys.onDigit6Pressed: { digitClicked(6); sixButton.forceActiveFocus(Qt.TabFocusReason); } 0255 Keys.onDigit7Pressed: { digitClicked(7); sevenButton.forceActiveFocus(Qt.TabFocusReason); } 0256 Keys.onDigit8Pressed: { digitClicked(8); eightButton.forceActiveFocus(Qt.TabFocusReason); } 0257 Keys.onDigit9Pressed: { digitClicked(9); nineButton.forceActiveFocus(Qt.TabFocusReason); } 0258 Keys.onEscapePressed: { allClearClicked(); allClearButton.forceActiveFocus(Qt.TabFocusReason); } 0259 Keys.onDeletePressed: { clearClicked(); clearButton.forceActiveFocus(Qt.TabFocusReason); } 0260 Keys.onPressed: { 0261 switch (event.key) { 0262 case Qt.Key_Plus: 0263 setOperator("+"); 0264 plusButton.forceActiveFocus(Qt.TabFocusReason); 0265 break; 0266 case Qt.Key_Minus: 0267 setOperator("-"); 0268 minusButton.forceActiveFocus(Qt.TabFocusReason); 0269 break; 0270 case Qt.Key_Asterisk: 0271 setOperator("*"); 0272 multiplyButton.forceActiveFocus(Qt.TabFocusReason); 0273 break; 0274 case Qt.Key_Slash: 0275 setOperator("/"); 0276 divideButton.forceActiveFocus(Qt.TabFocusReason); 0277 break; 0278 case Qt.Key_Comma: 0279 case Qt.Key_Period: 0280 decimalClicked(); 0281 decimalButton.forceActiveFocus(Qt.TabFocusReason); 0282 break; 0283 case Qt.Key_Equal: 0284 case Qt.Key_Return: 0285 case Qt.Key_Enter: 0286 equalsClicked(); 0287 break; 0288 case Qt.Key_Backspace: 0289 deleteDigit(); 0290 display.forceActiveFocus(Qt.TabFocusReason); 0291 break; 0292 default: 0293 if (event.matches(StandardKey.Copy)) { 0294 copyToClipboard(); 0295 } else if (event.matches(StandardKey.Paste)) { 0296 pasteFromClipboard(); 0297 } 0298 break; 0299 } 0300 } 0301 0302 KeyNavigation.up: zeroButton 0303 KeyNavigation.down: clearButton 0304 KeyNavigation.left: allClearButton 0305 KeyNavigation.right: clearButton 0306 0307 KSvg.FrameSvgItem { 0308 id: displayFrame; 0309 Layout.fillWidth: true 0310 Layout.minimumHeight: 2 * display.font.pixelSize; 0311 imagePath: "widgets/frame"; 0312 prefix: "plain"; 0313 0314 TextEdit { 0315 id: display; 0316 anchors { 0317 fill: parent; 0318 margins: parent.margins.right; 0319 } 0320 text: "0"; 0321 font.pointSize: Kirigami.Theme.defaultFont.pointSize * 2; 0322 font.weight: Font.Bold; 0323 Kirigami.Theme.colorSet: Kirigami.Theme.View 0324 color: Kirigami.Theme.textColor 0325 horizontalAlignment: TextEdit.AlignRight; 0326 verticalAlignment: TextEdit.AlignVCenter; 0327 readOnly: true; 0328 0329 focus: main.expanded 0330 0331 Accessible.name: text 0332 Accessible.description: i18nc("@label calculation result", "Result") 0333 0334 Binding { 0335 target: main 0336 property: "display" 0337 value: display 0338 } 0339 } 0340 } 0341 0342 GridLayout { 0343 id: buttonsGrid; 0344 columns: 4; 0345 rows: 5; 0346 columnSpacing: 4 0347 rowSpacing: 4 0348 0349 Layout.fillWidth: true 0350 Layout.fillHeight: true 0351 0352 PlasmaComponents.Button { 0353 id: clearButton 0354 0355 Layout.fillWidth: true 0356 Layout.fillHeight: true 0357 0358 KeyNavigation.down: sevenButton 0359 KeyNavigation.right: divideButton 0360 0361 text: i18nc("Text of the clear button", "C"); 0362 onClicked: clearClicked(); 0363 } 0364 0365 PlasmaComponents.Button { 0366 id: divideButton 0367 0368 Layout.fillWidth: true 0369 Layout.fillHeight: true 0370 0371 KeyNavigation.down: eightButton 0372 KeyNavigation.right: multiplyButton 0373 0374 text: i18nc("Text of the division button", "÷"); 0375 onClicked: setOperator("/"); 0376 } 0377 0378 PlasmaComponents.Button { 0379 id: multiplyButton 0380 0381 Layout.fillWidth: true 0382 Layout.fillHeight: true 0383 0384 KeyNavigation.down: nineButton 0385 KeyNavigation.right: allClearButton 0386 0387 text: i18nc("Text of the multiplication button", "×"); 0388 onClicked: setOperator("*"); 0389 } 0390 0391 PlasmaComponents.Button { 0392 id: allClearButton 0393 0394 Layout.fillWidth: true 0395 Layout.fillHeight: true 0396 0397 KeyNavigation.down: minusButton 0398 0399 text: i18nc("Text of the all clear button", "AC"); 0400 onClicked: allClearClicked(); 0401 } 0402 0403 0404 PlasmaComponents.Button { 0405 id: sevenButton 0406 0407 Layout.fillWidth: true 0408 Layout.fillHeight: true 0409 0410 KeyNavigation.down: fourButton 0411 KeyNavigation.right: eightButton 0412 0413 text: "7"; 0414 onClicked: digitClicked(7); 0415 } 0416 0417 PlasmaComponents.Button { 0418 id: eightButton 0419 0420 Layout.fillWidth: true 0421 Layout.fillHeight: true 0422 0423 KeyNavigation.down: fiveButton 0424 KeyNavigation.right: nineButton 0425 0426 text: "8"; 0427 onClicked: digitClicked(8); 0428 } 0429 0430 PlasmaComponents.Button { 0431 id: nineButton 0432 0433 Layout.fillWidth: true 0434 Layout.fillHeight: true 0435 0436 KeyNavigation.down: sixButton 0437 KeyNavigation.right: minusButton 0438 0439 text: "9"; 0440 onClicked: digitClicked(9); 0441 } 0442 0443 PlasmaComponents.Button { 0444 id: minusButton 0445 0446 Layout.fillWidth: true 0447 Layout.fillHeight: true 0448 0449 KeyNavigation.down: plusButton 0450 0451 text: i18nc("Text of the minus button", "-"); 0452 onClicked: setOperator("-"); 0453 } 0454 0455 0456 PlasmaComponents.Button { 0457 id: fourButton 0458 0459 Layout.fillWidth: true 0460 Layout.fillHeight: true 0461 0462 KeyNavigation.down: oneButton 0463 KeyNavigation.right: fiveButton 0464 0465 text: "4"; 0466 onClicked: digitClicked(4); 0467 } 0468 0469 PlasmaComponents.Button { 0470 id: fiveButton 0471 0472 Layout.fillWidth: true 0473 Layout.fillHeight: true 0474 0475 KeyNavigation.down: twoButton 0476 KeyNavigation.right: sixButton 0477 0478 text: "5"; 0479 onClicked: digitClicked(5); 0480 } 0481 0482 PlasmaComponents.Button { 0483 id: sixButton 0484 0485 Layout.fillWidth: true 0486 Layout.fillHeight: true 0487 0488 KeyNavigation.down: threeButton 0489 KeyNavigation.right: plusButton 0490 0491 text: "6"; 0492 onClicked: digitClicked(6); 0493 } 0494 0495 PlasmaComponents.Button { 0496 id: plusButton 0497 0498 Layout.fillWidth: true 0499 Layout.fillHeight: true 0500 0501 KeyNavigation.down: ansButton 0502 0503 text: i18nc("Text of the plus button", "+"); 0504 onClicked: setOperator("+"); 0505 } 0506 0507 0508 PlasmaComponents.Button { 0509 id: oneButton 0510 0511 Layout.fillWidth: true 0512 Layout.fillHeight: true 0513 0514 KeyNavigation.down: zeroButton 0515 KeyNavigation.right: twoButton 0516 0517 text: "1"; 0518 onClicked: digitClicked(1); 0519 } 0520 0521 PlasmaComponents.Button { 0522 id: twoButton 0523 0524 Layout.fillWidth: true 0525 Layout.fillHeight: true 0526 0527 KeyNavigation.down: zeroButton 0528 KeyNavigation.right: threeButton 0529 0530 text: "2"; 0531 onClicked: digitClicked(2); 0532 } 0533 0534 PlasmaComponents.Button { 0535 id: threeButton 0536 0537 Layout.fillWidth: true 0538 Layout.fillHeight: true 0539 0540 KeyNavigation.down: decimalButton 0541 KeyNavigation.right: ansButton 0542 0543 text: "3"; 0544 onClicked: digitClicked(3); 0545 } 0546 0547 PlasmaComponents.Button { 0548 id: ansButton 0549 0550 Layout.fillWidth: true 0551 Layout.fillHeight: true 0552 0553 Layout.rowSpan: 2 0554 text: i18nc("Text of the equals button", "="); 0555 onClicked: equalsClicked(); 0556 } 0557 0558 PlasmaComponents.Button { 0559 id: zeroButton 0560 0561 Layout.fillWidth: true 0562 Layout.fillHeight: true 0563 0564 KeyNavigation.right: decimalButton 0565 0566 Layout.columnSpan: 2 0567 text: "0"; 0568 onClicked: digitClicked(0); 0569 } 0570 0571 PlasmaComponents.Button { 0572 id: decimalButton 0573 0574 Layout.fillWidth: true 0575 Layout.fillHeight: true 0576 0577 KeyNavigation.right: ansButton 0578 0579 text: Qt.locale().decimalPoint; 0580 onClicked: decimalClicked(); 0581 } 0582 } 0583 } 0584 } 0585 } 0586