mirror of https://gitlab.com/openlp/openlp.git
578 lines
26 KiB
Python
578 lines
26 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
##########################################################################
|
|
# OpenLP - Open Source Lyrics Projection #
|
|
# ---------------------------------------------------------------------- #
|
|
# Copyright (c) 2008-2021 OpenLP Developers #
|
|
# ---------------------------------------------------------------------- #
|
|
# 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 <https://www.gnu.org/licenses/>. #
|
|
##########################################################################
|
|
import logging
|
|
|
|
from PyQt5 import QtCore, QtWidgets
|
|
from sqlalchemy.sql import and_
|
|
|
|
from openlp.core.common.i18n import UiStrings, get_natural_key, translate
|
|
from openlp.core.common.mixins import RegistryProperties
|
|
from openlp.core.common.registry import Registry
|
|
from openlp.core.lib.ui import critical_error_message_box
|
|
from openlp.plugins.songs.forms.authorsform import AuthorsForm
|
|
from openlp.plugins.songs.forms.songbookform import SongBookForm
|
|
from openlp.plugins.songs.forms.topicsform import TopicsForm
|
|
from openlp.plugins.songs.lib.db import Author, Book, Song, Topic, SongBookEntry
|
|
|
|
from .songmaintenancedialog import Ui_SongMaintenanceDialog
|
|
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
class SongMaintenanceForm(QtWidgets.QDialog, Ui_SongMaintenanceDialog, RegistryProperties):
|
|
"""
|
|
Class documentation goes here.
|
|
"""
|
|
def __init__(self, manager, parent=None):
|
|
"""
|
|
Constructor
|
|
"""
|
|
super(SongMaintenanceForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint |
|
|
QtCore.Qt.WindowCloseButtonHint)
|
|
self.setup_ui(self)
|
|
self.manager = manager
|
|
self.author_form = AuthorsForm(self)
|
|
self.topic_form = TopicsForm(self)
|
|
self.song_book_form = SongBookForm(self)
|
|
# Disable all edit and delete buttons, as there is no row selected.
|
|
self.delete_author_button.setEnabled(False)
|
|
self.edit_author_button.setEnabled(False)
|
|
self.delete_topic_button.setEnabled(False)
|
|
self.edit_topic_button.setEnabled(False)
|
|
self.delete_book_button.setEnabled(False)
|
|
self.edit_book_button.setEnabled(False)
|
|
# Signals
|
|
self.add_author_button.clicked.connect(self.on_add_author_button_clicked)
|
|
self.add_topic_button.clicked.connect(self.on_add_topic_button_clicked)
|
|
self.add_book_button.clicked.connect(self.on_add_book_button_clicked)
|
|
self.edit_author_button.clicked.connect(self.on_edit_author_button_clicked)
|
|
self.edit_topic_button.clicked.connect(self.on_edit_topic_button_clicked)
|
|
self.edit_book_button.clicked.connect(self.on_edit_book_button_clicked)
|
|
self.delete_author_button.clicked.connect(self.on_delete_author_button_clicked)
|
|
self.delete_topic_button.clicked.connect(self.on_delete_topic_button_clicked)
|
|
self.delete_book_button.clicked.connect(self.on_delete_book_button_clicked)
|
|
self.authors_list_widget.currentRowChanged.connect(self.on_authors_list_row_changed)
|
|
self.topics_list_widget.currentRowChanged.connect(self.on_topics_list_row_changed)
|
|
self.song_books_list_widget.currentRowChanged.connect(self.on_song_books_list_row_changed)
|
|
|
|
def exec(self, from_song_edit=False):
|
|
"""
|
|
Show the dialog.
|
|
|
|
|
|
:param from_song_edit: Indicates if the maintenance dialog has been opened from song edit
|
|
or from the media manager. Defaults to **False**.
|
|
"""
|
|
self.from_song_edit = from_song_edit
|
|
self.type_list_widget.setCurrentRow(0)
|
|
self.reset_authors()
|
|
self.reset_topics()
|
|
self.reset_song_books()
|
|
self.type_list_widget.setFocus()
|
|
return QtWidgets.QDialog.exec(self)
|
|
|
|
def _get_current_item_id(self, list_widget):
|
|
"""
|
|
Get the ID of the currently selected item.
|
|
|
|
:param list_widget: The list widget to examine.
|
|
"""
|
|
item = list_widget.currentItem()
|
|
if item:
|
|
item_id = (item.data(QtCore.Qt.UserRole))
|
|
return item_id
|
|
else:
|
|
return -1
|
|
|
|
def _delete_item(self, item_class, list_widget, reset_func, dlg_title, del_text, err_text):
|
|
"""
|
|
Delete an item.
|
|
"""
|
|
item_id = self._get_current_item_id(list_widget)
|
|
if item_id != -1:
|
|
item = self.manager.get_object(item_class, item_id)
|
|
if item and not item.songs:
|
|
if critical_error_message_box(dlg_title, del_text, self, True) == QtWidgets.QMessageBox.Yes:
|
|
self.manager.delete_object(item_class, item.id)
|
|
reset_func()
|
|
else:
|
|
critical_error_message_box(dlg_title, err_text)
|
|
else:
|
|
critical_error_message_box(dlg_title, UiStrings().NISs)
|
|
|
|
def reset_authors(self):
|
|
"""
|
|
Reloads the Authors list.
|
|
"""
|
|
def get_author_key(author):
|
|
"""Get the key to sort by"""
|
|
return get_natural_key(author.display_name)
|
|
|
|
self.authors_list_widget.clear()
|
|
authors = self.manager.get_all_objects(Author)
|
|
authors.sort(key=get_author_key)
|
|
for author in authors:
|
|
if author.display_name:
|
|
author_name = QtWidgets.QListWidgetItem(author.display_name)
|
|
else:
|
|
author_name = QtWidgets.QListWidgetItem(' '.join([author.first_name, author.last_name]))
|
|
author_name.setData(QtCore.Qt.UserRole, author.id)
|
|
self.authors_list_widget.addItem(author_name)
|
|
|
|
def reset_topics(self):
|
|
"""
|
|
Reloads the Topics list.
|
|
"""
|
|
def get_topic_key(topic):
|
|
"""Get the key to sort by"""
|
|
return get_natural_key(topic.name)
|
|
|
|
self.topics_list_widget.clear()
|
|
topics = self.manager.get_all_objects(Topic)
|
|
topics.sort(key=get_topic_key)
|
|
for topic in topics:
|
|
topic_name = QtWidgets.QListWidgetItem(topic.name)
|
|
topic_name.setData(QtCore.Qt.UserRole, topic.id)
|
|
self.topics_list_widget.addItem(topic_name)
|
|
|
|
def reset_song_books(self):
|
|
"""
|
|
Reloads the Books list.
|
|
"""
|
|
def get_book_key(book):
|
|
"""Get the key to sort by"""
|
|
return get_natural_key(book.name)
|
|
|
|
self.song_books_list_widget.clear()
|
|
books = self.manager.get_all_objects(Book)
|
|
books.sort(key=get_book_key)
|
|
for book in books:
|
|
book_name = QtWidgets.QListWidgetItem('{name} ({publisher})'.format(name=book.name,
|
|
publisher=book.publisher))
|
|
book_name.setData(QtCore.Qt.UserRole, book.id)
|
|
self.song_books_list_widget.addItem(book_name)
|
|
|
|
def check_author_exists(self, new_author, edit=False):
|
|
"""
|
|
Returns *False* if the given Author already exists, otherwise *True*.
|
|
|
|
:param new_author: The new Author.
|
|
:param edit: Are we editing the song?
|
|
"""
|
|
authors = self.manager.get_all_objects(
|
|
Author,
|
|
and_(
|
|
Author.first_name == new_author.first_name,
|
|
Author.last_name == new_author.last_name,
|
|
Author.display_name == new_author.display_name
|
|
)
|
|
)
|
|
return self._check_object_exists(authors, new_author, edit)
|
|
|
|
def check_topic_exists(self, new_topic, edit=False):
|
|
"""
|
|
Returns *False* if the given Topic already exists, otherwise *True*.
|
|
|
|
:param new_topic: The new Topic.
|
|
:param edit: Are we editing the song?
|
|
"""
|
|
topics = self.manager.get_all_objects(Topic, Topic.name == new_topic.name)
|
|
return self._check_object_exists(topics, new_topic, edit)
|
|
|
|
def check_song_book_exists(self, new_book, edit=False):
|
|
"""
|
|
Returns *False* if the given Topic already exists, otherwise *True*.
|
|
|
|
:param new_book: The new Book.
|
|
:param edit: Are we editing the song?
|
|
"""
|
|
books = self.manager.get_all_objects(
|
|
Book, and_(Book.name == new_book.name, Book.publisher == new_book.publisher))
|
|
return self._check_object_exists(books, new_book, edit)
|
|
|
|
def _check_object_exists(self, existing_objects, new_object, edit):
|
|
"""
|
|
Utility method to check for an existing object.
|
|
|
|
:param existing_objects: The objects reference
|
|
:param new_object: An individual object
|
|
:param edit: If we edit an item, this should be *True*.
|
|
"""
|
|
if existing_objects:
|
|
# If we edit an existing object, we need to make sure that we do
|
|
# not return False when nothing has changed.
|
|
if edit:
|
|
for existing_object in existing_objects:
|
|
if existing_object.id != new_object.id:
|
|
return False
|
|
return True
|
|
else:
|
|
return False
|
|
else:
|
|
return True
|
|
|
|
def on_add_author_button_clicked(self):
|
|
"""
|
|
Add an author to the list.
|
|
"""
|
|
self.author_form.auto_display_name = True
|
|
if self.author_form.exec():
|
|
author = Author.populate(
|
|
first_name=self.author_form.first_name,
|
|
last_name=self.author_form.last_name,
|
|
display_name=self.author_form.display_name
|
|
)
|
|
if self.check_author_exists(author):
|
|
if self.manager.save_object(author):
|
|
self.reset_authors()
|
|
else:
|
|
critical_error_message_box(
|
|
message=translate('SongsPlugin.SongMaintenanceForm', 'Could not add your author.'))
|
|
else:
|
|
critical_error_message_box(
|
|
message=translate('SongsPlugin.SongMaintenanceForm', 'This author already exists.'))
|
|
|
|
def on_add_topic_button_clicked(self):
|
|
"""
|
|
Add a topic to the list.
|
|
"""
|
|
if self.topic_form.exec():
|
|
topic = Topic.populate(name=self.topic_form.name)
|
|
if self.check_topic_exists(topic):
|
|
if self.manager.save_object(topic):
|
|
self.reset_topics()
|
|
else:
|
|
critical_error_message_box(
|
|
message=translate('SongsPlugin.SongMaintenanceForm', 'Could not add your topic.'))
|
|
else:
|
|
critical_error_message_box(
|
|
message=translate('SongsPlugin.SongMaintenanceForm', 'This topic already exists.'))
|
|
|
|
def on_add_book_button_clicked(self):
|
|
"""
|
|
Add a book to the list.
|
|
"""
|
|
if self.song_book_form.exec():
|
|
book = Book.populate(name=self.song_book_form.name_edit.text(),
|
|
publisher=self.song_book_form.publisher_edit.text())
|
|
if self.check_song_book_exists(book):
|
|
if self.manager.save_object(book):
|
|
self.reset_song_books()
|
|
else:
|
|
critical_error_message_box(
|
|
message=translate('SongsPlugin.SongMaintenanceForm', 'Could not add your book.'))
|
|
else:
|
|
critical_error_message_box(
|
|
message=translate('SongsPlugin.SongMaintenanceForm', 'This book already exists.'))
|
|
|
|
def on_edit_author_button_clicked(self):
|
|
"""
|
|
Edit an author.
|
|
"""
|
|
author_id = self._get_current_item_id(self.authors_list_widget)
|
|
if author_id == -1:
|
|
return
|
|
author = self.manager.get_object(Author, author_id)
|
|
self.author_form.auto_display_name = False
|
|
self.author_form.first_name_edit.setText(author.first_name)
|
|
self.author_form.last_name_edit.setText(author.last_name)
|
|
self.author_form.display_edit.setText(author.display_name)
|
|
# Save the author's first and last name as well as the display name
|
|
# for the case that they have to be restored.
|
|
temp_first_name = author.first_name
|
|
temp_last_name = author.last_name
|
|
temp_display_name = author.display_name
|
|
if self.author_form.exec(False):
|
|
author.first_name = self.author_form.first_name_edit.text()
|
|
author.last_name = self.author_form.last_name_edit.text()
|
|
author.display_name = self.author_form.display_edit.text()
|
|
if self.check_author_exists(author, True):
|
|
if self.manager.save_object(author):
|
|
self.reset_authors()
|
|
if not self.from_song_edit:
|
|
Registry().execute('songs_load_list')
|
|
else:
|
|
critical_error_message_box(
|
|
message=translate('SongsPlugin.SongMaintenanceForm', 'Could not save your changes.'))
|
|
elif critical_error_message_box(
|
|
message=translate(
|
|
'SongsPlugin.SongMaintenanceForm',
|
|
'The author {original} already exists. Would you like to make songs with author {new} use the '
|
|
'existing author {original}?').format(original=author.display_name, new=temp_display_name),
|
|
parent=self, question=True) == QtWidgets.QMessageBox.Yes:
|
|
self._merge_objects(author, self.merge_authors, self.reset_authors)
|
|
else:
|
|
# We restore the author's old first and last name as well as
|
|
# his display name.
|
|
author.first_name = temp_first_name
|
|
author.last_name = temp_last_name
|
|
author.display_name = temp_display_name
|
|
critical_error_message_box(
|
|
message=translate('SongsPlugin.SongMaintenanceForm',
|
|
'Could not save your modified author, because the author already exists.'))
|
|
|
|
def on_edit_topic_button_clicked(self):
|
|
"""
|
|
Edit a topic.
|
|
"""
|
|
topic_id = self._get_current_item_id(self.topics_list_widget)
|
|
if topic_id == -1:
|
|
return
|
|
topic = self.manager.get_object(Topic, topic_id)
|
|
self.topic_form.name = topic.name
|
|
# Save the topic's name for the case that he has to be restored.
|
|
temp_name = topic.name
|
|
if self.topic_form.exec(False):
|
|
topic.name = self.topic_form.name_edit.text()
|
|
if self.check_topic_exists(topic, True):
|
|
if self.manager.save_object(topic):
|
|
self.reset_topics()
|
|
else:
|
|
critical_error_message_box(
|
|
message=translate('SongsPlugin.SongMaintenanceForm', 'Could not save your changes.'))
|
|
elif critical_error_message_box(
|
|
message=translate('SongsPlugin.SongMaintenanceForm',
|
|
'The topic {original} already exists. Would you like to make songs with '
|
|
'topic {new} use the existing topic {original}?').format(original=topic.name,
|
|
new=temp_name),
|
|
parent=self, question=True) == QtWidgets.QMessageBox.Yes:
|
|
self._merge_objects(topic, self.merge_topics, self.reset_topics)
|
|
else:
|
|
# We restore the topics's old name.
|
|
topic.name = temp_name
|
|
critical_error_message_box(
|
|
message=translate('SongsPlugin.SongMaintenanceForm',
|
|
'Could not save your modified topic, because it already exists.'))
|
|
|
|
def on_edit_book_button_clicked(self):
|
|
"""
|
|
Edit a book.
|
|
"""
|
|
book_id = self._get_current_item_id(self.song_books_list_widget)
|
|
if book_id == -1:
|
|
return
|
|
book = self.manager.get_object(Book, book_id)
|
|
if book.publisher is None:
|
|
book.publisher = ''
|
|
self.song_book_form.name_edit.setText(book.name)
|
|
self.song_book_form.publisher_edit.setText(book.publisher)
|
|
# Save the book's name and publisher for the case that they have to
|
|
# be restored.
|
|
temp_name = book.name
|
|
temp_publisher = book.publisher
|
|
if self.song_book_form.exec(False):
|
|
book.name = self.song_book_form.name_edit.text()
|
|
book.publisher = self.song_book_form.publisher_edit.text()
|
|
if self.check_song_book_exists(book, True):
|
|
if self.manager.save_object(book):
|
|
self.reset_song_books()
|
|
else:
|
|
critical_error_message_box(
|
|
message=translate('SongsPlugin.SongMaintenanceForm', 'Could not save your changes.'))
|
|
elif critical_error_message_box(
|
|
message=translate('SongsPlugin.SongMaintenanceForm',
|
|
'The book {original} already exists. Would you like to make songs with '
|
|
'book {new} use the existing book {original}?').format(original=book.name,
|
|
new=temp_name),
|
|
parent=self, question=True) == QtWidgets.QMessageBox.Yes:
|
|
self._merge_objects(book, self.merge_song_books, self.reset_song_books)
|
|
else:
|
|
# We restore the book's old name and publisher.
|
|
book.name = temp_name
|
|
book.publisher = temp_publisher
|
|
|
|
def _merge_objects(self, db_object, merge, reset):
|
|
"""
|
|
Utility method to merge two objects to leave one in the database.
|
|
"""
|
|
self.application.set_busy_cursor()
|
|
merge(db_object)
|
|
reset()
|
|
if not self.from_song_edit:
|
|
Registry().execute('songs_load_list')
|
|
self.application.set_normal_cursor()
|
|
|
|
def merge_authors(self, old_author):
|
|
"""
|
|
Merges two authors into one author.
|
|
|
|
:param old_author: The object, which was edited, that will be deleted
|
|
"""
|
|
# Find the duplicate.
|
|
existing_author = self.manager.get_object_filtered(
|
|
Author,
|
|
and_(
|
|
Author.first_name == old_author.first_name,
|
|
Author.last_name == old_author.last_name,
|
|
Author.display_name == old_author.display_name,
|
|
Author.id != old_author.id
|
|
)
|
|
)
|
|
# Find the songs, which have the old_author as author.
|
|
songs = self.manager.get_all_objects(Song, Song.authors.contains(old_author))
|
|
for song in songs:
|
|
for author_song in song.authors_songs:
|
|
song.add_author(existing_author, author_song.author_type)
|
|
song.remove_author(old_author, author_song.author_type)
|
|
self.manager.save_object(song)
|
|
self.manager.delete_object(Author, old_author.id)
|
|
|
|
def merge_topics(self, old_topic):
|
|
"""
|
|
Merges two topics into one topic.
|
|
|
|
:param old_topic: The object, which was edited, that will be deleted
|
|
"""
|
|
# Find the duplicate.
|
|
existing_topic = self.manager.get_object_filtered(
|
|
Topic, and_(Topic.name == old_topic.name, Topic.id != old_topic.id)
|
|
)
|
|
# Find the songs, which have the old_topic as topic.
|
|
songs = self.manager.get_all_objects(Song, Song.topics.contains(old_topic))
|
|
for song in songs:
|
|
# We check if the song has already existing_topic as topic. If that
|
|
# is not the case we add it.
|
|
if existing_topic not in song.topics:
|
|
song.topics.append(existing_topic)
|
|
song.topics.remove(old_topic)
|
|
self.manager.save_object(song)
|
|
self.manager.delete_object(Topic, old_topic.id)
|
|
|
|
def merge_song_books(self, old_song_book):
|
|
"""
|
|
Merges two books into one book.
|
|
|
|
``old_song_book``
|
|
The object, which was edited, that will be deleted
|
|
"""
|
|
# Find the duplicate.
|
|
existing_book = self.manager.get_object_filtered(
|
|
Book,
|
|
and_(
|
|
Book.name == old_song_book.name,
|
|
Book.publisher == old_song_book.publisher,
|
|
Book.id != old_song_book.id
|
|
)
|
|
)
|
|
if existing_book is None:
|
|
return False
|
|
# Find the songs which have the old_song_book as book, via matching entries in the songs_songbooks table
|
|
songbook_entries = self.manager.get_all_objects(SongBookEntry, SongBookEntry.songbook_id == old_song_book.id)
|
|
affected_songs = []
|
|
for songbook_entry in songbook_entries:
|
|
affected_songs.append(songbook_entry.song_id)
|
|
for song_id in affected_songs:
|
|
song = self.manager.get_object(Song, song_id)
|
|
# Go through the song's song/songbook link records to look for the link to the old songbook.
|
|
# Store the song number in that book so we can apply it in the link record to the existing songbook.
|
|
old_book_song_number = ''
|
|
for index, record in enumerate(song.songbook_entries):
|
|
if record.songbook_id == old_song_book.id:
|
|
old_book_song_number = record.entry
|
|
break
|
|
# Look through the same link records to see if there's a link to the duplicate (existing) songbook
|
|
# If so, transfer the song number in 'entry' field (if appropriate) ...
|
|
found = False
|
|
for record in song.songbook_entries:
|
|
if record.songbook_id == existing_book.id:
|
|
if not record.entry and old_book_song_number:
|
|
record.entry = old_book_song_number
|
|
found = True
|
|
break
|
|
# ... otherwise create a new link record
|
|
if not found:
|
|
new_songbook_entry = SongBookEntry()
|
|
new_songbook_entry.songbook_id = existing_book.id
|
|
new_songbook_entry.song_id = song.id
|
|
new_songbook_entry.entry = old_book_song_number
|
|
song.songbook_entries.append(new_songbook_entry)
|
|
self.manager.save_object(song)
|
|
self.manager.delete_object(SongBookEntry, (old_song_book.id, song_id, old_book_song_number))
|
|
|
|
self.manager.delete_object(Book, old_song_book.id)
|
|
|
|
def on_delete_author_button_clicked(self):
|
|
"""
|
|
Delete the author if the author is not attached to any songs.
|
|
"""
|
|
self._delete_item(Author, self.authors_list_widget, self.reset_authors,
|
|
translate('SongsPlugin.SongMaintenanceForm', 'Delete Author'),
|
|
translate('SongsPlugin.SongMaintenanceForm',
|
|
'Are you sure you want to delete the selected author?'),
|
|
translate('SongsPlugin.SongMaintenanceForm',
|
|
'This author cannot be deleted, they are currently assigned to at least one song'
|
|
'.'))
|
|
|
|
def on_delete_topic_button_clicked(self):
|
|
"""
|
|
Delete the Book if the Book is not attached to any songs.
|
|
"""
|
|
self._delete_item(Topic, self.topics_list_widget, self.reset_topics,
|
|
translate('SongsPlugin.SongMaintenanceForm', 'Delete Topic'),
|
|
translate('SongsPlugin.SongMaintenanceForm',
|
|
'Are you sure you want to delete the selected topic?'),
|
|
translate('SongsPlugin.SongMaintenanceForm',
|
|
'This topic cannot be deleted, it is currently assigned to at least one song.'))
|
|
|
|
def on_delete_book_button_clicked(self):
|
|
"""
|
|
Delete the Book if the Book is not attached to any songs.
|
|
"""
|
|
self._delete_item(Book, self.song_books_list_widget, self.reset_song_books,
|
|
translate('SongsPlugin.SongMaintenanceForm', 'Delete Book'),
|
|
translate('SongsPlugin.SongMaintenanceForm',
|
|
'Are you sure you want to delete the selected book?'),
|
|
translate('SongsPlugin.SongMaintenanceForm',
|
|
'This book cannot be deleted, it is currently assigned to at least one song.'))
|
|
|
|
def on_authors_list_row_changed(self, row):
|
|
"""
|
|
Called when the *authors_list_widget*'s current row has changed.
|
|
"""
|
|
self._row_change(row, self.edit_author_button, self.delete_author_button)
|
|
|
|
def on_topics_list_row_changed(self, row):
|
|
"""
|
|
Called when the *topics_list_widget*'s current row has changed.
|
|
"""
|
|
self._row_change(row, self.edit_topic_button, self.delete_topic_button)
|
|
|
|
def on_song_books_list_row_changed(self, row):
|
|
"""
|
|
Called when the *song_books_list_widget*'s current row has changed.
|
|
"""
|
|
self._row_change(row, self.edit_book_button, self.delete_book_button)
|
|
|
|
def _row_change(self, row, edit_button, delete_button):
|
|
"""
|
|
Utility method to toggle if buttons are enabled.
|
|
|
|
``row``
|
|
The current row. If there is no current row, the value is -1.
|
|
"""
|
|
if row == -1:
|
|
delete_button.setEnabled(False)
|
|
edit_button.setEnabled(False)
|
|
else:
|
|
delete_button.setEnabled(True)
|
|
edit_button.setEnabled(True)
|