2015-09-12 12:28:27 +02:00
|
|
|
/*
|
|
|
|
* Copyright 2015 Aleix Pol Gonzalez <aleixpol@kde.org>
|
|
|
|
* Copyright 2015 Albert Vaca Cintora <albertvaka@gmail.com>
|
|
|
|
*
|
|
|
|
* 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) version 3 or any later version
|
|
|
|
* accepted by the membership of KDE e.V. (or its successor approved
|
|
|
|
* by the membership of KDE e.V.), which shall act as a proxy
|
|
|
|
* defined in Section 14 of version 3 of the license.
|
|
|
|
*
|
|
|
|
* 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
|
2018-05-10 19:46:47 +02:00
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
2015-09-12 12:28:27 +02:00
|
|
|
|
|
|
|
package org.kde.kdeconnect.Plugins.RunCommandPlugin;
|
|
|
|
|
2018-07-27 07:55:30 +02:00
|
|
|
import android.content.ClipboardManager;
|
|
|
|
import android.content.Context;
|
|
|
|
import android.os.Build;
|
2015-09-12 12:28:27 +02:00
|
|
|
import android.os.Bundle;
|
2018-07-27 07:55:30 +02:00
|
|
|
import android.support.annotation.RequiresApi;
|
2018-03-04 14:38:10 +01:00
|
|
|
import android.support.design.widget.FloatingActionButton;
|
2018-05-10 19:46:47 +02:00
|
|
|
import android.support.v7.app.AlertDialog;
|
2017-07-25 18:12:18 +02:00
|
|
|
import android.support.v7.app.AppCompatActivity;
|
2015-09-12 12:28:27 +02:00
|
|
|
import android.util.Log;
|
2018-07-27 07:55:30 +02:00
|
|
|
import android.view.ContextMenu;
|
|
|
|
import android.view.MenuInflater;
|
|
|
|
import android.view.MenuItem;
|
2015-09-12 12:28:27 +02:00
|
|
|
import android.view.View;
|
|
|
|
import android.widget.AdapterView;
|
|
|
|
import android.widget.ListView;
|
2018-03-04 14:38:10 +01:00
|
|
|
import android.widget.TextView;
|
2018-07-27 07:55:30 +02:00
|
|
|
import android.widget.Toast;
|
2015-09-12 12:28:27 +02:00
|
|
|
|
|
|
|
import org.json.JSONException;
|
|
|
|
import org.json.JSONObject;
|
|
|
|
import org.kde.kdeconnect.BackgroundService;
|
|
|
|
import org.kde.kdeconnect.Device;
|
|
|
|
import org.kde.kdeconnect.UserInterface.List.ListAdapter;
|
Add a dark theme
Summary:
BUG: 375376
This revision adds dark mode support to the app ( T7044 ). It does so by injecting
theme information into each activity, and making sure that all Views
define their colors by reference to theme attributes.
In order to make this work, all of the buttons with images (like the list
of available devices) now are tinted according to the theme.
While all versions of android support the theme, only devices running
Android ICS or higher will have a toggle button in the drawer.
Test Plan: Open all the screens, both with and without the dark theme on.
Reviewers: #kde_connect, mtijink, #vdg, nicolasfella
Reviewed By: #kde_connect, mtijink, nicolasfella
Subscribers: apol, ngraham, nicolasfella, mtijink
Tags: #kde_connect
Differential Revision: https://phabricator.kde.org/D11694
2018-04-23 18:31:44 +02:00
|
|
|
import org.kde.kdeconnect.UserInterface.ThemeUtil;
|
2015-09-12 12:28:27 +02:00
|
|
|
import org.kde.kdeconnect_tp.R;
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
2016-09-29 11:08:25 +02:00
|
|
|
import java.util.Collections;
|
2015-09-12 12:28:27 +02:00
|
|
|
|
2017-07-25 18:12:18 +02:00
|
|
|
public class RunCommandActivity extends AppCompatActivity {
|
2015-09-12 12:28:27 +02:00
|
|
|
|
|
|
|
private String deviceId;
|
2018-05-09 14:02:56 +02:00
|
|
|
private final RunCommandPlugin.CommandsChangedCallback commandsChangedCallback = this::updateView;
|
2018-07-27 07:55:30 +02:00
|
|
|
private ArrayList<ListAdapter.Item> commandItems;
|
2015-09-12 12:28:27 +02:00
|
|
|
|
|
|
|
private void updateView() {
|
2018-05-09 14:02:56 +02:00
|
|
|
BackgroundService.RunCommand(this, service -> {
|
|
|
|
|
|
|
|
final Device device = service.getDevice(deviceId);
|
|
|
|
final RunCommandPlugin plugin = device.getPlugin(RunCommandPlugin.class);
|
|
|
|
if (plugin == null) {
|
|
|
|
Log.e("RunCommandActivity", "device has no runcommand plugin!");
|
|
|
|
return;
|
|
|
|
}
|
2015-09-12 12:28:27 +02:00
|
|
|
|
2018-05-09 14:02:56 +02:00
|
|
|
runOnUiThread(() -> {
|
|
|
|
ListView view = (ListView) findViewById(R.id.runcommandslist);
|
|
|
|
|
2018-07-27 07:55:30 +02:00
|
|
|
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
|
|
|
|
registerForContextMenu(view);
|
|
|
|
}
|
|
|
|
|
|
|
|
commandItems = new ArrayList<>();
|
2018-05-09 14:02:56 +02:00
|
|
|
for (JSONObject obj : plugin.getCommandList()) {
|
|
|
|
try {
|
|
|
|
commandItems.add(new CommandEntry(obj.getString("name"),
|
|
|
|
obj.getString("command"), obj.getString("key")));
|
|
|
|
} catch (JSONException e) {
|
|
|
|
e.printStackTrace();
|
2015-09-12 12:28:27 +02:00
|
|
|
}
|
2018-05-09 14:02:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
Collections.sort(commandItems, (lhs, rhs) -> {
|
|
|
|
String lName = ((CommandEntry) lhs).getName();
|
|
|
|
String rName = ((CommandEntry) rhs).getName();
|
|
|
|
return lName.compareTo(rName);
|
2015-09-12 12:28:27 +02:00
|
|
|
});
|
2018-05-09 14:02:56 +02:00
|
|
|
|
|
|
|
ListAdapter adapter = new ListAdapter(RunCommandActivity.this, commandItems);
|
|
|
|
|
|
|
|
view.setAdapter(adapter);
|
|
|
|
view.setOnItemClickListener((adapterView, view1, i, l) -> {
|
|
|
|
CommandEntry entry = (CommandEntry) commandItems.get(i);
|
|
|
|
plugin.runCommand(entry.getKey());
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
TextView explanation = (TextView) findViewById(R.id.addcomand_explanation);
|
|
|
|
String text = getString(R.string.addcommand_explanation);
|
|
|
|
if (!plugin.canAddCommand()) {
|
|
|
|
text += "\n" + getString(R.string.addcommand_explanation2);
|
|
|
|
}
|
|
|
|
explanation.setText(text);
|
|
|
|
explanation.setVisibility(commandItems.isEmpty() ? View.VISIBLE : View.GONE);
|
|
|
|
});
|
2015-09-12 12:28:27 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onCreate(Bundle savedInstanceState) {
|
|
|
|
super.onCreate(savedInstanceState);
|
Add a dark theme
Summary:
BUG: 375376
This revision adds dark mode support to the app ( T7044 ). It does so by injecting
theme information into each activity, and making sure that all Views
define their colors by reference to theme attributes.
In order to make this work, all of the buttons with images (like the list
of available devices) now are tinted according to the theme.
While all versions of android support the theme, only devices running
Android ICS or higher will have a toggle button in the drawer.
Test Plan: Open all the screens, both with and without the dark theme on.
Reviewers: #kde_connect, mtijink, #vdg, nicolasfella
Reviewed By: #kde_connect, mtijink, nicolasfella
Subscribers: apol, ngraham, nicolasfella, mtijink
Tags: #kde_connect
Differential Revision: https://phabricator.kde.org/D11694
2018-04-23 18:31:44 +02:00
|
|
|
ThemeUtil.setUserPreferredTheme(this);
|
2018-03-04 14:38:10 +01:00
|
|
|
setContentView(R.layout.activity_runcommand);
|
2015-09-12 12:28:27 +02:00
|
|
|
|
|
|
|
deviceId = getIntent().getStringExtra("deviceId");
|
|
|
|
|
2018-03-04 14:38:10 +01:00
|
|
|
boolean canAddCommands = BackgroundService.getInstance().getDevice(deviceId).getPlugin(RunCommandPlugin.class).canAddCommand();
|
|
|
|
|
|
|
|
FloatingActionButton addCommandButton = (FloatingActionButton) findViewById(R.id.add_command_button);
|
|
|
|
addCommandButton.setVisibility(canAddCommands ? View.VISIBLE : View.GONE);
|
2018-05-10 19:46:47 +02:00
|
|
|
|
|
|
|
addCommandButton.setOnClickListener(view -> BackgroundService.RunCommand(RunCommandActivity.this, service -> {
|
|
|
|
|
|
|
|
final Device device = service.getDevice(deviceId);
|
|
|
|
final RunCommandPlugin plugin = device.getPlugin(RunCommandPlugin.class);
|
|
|
|
if (plugin == null) {
|
|
|
|
Log.e("RunCommandActivity", "device has no runcommand plugin!");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
plugin.sendSetupPacket();
|
|
|
|
|
|
|
|
AlertDialog dialog = new AlertDialog.Builder(RunCommandActivity.this)
|
|
|
|
.setTitle(R.string.add_command)
|
|
|
|
.setMessage(R.string.add_command_description)
|
|
|
|
.setPositiveButton(R.string.ok, null)
|
|
|
|
.create();
|
|
|
|
dialog.show();
|
|
|
|
|
|
|
|
}));
|
2018-03-04 14:38:10 +01:00
|
|
|
|
2015-09-12 12:28:27 +02:00
|
|
|
updateView();
|
|
|
|
}
|
|
|
|
|
2018-07-27 07:55:30 +02:00
|
|
|
@Override
|
|
|
|
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
|
|
|
|
super.onCreateContextMenu(menu, v, menuInfo);
|
|
|
|
MenuInflater inflater = getMenuInflater();
|
|
|
|
inflater.inflate(R.menu.runcommand_context, menu);
|
|
|
|
}
|
|
|
|
|
|
|
|
@RequiresApi(api = Build.VERSION_CODES.HONEYCOMB)
|
|
|
|
@Override
|
|
|
|
public boolean onContextItemSelected(MenuItem item) {
|
|
|
|
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
|
|
|
|
if (item.getItemId() == R.id.copy_url_to_clipboard) {
|
|
|
|
CommandEntry entry = (CommandEntry) commandItems.get(info.position);
|
|
|
|
String url = "kdeconnect://runcommand/" + deviceId + "/" + entry.getKey();
|
|
|
|
ClipboardManager cm = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
|
|
|
|
cm.setText(url);
|
|
|
|
Toast toast = Toast.makeText(this, R.string.clipboard_toast, Toast.LENGTH_SHORT);
|
|
|
|
toast.show();
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-09-12 12:28:27 +02:00
|
|
|
@Override
|
|
|
|
protected void onResume() {
|
|
|
|
super.onResume();
|
|
|
|
|
2018-05-09 14:02:56 +02:00
|
|
|
BackgroundService.RunCommand(this, service -> {
|
2015-09-12 12:28:27 +02:00
|
|
|
|
2018-05-09 14:02:56 +02:00
|
|
|
final Device device = service.getDevice(deviceId);
|
|
|
|
final RunCommandPlugin plugin = device.getPlugin(RunCommandPlugin.class);
|
|
|
|
if (plugin == null) {
|
|
|
|
Log.e("RunCommandActivity", "device has no runcommand plugin!");
|
|
|
|
return;
|
2015-09-12 12:28:27 +02:00
|
|
|
}
|
2018-05-09 14:02:56 +02:00
|
|
|
plugin.addCommandsUpdatedCallback(commandsChangedCallback);
|
2015-09-12 12:28:27 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onPause() {
|
|
|
|
super.onPause();
|
|
|
|
|
2018-05-09 14:02:56 +02:00
|
|
|
BackgroundService.RunCommand(this, service -> {
|
2015-09-12 12:28:27 +02:00
|
|
|
|
2018-05-09 14:02:56 +02:00
|
|
|
final Device device = service.getDevice(deviceId);
|
|
|
|
final RunCommandPlugin plugin = device.getPlugin(RunCommandPlugin.class);
|
|
|
|
if (plugin == null) {
|
|
|
|
Log.e("RunCommandActivity", "device has no runcommand plugin!");
|
|
|
|
return;
|
2018-03-04 14:38:10 +01:00
|
|
|
}
|
2018-05-09 14:02:56 +02:00
|
|
|
plugin.removeCommandsUpdatedCallback(commandsChangedCallback);
|
2018-03-04 14:38:10 +01:00
|
|
|
});
|
|
|
|
}
|
2015-09-12 12:28:27 +02:00
|
|
|
}
|