filtereditdialog.cpp 11.8 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/*
  This file is part of KOrganizer.

  Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
  Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
  Copyright (C) 2005 Thomas Zander <zander@kde.org>

  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 2 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, write to the Free Software Foundation, Inc.,
  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

  As a special exception, permission is given to link this program
  with any edition of Qt, and distribute the resulting executable,
  without including the source code for Qt in the source distribution.
*/

#include "filtereditdialog.h"
Laurent Montel's avatar
Laurent Montel committed
28
#include "prefs/koprefs.h"
29

Laurent Montel's avatar
Laurent Montel committed
30
#include <CalendarSupport/CategoryConfig>
Laurent Montel's avatar
Laurent Montel committed
31
#include <Libkdepim/TagWidgets>
Laurent Montel's avatar
Laurent Montel committed
32
#include <PimCommon/PimUtil>
33

34
#include <KCalCore/CalFilter>
35
36

#include <KMessageBox>
Laurent Montel's avatar
Laurent Montel committed
37
#include "korganizer_debug.h"
Laurent Montel's avatar
Laurent Montel committed
38
39
40
41
#include <KConfigGroup>
#include <QDialogButtonBox>
#include <QPushButton>
#include <QVBoxLayout>
42
#include <kcolorscheme.h>
43
#include <KHelpClient>
44

Laurent Montel's avatar
Laurent Montel committed
45
46
FilterEditDialog::FilterEditDialog(QList<KCalCore::CalFilter *> *filters, QWidget *parent)
    : QDialog(parent)
47
{
Laurent Montel's avatar
Laurent Montel committed
48
    setWindowTitle(i18nc("@title::window", "Edit Calendar Filters"));
Laurent Montel's avatar
Laurent Montel committed
49
    QVBoxLayout *mainLayout = new QVBoxLayout(this);
Laurent Montel's avatar
Laurent Montel committed
50
51

    QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Apply, this);
Laurent Montel's avatar
Laurent Montel committed
52
53
54
55
56
57
58
59
60
61
62
63
64
65
    mOkButton = buttonBox->button(QDialogButtonBox::Ok);
    mApplyButton = buttonBox->button(QDialogButtonBox::Apply);
    mOkButton->setDefault(true);
    mOkButton->setShortcut(Qt::CTRL | Qt::Key_Return);
    connect(buttonBox, &QDialogButtonBox::accepted, this, &FilterEditDialog::slotOk);
    connect(buttonBox, &QDialogButtonBox::rejected, this, &FilterEditDialog::reject);
    mainLayout->addWidget(mFilterEdit = new FilterEdit(filters, this));
    mainLayout->addWidget(buttonBox);

    connect(mFilterEdit, &FilterEdit::dataConsistent, this, &FilterEditDialog::setDialogConsistent);
    updateFilterList();
    connect(mFilterEdit, &FilterEdit::editCategories, this, &FilterEditDialog::editCategories);
    connect(mFilterEdit, &FilterEdit::filterChanged, this, &FilterEditDialog::filterChanged);
    connect(buttonBox->button(QDialogButtonBox::Apply), &QPushButton::clicked, this, &FilterEditDialog::slotApply);
66
67
68
69
}

FilterEditDialog::~FilterEditDialog()
{
Laurent Montel's avatar
Laurent Montel committed
70
    delete mFilterEdit;
Laurent Montel's avatar
Laurent Montel committed
71
    mFilterEdit = Q_NULLPTR;
72
73
74
75
}

void FilterEditDialog::updateFilterList()
{
Laurent Montel's avatar
Laurent Montel committed
76
    mFilterEdit->updateFilterList();
77
78
79
80
}

void FilterEditDialog::slotApply()
{
Laurent Montel's avatar
Laurent Montel committed
81
    mFilterEdit->saveChanges();
82
83
84
85
}

void FilterEditDialog::slotOk()
{
Laurent Montel's avatar
Laurent Montel committed
86
87
    slotApply();
    accept();
88
89
}

Laurent Montel's avatar
Laurent Montel committed
90
void FilterEditDialog::setDialogConsistent(bool consistent)
91
{
Laurent Montel's avatar
Laurent Montel committed
92
    mOkButton->setEnabled(consistent);
Laurent Montel's avatar
Laurent Montel committed
93
    mApplyButton->setEnabled(consistent);
94
95
}

