Skip to content

Commit

Permalink
Merge pull request #220 from nxt-dev/dev
Browse files Browse the repository at this point in the history
Release editor-v3.11.0
  • Loading branch information
MichaelAldrich authored Nov 16, 2021
2 parents 7497c28 + d96001c commit 346583a
Show file tree
Hide file tree
Showing 15 changed files with 385 additions and 109 deletions.
2 changes: 0 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ before_install:
install:
- cd ..
- git clone https://github.com/nxt-dev/nxt.git
- pip install ./nxt
- pip install ./nxt_editor
- pip install importlib-metadata==3.4
- pip install twine
Expand Down
17 changes: 17 additions & 0 deletions nxt_editor/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,22 @@ def clear_logs():
self.clear_logs_action.setShortcutContext(context)
self.available_without_model.append(self.clear_logs_action)

# Toggle error ding sound
def toggle_ding():
pref_key = user_dir.USER_PREF.DING
ding_state = self.toggle_ding_action.isChecked()
user_dir.user_prefs[pref_key] = ding_state

self.toggle_ding_action = NxtAction('Error sound', parent=self)
self.toggle_ding_action.setWhatsThis('When enabled a "ding" sound will be played when NXT is given bad input '
'or encounters and error')
self.toggle_ding_action.setCheckable(True)
_ding_state = user_dir.user_prefs.get(user_dir.USER_PREF.DING, True)
self.toggle_ding_action.setChecked(_ding_state)
self.toggle_ding_action.triggered.connect(toggle_ding)
self.toggle_ding_action.setShortcutContext(context)
self.available_without_model.append(self.toggle_ding_action)

self.action_display_order = [self.find_node_action,
self.new_graph_action,
self.open_file_action, self.undo_action,
Expand All @@ -400,6 +416,7 @@ def clear_logs():
self.output_log_action,
self.hotkey_editor_action,
self.workflow_tools_action,
self.toggle_ding_action,
self.clear_logs_action,
self.close_action]

Expand Down
47 changes: 47 additions & 0 deletions nxt_editor/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -1649,6 +1649,53 @@ def redo(self):
self.setText("Set {} color to {}".format(layer.filepath, self.color))


class SetLayerLock(NxtCommand):
def __init__(self, lock, layer_path, model):
"""Sets the color for a given layer, if the layer is not a top layer
the top layer store an overrides.
:param lock: bool of the desired lock state, if None is passed its
considered a revert.
:param layer_path: real path of layer
:param model: StageModel
"""
super(SetLayerLock, self).__init__(model)
self.layer_path = layer_path
self.lock = lock
self.old_lock = None
self.model = model
self.stage = model.stage
self.prev_target_layer_path = None

@processing
def undo(self):
layer = self.model.lookup_layer(self.layer_path)
if layer is self.model.top_layer:
layer.lock = self.old_lock
else:
layer.set_locked_over(self.old_lock)
self.undo_effected_layer(self.model.top_layer.real_path)
self.model.layer_lock_changed.emit(self.layer_path)
if self.prev_target_layer_path:
prev_tgt = self.model.lookup_layer(self.prev_target_layer_path)
if prev_tgt != self.model.target_layer:
self.model._set_target_layer(prev_tgt)

@processing
def redo(self):
layer = self.model.lookup_layer(self.layer_path)
self.prev_target_layer_path = self.model.get_layer_path(self.model.target_layer, LAYERS.TARGET)
self.old_lock = layer.get_locked(fallback_to_local=False)
layer.set_locked_over(self.lock)
self.redo_effected_layer(self.model.top_layer.real_path)
self.model.layer_lock_changed.emit(self.layer_path)
move_tgt = layer == self.model.target_layer
if move_tgt:
self.model._set_target_layer(self.model.top_layer)
logger.warning('You locked your target layer, setting target layer to TOP layer.')
self.model.request_ding.emit()
self.setText("Set {} lock to {}".format(layer.filepath, self.lock))


def _add_node_hierarchy(base_node_path, model, layer):
stage = model.stage
comp_layer = model.comp_layer
Expand Down
40 changes: 29 additions & 11 deletions nxt_editor/dockwidgets/code_editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,16 @@
class CodeEditor(DockWidgetBase):

def __init__(self, title='Code Editor', parent=None, minimum_width=500):
super(CodeEditor, self).__init__(title=title, parent=parent, minimum_width=minimum_width)
super(CodeEditor, self).__init__(title=title, parent=parent,
minimum_width=minimum_width)
self.setObjectName('Code Editor')
self.main_window = parent
self.ce_actions = self.main_window.code_editor_actions
self.exec_actions = self.main_window.execute_actions
# local attributes
self.editing_active = False
self.code_is_local = False
self.locked = False
self.node_path = None
self.node_name = ''
self.actual_display_state = ''
Expand Down Expand Up @@ -187,15 +189,15 @@ def __init__(self, title='Code Editor', parent=None, minimum_width=500):
QtCore.Qt.AlignRight)

