Skip to content
Draft
Show file tree
Hide file tree
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
6 changes: 4 additions & 2 deletions src/skin/legacy/legacyskinparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1176,13 +1176,15 @@ QWidget* LegacySkinParser::parseTrackProperty(const QDomElement& node) {
return nullptr;
}

bool isMainDeck = PlayerManager::isDeckGroup(group);
int mainDeckNum = 0;
bool isMainDeck = PlayerManager::isDeckGroup(group, &mainDeckNum);
WTrackProperty* pTrackProperty = new WTrackProperty(
m_pParent,
m_pConfig,
m_pLibrary,
group,
isMainDeck);
isMainDeck,
mainDeckNum);
setupLabelWidget(node, pTrackProperty);

// Ensure 'show_track_menu' control is created for each main deck and
Expand Down
125 changes: 96 additions & 29 deletions src/widget/wtrackproperty.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,15 @@ WTrackProperty::WTrackProperty(
UserSettingsPointer pConfig,
Library* pLibrary,
const QString& group,
bool isMainDeck)
bool isMainDeck,
int deckNum)
: WLabel(pParent),
m_group(group),
m_pConfig(pConfig),
m_pLibrary(pLibrary),
m_isMainDeck(isMainDeck),
m_isComment(false),
m_mainDeckNum(deckNum),
m_propertyIsWritable(false),
m_pSelectedClickTimer(nullptr),
m_bSelected(false),
Expand Down Expand Up @@ -65,6 +68,34 @@ void WTrackProperty::setup(const QDomNode& node, const SkinContext& context) {
return;
}
m_editProperty = m_displayProperty;
if (m_editProperty == QStringLiteral("comment")) {
m_isComment = true;
}
}