Laurent Montel's avatar
Laurent Montel committed
96
FilterEdit::FilterEdit(QList<KCalCore::CalFilter *> *filters, QWidget *parent)
Laurent Montel's avatar
Laurent Montel committed
97
    : QWidget(parent), mCurrent(Q_NULLPTR), mCategorySelectDialog(Q_NULLPTR)
98
{
Laurent Montel's avatar
Laurent Montel committed
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
    setupUi(this);
    searchline->setListWidget(mRulesList);
    mDetailsFrame->setEnabled(false);
    mFilters = filters;
    mNewButton->setWhatsThis(
        i18nc("@info:whatsthis",
              "Press this button to define a new filter."));
    mDeleteButton->setWhatsThis(
        i18nc("@info:whatsthis",
              "Press this button to remove the currently active filter."));

    connect(mRulesList, SIGNAL(itemSelectionChanged()),
            this, SLOT(filterSelected()));

    connect(mNewButton, &QPushButton::clicked, this, &FilterEdit::bNewPressed);
    connect(mDeleteButton, &QPushButton::clicked, this, &FilterEdit::bDeletePressed);
    connect(mNameLineEdit, &QLineEdit::textChanged, this, &FilterEdit::updateSelectedName);
    connect(mCatEditButton, &QPushButton::clicked, this, &FilterEdit::editCategorySelection);
    connect(mCompletedCheck, &QCheckBox::toggled, mCompletedTimeSpanLabel, &QLabel::setEnabled);
    connect(mCompletedCheck, &QCheckBox::toggled, mCompletedTimeSpan, &QSpinBox::setEnabled);
119
120
121
122
123
124
125
126
127

}

FilterEdit::~FilterEdit()
{
}

void FilterEdit::updateFilterList()
{
Laurent Montel's avatar
Laurent Montel committed
128
129
130
    mRulesList->clear();
    if (!mFilters || mFilters->empty()) {
        mDetailsFrame->setEnabled(false);
Laurent Montel's avatar
Laurent Montel committed
131
        Q_EMIT(dataConsistent(false));
Laurent Montel's avatar
Laurent Montel committed
132
133
    } else {
        QList<KCalCore::CalFilter *>::iterator i;
Laurent Montel's avatar
Laurent Montel committed
134
135
        QList<KCalCore::CalFilter *>::iterator end(mFilters->end());
        for (i = mFilters->begin(); i != end; ++i) {
Laurent Montel's avatar
Laurent Montel committed
136
137
138
139
140
141
142
143
144
145
            if (*i) {
                mRulesList->addItem((*i)->name());
            }
        }
        if (mRulesList->currentRow() != -1) {
            KCalCore::CalFilter *f = mFilters->at(mRulesList->currentRow());
            if (f) {
                filterSelected(f);
            }
        }
Laurent Montel's avatar
Laurent Montel committed
146
        Q_EMIT(dataConsistent(true));
Laurent Montel's avatar
Laurent Montel committed
147
    }
Laurent Montel's avatar
Laurent Montel committed
148
    if (mFilters && !mFilters->isEmpty() && !mCurrent) {
Laurent Montel's avatar
Laurent Montel committed
149
150
151
152
        filterSelected(mFilters->at(0));
    }
    if (mFilters) {
        mDeleteButton->setEnabled(!mFilters->isEmpty());
153
154
155
156
157
    }
}

void FilterEdit::saveChanges()
{
Laurent Montel's avatar
Laurent Montel committed
158
159
160
161
162
163
164
165
    if (!mCurrent) {
        return;
    }

    mCurrent->setName(mNameLineEdit->text());
    int criteria = 0;
    if (mCompletedCheck->isChecked()) {
        criteria |= KCalCore::CalFilter::HideCompletedTodos;
166
    }
Laurent Montel's avatar
Laurent Montel committed
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
    if (mRecurringCheck->isChecked()) {
        criteria |= KCalCore::CalFilter::HideRecurring;
    }
    if (mCatShowCheck->isChecked()) {
        criteria |= KCalCore::CalFilter::ShowCategories;
    }
    if (mHideInactiveTodosCheck->isChecked()) {
        criteria |= KCalCore::CalFilter::HideInactiveTodos;
    }
    if (mHideTodosNotAssignedToMeCheck->isChecked()) {
        criteria |= KCalCore::CalFilter::HideNoMatchingAttendeeTodos;
    }
    mCurrent->setCriteria(criteria);
    mCurrent->setCompletedTimeSpan(mCompletedTimeSpan->value());

    QStringList categoryList;
Laurent Montel's avatar
Minor    
Laurent Montel committed
183
184
    const int numberOfCat(mCatList->count());
    for (int i = 0; i < numberOfCat; ++i) {
Laurent Montel's avatar
Laurent Montel committed
185
186
187
188
189
190
        QListWidgetItem *item = mCatList->item(i);
        if (item) {
            categoryList.append(item->text());
        }
    }
    mCurrent->setCategoryList(categoryList);
Laurent Montel's avatar
Laurent Montel committed
191
    Q_EMIT filterChanged();
192
193
194
195
}

