Reworked the repeat schedule wizard (#4850)

* Simplified design and concept
* Sticking closer to the original schedule
* Added option to keep gap days (front and back)
* Added option to use originally planned dates
* Removed options to insert rest days or spread same day activities
* Improved source range preselection
This commit is contained in:
Joachim Kohlhammer
2026-03-31 16:48:55 +02:00
committed by GitHub
parent e30ce69ef2
commit 30a9155b20
2 changed files with 827 additions and 292 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -26,6 +26,76 @@
#include <QWizardPage>
#include <QLabel>
#include <QTreeWidget>
#include <QCheckBox>
#include <QRadioButton>
#include <QStyledItemDelegate>
struct SourceRide {
RideItem *rideItem = nullptr;
QDate sourceDate;
QDate targetDate;
bool selected = false;
int conflictGroup = -1;
bool targetBlocked = false;
};
class TargetRangeBar : public QFrame
{
Q_OBJECT
Q_PROPERTY(QColor highlightColor READ highlightColor WRITE setHighlightColor)
public:
explicit TargetRangeBar(QString errorMsg, QWidget *parent = nullptr);
void setResult(const QDate &start, const QDate &end, int activityCount, int deletedCount);
void setFlashEnabled(bool enabled);
private:
enum class State {
Neutral,
Warning,
Error
};
QLabel *iconLabel;
QLabel *textLabel;
QColor baseColor;
QColor borderColor;
QColor hlColor;
State currentState;
const QString errorMsg;
bool flashEnabled = true;
void applyStateStyle(State state);
QString formatDuration(const QDate &start, const QDate &end) const;
QColor highlightColor() const;
void setHighlightColor(const QColor& color);
void flash();
};
class IndicatorDelegate : public QStyledItemDelegate
{
public:
enum Roles {
IndicatorTypeRole = Qt::UserRole + 1, // [IndicatorType] Whether this item has an indicator
IndicatorStateRole // [bool] Whether this items indicator is checked
};
enum IndicatorType {
NoIndicator = 0,
RadioIndicator = 1,
CheckIndicator = 2
};
explicit IndicatorDelegate(QObject *parent = nullptr);
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) override;
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
};
class RepeatScheduleWizard : public QWizard
@@ -42,12 +112,34 @@ class RepeatScheduleWizard : public QWizard
RepeatScheduleWizard(Context *context, const QDate &when, QWidget *parent = nullptr);
QList<SourceRide> sourceRides;
QDate getTargetRangeStart() const;
QDate getTargetRangeEnd() const;
int getPlannedInTargetRange() const;
const QList<RideItem*> &getDeletionList() const;
void updateTargetRange();
void updateTargetRange(QDate sourceStart, QDate sourceEnd, bool keepGap, bool preferOriginal);
signals:
void targetRangeChanged();
protected:
virtual void done(int result) override;
private:
Context *context;
QDate when;
QDate sourceRangeStart;
QDate sourceRangeEnd;
QDate targetRangeStart;
QDate targetRangeEnd;
int frontGap = 0;
QList<RideItem*> deletionList;
bool keepGap = false;
bool preferOriginal = false;
QDate getDate(RideItem const * const rideItem, bool preferOriginal) const;
};
@@ -59,9 +151,20 @@ class RepeatSchedulePageSetup : public QWizardPage
RepeatSchedulePageSetup(Context *context, const QDate &when, QWidget *parent = nullptr);
int nextId() const override;
void initializePage() override;
bool isComplete() const override;
private:
Context *context;
QDateEdit *startDate;
QDateEdit *endDate;
QCheckBox *keepGapCheck;
QRadioButton *originalRadio;
QRadioButton *currentRadio;
TargetRangeBar *targetRangeBar;
private slots:
void refresh();
};
@@ -76,12 +179,12 @@ class RepeatSchedulePageActivities : public QWizardPage
void initializePage() override;
bool isComplete() const override;
QList<RideItem*> getSelectedRideItems() const;
private:
Context *context;
QTreeWidget *activityTree;
TargetRangeBar *targetRangeBar;
int numSelected = 0;
QMetaObject::Connection dataChangedConnection;
};
@@ -90,28 +193,19 @@ class RepeatSchedulePageSummary : public QWizardPage
Q_OBJECT
public:
RepeatSchedulePageSummary(Context *context, const QDate &when, QWidget *parent = nullptr);
RepeatSchedulePageSummary(Context *context, QWidget *parent = nullptr);
int nextId() const override;
void initializePage() override;
bool isComplete() const override;
QList<RideItem*> getDeletionList() const;
QList<std::pair<RideItem*, QDate>> getScheduleList() const;
private:
Context *context;
QDate when;
bool failed = false;
QList<RideItem*> deletionList; // was: preexistingPlanned
QList<std::pair<RideItem*, QDate>> scheduleList; // was: targetMap
QLabel *failedLabel;
QLabel *scheduleLabel;
QTreeWidget *scheduleTree;
QLabel *deletionLabel;
QTreeWidget *deletionTree;
TargetRangeBar *targetRangeBar;
};
#endif // _GC_ManualActivityWizard_h
#endif