Skip to content

Commit a1cbe72

Browse files
committed
Implement before:<date_expr> and after:<date_expr> in the search bar.
1 parent 6f68a80 commit a1cbe72

File tree

2 files changed

+82
-26
lines changed

2 files changed

+82
-26
lines changed

src/selectmail.cpp

Lines changed: 69 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,9 @@ msgs_filter::init()
7272
m_include_trash = false;
7373
m_newer_than=0;
7474
m_has_progress_bar = false;
75-
m_date_clause=QString::null;
75+
m_date_clause = QString::null;
76+
m_date_before_clause = QString::null;
77+
m_date_after_clause = QString::null;
7678
m_max_results=get_config().get_number("max_msgs_per_selection");
7779
if (m_max_results==0)
7880
m_max_results=1000;
@@ -445,12 +447,19 @@ msgs_filter::build_query(sql_query& q)
445447

446448
/* The date from the search bar is ignored if a date clause already exists.
447449
It shouldn't normally happen that both are specified. */
448-
if (m_date_clause.isEmpty())
450+
if (m_date_clause.isEmpty()) {
449451
m_date_clause = m_fts.m_operators["date"];
452+
m_date_before_clause = m_fts.m_operators["before"];
453+
m_date_after_clause = m_fts.m_operators["after"];
454+
}
450455

451456
if (!m_date_clause.isEmpty())
452-
process_date_clause(q, m_date_clause);
453-
457+
process_date_clause(q, date_equal, m_date_clause);
458+
if (!m_date_before_clause.isEmpty())
459+
process_date_clause(q, date_before, m_date_before_clause);
460+
if (!m_date_after_clause.isEmpty())
461+
process_date_clause(q, date_after, m_date_after_clause);
462+
454463
// </date clause>
455464

456465
if (!m_body_substring.isEmpty()) {
@@ -566,31 +575,46 @@ msgs_filter::empty_list_query()
566575
}
567576

