8#include "TourItemDelegate.h" 
   10#include <QAbstractTextDocumentLayout> 
   11#include <QApplication> 
   15#include <QStyleOptionButton> 
   17#include "EditPlacemarkDialog.h" 
   18#include "FlyToEditWidget.h" 
   19#include "GeoDataChange.h" 
   20#include "GeoDataCreate.h" 
   21#include "GeoDataDelete.h" 
   22#include "GeoDataPlacemark.h" 
   23#include "GeoDataPlaylist.h" 
   24#include "GeoDataUpdate.h" 
   25#include "MarblePlacemarkModel.h" 
   27#include "RemoveItemEditWidget.h" 
   28#include "SoundCueEditWidget.h" 
   29#include "TourControlEditWidget.h" 
   30#include "TourWidget.h" 
   31#include "WaitEditWidget.h" 
   32#include "geodata/data/GeoDataAnimatedUpdate.h" 
   33#include "geodata/data/GeoDataContainer.h" 
   34#include "geodata/data/GeoDataCoordinates.h" 
   35#include "geodata/data/GeoDataFlyTo.h" 
   36#include "geodata/data/GeoDataObject.h" 
   37#include "geodata/data/GeoDataSoundCue.h" 
   38#include "geodata/data/GeoDataTourControl.h" 
   39#include "geodata/data/GeoDataWait.h" 
   44TourItemDelegate::TourItemDelegate(QListView *view, 
MarbleWidget *widget, TourWidget *tour)
 
   65    if (m_listView->currentIndex() == index && m_tourWidget->isPlaying()) {
 
   71    QRect const labelRect = position(Label, option);
 
   73    label.setDefaultFont(option.font);
 
   76    button.state = option.state;
 
   77    button.palette = option.palette;
 
   79    button.iconSize = 
QSize(16, 16);
 
   80    button.state &= 
~QStyle::State_HasFocus;
 
   82        button.state &= 
~QStyle::State_Enabled;
 
   85    QRect const iconRect = position(GeoDataElementIcon, option);
 
   87    const GeoDataObject *
object = qvariant_cast<GeoDataObject *>(index.
data(MarblePlacemarkModel::ObjectPointerRole));
 
   88    if (!m_editingIndices.contains(index)) {
 
   89        if (
const auto tourControl = geodata_cast<GeoDataTourControl>(
object)) {
 
   90            GeoDataTourControl::PlayMode 
const playMode = tourControl->playMode();
 
   92            if (playMode == GeoDataTourControl::Play) {
 
   93                label.setHtml(tr(
"Play the tour"));
 
   94            } 
else if (playMode == GeoDataTourControl::Pause) {
 
   95                label.setHtml(tr(
"Pause the tour"));
 
  100            label.documentLayout()->draw(painter, paintContext);
 
  102            button.icon = 
QIcon(QStringLiteral(
":/marble/document-edit.png"));
 
  104            QRect const buttonRect = position(EditButton, option);
 
  105            button.rect = buttonRect;
 
  107            QIcon const icon = 
QIcon(QStringLiteral(
":/marble/media-playback-pause.png"));
 
  110        } 
else if (geodata_cast<GeoDataFlyTo>(
object)) {
 
  112            label.setHtml(flyToCoords.toString());
 
  113            button.icon = 
QIcon(QStringLiteral(
":/marble/document-edit.png"));
 
  118            label.documentLayout()->draw(painter, paintContext);
 
  121            QRect const buttonRect = position(EditButton, option);
 
  122            button.rect = buttonRect;
 
  124            QIcon const icon = 
QIcon(QStringLiteral(
":/marble/flag.png"));
 
  126        } 
else if (
const auto wait = geodata_cast<GeoDataWait>(
object)) {
 
  132            label.documentLayout()->draw(painter, paintContext);
 
  135            button.icon = 
QIcon(QStringLiteral(
":/marble/document-edit.png"));
 
  137            QRect const buttonRect = position(EditButton, option);
 
  138            button.rect = buttonRect;
 
  140            QIcon const icon = 
QIcon(QStringLiteral(
":/marble/player-time.png"));
 
  142        } 
else if (
const auto soundCue = geodata_cast<GeoDataSoundCue>(
object)) {
 
  148            label.documentLayout()->draw(painter, paintContext);
 
  153            button.icon = 
QIcon(QStringLiteral(
":/marble/document-edit.png"));
 
  154            QRect const buttonRect = position(EditButton, option);
 
  155            button.rect = buttonRect;
 
  157            playButton.icon = 
QIcon(QStringLiteral(
":/marble/playback-play.png"));
 
  158            QRect const playButtonRect = position(ActionButton, option);
 
  159            playButton.rect = playButtonRect;
 
  162            QIcon const icon = 
QIcon(QStringLiteral(
":/marble/audio-x-generic.png"));
 
  164        } 
else if (
const auto animUpdate = geodata_cast<GeoDataAnimatedUpdate>(
object)) {
 
  165            const GeoDataUpdate *
update = animUpdate->update();
 
  168            if (update && 
update->create() && 
update->create()->size() != 0 && (
dynamic_cast<const GeoDataContainer *
>(&
update->create()->first()))) {
 
  169                const auto container = 
static_cast<const GeoDataContainer *
>(
update->create()->child(0));
 
  170                if (container->size() > 0) {
 
  171                    label.setHtml(tr(
"Create item %1").arg(container->first().id()));
 
  173                    iconString = QStringLiteral(
":/icons/add-placemark.png");
 
  175            } 
else if (update && 
update->getDelete() && 
update->getDelete()->size() != 0) {
 
  176                label.setHtml(tr(
"Remove item %1").arg(
update->getDelete()->first().targetId()));
 
  178                iconString = QStringLiteral(
":/icons/remove.png");
 
  179            } 
else if (update && 
update->change() && 
update->change()->size() != 0) {
 
  180                label.setHtml(tr(
"Change item %1").arg(
update->change()->first().targetId()));
 
  182                iconString = QStringLiteral(
":/marble/document-edit.png");
 
  185                label.setHtml(tr(
"Update items"));
 
  192            label.documentLayout()->draw(painter, paintContext);
 
  195            button.icon = 
QIcon(QStringLiteral(
":/marble/document-edit.png"));
 
  196            QRect const buttonRect = position(EditButton, option);
 
  197            button.rect = buttonRect;
 
  209    QPoint const topCol1 = option.rect.topLeft() + 
QPoint(10, 10);
 
  217    case GeoDataElementIcon:
 
  218        return QRect(topCol1, iconsSize);
 
  220        return QRect(topCol2, labelSize);
 
  222        return QRect(topCol3, iconsSize);
 
  224        return QRect(topCol4, iconsSize);
 
  229QStringList TourItemDelegate::findIds(
const GeoDataPlaylist &playlist, 
bool onlyFeatures)
 
  232    for (
int i = 0; i < playlist.size(); ++i) {
 
  233        const GeoDataTourPrimitive *primitive = playlist.primitive(i);
 
  234        if (!primitive->id().isEmpty() && !onlyFeatures) {
 
  235            result << primitive->id();
 
  237        if (
const auto animatedUpdate = geodata_cast<GeoDataAnimatedUpdate>(primitive)) {
 
  238            if (animatedUpdate->update() != 
nullptr) {
 
  239                const GeoDataUpdate *
update = animatedUpdate->update();
 
  240                if (!
update->id().isEmpty() && !onlyFeatures) {
 
  243                if (
update->create() != 
nullptr) {
 
  244                    if (!
update->create()->id().isEmpty() && !onlyFeatures) {
 
  245                        result << 
update->create()->id();
 
  247                    for (
int j = 0; j < 
update->create()->size(); ++j) {
 
  248                        if (!
update->create()->at(j).id().isEmpty()) {
 
  249                            result << 
update->create()->at(j).id();
 
  253                if (
update->change() != 
nullptr) {
 
  254                    if (!
update->change()->id().isEmpty() && !onlyFeatures) {
 
  255                        result << 
update->change()->id();
 
  257                    for (
int j = 0; j < 
update->change()->size(); ++j) {
 
  258                        if (!
update->change()->at(j).id().isEmpty()) {
 
  259                            result << 
update->change()->at(j).id();
 
  263                if (
update->getDelete() != 
nullptr) {
 
  264                    if (!
update->getDelete()->id().isEmpty() && !onlyFeatures) {
 
  265                        result << 
update->getDelete()->id();
 
  267                    for (
int j = 0; j < 
update->getDelete()->size(); ++j) {
 
  268                        if (!
update->getDelete()->at(j).id().isEmpty()) {
 
  269                            result << 
update->getDelete()->at(j).id();
 
  279GeoDataPlaylist *TourItemDelegate::playlist()
 const 
  281    QModelIndex const rootIndex = m_listView->rootIndex();
 
  283        auto rootObject = 
static_cast<GeoDataObject *
>(rootIndex.
internalPointer());
 
  284        if (
auto playlist = geodata_cast<GeoDataPlaylist>(rootObject)) {
 
  301    auto object = qvariant_cast<GeoDataObject *>(index.
data(MarblePlacemarkModel::ObjectPointerRole));
 
  302    if (geodata_cast<GeoDataFlyTo>(
object)) {
 
  303        auto widget = 
new FlyToEditWidget(index, m_widget, parent);
 
  304        widget->setFirstFlyTo(m_firstFlyTo);
 
  306        connect(
this, SIGNAL(editableChanged(
bool)), widget, SLOT(setEditable(
bool)));
 
  310    } 
else if (geodata_cast<GeoDataTourControl>(
object)) {
 
  311        auto widget = 
new TourControlEditWidget(index, parent);
 
  313        connect(
this, SIGNAL(editableChanged(
bool)), widget, SLOT(setEditable(
bool)));
 
  316    } 
else if (geodata_cast<GeoDataWait>(
object)) {
 
  317        auto widget = 
new WaitEditWidget(index, parent);
 
  319        connect(
this, SIGNAL(editableChanged(
bool)), widget, SLOT(setEditable(
bool)));
 
  322    } 
else if (geodata_cast<GeoDataSoundCue>(
object)) {
 
  323        auto widget = 
new SoundCueEditWidget(index, parent);
 
  325        connect(
this, SIGNAL(editableChanged(
bool)), widget, SLOT(setEditable(
bool)));
 
  328    } 
else if (geodata_cast<GeoDataAnimatedUpdate>(
object)) {
 
  329        auto widget = 
new RemoveItemEditWidget(index, parent);
 
  330        GeoDataPlaylist *playlistObject = playlist();
 
  331        if (playlistObject != 
nullptr) {
 
  332            widget->setFeatureIds(findIds(*playlistObject));
 
  334        widget->setDefaultFeatureId(m_defaultFeatureId);
 
  336        connect(
this, SIGNAL(editableChanged(
bool)), widget, SLOT(setEditable(
bool)));
 
  344bool TourItemDelegate::editable()
 const 
  349void TourItemDelegate::setEditable(
bool editable)
 
  351    if (m_editable != editable) {
 
  352        m_editable = editable;
 
  353        Q_EMIT editableChanged(m_editable);
 
  362bool TourItemDelegate::editAnimatedUpdate(GeoDataAnimatedUpdate *animatedUpdate, 
bool create)
 
  364    if (animatedUpdate->update() == 
nullptr) {
 
  367    GeoDataFeature *feature = 
nullptr;
 
  368    if (create && !(animatedUpdate->update()->create() == 
nullptr || animatedUpdate->update()->create()->size() == 0)) {
 
  369        auto container = 
dynamic_cast<GeoDataContainer *
>(animatedUpdate->update()->
create()->child(0));
 
  370        if (container != 
nullptr && container->size()) {
 
  371            feature = container->child(0);
 
  373    } 
else if (!create && !(animatedUpdate->update()->change() == 
nullptr || animatedUpdate->update()->change()->size() == 0)) {
 
  374        auto container = 
dynamic_cast<GeoDataContainer *
>(animatedUpdate->update()->change()->child(0));
 
  375        if (container != 
nullptr && container->size()) {
 
  376            feature = container->child(0);
 
  379    if (feature == 
nullptr) {
 
  385    auto placemark = 
static_cast<GeoDataPlacemark *
>(feature);
 
  388        if (placemark->targetId().isEmpty() && !defaultFeatureId().isEmpty()) {
 
  389            GeoDataFeature *feature = findFeature(defaultFeatureId());
 
  390            if (GeoDataPlacemark *targetPlacemark = (feature != 
nullptr ? geodata_cast<GeoDataPlacemark>(feature) : 
nullptr)) {
 
  391                animatedUpdate->update()->change()->placemarkList().remove(0);
 
  393                placemark = 
new GeoDataPlacemark(*targetPlacemark);
 
  394                animatedUpdate->update()->change()->placemarkList().insert(0, placemark);
 
  395                placemark->setTargetId(defaultFeatureId());
 
  403        dialog->setWindowTitle(
QObject::tr(
"Add Placemark to Tour"));
 
  405        dialog->setWindowTitle(
QObject::tr(
"Change Placemark in Tour"));
 
  406        dialog->setTargetIdFieldVisible(
true);
 
  407        dialog->setIdFieldVisible(
false);
 
  409    GeoDataPlaylist *playlistObject = playlist();
 
  410    if (playlistObject != 
nullptr) {
 
  411        ids.
append(findIds(*playlistObject, 
true));
 
  415        dialog->setIdFilter(ids);
 
  417        dialog->setTargetIds(ids);
 
  419    bool status = dialog->exec();
 
  426QString TourItemDelegate::defaultFeatureId()
 const 
  428    return m_defaultFeatureId;
 
  431GeoDataFeature *TourItemDelegate::findFeature(
const QString &
id)
 const 
  433    GeoDataPlaylist *playlistObject = playlist();
 
  434    if (playlistObject == 
nullptr) {
 
  437    GeoDataFeature *result = 
nullptr;
 
  438    for (
int i = 0; i < playlistObject->size(); ++i) {
 
  439        GeoDataTourPrimitive *primitive = playlistObject->primitive(i);
 
  440        if (
auto animatedUpdate = geodata_cast<GeoDataAnimatedUpdate>(primitive)) {
 
  441            if (animatedUpdate->update() != 
nullptr) {
 
  442                GeoDataUpdate *
update = animatedUpdate->update();
 
  443                if (
update->create() != 
nullptr) {
 
  444                    for (
int j = 0; j < 
update->create()->featureList().size(); ++j) {
 
  445                        if (
update->create()->at(j).id() == 
id) {
 
  446                            result = 
update->create()->featureList().at(j);
 
  450                if (
update->change() != 
nullptr) {
 
  451                    for (
int j = 0; j < 
update->change()->featureList().size(); ++j) {
 
  452                        if (
update->change()->at(j).id() == 
id) {
 
  453                            result = 
update->change()->featureList().at(j);
 
  457                if (
update->getDelete() != 
nullptr) {
 
  458                    for (
int j = 0; j < 
update->getDelete()->featureList().size(); ++j) {
 
  459                        if (
update->getDelete()->at(j).id() == 
id) {
 
  460                            result = 
update->getDelete()->featureList().at(j);
 
  472    m_firstFlyTo = index;
 
  473    Q_EMIT firstFlyToChanged(m_firstFlyTo);
 
  476void TourItemDelegate::setDefaultFeatureId(
const QString &
id)
 
  478    m_defaultFeatureId = id;
 
  480    Q_EMIT featureIdsChanged(ids);
 
  481    Q_EMIT defaultFeatureIdChanged(
id);
 
  489        QRect editRect = position(EditButton, option);
 
  490        if (editRect.
contains(mouseEvent->pos())) {
 
  491            if (m_editingIndices.contains(index)) {
 
  492                m_editingIndices.removeOne(index);
 
  493                Q_EMIT editingChanged(index);
 
  496                auto object = qvariant_cast<GeoDataObject *>(index.
data(MarblePlacemarkModel::ObjectPointerRole));
 
  497                if (
auto animatedUpdate = geodata_cast<GeoDataAnimatedUpdate>(
object)) {
 
  498                    if (animatedUpdate->update() && animatedUpdate->update()->create()) {
 
  499                        if (editAnimatedUpdate(animatedUpdate)) {
 
  500                            setDefaultFeatureId(m_defaultFeatureId);
 
  502                    } 
else if (animatedUpdate->update() && animatedUpdate->update()->change()) {
 
  503                        editAnimatedUpdate(animatedUpdate, 
false);
 
  504                    } 
else if (animatedUpdate->update() && animatedUpdate->update()->getDelete()) {
 
  505                        m_editingIndices.append(index);
 
  506                        m_listView->openPersistentEditor(index);
 
  509                    m_editingIndices.append(index);
 
  510                    m_listView->openPersistentEditor(index);
 
  513            Q_EMIT editingChanged(index);
 
  520void TourItemDelegate::closeEditor(
const QModelIndex &index)
 
  522    Q_EMIT edited(index);
 
  523    m_listView->closePersistentEditor(index);
 
  524    m_editingIndices.removeOne(index);
 
  529#include "moc_TourItemDelegate.cpp" 
A 3d point representation.
 
Q_SCRIPTABLE CaptureState status()
 
AKONADI_CALENDAR_EXPORT KCalendarCore::Event::Ptr event(const Akonadi::Item &item)
 
void update(Part *part, const QByteArray &data, qint64 dataSize)
 
QAction * create(StandardAction id, const Receiver *recvr, Func slot, QObject *parent, std::optional< Qt::ConnectionType > connectionType=std::nullopt)
 
QString label(StandardShortcut id)
 
Binds a QML item to a specific geodetic location in screen coordinates.
 
QPixmap pixmap(QWindow *window, const QSize &size, Mode mode, State state) const const
 
void append(QList< T > &&value)
 
bool removeOne(const AT &t)
 
QVariant data(int role) const const
 
void * internalPointer() const const
 
bool isValid() const const
 
QString tr(const char *sourceText, const char *disambiguation, int n)
 
void drawPixmap(const QPoint &point, const QPixmap &pixmap)
 
void fillRect(const QRect &rectangle, QGradient::Preset preset)
 
void setClipRect(const QRect &rectangle, Qt::ClipOperation operation)
 
void translate(const QPoint &offset)
 
bool contains(const QPoint &point, bool proper) const const
 
QPoint topLeft() const const
 
QString number(double n, char format, int precision)
 
virtual void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const const=0
 
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const const override
 
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)