// Create a QAction with a hotkey which allows us to open the editor without
// having to use the mouse
if (m_isComment && m_isMainDeck && m_mainDeckNum > 0) {
parented_ptr<QAction> pEditCommentAction = make_parented<QAction>("edit comment", this);
pEditCommentAction->setShortcut(QKeySequence(tr("Alt+%1").arg(m_mainDeckNum)));
connect(pEditCommentAction.get(),
&QAction::triggered,
this,
[this]() {
// Assumes only one comment label is visible.
// If there are more, Qt _should_ trigger the first QAction
// in the internal list and throw a warning for the others
// "QAction::event: Ambiguous shortcut overload: [shortcut]"
// Anyways, as soon as one editor is opened (gets focus),
// others will receive a focusOut event and close.
if (isVisible() &&
(!m_pEditor || (m_pEditor && !m_pEditor->isVisible()))) {
// Note: if the editor is already visible, this would
// reload/reset the comment from the track
openEditor();
}
});
addAction(pEditCommentAction);
}
m_propertyIsWritable = true;
}
Expand Down Expand Up @@ -97,6 +128,10 @@ void WTrackProperty::slotLoadingTrack(TrackPointer pNewTrack, TrackPointer pOldT
void WTrackProperty::slotTrackChanged(TrackId trackId) {
Q_UNUSED(trackId);
updateLabel();
if (m_pEditor && m_pEditor->isVisible()) {
// Close and discard new text
m_pEditor->hide();
}
}

void WTrackProperty::updateLabel() {
Expand Down Expand Up @@ -149,28 +184,7 @@ void WTrackProperty::mousePressEvent(QMouseEvent* pEvent) {
this, &WTrackProperty::resetSelectedState);
} else if (m_pSelectedClickTimer->isActive()) {
resetSelectedState();
// create the persistent editor, populate & connect
if (!m_pEditor) {
m_pEditor = make_parented<WTrackPropertyEditor>(this);
connect(m_pEditor,
// use custom signal. editingFinished() doesn't suit since it's
// also emitted weh pressing Esc (which should cancel editing)
&WTrackPropertyEditor::commitEditorData,
this,
&WTrackProperty::slotCommitEditorData);
}
// Don't let the editor expand beyond its initial size
m_pEditor->setFixedSize(size());

QString editText = getPropertyStringFromTrack(m_editProperty);
if (m_displayProperty == "titleInfo" && editText.isEmpty()) {
editText = tr("title");
}
m_pEditor->setText(editText);
m_pEditor->selectAll();
m_pEditor->show();
m_pEditor->setFocus();
return;
openEditor();
}
// start timer
m_pSelectedClickTimer->start();
Expand Down Expand Up @@ -308,15 +322,68 @@ void WTrackProperty::slotShowTrackMenuChangeRequest(bool show) {
contextMenuEvent(pEvent);
}

void WTrackProperty::openEditor() {
resetSelectedState();
if (!m_pCurrentTrack) {
return;
}
// create the persistent editor, populate & connect
if (!m_pEditor) {
m_pEditor = make_parented<WTrackPropertyEditor>(this);
connect(m_pEditor,
// use custom signal. editingFinished() doesn't suit since it's
// also emitted weh pressing Esc (which should cancel editing)
&WTrackPropertyEditor::commitEditorData,
this,
&WTrackProperty::slotCommitEditorData);
}
// Don't let the editor expand beyond its initial size
m_pEditor->setFixedSize(size());

QString editText = getPropertyStringFromTrack(m_editProperty);
if (m_displayProperty == "titleInfo" && editText.isEmpty()) {
editText = tr("title");
}
m_pEditor->setText(editText);
m_pEditor->selectAll();
m_pEditor->show();
m_pEditor->setFocus();
}

void WTrackProperty::slotCommitEditorData(const QString& text) {
if (!m_pCurrentTrack) {
return;
}

// use real track data instead of text() to be independent from display text
if (m_pCurrentTrack && text != getPropertyStringFromTrack(m_editProperty)) {
const QVariant var(QVariant::fromValue(text));
m_pCurrentTrack->setProperty(
m_editProperty.toUtf8().constData(),
var);
// Track::changed() will update label
const QString trackText = getPropertyStringFromTrack(m_editProperty);
QString editorText = text;
if (m_isComment) {
// Transform ALL occurrences of \n into linebreaks.
// Existing linebreaks are not affected.
QString cr(QChar::CarriageReturn);
cr.append(QChar::LineFeed);
editorText.replace("\\n", cr);
// For multi-line comments, the editor received only the first line.
// In order to keep the other lines, we need to replace
// the first line of the original text with the editor text.
// (which may add new linebreaks)
// Note: assumes the comment didn't change while we were editing it.
int firstLB = trackText.indexOf('\n');
if (firstLB >= 0) { // has linebreak
QString trackTSliced = trackText;
trackTSliced = trackTSliced.sliced(firstLB);
editorText.append(trackTSliced);
}
}
if (editorText == trackText) {
return;
}
const QVariant var(QVariant::fromValue(editorText));
m_pCurrentTrack->setProperty(
m_editProperty.toUtf8().constData(),
var);
// Track::changed() will update label
}

void WTrackProperty::resetSelectedState() {
Expand Down
8 changes: 7 additions & 1 deletion src/widget/wtrackproperty.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ class WTrackProperty : public WLabel, public TrackDropTarget {
UserSettingsPointer pConfig,
Library* pLibrary,
const QString& group,
bool isMainDeck);
bool isMainDeck,
int mainDeckNum);
~WTrackProperty() override;
// Custom property to allow skins to style the 'selected' state when the
// widget awaits a second click to open the editor. It's reset automatically
Expand Down Expand Up @@ -89,10 +90,15 @@ class WTrackProperty : public WLabel, public TrackDropTarget {
void restyleAndRepaint();

void ensureTrackMenuIsCreated();
void openEditor();

const QString m_group;
const UserSettingsPointer m_pConfig;
Library* m_pLibrary;
const bool m_isMainDeck;
bool m_isComment;
int m_mainDeckNum;

TrackPointer m_pCurrentTrack;

QString m_displayProperty;
Expand Down