# remove code button
self.remove_code_button = PixmapButton(pixmap=':icons/icons/delete.png',
pixmap_hover=':icons/icons/delete_hover.png',
pixmap_pressed=':icons/icons/delete_pressed.png',
size=12,
parent=self.code_frame)
self.remove_code_button.setToolTip('Remove Compute')
self.remove_code_button.setStyleSheet('QToolTip {color: white; border: 1px solid #3E3E3E}')
self.remove_code_button.clicked.connect(self.revert_code)
self.buttons_layout.addWidget(self.remove_code_button, 0, 7,
self.revert_code_button = PixmapButton(pixmap=':icons/icons/delete.png',
pixmap_hover=':icons/icons/delete_hover.png',
pixmap_pressed=':icons/icons/delete_pressed.png',
size=12,
parent=self.code_frame)
self.revert_code_button.setToolTip('Remove Compute')
self.revert_code_button.setStyleSheet('QToolTip {color: white; border: 1px solid #3E3E3E}')
self.revert_code_button.clicked.connect(self.revert_code)
self.buttons_layout.addWidget(self.revert_code_button, 0, 7,
QtCore.Qt.AlignRight)
if not self.main_window.in_startup:
# default state
Expand Down Expand Up @@ -230,6 +232,7 @@ def set_stage_model_connections(self, model, connect):
self.model_signal_connections = [
(model.node_focus_changed, self.accept_edit),
(model.node_focus_changed, self.set_represented_node),
(model.layer_lock_changed, self.handle_lock_changed),
(model.nodes_changed, self.update_editor),
(model.attrs_changed, self.update_editor),
(model.data_state_changed, self.update_editor),
Expand All @@ -247,6 +250,20 @@ def on_stage_model_destroyed(self):
self.editor.hide()
self.update_background()

def handle_lock_changed(self, *args):
# TODO: Make it a user pref to lock the code editor when node is locked?
# self.locked = self.stage_model.get_node_locked(self.node_path)
self.name_label.setReadOnly(self.locked)
# Enable/Disable
self.accept_button.setEnabled(not self.locked)
self.cancel_button.setEnabled(not self.locked)
self.revert_code_button.setEnabled(not self.locked)
keep_active = [self.ce_actions.copy_resolved_action]
for action in self.ce_actions.actions() + self.exec_actions.actions():
if action in keep_active:
continue
action.setEnabled(not self.locked)

def set_represented_node(self):
self.node_path = self.stage_model.node_focus
if not self.node_path:
Expand All @@ -265,6 +282,7 @@ def set_represented_node(self):

self.display_editor()
self.display_details()
self.handle_lock_changed()

def copy_resolved(self):
if not self.stage_model:
Expand Down Expand Up @@ -429,7 +447,7 @@ def edit_format_characters(self, value=None):

def enter_editing(self):
# prevent re-activating when the mouse is clicked inside the editor
if self.editing_active:
if self.editing_active or self.locked:
return
self.cached_code = self.editor.toPlainText()
self.cached_code_lines = self.cached_code.split('\n')
Expand Down
34 changes: 29 additions & 5 deletions nxt_editor/dockwidgets/layer_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,9 @@ def __init__(self, layer_actions):
self.target_delegate = PixMapCheckboxDelegate(pencil_pix)
layer_pix = QtGui.QPixmap(':icons/icons/layers_hover.png')
self.display_delegate = PixMapCheckboxDelegate(layer_pix)
self.solo_delegate = LetterCheckboxDelegeate('S')
self.mute_delgate = LetterCheckboxDelegeate('M')
self.solo_delegate = LetterCheckboxDelegeate('S')
self.lock_delegate = LetterCheckboxDelegeate('L')
self.setItemDelegateForColumn(LayerModel.ALIAS_COLUMN,
self.alias_delegate)
self.setItemDelegateForColumn(LayerModel.TARGET_COLUMN,
Expand All @@ -83,6 +84,8 @@ def __init__(self, layer_actions):
self.mute_delgate)
self.setItemDelegateForColumn(LayerModel.SOLO_COLUMN,
self.solo_delegate)
self.setItemDelegateForColumn(LayerModel.LOCK_COLUMN,
self.lock_delegate)
self.setHeaderHidden(True)
self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.customContextMenuRequested.connect(self.custom_context_menu)
Expand Down Expand Up @@ -121,13 +124,21 @@ def on_item_clicked(self, clicked_idx):
return
layer = clicked_idx.internalPointer()
layer_path = self.model().stage_model.get_layer_path(layer)
if self.model().stage_model.get_layer_locked(layer_path):
logger.warning('The layer "{}" is locked!'.format(layer.alias))
self.model().stage_model.request_ding.emit()
return
self.model().stage_model.set_target_layer(layer_path)

def on_item_dbl_clicked(self, clicked_idx):
if not clicked_idx.column() == LayerModel.ALIAS_COLUMN:
return
if not self.model().stage_model:
return
layer = clicked_idx.internalPointer()
layer_path = self.model().stage_model.get_layer_path(layer)
if self.model().stage_model.get_layer_locked(layer_path):
return
self.model().stage_model.set_selection([nxt_path.WORLD])

def custom_context_menu(self, pos):
Expand Down Expand Up @@ -208,8 +219,9 @@ class LayerModel(QtCore.QAbstractItemModel):
TARGET_COLUMN = 2
MUTE_COLUMN = 3
SOLO_COLUMN = 4
HAS_SELECTED_COLUMN = 5
UNSAVED = 6
LOCK_COLUMN = 5
HAS_SELECTED_COLUMN = 6
UNSAVED = 7

def __init__(self, stage_model):
super(LayerModel, self).__init__()
Expand Down Expand Up @@ -406,7 +418,7 @@ def columnCount(self, parent=None):
"""Returns number of columns in the model.
Part of QAbstractItemModel
"""
return 5
return 6

def data(self, index, role=None):
"""Returns the data continaed at given model index with given role.
Expand All @@ -423,6 +435,7 @@ def data(self, index, role=None):
return
is_disp = layer == self.stage_model.display_layer
is_target = layer == self.stage_model.target_layer
is_locked = layer.get_locked()
if role == QtCore.Qt.EditRole:
if column == self.ALIAS_COLUMN:
return layer.get_alias()
Expand All @@ -434,6 +447,8 @@ def data(self, index, role=None):
return layer.get_muted()
if column == self.SOLO_COLUMN:
return layer.get_soloed()
if column == self.LOCK_COLUMN:
return is_locked
if column == self.HAS_SELECTED_COLUMN:
return layer in self.layers_with_selected
if column == self.UNSAVED:
Expand All @@ -450,6 +465,8 @@ def data(self, index, role=None):
if column == self.SOLO_COLUMN:
soloed = layer.get_soloed()
return QtCore.Qt.Checked if soloed else QtCore.Qt.Unchecked
if column == self.LOCK_COLUMN:
return QtCore.Qt.Checked if is_locked else QtCore.Qt.Unchecked

def setData(self, index, value, role=QtCore.Qt.EditRole):
"""Allows editing of layers via qt model interface.
Expand Down Expand Up @@ -481,12 +498,16 @@ def setData(self, index, value, role=QtCore.Qt.EditRole):
if column == self.SOLO_COLUMN:
self.stage_model.solo_toggle_layer(layer)
return True
if column == self.LOCK_COLUMN:
self.stage_model.set_layer_locked(layer_path,
lock=not layer.get_locked())
return True
return False

def flags(self, index):
column = index.column()
if column in (self.TARGET_COLUMN, self.DISPLAY_COLUMN,
self.MUTE_COLUMN, self.SOLO_COLUMN,):
self.MUTE_COLUMN, self.SOLO_COLUMN, self.LOCK_COLUMN):
return (QtCore.Qt.ItemIsEnabled |
QtCore.Qt.ItemIsUserCheckable)
return (QtCore.Qt.ItemIsEnabled |
Expand Down Expand Up @@ -580,6 +601,7 @@ def __init__(self):
super(AliasDelegate, self).__init__()
self.muted = False
self.soloed = False
self.locked = False
self.is_tgt = False
self.has_selected = False
self.unsaved = False
Expand Down Expand Up @@ -639,6 +661,8 @@ def paint(self, painter, option, index):
self.muted = model.data(mute_index, role=QtCore.Qt.EditRole)
solo_index = model.index(row, LayerModel.SOLO_COLUMN, parent)
self.soloed = model.data(solo_index, role=QtCore.Qt.EditRole)
lock_index = model.index(row, LayerModel.LOCK_COLUMN, parent)
self.locked = model.data(lock_index, role=QtCore.Qt.EditRole)
tgt_index = model.index(row, LayerModel.TARGET_COLUMN, parent)
self.is_tgt = model.data(tgt_index, role=QtCore.Qt.EditRole)
sel_idx = model.index(row, LayerModel.HAS_SELECTED_COLUMN, parent)
Expand Down
Loading

0 comments on commit 346583a

Please sign in to comment.