From fa1e90dc38c70656db1be7bf234bdee859c55915 Mon Sep 17 00:00:00 2001 From: marc-vdm Date: Wed, 27 Dec 2023 11:41:42 +0100 Subject: [PATCH 1/3] fix empty database missing 'modified' time --- activity_browser/controllers/database.py | 1 + activity_browser/ui/tables/models/inventory.py | 7 ++----- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/activity_browser/controllers/database.py b/activity_browser/controllers/database.py index ec3a3db81..9d7d1050f 100644 --- a/activity_browser/controllers/database.py +++ b/activity_browser/controllers/database.py @@ -117,6 +117,7 @@ def add_database(self): if ok and name: if name not in bw.databases: bw.Database(name).register() + bw.Database(name).write({}) # write nothing to the database so we set a modified time project_settings.add_db(name, False) signals.databases_changed.emit() signals.database_selected.emit(name) diff --git a/activity_browser/ui/tables/models/inventory.py b/activity_browser/ui/tables/models/inventory.py index af78ea7e3..44455c60d 100644 --- a/activity_browser/ui/tables/models/inventory.py +++ b/activity_browser/ui/tables/models/inventory.py @@ -34,13 +34,10 @@ def get_db_name(self, proxy: QModelIndex) -> str: return self._dataframe.iat[idx.row(), 0] def sync(self): - # code below is based on the assumption that bw uses utc timestamps - tz = datetime.datetime.now(datetime.timezone.utc).astimezone() - time_shift = - tz.utcoffset().total_seconds() - data = [] for name in natural_sort(bw.databases): - dt = datetime.datetime.strptime(bw.databases[name].get("modified", ""), '%Y-%m-%dT%H:%M:%S.%f') + # get the modified time, in case it doesn't exist, just write 'now' in the correct format + dt = bw.databases[name].get("modified", datetime.datetime.now().isoformat()) # final column includes interactive checkbox which shows read-only state of db database_read_only = project_settings.db_is_readonly(name) data.append({ From 3ae7e5c7e3bf5d8e1f875563e244a1a85d9940ba Mon Sep 17 00:00:00 2001 From: marc-vdm Date: Wed, 27 Dec 2023 12:09:32 +0100 Subject: [PATCH 2/3] Add tooltip for datetime as actual date instead of the humanized data. --- activity_browser/ui/tables/models/base.py | 21 +++++++++++++------ .../ui/tables/models/inventory.py | 2 ++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/activity_browser/ui/tables/models/base.py b/activity_browser/ui/tables/models/base.py index 521d41ffc..57f7cd184 100644 --- a/activity_browser/ui/tables/models/base.py +++ b/activity_browser/ui/tables/models/base.py @@ -64,14 +64,22 @@ def data(self, index, role=Qt.DisplayRole): value = value.item() elif isinstance(value, tuple): value = str(value) - elif isinstance(value, datetime.datetime) and role != 'sorting': + elif isinstance(value, datetime.datetime) and (Qt.DisplayRole or Qt.ToolTipRole): tz = datetime.datetime.now(datetime.timezone.utc).astimezone() time_shift = - tz.utcoffset().total_seconds() - value = arrow.get(value).shift(seconds=time_shift).humanize() + if role == Qt.ToolTipRole: + value = arrow.get(value).shift(seconds=time_shift).format('YYYY-MM-DD HH:mm:ss') + elif role == Qt.DisplayRole: + value = arrow.get(value).shift(seconds=time_shift).humanize() + + # immediately return value in case of DisplayRole or sorting + if role == Qt.DisplayRole or role == 'sorting': + return value + + # in case of ToolTipRole and value is datetime object + if role == Qt.ToolTipRole and isinstance(value, datetime.datetime): + return value - # immediately return value in case of DisplayRole - if role == Qt.DisplayRole or role == 'sorting': return value - # in case of ToolTipRole, check whether content fits the cell if role == Qt.ToolTipRole: parent = self.parent() @@ -83,7 +91,8 @@ def data(self, index, role=Qt.DisplayRole): margin = 10 # only show tooltip if the text is wider then the cell minus the margin - if text_width > column_width - margin: return value + if text_width > column_width - margin: + return value if role == Qt.ForegroundRole: col_name = self._dataframe.columns[index.column()] diff --git a/activity_browser/ui/tables/models/inventory.py b/activity_browser/ui/tables/models/inventory.py index 44455c60d..eda93357b 100644 --- a/activity_browser/ui/tables/models/inventory.py +++ b/activity_browser/ui/tables/models/inventory.py @@ -38,6 +38,8 @@ def sync(self): for name in natural_sort(bw.databases): # get the modified time, in case it doesn't exist, just write 'now' in the correct format dt = bw.databases[name].get("modified", datetime.datetime.now().isoformat()) + dt = datetime.datetime.strptime(dt, '%Y-%m-%dT%H:%M:%S.%f') + # final column includes interactive checkbox which shows read-only state of db database_read_only = project_settings.db_is_readonly(name) data.append({ From cc0e16273bedc5a156b5c0a485ddde97bca6c109 Mon Sep 17 00:00:00 2001 From: marc-vdm Date: Wed, 27 Dec 2023 12:25:49 +0100 Subject: [PATCH 3/3] Write proper date as tooltip --- activity_browser/ui/tables/models/base.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/activity_browser/ui/tables/models/base.py b/activity_browser/ui/tables/models/base.py index 57f7cd184..5f138e3c8 100644 --- a/activity_browser/ui/tables/models/base.py +++ b/activity_browser/ui/tables/models/base.py @@ -54,6 +54,7 @@ def data(self, index, role=Qt.DisplayRole): # instantiate value only in case of DisplayRole or ToolTipRole value = None + tt_date_flag = False # flag to indicate if value is datetime object and role is ToolTipRole if role == Qt.DisplayRole or role == Qt.ToolTipRole or role == 'sorting': value = self._dataframe.iat[index.row(), index.column()] if isinstance(value, np.float64): @@ -69,6 +70,7 @@ def data(self, index, role=Qt.DisplayRole): time_shift = - tz.utcoffset().total_seconds() if role == Qt.ToolTipRole: value = arrow.get(value).shift(seconds=time_shift).format('YYYY-MM-DD HH:mm:ss') + tt_date_flag = True elif role == Qt.DisplayRole: value = arrow.get(value).shift(seconds=time_shift).humanize() @@ -76,8 +78,8 @@ def data(self, index, role=Qt.DisplayRole): if role == Qt.DisplayRole or role == 'sorting': return value - # in case of ToolTipRole and value is datetime object - if role == Qt.ToolTipRole and isinstance(value, datetime.datetime): + # in case of ToolTipRole and date, always show the full date + if tt_date_flag and role == Qt.ToolTipRole: return value # in case of ToolTipRole, check whether content fits the cell