├── .gitignore ├── Process ├── Process │ └── qmldir ├── plugin.cpp ├── plugin.pro ├── process.json └── test.qml ├── README.md ├── Ubuntutu.icns ├── Ubuntutu.pro ├── images └── screenshot.png ├── main.cpp ├── qml ├── Home.qml ├── Install.qml ├── Log.qml ├── Screenshot.qml ├── Setting.qml ├── colour.js └── main.qml └── utils ├── adb ├── contacts.sh ├── convert ├── install.sh ├── linux ├── adb └── convert ├── mac ├── adb └── convert └── screenshot.sh /.gitignore: -------------------------------------------------------------------------------- 1 | # C++ objects and libs 2 | 3 | *.slo 4 | *.lo 5 | *.o 6 | *.a 7 | *.la 8 | *.lai 9 | *.so 10 | *.dll 11 | *.dylib 12 | 13 | # Qt-es 14 | 15 | /.qmake.cache 16 | /.qmake.stash 17 | *.pro.user 18 | *.pro.user.* 19 | *.moc 20 | moc_*.cpp 21 | qrc_*.cpp 22 | ui_*.h 23 | Makefile* 24 | *-build-* 25 | 26 | # QtCreator 27 | 28 | *.autosave 29 | *.swp 30 | *.app 31 | *.dmg 32 | *deployment-settings.json 33 | 34 | # Project files 35 | vaju-camera 36 | vaju-camera.build 37 | vaju-camera.xcodeproj 38 | .tmp 39 | vaju-camera_plugin_import.cpp 40 | vaju-camera_qml_plugin_import.cpp 41 | qt.conf 42 | -------------------------------------------------------------------------------- /Process/Process/qmldir: -------------------------------------------------------------------------------- 1 | module Process 2 | plugin qmlprocessplugin 3 | -------------------------------------------------------------------------------- /Process/plugin.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | class ProcessModel : public QProcess 8 | { 9 | Q_OBJECT 10 | 11 | public: 12 | ProcessModel(QObject *parent=0) : QProcess(parent) 13 | { 14 | } 15 | 16 | ~ProcessModel() 17 | { 18 | } 19 | 20 | Q_INVOKABLE void start(const QString &program, const QVariantList &arguments) { 21 | QStringList args; 22 | for (int i = 0; i < arguments.length(); i++) 23 | args << arguments[i].toString(); 24 | 25 | qDebug() << program << args; 26 | 27 | QProcess::start(program, args); 28 | } 29 | 30 | Q_INVOKABLE QByteArray readAll() { 31 | return QProcess::readAll(); 32 | } 33 | Q_INVOKABLE void cmd(const QString &s) { 34 | qDebug() << s; 35 | QProcess::startDetached(s); 36 | } 37 | }; 38 | 39 | class ProcessPlugin : public QQmlExtensionPlugin 40 | { 41 | Q_OBJECT 42 | Q_PLUGIN_METADATA(IID "org.slatekit.Process" FILE "process.json") 43 | 44 | public: 45 | void registerTypes(const char *uri) 46 | { 47 | qmlRegisterType(uri, 1, 0, "Process"); 48 | } 49 | 50 | }; 51 | 52 | #include "plugin.moc" 53 | -------------------------------------------------------------------------------- /Process/plugin.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = lib 2 | CONFIG += qt plugin 3 | QT += qml quick 4 | 5 | DESTDIR = Process 6 | TARGET = qmlprocessplugin 7 | 8 | SOURCES += plugin.cpp 9 | 10 | lib.files = Process 11 | lib.path = $$[QT_INSTALL_QML] 12 | INSTALLS += lib 13 | -------------------------------------------------------------------------------- /Process/process.json: -------------------------------------------------------------------------------- 1 | { "Keys": [ "Process" ] } 2 | -------------------------------------------------------------------------------- /Process/test.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import Process 1.0 3 | 4 | Rectangle { 5 | 6 | Process { 7 | id: process 8 | onReadyRead: { 9 | text.text += readAll(); 10 | console.log('onReadyRead: ' + text.text); 11 | } 12 | } 13 | 14 | width: 300 15 | height: 400 16 | 17 | Text { 18 | id: text 19 | anchors.centerIn: parent 20 | } 21 | 22 | MouseArea { 23 | anchors.fill: parent 24 | onClicked: { 25 | console.log('clicked') 26 | process.start("ping", [ "-c 3", "google.com" ]); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UbunTuTu - ADB for Human Beings 2 | 3 | UbunTuTu is a graphical replacement of adb command for Ubuntu Phone 4 | 5 | ![screenshot](https://raw.githubusercontent.com/penk/UbunTuTu/master/images/screenshot.png) 6 | 7 | ## Features 8 | 9 | * Get system image version 10 | * Install click package 11 | * Grab screenshot 12 | * Fetch log 13 | * Import & export contacts 14 | 15 | ## Build 16 | 17 | On Linux: 18 | 19 | cd Process; qmake && make && sudo make install; cd .. 20 | qmake && make 21 | ./UbunTuTu 22 | 23 | On OS X: 24 | 25 | cd Process; qmake && make && make install; cd .. 26 | qmake && make 27 | macdeployqt UbunTuTu.app -qmldir=qml/ -verbose=1 28 | 29 | ## Credits 30 | 31 | * `utils/mac/adb` is ADB version 1.0.32 from Android SDK platform tool 32 | * `utils/mac/convert` is a statically linked ImageMagick version 7.0.1-7 built with `png` delegate 33 | * `utils/linux/adb` is ADB version 1.0.32 from Android SDK platform tool 34 | * `utils/linux/convert` is a soft link to /usr/bin/convert 35 | 36 | ## License 37 | 38 | Copyright © 2016 Ping-Hsun (penk) Chen <> 39 | 40 | The source code is, unless otherwise specified, distributed under the terms of the MIT License. 41 | -------------------------------------------------------------------------------- /Ubuntutu.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/penk/UbunTuTu/b44a51fb862cbfa5fbe5d867abfa7d031698f3a2/Ubuntutu.icns -------------------------------------------------------------------------------- /Ubuntutu.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = app 2 | TARGET = UbunTuTu 3 | 4 | QT += qml quick 5 | SOURCES += main.cpp 6 | 7 | mac { 8 | UtilFiles.files = utils 9 | UtilFiles.path = Contents/MacOS 10 | QMAKE_BUNDLE_DATA += UtilFiles 11 | 12 | QMLFiles.files = qml 13 | QMLFiles.path = Contents/MacOS 14 | QMAKE_BUNDLE_DATA += QMLFiles 15 | 16 | ICON = Ubuntutu.icns 17 | } 18 | -------------------------------------------------------------------------------- /images/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/penk/UbunTuTu/b44a51fb862cbfa5fbe5d867abfa7d031698f3a2/images/screenshot.png -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | QGuiApplication app(argc, argv); 8 | QQmlApplicationEngine engine; 9 | engine.rootContext()->setContextProperty("applicationDirPath", app.applicationDirPath()); 10 | engine.load(QUrl::fromLocalFile(app.applicationDirPath() + "/qml/main.qml")); 11 | 12 | return app.exec(); 13 | } 14 | -------------------------------------------------------------------------------- /qml/Home.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import Process 1.0 3 | import "colour.js" as Colour 4 | 5 | Item { 6 | Component.onCompleted: { 7 | console.log('Home loaded') 8 | sic.start(applicationDirPath + '/utils/adb', ['shell', 'system-image-cli', '-i']) 9 | } 10 | Process { 11 | id: sic 12 | onReadyRead: { 13 | console.log('onReadyRead'); 14 | systemImageCli.text += readAll(); 15 | console.log(systemImageCli.text) 16 | } 17 | } 18 | 19 | Text { 20 | anchors { 21 | top: parent.top 22 | topMargin: 50 23 | horizontalCenter: parent.horizontalCenter 24 | } 25 | text: "System Information" 26 | font.pointSize: 20 27 | } 28 | 29 | TextEdit { 30 | id: systemImageCli 31 | anchors.centerIn: parent 32 | font.pointSize: 16 33 | selectionColor: Colour.palette['Green'] 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /qml/Install.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import Process 1.0 3 | import "colour.js" as Colour 4 | import QtQuick.Dialogs 1.2 5 | 6 | Item { 7 | Component.onCompleted: { 8 | console.log('Install loaded') 9 | } 10 | 11 | Rectangle { 12 | id: button 13 | anchors { 14 | horizontalCenter: parent.horizontalCenter 15 | top: title.bottom 16 | topMargin: 100 17 | } 18 | width: 300 19 | height: 50 20 | radius: 5 21 | color: Colour.palette['Green'] 22 | Text { 23 | anchors.centerIn: parent 24 | text: 'Browse...' 25 | color: 'white' 26 | font.bold: true 27 | font.pointSize: 14 28 | } 29 | MouseArea { 30 | anchors.fill: parent 31 | onClicked: fileDialog.visible = true 32 | } 33 | } 34 | 35 | FileDialog { 36 | id: fileDialog 37 | title: "Please choose a file" 38 | folder: shortcuts.home 39 | selectMultiple: false 40 | selectFolder: false 41 | onAccepted: { 42 | console.log("You chose: " + fileDialog.fileUrls) 43 | shell.start(applicationDirPath + '/utils/install.sh', [ applicationDirPath, fileDialog.fileUrls.toString().replace(/file:\/\//, "") ]) 44 | } 45 | onRejected: { 46 | console.log("Canceled") 47 | } 48 | nameFilters: [ "Click package (*.click)"] 49 | } 50 | Process { 51 | id: shell 52 | onReadyRead: { 53 | console.log('onReadyRead'); 54 | adbText.text += readAll(); 55 | console.log(adbText.text) 56 | } 57 | } 58 | 59 | Text { 60 | id: title 61 | anchors { 62 | top: parent.top 63 | topMargin: 50 64 | horizontalCenter: parent.horizontalCenter 65 | } 66 | text: "Choose a Package to Install" 67 | font.pointSize: 20 68 | } 69 | 70 | TextEdit { 71 | id: adbText 72 | clip: true 73 | anchors { 74 | right: parent.right 75 | top: button.bottom 76 | bottom: parent.bottom 77 | left: parent.left 78 | margins: 30 79 | } 80 | font.pointSize: 16 81 | selectionColor: Colour.palette['Green'] 82 | wrapMode: TextEdit.WordWrap 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /qml/Log.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import Process 1.0 3 | import "colour.js" as Colour 4 | 5 | Item { 6 | 7 | Component.onCompleted: { 8 | console.log('Log loaded') 9 | shell.start(applicationDirPath + '/utils/adb', ['shell', 'tail', '-f', '/home/phablet/.cache/upstart/scope-registry.log']) 10 | } 11 | Process { 12 | id: shell 13 | onReadyRead: { 14 | log.text += readAll(); 15 | flickable.contentY = log.contentHeight - parent.height + 100 16 | console.log(log.text) 17 | } 18 | } 19 | 20 | Text { 21 | id: title 22 | anchors { 23 | top: parent.top 24 | topMargin: 50 25 | horizontalCenter: parent.horizontalCenter 26 | } 27 | text: "System Log" 28 | font.pointSize: 20 29 | } 30 | 31 | Flickable { 32 | id: flickable 33 | anchors { 34 | top: title.bottom 35 | left: parent.left 36 | right: parent.right 37 | bottom: parent.bottom 38 | margins: 30 39 | } 40 | clip: true 41 | contentHeight: log.contentHeight 42 | 43 | TextEdit { 44 | id: log 45 | anchors { 46 | margins: 30 47 | } 48 | width: parent.width 49 | font.pointSize: 16 50 | selectionColor: Colour.palette['Green'] 51 | wrapMode: TextEdit.WordWrap 52 | cursorPosition: log.text.length 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /qml/Screenshot.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import Process 1.0 3 | import "colour.js" as Colour 4 | import QtQuick.Dialogs 1.2 5 | 6 | Item { 7 | Component.onCompleted: { 8 | console.log('Screenshot loaded') 9 | } 10 | FileDialog { 11 | id: fileDialog 12 | title: "Please choose a file" 13 | folder: shortcuts.pictures 14 | selectMultiple: false 15 | selectFolder: true 16 | onAccepted: { 17 | console.log("You chose: " + fileDialog.fileUrls) 18 | } 19 | onRejected: { 20 | console.log("Canceled") 21 | } 22 | } 23 | 24 | Row { 25 | spacing: 50 26 | id: button 27 | anchors { 28 | horizontalCenter: parent.horizontalCenter 29 | bottom: parent.bottom 30 | bottomMargin: 70 31 | } 32 | 33 | Rectangle { 34 | id: pathButton 35 | width: 200 36 | height: 50 37 | radius: 5 38 | color: Colour.palette['Silk'] 39 | Text { 40 | anchors.horizontalCenter: parent.horizontalCenter 41 | anchors.verticalCenter: parent.verticalCenter 42 | text: 'Save to ' + fileDialog.folder.toString().replace(/.*\//, "") 43 | clip: true 44 | font.bold: true 45 | font.pointSize: 14 46 | width: parent.width - 30 47 | color: Colour.palette['Inkstone'] 48 | elide: Text.ElideRight 49 | } 50 | Text { 51 | anchors.right: parent.right 52 | anchors.verticalCenter: parent.verticalCenter 53 | anchors.rightMargin: 10 54 | text: '▾' 55 | color: Colour.palette['Inkstone'] 56 | font.bold: true 57 | font.pointSize: 14 58 | } 59 | MouseArea { 60 | anchors.fill: parent 61 | onClicked: fileDialog.visible = true; 62 | } 63 | } 64 | 65 | Rectangle { 66 | id: grabButton 67 | width: 200 68 | height: 50 69 | radius: 5 70 | color: Colour.palette['Green'] 71 | Text { 72 | anchors.centerIn: parent 73 | text: 'Grab a Screenshot' 74 | color: 'white' 75 | font.bold: true 76 | font.pointSize: 14 77 | } 78 | MouseArea { 79 | anchors.fill: parent 80 | onClicked: { 81 | screenpath.text = 'Waiting..' 82 | shell.start(applicationDirPath + '/utils/screenshot.sh', [ applicationDirPath, fileDialog.folder.toString().replace(/file:\/\//, "") ]); 83 | } 84 | } 85 | } 86 | } 87 | 88 | Process { 89 | id: shell 90 | onReadyRead: { 91 | console.log('onReadyRead'); 92 | var path = readAll(); 93 | console.log('Path: ' + path) 94 | if (path.toString() !== "") 95 | screenpath.text = 'file://' + path.toString().replace(/(?:\r\n|\r|\n)/g, '') 96 | 97 | img.source = 'file://' + path.toString().replace(/(?:\r\n|\r|\n)/g, ''); 98 | } 99 | } 100 | 101 | Rectangle { 102 | anchors { 103 | top: button.bottom 104 | margins: 20 105 | bottom: parent.bottom 106 | horizontalCenter: parent.horizontalCenter 107 | } 108 | width: parent.width 109 | visible: screenpath.text !== "" 110 | color: Colour.palette['Silk'] 111 | 112 | TextEdit { 113 | id: screenpath 114 | anchors.fill: parent 115 | anchors.margins: 8 116 | horizontalAlignment: TextEdit.AlignHCenter 117 | font.pointSize: 14 118 | selectionColor: Colour.palette['Green'] 119 | } 120 | } 121 | 122 | Image { 123 | id: img 124 | anchors { 125 | top: parent.top 126 | horizontalCenter: parent.horizontalCenter 127 | margins: 15 128 | topMargin: 25 129 | } 130 | fillMode: Image.PreserveAspectFit 131 | width: 250 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /qml/Setting.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import Process 1.0 3 | import "colour.js" as Colour 4 | import QtQuick.Dialogs 1.2 5 | 6 | Item { 7 | Component.onCompleted: { 8 | console.log('Setting loaded') 9 | } 10 | 11 | Row { 12 | spacing: 50 13 | id: button 14 | anchors { 15 | horizontalCenter: parent.horizontalCenter 16 | bottom: parent.bottom 17 | bottomMargin: 150 18 | } 19 | 20 | Rectangle { 21 | id: importButton 22 | width: 200 23 | height: 50 24 | radius: 5 25 | color: Colour.palette['Green'] 26 | Text { 27 | anchors.centerIn: parent 28 | text: 'Import Contacts' 29 | color: 'white' 30 | font.bold: true 31 | font.pointSize: 14 32 | } 33 | MouseArea { 34 | anchors.fill: parent 35 | onClicked: fileDialog.visible = true; 36 | } 37 | } 38 | 39 | Rectangle { 40 | id: exportButton 41 | width: 200 42 | height: 50 43 | radius: 5 44 | color: Colour.palette['Silk'] 45 | Text { 46 | anchors.horizontalCenter: parent.horizontalCenter 47 | anchors.verticalCenter: parent.verticalCenter 48 | text: 'Export Contacts' 49 | clip: true 50 | font.bold: true 51 | font.pointSize: 14 52 | width: parent.width - 30 53 | color: Colour.palette['Inkstone'] 54 | elide: Text.ElideRight 55 | } 56 | Text { 57 | anchors.right: parent.right 58 | anchors.verticalCenter: parent.verticalCenter 59 | anchors.rightMargin: 10 60 | text: '▾' 61 | color: Colour.palette['Inkstone'] 62 | font.bold: true 63 | font.pointSize: 14 64 | } 65 | MouseArea { 66 | anchors.fill: parent 67 | onClicked: dirDialog.visible = true; 68 | } 69 | } 70 | } 71 | 72 | FileDialog { 73 | id: fileDialog 74 | title: "Please choose a contact file" 75 | folder: shortcuts.documents 76 | //selectMultiple: false 77 | //selectFolder: false 78 | //selectFolder: fileDialogSelectFolder.checked 79 | //nameFilters: [ "Contacts file (*.vcf)" ] 80 | //selectedNameFilter: "All files (*)" 81 | selectFolder: fileDialogSelectFolder.checked 82 | onAccepted: { 83 | console.log("You chose: " + fileDialog.fileUrls) 84 | shell.start(applicationDirPath + '/utils/contacts.sh', [ applicationDirPath, fileDialog.fileUrls.toString().replace(/file:\/\//, ""), "import" ]) 85 | } 86 | onRejected: { 87 | console.log("Canceled") 88 | } 89 | } 90 | 91 | FileDialog { 92 | id: dirDialog 93 | title: "Please choose a directory" 94 | folder: shortcuts.home 95 | //selectMultiple: false 96 | //selectFolder: true 97 | onAccepted: { 98 | console.log("You chose: " + fileDialog.folder) 99 | shell.start(applicationDirPath + '/utils/contacts.sh', [ applicationDirPath, dirDialog.folder.toString().replace(/file:\/\//, ""), "export" ]) 100 | } 101 | onRejected: { 102 | console.log("Canceled") 103 | } 104 | } 105 | 106 | Process { 107 | id: shell 108 | onReadyRead: { 109 | console.log('onReadyRead'); 110 | var text = readAll() 111 | console.log(text) 112 | adbText.text = text 113 | } 114 | } 115 | 116 | Text { 117 | id: title 118 | anchors { 119 | top: parent.top 120 | topMargin: 50 121 | horizontalCenter: parent.horizontalCenter 122 | } 123 | text: "Import & export contacts" 124 | font.pointSize: 20 125 | } 126 | 127 | TextEdit { 128 | id: adbText 129 | clip: true 130 | anchors { 131 | right: parent.right 132 | top: button.bottom 133 | bottom: parent.bottom 134 | left: parent.left 135 | margins: 30 136 | } 137 | font.pointSize: 16 138 | selectionColor: Colour.palette['Green'] 139 | wrapMode: TextEdit.WordWrap 140 | } 141 | } 142 | 143 | 144 | -------------------------------------------------------------------------------- /qml/colour.js: -------------------------------------------------------------------------------- 1 | var palette = { 2 | 3 | 'Jet': '#111111', 4 | 'Inkstone': '#3B3B3B', 5 | 'Slate': '#5D5D5D', 6 | 'Graphite': '#666666', 7 | 8 | 'Ash': '#888888', 9 | 'Silk': '#CDCDCD', 10 | 'Porcelain': '#F7F7F7', 11 | 12 | 'Blue': '#00B6F4', 13 | 'Green': '#00BC46', 14 | 'Yellow': '#FF9700', 15 | 'Orange': '#FF3D00', 16 | 'Red': '#FF002E' 17 | 18 | } 19 | -------------------------------------------------------------------------------- /qml/main.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QtQuick.Window 2.0 3 | import "colour.js" as Colour 4 | import Process 1.0 5 | 6 | Window { 7 | 8 | title: "UbunTuTu - ADB for human beings" 9 | visible: true 10 | width: 800 11 | height: 600 12 | color: Colour.palette['Porcelain'] 13 | 14 | Process { 15 | id: process 16 | onReadyRead: { 17 | var connectStatus = readAll(); 18 | if (connectStatus.toString().match(/\tdevice/)) { 19 | connectIndicator.color = Colour.palette['Green'] 20 | connectText.text = "Connected" 21 | } 22 | } 23 | } 24 | 25 | Component.onCompleted: { 26 | process.start(applicationDirPath + "/utils/adb", ["devices"]); 27 | loader.source = "Home.qml"; 28 | } 29 | 30 | Rectangle { 31 | width: 200 32 | height: parent.height 33 | color: Colour.palette['Ash'] 34 | anchors { 35 | top: parent.top 36 | left: parent.left 37 | } 38 | 39 | Row { 40 | anchors { 41 | bottom: parent.bottom 42 | left: parent.left 43 | margins: 20 44 | } 45 | height: 50 46 | width: parent.width 47 | spacing: 15 48 | Rectangle { 49 | id: connectIndicator 50 | width: 20 51 | height: 20 52 | radius: width/2 53 | color: Colour.palette['Yellow'] 54 | } 55 | Text { 56 | id: connectText 57 | text: "Not Connected" 58 | font.pointSize: 16 59 | } 60 | } 61 | } 62 | 63 | Loader { 64 | id: loader 65 | anchors { 66 | top: parent.top 67 | right: parent.right 68 | left: listView.right 69 | bottom: parent.bottom 70 | } 71 | } 72 | 73 | ListView { 74 | id: listView 75 | anchors { 76 | left: parent.left 77 | top: parent.top 78 | bottom: parent.bottom 79 | } 80 | width: 200 81 | 82 | model: ListModel { 83 | ListElement { name: "Home" } 84 | ListElement { name: "Install" } 85 | ListElement { name: "Screenshot" } 86 | ListElement { name: "Log" } 87 | //ListElement { name: "Setting" } 88 | } 89 | 90 | delegate: Component { 91 | Rectangle { 92 | width: listView.width 93 | height: 80 94 | color: listView.currentIndex == index ? Colour.palette['Blue'] : Colour.palette['Ash'] 95 | Text { 96 | text: name 97 | anchors.centerIn: parent 98 | font.pointSize: 20 99 | font.bold: true 100 | color: Colour.palette['Inkstone'] 101 | } 102 | MouseArea { 103 | anchors.fill: parent 104 | onClicked: { 105 | listView.currentIndex = index 106 | loader.source = name + '.qml' 107 | } 108 | } 109 | Rectangle { 110 | width: parent.height / Math.sqrt(2) 111 | height: width 112 | color: Colour.palette['Blue'] 113 | transform: Rotation { origin.x: 25; origin.y: 25; angle: 45} 114 | anchors { 115 | right: parent.right 116 | verticalCenter: parent.verticalCenter 117 | rightMargin: -width/2 -3 118 | } 119 | visible: listView.currentIndex == index 120 | } 121 | } 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /utils/adb: -------------------------------------------------------------------------------- 1 | mac/adb -------------------------------------------------------------------------------- /utils/contacts.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -x 3 | D=$(date +"%Y%m%d%H%M%S") 4 | DEST=$2 5 | 6 | if [ "$3" = "export" ] 7 | then 8 | $1/utils/adb shell syncevolution --export /home/phablet/Documents/utcontacts-${D}.vcf backend=evolution-contacts 9 | $1/utils/adb pull /home/phablet/Documents/utcontacts-${D}.vcf $DEST 2>/dev/null 10 | $1/utils/adb shell rm /home/phablet/Documents/utcontacts-${D}.vcf 11 | echo "$DEST/utcontacts-${D}.vcf" 12 | elif [ "$3" = "import" ] 13 | then 14 | $1/utils/adb push ${DEST} /home/phablet/Documents/ 15 | VCF_FILE=`echo "${DEST}" | sed "s/.*\///"` 16 | $1/utils/adb shell syncevolution --import /home/phablet/Documents/${VCF_FILE} backend=evolution-contacts 17 | $1/utils/adb shell rm /home/phablet/Documents/${VCF_FILE} 18 | echo "import ${DEST} ok" 19 | else 20 | echo "$3 is error" 21 | fi 22 | -------------------------------------------------------------------------------- /utils/convert: -------------------------------------------------------------------------------- 1 | mac/convert -------------------------------------------------------------------------------- /utils/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #set -x 3 | 4 | $1/utils/adb push $2 /tmp/ 5 | CLICK=`basename $2` 6 | $1/utils/adb shell pkcon -p install-local --allow-untrusted /tmp/$CLICK 7 | -------------------------------------------------------------------------------- /utils/linux/adb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/penk/UbunTuTu/b44a51fb862cbfa5fbe5d867abfa7d031698f3a2/utils/linux/adb -------------------------------------------------------------------------------- /utils/linux/convert: -------------------------------------------------------------------------------- 1 | /usr/bin/convert -------------------------------------------------------------------------------- /utils/mac/adb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/penk/UbunTuTu/b44a51fb862cbfa5fbe5d867abfa7d031698f3a2/utils/mac/adb -------------------------------------------------------------------------------- /utils/mac/convert: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/penk/UbunTuTu/b44a51fb862cbfa5fbe5d867abfa7d031698f3a2/utils/mac/convert -------------------------------------------------------------------------------- /utils/screenshot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -x 3 | D=$(date +"%Y%m%d%H%M%S") 4 | size=$($1/utils/adb shell "fbset|sed -n -e's/^mode.*\"\([0-9]\+x[0-9]\+\)[-\"].*$/\1/p'") 5 | DEST=$2 6 | 7 | $1/utils/adb shell mirscreencast -m /var/run/mir_socket -n 1 -f /tmp/${D}.rgba 8 | $1/utils/adb pull /tmp/${D}.rgba /tmp/ 2>/dev/null 9 | $1/utils/convert -alpha off -depth 8 -size $size rgba:/tmp/${D}.rgba "$DEST"/${D}.png 10 | 11 | echo "$DEST/${D}.png" 12 | --------------------------------------------------------------------------------