mirror of
https://github.com/chris2511/xca.git
synced 2026-09-12 19:51:05 +05:00
Inspired by #42: display insertion date relative
Easy to find the most recent entry, because it says "3 seconds ago"
This commit is contained in:
parent
5ff5d77d68
commit
b10b4f7a53
@ -22,6 +22,8 @@
|
||||
#define UTC_FORMAT "yyMMddHHmmss'Z'"
|
||||
#define GEN_FORMAT "yy" UTC_FORMAT
|
||||
|
||||
#define TR QObject::tr
|
||||
|
||||
bool a1time::isUndefined() const
|
||||
{
|
||||
return toTime_t() == 0;
|
||||
@ -151,9 +153,9 @@ a1time &a1time::set(const ASN1_TIME *a)
|
||||
QString a1time::toString(QString fmt, Qt::TimeSpec spec) const
|
||||
{
|
||||
if (isUndefined())
|
||||
return QObject::tr("Undefined");
|
||||
return TR("Undefined");
|
||||
if (!isValid())
|
||||
return QObject::tr("Broken / Invalid");
|
||||
return TR("Broken / Invalid");
|
||||
return (spec == Qt::UTC ? toUTC() : toLocalTime()).toString(fmt);
|
||||
}
|
||||
|
||||
@ -182,6 +184,41 @@ QString a1time::toPlain(const QString &fmt) const
|
||||
return toString(fmt.isEmpty() ? GEN_FORMAT : fmt);
|
||||
}
|
||||
|
||||
qint64 a1time::age() const
|
||||
{
|
||||
return secsTo(now());
|
||||
}
|
||||
|
||||
QString a1time::toFancy() const
|
||||
{
|
||||
QString fmt("Dunno");
|
||||
qint64 diff = age();
|
||||
bool future = false;
|
||||
if (diff < 0) {
|
||||
future = true;
|
||||
diff *= -1;
|
||||
}
|
||||
if (diff < 2 * SECS_PER_MINUTE) {
|
||||
fmt = future ? TR("in %1 seconds") : TR("%1 seconds ago");
|
||||
} else if (diff < 2 *SECS_PER_HOUR) {
|
||||
diff /= SECS_PER_MINUTE;
|
||||
fmt = future ? TR("in %1 minutes") : TR("%1 minutes ago");
|
||||
} else if (diff < 2 *SECS_PER_DAY) {
|
||||
diff /= SECS_PER_HOUR;
|
||||
fmt = future ? TR("in %1 hours") : TR("%1 hours ago");
|
||||
} else if (diff < 2 *SECS_PER_WEEK) {
|
||||
diff /= SECS_PER_DAY;
|
||||
fmt = future ? TR("in %1 days") : TR("%1 days ago");
|
||||
} else if (diff < 2 *SECS_PER_MONTH) {
|
||||
diff /= SECS_PER_WEEK;
|
||||
fmt = future ? TR("in %1 weeks") : TR("%1 weeks ago");
|
||||
} else {
|
||||
diff /= SECS_PER_MONTH;
|
||||
fmt = future ? TR("in %1 months") : TR("%1 months ago");
|
||||
}
|
||||
return fmt.arg(diff);
|
||||
}
|
||||
|
||||
QString a1time::toPlainUTC() const
|
||||
{
|
||||
return toPlain(UTC_FORMAT);
|
||||
|
||||
@ -12,7 +12,14 @@
|
||||
#include <QDateTime>
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#define SECONDS_PER_DAY (60*60*24)
|
||||
#define SECS_PER_MINUTE (60)
|
||||
#define SECS_PER_HOUR (SECS_PER_MINUTE *60)
|
||||
#define SECS_PER_DAY (SECS_PER_HOUR*24)
|
||||
#define SECS_PER_WEEK (SECS_PER_DAY*7)
|
||||
#define SECS_PER_MONTH (SECS_PER_DAY*30)
|
||||
|
||||
#define MSECS_PER_MINUTE (SECS_PER_MINUTE*1000)
|
||||
#define MSECS_PER_HOUR (SECS_PER_HOUR*1000)
|
||||
|
||||
class a1time : public QDateTime
|
||||
{
|
||||
@ -39,13 +46,14 @@ class a1time : public QDateTime
|
||||
QString toPlain(const QString &fmt = QString()) const;
|
||||
QString toPlainUTC() const;
|
||||
QString toSortable() const;
|
||||
QString toISO8601() const;
|
||||
QString toFancy() const;
|
||||
QString isoLocalDate() const;
|
||||
ASN1_TIME *get();
|
||||
ASN1_TIME *get_utc();
|
||||
static QDateTime now(int delta = 0);
|
||||
QByteArray i2d();
|
||||
void d2i(QByteArray &ba);
|
||||
qint64 age() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -22,6 +22,17 @@
|
||||
|
||||
QHash<quint64, pki_base*> db_base::lookup;
|
||||
|
||||
void db_base::restart_timer()
|
||||
{
|
||||
killTimer(secondsTimer);
|
||||
killTimer(minutesTimer);
|
||||
killTimer(hoursTimer);
|
||||
|
||||
secondsTimer = startTimer(1000);
|
||||
minutesTimer = startTimer(MSECS_PER_MINUTE);
|
||||
hoursTimer = startTimer(MSECS_PER_HOUR);
|
||||
}
|
||||
|
||||
db_base::db_base(MainWindow *mw)
|
||||
:QAbstractItemModel(NULL)
|
||||
{
|
||||
@ -31,6 +42,7 @@ db_base::db_base(MainWindow *mw)
|
||||
colResizing = 0;
|
||||
currentIdx = QModelIndex();
|
||||
class_name = "base";
|
||||
restart_timer();
|
||||
}
|
||||
|
||||
db_base::~db_base()
|
||||
@ -124,6 +136,7 @@ void db_base::loadContainer()
|
||||
} else {
|
||||
allHeaders.fromData(view);
|
||||
}
|
||||
restart_timer();
|
||||
emit columnsContentChanged();
|
||||
}
|
||||
|
||||
@ -221,6 +234,7 @@ void db_base::insertPKI(pki_base *pki)
|
||||
lookup[pki->getSqlItemId().toULongLong()] = pki;
|
||||
inToCont(pki);
|
||||
TransCommit();
|
||||
restart_timer();
|
||||
emit columnsContentChanged();
|
||||
}
|
||||
|
||||
@ -435,7 +449,7 @@ QVariant db_base::data(const QModelIndex &index, int role) const
|
||||
switch (role) {
|
||||
case Qt::EditRole:
|
||||
case Qt::DisplayRole:
|
||||
if (hd->id == HD_internal_name || item->isVisible() == 1)
|
||||
if (hd->id==HD_internal_name || item->isVisible()==1)
|
||||
return item->column_data(hd);
|
||||
break;
|
||||
case Qt::DecorationRole:
|
||||
@ -448,6 +462,10 @@ QVariant db_base::data(const QModelIndex &index, int role) const
|
||||
return item->bg_color(hd);
|
||||
case Qt::UserRole:
|
||||
return item->isVisible();
|
||||
case Qt::ToolTipRole:
|
||||
if (hd->id==HD_internal_name || item->isVisible()==1)
|
||||
return item->column_tooltip(hd);
|
||||
break;
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
@ -538,6 +556,41 @@ void db_base::updateItem(pki_base *pki, QString name, QString comment)
|
||||
j = index(i.row(), allHeaders.size(), i.parent());
|
||||
emit dataChanged(i, j);
|
||||
emit pkiChanged(pki);
|
||||
restart_timer();
|
||||
}
|
||||
|
||||
void db_base::timerEvent(QTimerEvent *event)
|
||||
{
|
||||
int youngest = SECS_PER_DAY;
|
||||
int id = event->timerId();
|
||||
int idx = allHeaders.column(HD_creation);
|
||||
|
||||
FOR_ALL_pki(pki, pki_base) {
|
||||
int age = pki->getInsertionDate().age();
|
||||
bool do_emit = false;
|
||||
if (age < youngest)
|
||||
youngest = age;
|
||||
|
||||
if (id == secondsTimer &&
|
||||
(age < SECS_PER_MINUTE *2 || age % SECS_PER_MINUTE < 2))
|
||||
do_emit = true;
|
||||
if (id == minutesTimer && (age % SECS_PER_HOUR < 60))
|
||||
do_emit = true;
|
||||
if (id == hoursTimer && (age % SECS_PER_DAY < SECS_PER_HOUR))
|
||||
do_emit = true;
|
||||
if (do_emit) {
|
||||
QModelIndex i = createIndex(pki->row(), idx, pki);
|
||||
emit dataChanged(i, i);
|
||||
}
|
||||
}
|
||||
if (secondsTimer && youngest > SECS_PER_HOUR *2) {
|
||||
killTimer(secondsTimer);
|
||||
secondsTimer = 0;
|
||||
}
|
||||
if (minutesTimer && youngest > SECS_PER_DAY *2) {
|
||||
killTimer(minutesTimer);
|
||||
minutesTimer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void db_base::editComment(const QModelIndex &index)
|
||||
|
||||
@ -39,6 +39,7 @@ class db_base: public QAbstractItemModel
|
||||
protected:
|
||||
static QHash<quint64, pki_base*> lookup;
|
||||
QModelIndex currentIdx;
|
||||
int secondsTimer, minutesTimer, hoursTimer;
|
||||
void _writePKI(pki_base *pki, bool overwrite);
|
||||
void _removePKI(pki_base *pki );
|
||||
void removeItem(QString k);
|
||||
@ -59,6 +60,8 @@ class db_base: public QAbstractItemModel
|
||||
bool isValidCol(int col) const;
|
||||
static XSqlQuery sqlSELECTpki(QString query,
|
||||
QList<QVariant> values = QList<QVariant>());
|
||||
void timerEvent(QTimerEvent * event);
|
||||
void restart_timer();
|
||||
|
||||
public:
|
||||
template <class T> static T *lookupPki(quint64 i)
|
||||
|
||||
@ -250,5 +250,12 @@ class dbheaderList: public QList<dbheader*>
|
||||
}
|
||||
}
|
||||
}
|
||||
int column(int type) // HD_...
|
||||
{
|
||||
for (int i=0; i<count(); i++)
|
||||
if (at(i)->id == type)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -285,7 +285,7 @@ QVariant pki_base::column_data(const dbheader *hd) const
|
||||
case HD_internal_name:
|
||||
return QVariant(getIntName());
|
||||
case HD_creation:
|
||||
return QVariant(insertion_date.toSortable());
|
||||
return QVariant(insertion_date.toFancy());
|
||||
case HD_comment:
|
||||
return QVariant(comment.section('\n', 0, 0));
|
||||
case HD_source:
|
||||
@ -302,6 +302,17 @@ QVariant pki_base::getIcon(const dbheader *hd) const
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant pki_base::column_tooltip(const dbheader *hd) const
|
||||
{
|
||||
switch (hd->id) {
|
||||
case HD_creation:
|
||||
return QVariant(insertion_date.toPretty());
|
||||
case HD_comment:
|
||||
return QVariant(comment);
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool pki_base::compare(const pki_base *ref) const
|
||||
{
|
||||
bool ret;
|
||||
|
||||
@ -152,6 +152,7 @@ class pki_base : public QObject
|
||||
int row() const;
|
||||
virtual QVariant column_data(const dbheader *hd) const;
|
||||
virtual QVariant getIcon(const dbheader *hd) const;
|
||||
virtual QVariant column_tooltip(const dbheader *hd) const;
|
||||
virtual bool visible() const;
|
||||
int isVisible();
|
||||
bool childVisible() const;
|
||||
|
||||
@ -404,6 +404,17 @@ QVariant pki_crl::column_data(const dbheader *hd) const
|
||||
return pki_x509name::column_data(hd);
|
||||
}
|
||||
|
||||
QVariant pki_crl::column_tooltip(const dbheader *hd) const
|
||||
{
|
||||
switch (hd->id) {
|
||||
case HD_crl_lastUpdate:
|
||||
return QVariant(getLastUpdate().toPretty());
|
||||
case HD_crl_nextUpdate:
|
||||
return QVariant(getNextUpdate().toPretty());
|
||||
}
|
||||
return pki_x509name::column_tooltip(hd);
|
||||
}
|
||||
|
||||
QVariant pki_crl::getIcon(const dbheader *hd) const
|
||||
{
|
||||
return hd->id == HD_internal_name ? QVariant(*icon) : QVariant();
|
||||
|
||||
@ -77,6 +77,7 @@ class pki_crl: public pki_x509name
|
||||
a1int getCrlNumber() const;
|
||||
BIO *pem(BIO *, int);
|
||||
bool visible() const;
|
||||
QVariant column_tooltip(const dbheader *hd) const;
|
||||
QSqlError insertSqlData();
|
||||
QSqlError deleteSqlData();
|
||||
void restoreSql(const QSqlRecord &rec);
|
||||
|
||||
@ -939,8 +939,7 @@ QVariant pki_x509::column_data(const dbheader *hd) const
|
||||
case HD_cert_crl_expire:
|
||||
if (canSign() && !crlExpire.isUndefined())
|
||||
return QVariant(crlExpire.toSortable());
|
||||
else
|
||||
return QVariant();
|
||||
break;
|
||||
case HD_cert_md5fp:
|
||||
return QVariant(fingerprint(EVP_md5()));
|
||||
case HD_cert_sha1fp:
|
||||
@ -958,12 +957,30 @@ QVariant pki_x509::column_data(const dbheader *hd) const
|
||||
else
|
||||
return QVariant(tr("Yes"));
|
||||
}
|
||||
return QVariant("");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return pki_x509super::column_data(hd);
|
||||
}
|
||||
|
||||
QVariant pki_x509::column_tooltip(const dbheader *hd) const
|
||||
{
|
||||
switch (hd->id) {
|
||||
case HD_cert_notBefore:
|
||||
return QVariant(getNotBefore().toPretty());
|
||||
case HD_cert_notAfter:
|
||||
return QVariant(getNotAfter().toPretty());
|
||||
case HD_cert_revocation:
|
||||
return QVariant(isRevoked() ?
|
||||
revocation.getDate().toPretty() : "");
|
||||
case HD_cert_crl_expire:
|
||||
if (canSign() && !crlExpire.isUndefined())
|
||||
return QVariant(crlExpire.toPretty());
|
||||
break;
|
||||
}
|
||||
return pki_x509super::column_tooltip(hd);
|
||||
}
|
||||
|
||||
QStringList pki_x509::icsVEVENT() const
|
||||
{
|
||||
return pki_base::icsVEVENT(getNotAfter(),
|
||||
|
||||
@ -156,6 +156,7 @@ class pki_x509 : public pki_x509super
|
||||
void setRevocations(const x509revList &rl);
|
||||
x509revList getRevList() const;
|
||||
bool compareNameAndKey(pki_x509 *other);
|
||||
QVariant column_tooltip(const dbheader *hd) const;
|
||||
void setCrlExpire(a1time a)
|
||||
{
|
||||
crlExpire = a;
|
||||
|
||||
@ -15,7 +15,10 @@ bool XcaProxyModel::lessThan(const QModelIndex &left,
|
||||
if (!db)
|
||||
return QSortFilterProxyModel::lessThan(left, right);
|
||||
|
||||
if (left.column() < 0 || right.column() < 0) {
|
||||
dbheaderList headers = db->getAllHeaders();
|
||||
if (left.column() < 0 || left.column() >= headers.size() ||
|
||||
right.column() < 0 || right.column() >= headers.size())
|
||||
{
|
||||
qDebug("BAD COLUMN: %d %d\n", left.column(), right.column());
|
||||
return true;
|
||||
}
|
||||
@ -33,6 +36,15 @@ bool XcaProxyModel::lessThan(const QModelIndex &left,
|
||||
else
|
||||
return l < r;
|
||||
}
|
||||
if (headers[left.column()]->id == HD_creation &&
|
||||
headers[right.column()]->id == HD_creation)
|
||||
{
|
||||
pki_base *l = static_cast<pki_base*>(left.internalPointer());
|
||||
pki_base *r = static_cast<pki_base*>(right.internalPointer());
|
||||
if (l && r) {
|
||||
return l->getInsertionDate() < r->getInsertionDate();
|
||||
}
|
||||
}
|
||||
return QSortFilterProxyModel::lessThan(left, right);
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user