568577
/*
569-
Create SQL clauses from date_expr.
578+
Create SQL clauses from the given comparator (equal,before,after)
579+
to compare mail.msg_date with date_expr.
570580
Does not process m_date_min and m_date_max.
571-
May throw an exception with a QString
581+
For date_before and date_after, the boundary is included.
582+
May throw an exception with a QString.
572583
*/
573584
void
574-
msgs_filter::process_date_clause(sql_query& q, QString date_expr)
585+
msgs_filter::process_date_clause(sql_query& q, date_comparator comp, QString date_expr)
575586
{
576587
if (date_expr.isEmpty())
577588
return;
578589

579590
QDate qd;
580591

581592
if (date_expr == "today") {
582-
q.add_clause("msg_date>=date_trunc('day',now()) AND msg_date<date_trunc('day',now())+'1 day'::interval");
593+
if (comp == date_equal)
594+
q.add_clause("msg_date>=date_trunc('day',now()) AND msg_date<date_trunc('day',now())+'1 day'::interval");
595+
else if (comp == date_before) {
596+
q.add_clause("msg_date<current_date");
597+
}
598+
else if (comp == date_after) {
599+
q.add_clause("msg_date>=current_date");
600+
}
583601
}
584602
else if (date_expr == "yesterday") {
585-
q.add_clause("msg_date>=date_trunc('day',now())-'1 day'::interval"
586-
" AND msg_date<date_trunc('day',now())");
603+
if (comp == date_equal)
604+
q.add_clause("msg_date>=current_date-1 AND msg_date<current_date");
605+
else if (comp == date_before)
606+
q.add_clause("msg_date<current_date");
607+
else if (comp == date_after)
608+
q.add_clause("msg_date>=current_date-1");
587609
}
588610
else if (date_expr.at(0) == '-') {
589-
// -[0-9]+ means "at most N days old"
590-
QRegExp rx("^-([0-9]+)$");
591-
if (date_expr.indexOf(rx) == 0) {
592-
int days = rx.capturedTexts().at(1).toInt();
593-
q.add_clause(QString("msg_date>=now()-'%1 days'::interval").arg(days));
611+
// -[0-9]+ means "at most N days old". Implemented only for date_equal comparison
612+
if (comp == date_equal) {
613+
QRegExp rx("^-([0-9]+)$");
614+
if (date_expr.indexOf(rx) == 0) {
615+
int days = rx.capturedTexts().at(1).toInt();
616+
q.add_clause(QString("msg_date>=now()-'%1 days'::interval").arg(days));
617+
}
594618
}
595619
}
596620
else {
@@ -601,8 +625,13 @@ msgs_filter::process_date_clause(sql_query& q, QString date_expr)
601625
qd.setDate(year,1,1);
602626
if (!qd.isValid())
603627
throw QObject::tr("Invalid year in date parameter.");
604-
q.add_clause(QString("msg_date>='%1-01-01'::date AND msg_date<'%2-01-01'::date")
605-
.arg(year).arg(year+1));
628+
if (comp == date_equal)
629+
q.add_clause(QString("msg_date>='%1-01-01'::date AND msg_date<'%2-01-01'::date")
630+
.arg(year).arg(year+1));
631+
else if (comp == date_before)
632+
q.add_clause(QString("msg_date<'%1-01-01'::date").arg(year+1));
633+
else if (comp == date_after)
634+
q.add_clause(QString("msg_date>='%1-01-01'::date").arg(year));
606635
}
607636
else {
608637
QRegExp rx1("^(\\d{4})-(\\d{2})$");
@@ -611,9 +640,16 @@ msgs_filter::process_date_clause(sql_query& q, QString date_expr)
611640
qd.setDate(rx1.cap(1).toInt(), rx1.cap(2).toInt(), 1);
612641
if (!qd.isValid())
613642
throw QObject::tr("Invalid year-month in date parameter.");
614-
q.add_clause(QString("msg_date>='%1-%2-01'::date AND "
615-
"msg_date<'%1-%2-01'::date+'1 month'::interval")
616-
.arg(rx1.cap(1)).arg(rx1.cap(2)));
643+
if (comp == date_equal)
644+
q.add_clause(QString("msg_date>='%1-%2-01'::date AND "
645+
"msg_date<'%1-%2-01'::date+'1 month'::interval")
646+
.arg(rx1.cap(1)).arg(rx1.cap(2)));
647+
else if (comp == date_before)
648+
q.add_clause(QString("msg_date<'%1-%2-01'::date+'1 month'::interval")
649+
.arg(rx1.cap(1)).arg(rx1.cap(2)));
650+
if (comp == date_after)
651+
q.add_clause(QString("msg_date>='%1-%2-01'::date")
652+
.arg(rx1.cap(1)).arg(rx1.cap(2)));
617653
}
618654
else {
619655
QRegExp rx2("^(\\d{4})-(\\d{2})-(\\d{2})$");
@@ -622,9 +658,16 @@ msgs_filter::process_date_clause(sql_query& q, QString date_expr)
622658
qd.setDate(rx2.cap(1).toInt(), rx2.cap(2).toInt(), rx2.cap(3).toInt());
623659
if (!qd.isValid())
624660
throw QObject::tr("Invalid year-month-day in date parameter.");
625-
q.add_clause(QString("msg_date>='%1-%2-%3'::date AND "
626-
"msg_date<'%1-%2-%3'::date+'1 day'::interval")
627-
.arg(rx2.cap(1)).arg(rx2.cap(2)).arg(rx2.cap(3)));
661+
if (comp == date_equal)
662+
q.add_clause(QString("msg_date>='%1-%2-%3'::date AND "
663+
"msg_date<'%1-%2-%3'::date+'1 day'::interval")
664+
.arg(rx2.cap(1)).arg(rx2.cap(2)).arg(rx2.cap(3)));
665+
else if (comp == date_before)
666+
q.add_clause(QString("msg_date<'%1-%2-%3'::date+'1 day'::interval")
667+
.arg(rx2.cap(1)).arg(rx2.cap(2)).arg(rx2.cap(3)));
668+
else if (comp == date_after)
669+
q.add_clause(QString("msg_date>='%1-%2-%3'::date")
670+
.arg(rx2.cap(1)).arg(rx2.cap(2)).arg(rx2.cap(3)));
628671
}
629672
else
630673
throw QObject::tr("Unable to parse date expression.");
@@ -1188,7 +1231,9 @@ msg_select_dialog::to_filter(msgs_filter* filter)
11881231
}
11891232
}
11901233
else {
1191-
filter->m_date_clause=QString::null;
1234+
filter->m_date_clause = QString::null;
1235+
filter->m_date_before_clause = QString::null;
1236+
filter->m_date_after_clause = QString::null;
11921237
filter->m_date_min = QDate();
11931238
filter->m_date_max = QDate();
11941239
}

src/selectmail.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ class msgs_filter
128128

129129
int m_newer_than; /* newer than or N days old */
130130
QString m_date_clause;
131+
QString m_date_before_clause;
132+
QString m_date_after_clause;
131133

132134
int m_min_prio;
133135
uint m_tag_id;
@@ -163,8 +165,17 @@ class msgs_filter
163165
#endif
164166

165167
private:
166-
void process_date_clause(sql_query& q, QString date_expr);
167-
168+
enum date_comparator {
169+
date_equal,
170+
date_after,
171+
date_before
172+
};
173+
/* Add criteria to the sql_query that correspond to a comparison
174+
with date_expr using the date_comparator (equal or after or
175+
before) */
176+
void process_date_clause(sql_query& q,
177+
date_comparator comp,
178+
QString date_expr);
168179
bool m_auto_refresh;
169180
int add_address_selection (sql_query& q, const QString email_addr, int addr_type);
170181
/* number of criteria that needs to match an address from

0 commit comments

Comments
 (0)