782e592ad4
added play button for glissando also updated test case updated glissando accidentals to work correctly based on end note, even if in different staff
386 lines
20 KiB
C++
386 lines
20 KiB
C++
//=============================================================================
|
|
// MuseScore
|
|
// Music Composition & Notation
|
|
//
|
|
// Copyright (C) 2011 Werner Schweer
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License version 2
|
|
// as published by the Free Software Foundation and appearing in
|
|
// the file LICENCE.GPL
|
|
//=============================================================================
|
|
|
|
#include "property.h"
|
|
#include "mscore.h"
|
|
#include "layoutbreak.h"
|
|
#include "groups.h"
|
|
#include "xml.h"
|
|
#include "note.h"
|
|
|
|
namespace Ms {
|
|
|
|
//---------------------------------------------------------
|
|
// PropertyData
|
|
//---------------------------------------------------------
|
|
|
|
struct PropertyData {
|
|
P_ID id;
|
|
bool link; // link this property for linked elements
|
|
const char* name; // xml name of property
|
|
P_TYPE type;
|
|
};
|
|
|
|
//
|
|
// always: propertyList[subtype].id == subtype
|
|
//
|
|
//
|
|
static const PropertyData propertyList[] = {
|
|
{ P_ID::SUBTYPE, false, "subtype", P_TYPE::INT },
|
|
{ P_ID::SELECTED, false, "selected", P_TYPE::BOOL },
|
|
{ P_ID::GENERATED, false, "generated", P_TYPE::BOOL },
|
|
{ P_ID::COLOR, false, "color", P_TYPE::COLOR },
|
|
{ P_ID::VISIBLE, false, "visible", P_TYPE::BOOL },
|
|
{ P_ID::SMALL, false, "small", P_TYPE::BOOL },
|
|
{ P_ID::SHOW_COURTESY, false, "showCourtesy", P_TYPE::INT },
|
|
{ P_ID::LINE_TYPE, false, "lineType", P_TYPE::INT },
|
|
{ P_ID::PITCH, true, "pitch", P_TYPE::INT },
|
|
{ P_ID::TPC1, true, "tpc", P_TYPE::INT },
|
|
{ P_ID::TPC2, true, "tpc2", P_TYPE::INT },
|
|
|
|
{ P_ID::LINE, false, "line", P_TYPE::INT },
|
|
{ P_ID::FIXED, false, "fixed", P_TYPE::BOOL },
|
|
{ P_ID::FIXED_LINE, false, "fixedLine", P_TYPE::INT },
|
|
{ P_ID::HEAD_TYPE, false, "headType", P_TYPE::INT },
|
|
{ P_ID::HEAD_GROUP, false, "head", P_TYPE::INT },
|
|
{ P_ID::VELO_TYPE, false, "veloType", P_TYPE::VALUE_TYPE },
|
|
{ P_ID::VELO_OFFSET, false, "velocity", P_TYPE::INT },
|
|
{ P_ID::ARTICULATION_ANCHOR, false, "anchor", P_TYPE::INT },
|
|
{ P_ID::DIRECTION, false, "direction", P_TYPE::DIRECTION },
|
|
{ P_ID::STEM_DIRECTION, true, "StemDirection", P_TYPE::DIRECTION },
|
|
|
|
{ P_ID::NO_STEM, false, "noStem", P_TYPE::INT },
|
|
{ P_ID::SLUR_DIRECTION, false, "slurDirection", P_TYPE::INT },
|
|
{ P_ID::LEADING_SPACE, false, "leadingSpace", P_TYPE::SPATIUM },
|
|
{ P_ID::TRAILING_SPACE, false, "trailingSpace", P_TYPE::SPATIUM },
|
|
{ P_ID::DISTRIBUTE, false, "distribute", P_TYPE::BOOL },
|
|
{ P_ID::MIRROR_HEAD, false, "mirror", P_TYPE::DIRECTION_H },
|
|
{ P_ID::DOT_POSITION, false, "dotPosition", P_TYPE::DIRECTION },
|
|
{ P_ID::TUNING, false, "tuning", P_TYPE::REAL },
|
|
{ P_ID::PAUSE, false, "pause", P_TYPE::REAL },
|
|
{ P_ID::BARLINE_SPAN, false, "barlineSpan", P_TYPE::INT },
|
|
|
|
{ P_ID::BARLINE_SPAN_FROM, false, 0, P_TYPE::INT },
|
|
{ P_ID::BARLINE_SPAN_TO, false, 0, P_TYPE::INT },
|
|
{ P_ID::USER_OFF, false, "userOff", P_TYPE::POINT },
|
|
{ P_ID::FRET, true, "fret", P_TYPE::INT },
|
|
{ P_ID::STRING, true, "string", P_TYPE::INT },
|
|
{ P_ID::GHOST, true, "ghost", P_TYPE::BOOL },
|
|
{ P_ID::PLAY, false, "play", P_TYPE::BOOL },
|
|
{ P_ID::TIMESIG_NOMINAL, false, 0, P_TYPE::FRACTION },
|
|
{ P_ID::TIMESIG_ACTUAL, true, 0, P_TYPE::FRACTION },
|
|
{ P_ID::NUMBER_TYPE, false, "numberType", P_TYPE::INT },
|
|
|
|
{ P_ID::BRACKET_TYPE, false, "bracketType", P_TYPE::INT },
|
|
{ P_ID::NORMAL_NOTES, false, "normalNotes", P_TYPE::INT },
|
|
{ P_ID::ACTUAL_NOTES, false, "actualNotes", P_TYPE::INT },
|
|
{ P_ID::P1, false, "p1", P_TYPE::POINT },
|
|
{ P_ID::P2, false, "p2", P_TYPE::POINT },
|
|
{ P_ID::GROW_LEFT, false, "growLeft", P_TYPE::REAL },
|
|
{ P_ID::GROW_RIGHT, false, "growRight", P_TYPE::REAL },
|
|
{ P_ID::BOX_HEIGHT, false, "height", P_TYPE::SPATIUM },
|
|
{ P_ID::BOX_WIDTH, false, "width", P_TYPE::SPATIUM },
|
|
{ P_ID::TOP_GAP, false, "topGap", P_TYPE::SP_REAL },
|
|
|
|
{ P_ID::BOTTOM_GAP, false, "bottomGap", P_TYPE::SP_REAL },
|
|
{ P_ID::LEFT_MARGIN, false, "leftMargin", P_TYPE::REAL },
|
|
{ P_ID::RIGHT_MARGIN, false, "rightMargin", P_TYPE::REAL },
|
|
{ P_ID::TOP_MARGIN, false, "topMargin", P_TYPE::REAL },
|
|
{ P_ID::BOTTOM_MARGIN, false, "bottomMargin", P_TYPE::REAL },
|
|
{ P_ID::LAYOUT_BREAK, false, "subtype", P_TYPE::LAYOUT_BREAK },
|
|
{ P_ID::AUTOSCALE, false, "autoScale", P_TYPE::BOOL },
|
|
{ P_ID::SIZE, false, "size", P_TYPE::SIZE },
|
|
{ P_ID::SCALE, false, 0, P_TYPE::SCALE },
|
|
{ P_ID::LOCK_ASPECT_RATIO, false, "lockAspectRatio", P_TYPE::BOOL },
|
|
|
|
{ P_ID::SIZE_IS_SPATIUM, false, "sizeIsSpatium", P_TYPE::BOOL },
|
|
{ P_ID::TEXT_STYLE, false, "textStyle", P_TYPE::TEXT_STYLE },
|
|
{ P_ID::TEXT_STYLE_TYPE, false, "textStyleType", P_TYPE::INT },
|
|
{ P_ID::TEXT, false, 0, P_TYPE::STRING },
|
|
{ P_ID::HTML_TEXT, false, 0, P_TYPE::STRING },
|
|
{ P_ID::USER_MODIFIED, false, 0, P_TYPE::BOOL },
|
|
{ P_ID::BEAM_POS, false, 0, P_TYPE::POINT },
|
|
{ P_ID::BEAM_MODE, true, "BeamMode", P_TYPE::BEAM_MODE },
|
|
{ P_ID::BEAM_NO_SLOPE, true, "noSlope", P_TYPE::BOOL },
|
|
{ P_ID::USER_LEN, false, "userLen", P_TYPE::REAL },
|
|
|
|
{ P_ID::SPACE, false, "space", P_TYPE::SP_REAL},
|
|
{ P_ID::TEMPO, true, "tempo", P_TYPE::TEMPO },
|
|
{ P_ID::TEMPO_FOLLOW_TEXT, true, "followText", P_TYPE::BOOL },
|
|
{ P_ID::ACCIDENTAL_BRACKET, false, "bracket", P_TYPE::BOOL },
|
|
{ P_ID::NUMERATOR_STRING, false, "textN", P_TYPE::STRING },
|
|
{ P_ID::DENOMINATOR_STRING, false, "textD", P_TYPE::STRING },
|
|
{ P_ID::BREAK_HINT, false, "breakHint", P_TYPE::BOOL },
|
|
{ P_ID::FBPREFIX, false, "prefix", P_TYPE::INT },
|
|
{ P_ID::FBDIGIT, false, "digit", P_TYPE::INT },
|
|
{ P_ID::FBSUFFIX, false, "suffix", P_TYPE::INT },
|
|
|
|
{ P_ID::FBCONTINUATIONLINE, false, "continuationLine", P_TYPE::INT },
|
|
{ P_ID::FBPARENTHESIS1, false, "", P_TYPE::INT },
|
|
{ P_ID::FBPARENTHESIS2, false, "", P_TYPE::INT },
|
|
{ P_ID::FBPARENTHESIS3, false, "", P_TYPE::INT },
|
|
{ P_ID::FBPARENTHESIS4, false, "", P_TYPE::INT },
|
|
{ P_ID::FBPARENTHESIS5, false, "", P_TYPE::INT },
|
|
{ P_ID::VOLTA_TYPE, false, "", P_TYPE::INT },
|
|
{ P_ID::OTTAVA_TYPE, false, "", P_TYPE::INT },
|
|
{ P_ID::NUMBERS_ONLY, false, "numbersOnly", P_TYPE::BOOL },
|
|
{ P_ID::TRILL_TYPE, false, "", P_TYPE::INT },
|
|
|
|
{ P_ID::HAIRPIN_CIRCLEDTIP, false, "hairpinCircledTip", P_TYPE::BOOL },
|
|
{ P_ID::HAIRPIN_TYPE, true, "", P_TYPE::INT },
|
|
{ P_ID::HAIRPIN_HEIGHT, false, "hairpinHeight", P_TYPE::SPATIUM },
|
|
{ P_ID::HAIRPIN_CONT_HEIGHT, false, "hairpinContHeight", P_TYPE::SPATIUM },
|
|
{ P_ID::VELO_CHANGE, true, "veloChange", P_TYPE::INT },
|
|
{ P_ID::DYNAMIC_RANGE, true, "dynType", P_TYPE::INT },
|
|
{ P_ID::PLACEMENT, false, "placement", P_TYPE::PLACEMENT },
|
|
{ P_ID::VELOCITY, false, "velocity", P_TYPE::INT },
|
|
{ P_ID::JUMP_TO, false, "jumpTo", P_TYPE::STRING },
|
|
{ P_ID::PLAY_UNTIL, false, "playUntil", P_TYPE::STRING },
|
|
|
|
{ P_ID::CONTINUE_AT, false, "continueAt", P_TYPE::STRING },
|
|
{ P_ID::LABEL, false, "label", P_TYPE::STRING },
|
|
{ P_ID::MARKER_TYPE, false, 0, P_TYPE::INT },
|
|
{ P_ID::ARP_USER_LEN1, false, 0, P_TYPE::REAL },
|
|
{ P_ID::ARP_USER_LEN2, false, 0, P_TYPE::REAL },
|
|
{ P_ID::REPEAT_FLAGS, false, 0, P_TYPE::INT },
|
|
{ P_ID::END_BARLINE_TYPE, false, 0, P_TYPE::INT },
|
|
{ P_ID::END_BARLINE_VISIBLE, false, 0, P_TYPE::BOOL },
|
|
{ P_ID::END_BARLINE_COLOR, false, 0, P_TYPE::COLOR },
|
|
{ P_ID::MEASURE_NUMBER_MODE, false, "measureNumberMode", P_TYPE::INT },
|
|
|
|
{ P_ID::GLISS_TYPE, false, 0, P_TYPE::INT },
|
|
{ P_ID::GLISS_TEXT, false, 0, P_TYPE::STRING },
|
|
{ P_ID::GLISS_SHOW_TEXT, false, 0, P_TYPE::BOOL },
|
|
{ P_ID::DIAGONAL, false, 0, P_TYPE::BOOL },
|
|
{ P_ID::GROUPS, false, 0, P_TYPE::GROUPS },
|
|
{ P_ID::LINE_STYLE, false, "lineStyle", P_TYPE::INT },
|
|
{ P_ID::LINE_COLOR, false, 0, P_TYPE::COLOR },
|
|
{ P_ID::LINE_WIDTH, false, 0, P_TYPE::SPATIUM },
|
|
{ P_ID::LASSO_POS, false, 0, P_TYPE::POINT_MM },
|
|
{ P_ID::LASSO_SIZE, false, 0, P_TYPE::SIZE_MM },
|
|
|
|
{ P_ID::TIME_STRETCH, false, 0, P_TYPE::REAL },
|
|
{ P_ID::ORNAMENT_STYLE, false, "ornamentStyle", P_TYPE::ORNAMENT_STYLE},
|
|
{ P_ID::PLAY_ARTICULATION, false, "playArticulation", P_TYPE::BOOL},
|
|
|
|
{ P_ID::TIMESIG, false, 0, P_TYPE::FRACTION },
|
|
{ P_ID::TIMESIG_GLOBAL, false, 0, P_TYPE::FRACTION },
|
|
{ P_ID::TIMESIG_STRETCH, false, 0, P_TYPE::FRACTION },
|
|
{ P_ID::TIMESIG_TYPE, true, 0, P_TYPE::INT },
|
|
{ P_ID::SPANNER_TICK, true, "tick", P_TYPE::INT },
|
|
{ P_ID::SPANNER_TICKS, true, "ticks", P_TYPE::INT },
|
|
{ P_ID::SPANNER_TRACK2, true, "track2", P_TYPE::INT },
|
|
{ P_ID::USER_OFF2, false, "userOff2", P_TYPE::POINT },
|
|
{ P_ID::BEGIN_TEXT_PLACE, false, "beginTextPlace", P_TYPE::INT },
|
|
{ P_ID::CONTINUE_TEXT_PLACE, false, "continueTextPlace", P_TYPE::INT },
|
|
|
|
{ P_ID::END_TEXT_PLACE, false, "endTextPlace", P_TYPE::INT },
|
|
{ P_ID::BEGIN_HOOK, false, "beginHook", P_TYPE::BOOL },
|
|
{ P_ID::END_HOOK, false, "endHook", P_TYPE::BOOL },
|
|
{ P_ID::BEGIN_HOOK_HEIGHT, false, "beginHookHeight", P_TYPE::SPATIUM },
|
|
{ P_ID::END_HOOK_HEIGHT, false, "endHookHeight", P_TYPE::SPATIUM },
|
|
{ P_ID::BEGIN_HOOK_TYPE, false, "beginHookType", P_TYPE::INT },
|
|
{ P_ID::END_HOOK_TYPE, false, "endHookType", P_TYPE::INT },
|
|
{ P_ID::BEGIN_TEXT, true, "beginText", P_TYPE::STRING },
|
|
{ P_ID::CONTINUE_TEXT, true, "continueText", P_TYPE::STRING },
|
|
{ P_ID::END_TEXT, true, "endText", P_TYPE::STRING },
|
|
|
|
{ P_ID::BEGIN_TEXT_STYLE, false, "beginTextStyle", P_TYPE::TEXT_STYLE },
|
|
{ P_ID::CONTINUE_TEXT_STYLE, false, "continueTextStyle", P_TYPE::TEXT_STYLE },
|
|
{ P_ID::END_TEXT_STYLE, false, "endTextStyle", P_TYPE::TEXT_STYLE },
|
|
{ P_ID::BREAK_MMR, false, "breakMultiMeasureRest", P_TYPE::BOOL },
|
|
{ P_ID::REPEAT_COUNT, true, "endRepeat", P_TYPE::INT },
|
|
{ P_ID::USER_STRETCH, false, "stretch", P_TYPE::REAL },
|
|
{ P_ID::NO_OFFSET, false, "noOffset", P_TYPE::INT },
|
|
{ P_ID::IRREGULAR, true, "irregular", P_TYPE::BOOL },
|
|
{ P_ID::ANCHOR, false, "anchor", P_TYPE::INT },
|
|
{ P_ID::SLUR_UOFF1, false, "o1", P_TYPE::POINT },
|
|
|
|
{ P_ID::SLUR_UOFF2, false, "o2", P_TYPE::POINT },
|
|
{ P_ID::SLUR_UOFF3, false, "o3", P_TYPE::POINT },
|
|
{ P_ID::SLUR_UOFF4, false, "o4", P_TYPE::POINT },
|
|
{ P_ID::STAFF_MOVE, true, "move", P_TYPE::INT },
|
|
{ P_ID::SYLLABIC, true, "syllabic", P_TYPE::INT },
|
|
{ P_ID::LYRIC_TICKS, true, "ticks", P_TYPE::INT },
|
|
{ P_ID::VOLTA_ENDING, true, "endings", P_TYPE::INT_LIST },
|
|
{ P_ID::LINE_VISIBLE, true, "lineVisible", P_TYPE::BOOL },
|
|
|
|
{ P_ID::SYSTEM_INITIAL_BARLINE_TYPE, false, "sysInitBarLineType", P_TYPE::INT },
|
|
{ P_ID::MAG, false, "mag", P_TYPE::REAL },
|
|
{ P_ID::USE_DRUMSET, false, "useDrumset", P_TYPE::BOOL },
|
|
{ P_ID::PART_VOLUME, false, "volume", P_TYPE::INT },
|
|
{ P_ID::PART_MUTE, false, "mute", P_TYPE::BOOL },
|
|
{ P_ID::PART_PAN, false, "pan", P_TYPE::INT },
|
|
{ P_ID::PART_REVERB, false, "reverb", P_TYPE::INT },
|
|
{ P_ID::PART_CHORUS, false, "chorus", P_TYPE::INT },
|
|
|
|
{ P_ID::DURATION, false, 0, P_TYPE::FRACTION },
|
|
{ P_ID::DURATION_TYPE, false, 0, P_TYPE::TDURATION },
|
|
{ P_ID::ROLE, false, "role", P_TYPE::INT },
|
|
{ P_ID::TRACK, false, 0, P_TYPE::INT },
|
|
|
|
{ P_ID::GLISSANDO_STYLE, false, "glissandoStyle", P_TYPE::GLISSANDO_STYLE},
|
|
{ P_ID::PLAY_GLISSANDO, false, "playGlissando", P_TYPE::BOOL},
|
|
{ P_ID::END, false, "", P_TYPE::INT }
|
|
};
|
|
|
|
//---------------------------------------------------------
|
|
// propertyType
|
|
//---------------------------------------------------------
|
|
|
|
P_TYPE propertyType(P_ID id)
|
|
{
|
|
Q_ASSERT( propertyList[int(id)].id == id);
|
|
|
|
return propertyList[int(id)].type;
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// propertyLink
|
|
//---------------------------------------------------------
|
|
|
|
bool propertyLink(P_ID id)
|
|
{
|
|
Q_ASSERT( propertyList[int(id)].id == id);
|
|
return propertyList[int(id)].link;
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// propertyName
|
|
//---------------------------------------------------------
|
|
|
|
const char* propertyName(P_ID id)
|
|
{
|
|
Q_ASSERT( propertyList[int(id)].id == id);
|
|
return propertyList[int(id)].name;
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// getProperty
|
|
//---------------------------------------------------------
|
|
|
|
QVariant getProperty(P_ID id, XmlReader& e)
|
|
{
|
|
switch (propertyType(id)) {
|
|
case P_TYPE::BOOL:
|
|
return QVariant(bool(e.readInt()));
|
|
case P_TYPE::SUBTYPE:
|
|
case P_TYPE::INT:
|
|
return QVariant(e.readInt());
|
|
case P_TYPE::REAL:
|
|
case P_TYPE::SPATIUM:
|
|
case P_TYPE::SP_REAL:
|
|
case P_TYPE::TEMPO:
|
|
return QVariant(e.readDouble());
|
|
case P_TYPE::FRACTION:
|
|
return QVariant::fromValue(e.readFraction());
|
|
case P_TYPE::COLOR:
|
|
return QVariant(e.readColor());
|
|
case P_TYPE::POINT:
|
|
return QVariant(e.readPoint());
|
|
case P_TYPE::SCALE:
|
|
case P_TYPE::SIZE:
|
|
return QVariant(e.readSize());
|
|
case P_TYPE::STRING:
|
|
return QVariant(e.readElementText());
|
|
case P_TYPE::GLISSANDO_STYLE: {
|
|
QString value(e.readElementText());
|
|
if ( value == "White keys")
|
|
return QVariant(int(MScore::GlissandoStyle::WHITE_KEYS));
|
|
else if ( value == "Black keys")
|
|
return QVariant(int(MScore::GlissandoStyle::BLACK_KEYS));
|
|
else if ( value == "Diatonic")
|
|
return QVariant(int(MScore::GlissandoStyle::DIATONIC));
|
|
else // e.g., normally "Chromatic"
|
|
return QVariant(int(MScore::GlissandoStyle::CHROMATIC));
|
|
}
|
|
break;
|
|
case P_TYPE::ORNAMENT_STYLE:
|
|
{
|
|
QString value(e.readElementText());
|
|
if ( value == "Baroque")
|
|
return QVariant(int(MScore::OrnamentStyle::BAROQUE));
|
|
|
|
return QVariant(int(MScore::OrnamentStyle::DEFAULT));
|
|
}
|
|
break; // break is really not necessary because of the default return
|
|
case P_TYPE::DIRECTION:
|
|
{
|
|
QString value(e.readElementText());
|
|
if (value == "up")
|
|
return QVariant(int(MScore::Direction::UP));
|
|
else if (value == "down")
|
|
return QVariant(int(MScore::Direction::DOWN));
|
|
else if (value == "auto")
|
|
return QVariant(int(MScore::Direction::AUTO));
|
|
}
|
|
break;
|
|
case P_TYPE::DIRECTION_H:
|
|
{
|
|
QString value(e.readElementText());
|
|
if (value == "left" || value == "1")
|
|
return QVariant(int(MScore::DirectionH::LEFT));
|
|
else if (value == "right" || value == "2")
|
|
return QVariant(int(MScore::DirectionH::RIGHT));
|
|
else if (value == "auto")
|
|
return QVariant(int(MScore::DirectionH::AUTO));
|
|
}
|
|
break;
|
|
case P_TYPE::LAYOUT_BREAK: {
|
|
QString value(e.readElementText());
|
|
if (value == "line")
|
|
return QVariant(int(LayoutBreak::Type::LINE));
|
|
if (value == "page")
|
|
return QVariant(int(LayoutBreak::Type::PAGE));
|
|
if (value == "section")
|
|
return QVariant(int(LayoutBreak::Type::SECTION));
|
|
qDebug("getProperty: invalid P_TYPE::LAYOUT_BREAK: <%s>", qPrintable(value));
|
|
}
|
|
break;
|
|
case P_TYPE::VALUE_TYPE: {
|
|
QString value(e.readElementText());
|
|
if (value == "offset")
|
|
return QVariant(int(Note::ValueType::OFFSET_VAL));
|
|
else if (value == "user")
|
|
return QVariant(int(Note::ValueType::USER_VAL));
|
|
}
|
|
break;
|
|
case P_TYPE::PLACEMENT: {
|
|
QString value(e.readElementText());
|
|
if (value == "above")
|
|
return QVariant(int(Element::Placement::ABOVE));
|
|
else if (value == "below")
|
|
return QVariant(int(Element::Placement::BELOW));
|
|
}
|
|
break;
|
|
case P_TYPE::BEAM_MODE: // TODO
|
|
return QVariant(int(0));
|
|
|
|
case P_TYPE::GROUPS:
|
|
{
|
|
Groups g;
|
|
g.read(e);
|
|
return QVariant::fromValue(g);
|
|
}
|
|
case P_TYPE::POINT_MM: // not supported
|
|
case P_TYPE::TDURATION:
|
|
case P_TYPE::SIZE_MM:
|
|
case P_TYPE::SYMID:
|
|
case P_TYPE::TEXT_STYLE:
|
|
case P_TYPE::INT_LIST:
|
|
return QVariant();
|
|
}
|
|
return QVariant();
|
|
}
|
|
|
|
}
|
|
|