void FilterEdit::filterSelected()
{
Laurent Montel's avatar
Laurent Montel committed
196
197
198
199
    if (mRulesList->currentRow() < mFilters->count()) {
        mDetailsFrame->setEnabled(true);
        filterSelected(mFilters->at(mRulesList->currentRow()));
    }
200
201
}

Laurent Montel's avatar
Laurent Montel committed
202
void FilterEdit::filterSelected(KCalCore::CalFilter *filter)
203
{
Laurent Montel's avatar
Laurent Montel committed
204
205
206
    if (!filter || filter == mCurrent) {
        return;
    }
Laurent Montel's avatar
Laurent Montel committed
207
    qCDebug(KORGANIZER_LOG) << "Selected filter" << filter->name();
Laurent Montel's avatar
Laurent Montel committed
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
    saveChanges();

    mCurrent = filter;
    mNameLineEdit->blockSignals(true);
    mNameLineEdit->setText(mCurrent->name());
    mNameLineEdit->blockSignals(false);
    mDetailsFrame->setEnabled(true);
    mCompletedCheck->setChecked(mCurrent->criteria() & KCalCore::CalFilter::HideCompletedTodos);
    mCompletedTimeSpan->setValue(mCurrent->completedTimeSpan());
    mRecurringCheck->setChecked(mCurrent->criteria() & KCalCore::CalFilter::HideRecurring);
    mHideInactiveTodosCheck->setChecked(
        mCurrent->criteria() & KCalCore::CalFilter::HideInactiveTodos);
    mHideTodosNotAssignedToMeCheck->setChecked(
        mCurrent->criteria() & KCalCore::CalFilter::HideNoMatchingAttendeeTodos);

    if (mCurrent->criteria() & KCalCore::CalFilter::ShowCategories) {
        mCatShowCheck->setChecked(true);
    } else {
        mCatHideCheck->setChecked(true);
    }
    mCatList->clear();
    mCatList->addItems(mCurrent->categoryList());
230
231
232
233
}

void FilterEdit::bNewPressed()
{
Laurent Montel's avatar
Laurent Montel committed
234
235
    mDetailsFrame->setEnabled(true);
    saveChanges();
Laurent Montel's avatar
Laurent Montel committed
236
    QStringList filterNames;
237
238
239
    const int numRules = mRulesList->count();
    filterNames.reserve(numRules);
    for (int i = 0; i < numRules; ++i) {
Laurent Montel's avatar
Laurent Montel committed
240
241
242
243
244
245
246
247
248
249
        filterNames << mRulesList->item(i)->text();
    }
    QString newFilterName;
    for (int i = 1;; ++i) {
        newFilterName = i18nc("@label default filter name",
                              "New Filter %1", i);
        if (!filterNames.contains(newFilterName)) {
            break;
        }
    }
250

Laurent Montel's avatar
Laurent Montel committed
251
    KCalCore::CalFilter *newFilter =
252
        new KCalCore::CalFilter(newFilterName);
Laurent Montel's avatar
Laurent Montel committed
253
254
255
    mFilters->append(newFilter);
    updateFilterList();
    mRulesList->setCurrentRow(mRulesList->count() - 1);
Laurent Montel's avatar
Laurent Montel committed
256
    Q_EMIT filterChanged();
257
258
259
260
}

void FilterEdit::bDeletePressed()
{
Laurent Montel's avatar
Laurent Montel committed
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
    if (!mRulesList->currentItem()) {   // nothing selected
        return;
    }
    if (mFilters->isEmpty()) {   // We need at least a default filter object.
        return;
    }

    if (KMessageBox::warningContinueCancel(
                this,
                i18nc("@info",
                      "Do you really want to permanently remove the filter \"%1\"?", mCurrent->name()),
                i18nc("@title:window", "Delete Filter?"),
                KStandardGuiItem::del()) == KMessageBox::Cancel) {
        return;
    }

    int selected = mRulesList->currentRow();
    KCalCore::CalFilter *filter = mFilters->at(selected);
    mFilters->removeAll(filter);
    delete filter;
Laurent Montel's avatar
Laurent Montel committed
281
    mCurrent = Q_NULLPTR;
Laurent Montel's avatar
Laurent Montel committed
282
283
    updateFilterList();
    mRulesList->setCurrentRow(qMin(mRulesList->count() - 1, selected));
Laurent Montel's avatar
Laurent Montel committed
284
    Q_EMIT filterChanged();
285
286
}

