Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions gremlin/__init__.py
Original file line number Diff line number Diff line change
@@ -41,3 +41,4 @@
import gremlin.tts
import gremlin.util
import gremlin.windows_event_hook
import gremlin.clipboard
37 changes: 37 additions & 0 deletions gremlin/clipboard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# -*- coding: utf-8; -*-

# Copyright (C) 2015 - 2019 Lionel Ott
#
# 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 3 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 <http://www.gnu.org/licenses/>.

from . import common


@common.SingletonDecorator
class Clipboard:

"""Responsible for storing and restoring action related data."""

def __init__(self):
"""Creates a new instance, initializing empty clipboard."""
self.item_data = None

def copy(self, item_data):
""" Saves item_data to clipboard """
self.item_data = item_data

def paste(self):
""" Returns item_data saved in clipboard """
return self.item_data

34 changes: 30 additions & 4 deletions gremlin/ui/device_tab.py
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@

import logging

from PyQt5 import QtWidgets, QtCore
from PyQt5 import QtWidgets, QtCore, QtGui

import container_plugins.basic
import gremlin
@@ -35,7 +35,7 @@ class InputItemConfiguration(QtWidgets.QFrame):
# Signal emitted when the description changes
description_changed = QtCore.pyqtSignal(str)

def __init__(self, item_data, parent=None):
def __init__(self, item_data, parent=None, clipboard=None):
"""Creates a new object instance.

:param item_data profile data associated with the item
@@ -62,6 +62,21 @@ def __init__(self, item_data, parent=None):

self.main_layout.addWidget(self.action_view)

self.clipboard = clipboard
self.copy_shortcut = QtWidgets.QShortcut(QtGui.QKeySequence('Ctrl+C'), self)
self.copy_shortcut.activated.connect(self._copy_actions)
self.paste_shortcut = QtWidgets.QShortcut(QtGui.QKeySequence('Ctrl+V'), self)
self.paste_shortcut.activated.connect(self._paste_actions)

def update_item_data(self, item_data):
# delete old data containers, add new ones
for container_id in reversed(range(0, self.action_model.rows())):
container_data = self.action_model.data(container_id)
self.action_model.remove_container(container_data)
for container in item_data.containers:
self.action_model.add_container(container)
self.item_data = item_data

def _add_action(self, action_name):
"""Adds a new action to the input item.

@@ -185,6 +200,15 @@ def _valid_action_names(self):
action_names.append(entry.name)
return sorted(action_names)

def _copy_actions(self):
""" Copies current actions and makes them available for pasting """
self.clipboard.copy(self.item_data)

def _paste_actions(self):
""" Pastes copied actions into currently selected item """
data = self.clipboard.paste()
if data and data is not self.item_data:
self.update_item_data(data)

class ActionContainerModel(common.AbstractModel):

@@ -296,7 +320,8 @@ def __init__(
device,
device_profile,
current_mode,
parent=None
parent=None,
clipboard = None
):
"""Creates a new object instance.

@@ -371,6 +396,7 @@ def __init__(
self.left_panel_layout.addWidget(label)

self.main_layout.addLayout(self.left_panel_layout)
self.clipboard = clipboard

def input_item_selected_cb(self, index):
"""Handles the selection of an input item.
@@ -390,7 +416,7 @@ def input_item_selected_cb(self, index):
self.main_layout.removeItem(item)

if item_data is not None:
widget = InputItemConfiguration(item_data)
widget = InputItemConfiguration(item_data, clipboard=self.clipboard)
change_cb = self._create_change_cb(index)
widget.action_model.data_changed.connect(change_cb)
widget.description_changed.connect(change_cb)
11 changes: 8 additions & 3 deletions joystick_gremlin.py
Original file line number Diff line number Diff line change
@@ -100,6 +100,8 @@ def __init__(self, parent=None):
self._profile = gremlin.profile.Profile()
self._profile_fname = None
self._profile_auto_activated = False
self.clipboard = gremlin.clipboard.Clipboard()

# Input selection storage
self._last_input_timestamp = time.time()
self._last_input_event = None
@@ -606,7 +608,8 @@ def _create_tabs(self, activate_tab=None):
widget = gremlin.ui.device_tab.JoystickDeviceTabWidget(
device,
device_profile,
self._current_mode
self._current_mode,
clipboard = self.clipboard
)
self.tabs[device.device_guid] = widget
tab_label = device.name.strip()
@@ -627,7 +630,8 @@ def _create_tabs(self, activate_tab=None):
widget = gremlin.ui.device_tab.JoystickDeviceTabWidget(
device,
device_profile,
self._current_mode
self._current_mode,
clipboard = self.clipboard
)
self.tabs[device.device_guid] = widget
tab_label = device.name.strip()
@@ -662,7 +666,8 @@ def _create_tabs(self, activate_tab=None):
widget = gremlin.ui.device_tab.JoystickDeviceTabWidget(
device,
device_profile,
self._current_mode
self._current_mode,
clipboard = self.clipboard
)
self.tabs[device.device_guid] = widget
self.ui.devices.addTab(