Laurent Montel's avatar
Laurent Montel committed
287
void FilterEdit::updateSelectedName(const QString &newText)
288
{
Laurent Montel's avatar
Laurent Montel committed
289
290
291
292
    mRulesList->blockSignals(true);
    QListWidgetItem *item = mRulesList->currentItem();
    if (item) {
        item->setText(newText);
293
    }
Laurent Montel's avatar
Laurent Montel committed
294
295
    mRulesList->blockSignals(false);
    if (correctName(newText)) {
Laurent Montel's avatar
Laurent Montel committed
296
        Q_EMIT dataConsistent(false);
Laurent Montel's avatar
Laurent Montel committed
297
298
299
        return;
    }
    bool allOk = true;
300

Laurent Montel's avatar
Laurent Montel committed
301
302
303
304
305
306
    foreach (KCalCore::CalFilter *i, *mFilters) {
        if (i && i->name().isEmpty()) {
            allOk = false;
        }
    }

Laurent Montel's avatar
Laurent Montel committed
307
    Q_EMIT dataConsistent(allOk);
308
309
}

310
311
312
313
314
315
bool FilterEdit::correctName(const QString &newText)
{
#ifndef QT_NO_STYLE_STYLESHEET
    QString styleSheet;
    if (mNegativeBackground.isEmpty()) {
        KStatefulBrush bgBrush = KStatefulBrush(KColorScheme::View, KColorScheme::NegativeBackground);
Laurent Montel's avatar
Laurent Montel committed
316
        mNegativeBackground = QStringLiteral("QLineEdit{ background-color:%1 }").arg(bgBrush.brush(mNameLineEdit).color().name());
317
318
319
    }
    bool negative = false;
    if (!newText.isEmpty()) {
Laurent Montel's avatar
Laurent Montel committed
320
        for (int i = 0; i < mRulesList->count(); ++i) {
321
            QListWidgetItem *item = mRulesList->item(i);
Laurent Montel's avatar
Laurent Montel committed
322
            if (item && (mRulesList->currentItem() != item)) {
323
324
325
326
327
328
329
330
331
                if (newText == item->text()) {
                    negative = true;
                    break;
                }
            }
        }
    } else {
        negative = true;
    }
Laurent Montel's avatar
Laurent Montel committed
332
    if (negative) {
333
        styleSheet = mNegativeBackground;
Laurent Montel's avatar
Laurent Montel committed
334
    }
335
336
337
338
339
    mNameLineEdit->setStyleSheet(styleSheet);
#endif
    return negative;
}

340
341
void FilterEdit::editCategorySelection()
{
Laurent Montel's avatar
Laurent Montel committed
342
343
344
345
346
347
348
349
    if (!mCurrent) {
        return;
    }

    if (!mCategorySelectDialog) {
        mCategorySelectDialog = new KPIM::TagSelectionDialog(this);
        mCategorySelectDialog->buttons()->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Help);
        connect(mCategorySelectDialog, &KPIM::TagSelectionDialog::accepted, this, &FilterEdit::updateCategorySelection);
350
        connect(mCategorySelectDialog->buttons()->button(QDialogButtonBox::Help), &QPushButton::clicked, this, &FilterEdit::slotHelp);
Laurent Montel's avatar
Laurent Montel committed
351
352
353
354
    }
    mCategorySelectDialog->setSelection(mCurrent->categoryList());

    mCategorySelectDialog->show();
355
356
}

357
358
void FilterEdit::slotHelp()
{
Laurent Montel's avatar
Laurent Montel committed
359
    PimCommon::Util::invokeHelp(QStringLiteral("korganizer/filters-view.html"));
360
361
}

362
void FilterEdit::updateCategorySelection()
363
{
Laurent Montel's avatar
Laurent Montel committed
364
365
366
367
    const QStringList &categories = mCategorySelectDialog->selection();
    mCatList->clear();
    mCatList->addItems(categories);
    mCurrent->setCategoryList(categories);
368
}