Convert gui to use datetime instead of date for all date fields.

This commit is contained in:
Charles Haley 2011-11-08 11:30:43 +01:00
parent 5944a4126d
commit 4d0a2ad7bd
8 changed files with 95 additions and 89 deletions

View File

@ -6,7 +6,7 @@ from threading import RLock
from urllib import unquote
from PyQt4.Qt import (QVariant, QFileInfo, QObject, SIGNAL, QBuffer, Qt,
QByteArray, QTranslator, QCoreApplication, QThread,
QEvent, QTimer, pyqtSignal, QDate, QDesktopServices,
QEvent, QTimer, pyqtSignal, QDateTime, QDesktopServices,
QFileDialog, QFileIconProvider, QSettings,
QIcon, QApplication, QDialog, QUrl, QFont)
@ -104,7 +104,7 @@ gprefs.defaults['show_files_after_save'] = True
# }}}
NONE = QVariant() #: Null value to return from the data function of item models
UNDEFINED_QDATE = QDate(UNDEFINED_DATE)
UNDEFINED_QDATETIME = QDateTime(UNDEFINED_DATE)
ALL_COLUMNS = ['title', 'ondevice', 'authors', 'size', 'timestamp', 'rating', 'publisher',
'tags', 'series', 'pubdate']

View File

@ -7,15 +7,15 @@ __docformat__ = 'restructuredtext en'
from functools import partial
from PyQt4.Qt import QComboBox, QLabel, QSpinBox, QDoubleSpinBox, QDateEdit, \
QDate, QGroupBox, QVBoxLayout, QSizePolicy, \
from PyQt4.Qt import QComboBox, QLabel, QSpinBox, QDoubleSpinBox, QDateTimeEdit, \
QDateTime, QGroupBox, QVBoxLayout, QSizePolicy, \
QSpacerItem, QIcon, QCheckBox, QWidget, QHBoxLayout, SIGNAL, \
QPushButton
from calibre.utils.date import qt_to_dt, now
from calibre.gui2.complete import MultiCompleteLineEdit, MultiCompleteComboBox
from calibre.gui2.comments_editor import Editor as CommentsEditor
from calibre.gui2 import UNDEFINED_QDATE, error_dialog
from calibre.gui2 import UNDEFINED_QDATETIME, error_dialog
from calibre.utils.config import tweaks
from calibre.utils.icu import sort_key
from calibre.library.comments import comments_to_html
@ -142,27 +142,27 @@ class Rating(Int):
val *= 2
return val
class DateEdit(QDateEdit):
class DateTimeEdit(QDateTimeEdit):
def focusInEvent(self, x):
self.setSpecialValueText('')
QDateEdit.focusInEvent(self, x)
QDateTimeEdit.focusInEvent(self, x)
def focusOutEvent(self, x):
self.setSpecialValueText(_('Undefined'))
QDateEdit.focusOutEvent(self, x)
QDateTimeEdit.focusOutEvent(self, x)
def set_to_today(self):
self.setDate(now())
self.setDateTime(now())
def set_to_clear(self):
self.setDate(UNDEFINED_QDATE)
self.setDateTime(UNDEFINED_QDATETIME)
class DateTime(Base):
def setup_ui(self, parent):
cm = self.col_metadata
self.widgets = [QLabel('&'+cm['name']+':', parent), DateEdit(parent)]
self.widgets = [QLabel('&'+cm['name']+':', parent), DateTimeEdit(parent)]
self.widgets.append(QLabel(''))
w = QWidget(parent)
self.widgets.append(w)
@ -179,24 +179,25 @@ class DateTime(Base):
w = self.widgets[1]
format = cm['display'].get('date_format','')
if not format:
format = 'dd MMM yyyy'
format = 'dd MMM yyyy hh:mm'
w.setDisplayFormat(format)
w.setCalendarPopup(True)
w.setMinimumDate(UNDEFINED_QDATE)
w.setMinimumDateTime(UNDEFINED_QDATETIME)
w.setSpecialValueText(_('Undefined'))
self.today_button.clicked.connect(w.set_to_today)
self.clear_button.clicked.connect(w.set_to_clear)
def setter(self, val):
if val is None:
val = self.widgets[1].minimumDate()
val = self.widgets[1].minimumDateTime()
else:
val = QDate(val.year, val.month, val.day)
self.widgets[1].setDate(val)
val = QDateTime(val)
self.widgets[1].setDateTime(val)
def getter(self):
val = self.widgets[1].date()
if val == UNDEFINED_QDATE:
val = self.widgets[1].dateTime()
print val
if val <= UNDEFINED_QDATETIME:
val = None
else:
val = qt_to_dt(val)
@ -537,9 +538,9 @@ class BulkBase(Base):
if hasattr(self.main_widget, 'valueChanged'):
# spinbox widgets
self.main_widget.valueChanged.connect(self.a_c_checkbox_changed)
if hasattr(self.main_widget, 'dateChanged'):
if hasattr(self.main_widget, 'dateTimeChanged'):
# dateEdit widgets
self.main_widget.dateChanged.connect(self.a_c_checkbox_changed)
self.main_widget.dateTimeChanged.connect(self.a_c_checkbox_changed)
def a_c_checkbox_changed(self):
if not self.ignore_change_signals:
@ -658,7 +659,7 @@ class BulkDateTime(BulkBase):
def setup_ui(self, parent):
cm = self.col_metadata
self.make_widgets(parent, DateEdit)
self.make_widgets(parent, DateTimeEdit)
self.widgets.append(QLabel(''))
w = QWidget(parent)
self.widgets.append(w)
@ -678,25 +679,26 @@ class BulkDateTime(BulkBase):
format = 'dd MMM yyyy'
w.setDisplayFormat(format)
w.setCalendarPopup(True)
w.setMinimumDate(UNDEFINED_QDATE)
w.setMinimumDateTime(UNDEFINED_QDATETIME)
w.setSpecialValueText(_('Undefined'))
self.today_button.clicked.connect(w.set_to_today)
self.clear_button.clicked.connect(w.set_to_clear)
def setter(self, val):
if val is None:
val = self.main_widget.minimumDate()
val = self.main_widget.minimumDateTime()
else:
val = QDate(val.year, val.month, val.day)
self.main_widget.setDate(val)
val = QDateTime(val)
self.main_widget.setDateTime(val)
self.ignore_change_signals = False
def getter(self):
val = self.main_widget.date()
if val == UNDEFINED_QDATE:
val = self.main_widget.dateTime()
if val <= UNDEFINED_QDATETIME:
val = None
else:
val = qt_to_dt(val)
print val
return val
class BulkSeries(BulkBase):

View File

@ -7,14 +7,14 @@ import re, os, inspect
from PyQt4.Qt import Qt, QDialog, QGridLayout, QVBoxLayout, QFont, QLabel, \
pyqtSignal, QDialogButtonBox, QInputDialog, QLineEdit, \
QDate, QCompleter
QDateTime, QCompleter
from calibre.gui2.dialogs.metadata_bulk_ui import Ui_MetadataBulkDialog
from calibre.gui2.dialogs.tag_editor import TagEditor
from calibre.ebooks.metadata import string_to_authors, authors_to_string, title_sort
from calibre.ebooks.metadata.book.base import SafeFormat
from calibre.gui2.custom_column_widgets import populate_metadata_page
from calibre.gui2 import error_dialog, ResizableDialog, UNDEFINED_QDATE, \
from calibre.gui2 import error_dialog, ResizableDialog, UNDEFINED_QDATETIME, \
gprefs, question_dialog
from calibre.gui2.progress_indicator import ProgressIndicator
from calibre.utils.config import dynamic, JSONConfig
@ -306,18 +306,21 @@ class MetadataBulkDialog(ResizableDialog, Ui_MetadataBulkDialog):
self.series.editTextChanged.connect(self.series_changed)
self.tag_editor_button.clicked.connect(self.tag_editor)
self.autonumber_series.stateChanged[int].connect(self.auto_number_changed)
self.pubdate.setMinimumDate(UNDEFINED_QDATE)
self.pubdate.setMinimumDateTime(UNDEFINED_QDATETIME)
pubdate_format = tweaks['gui_pubdate_display_format']
if pubdate_format is not None:
self.pubdate.setDisplayFormat(pubdate_format)
self.pubdate.setSpecialValueText(_('Undefined'))
self.clear_pubdate_button.clicked.connect(self.clear_pubdate)
self.pubdate.dateChanged.connect(self.do_apply_pubdate)
self.adddate.setDate(QDate.currentDate())
self.adddate.setMinimumDate(UNDEFINED_QDATE)
self.pubdate.dateTimeChanged.connect(self.do_apply_pubdate)
self.adddate.setDateTime(QDateTime.currentDateTime())
self.adddate.setMinimumDateTime(UNDEFINED_QDATETIME)
adddate_format = tweaks['gui_timestamp_display_format']
if adddate_format is not None:
self.adddate.setDisplayFormat(adddate_format)
self.adddate.setSpecialValueText(_('Undefined'))
self.clear_adddate_button.clicked.connect(self.clear_adddate)
self.adddate.dateChanged.connect(self.do_apply_adddate)
self.adddate.dateTimeChanged.connect(self.do_apply_adddate)
if len(self.db.custom_field_keys(include_composites=False)) == 0:
self.central_widget.removeTab(1)
@ -347,13 +350,13 @@ class MetadataBulkDialog(ResizableDialog, Ui_MetadataBulkDialog):
self.apply_pubdate.setChecked(True)
def clear_pubdate(self, *args):
self.pubdate.setDate(UNDEFINED_QDATE)
self.pubdate.setMinimumDateTime(UNDEFINED_QDATETIME)
def do_apply_adddate(self, *args):
self.apply_adddate.setChecked(True)
def clear_adddate(self, *args):
self.adddate.setDate(UNDEFINED_QDATE)
self.adddate.setMinimumDateTime(UNDEFINED_QDATETIME)
def button_clicked(self, which):
if which == self.button_box.button(QDialogButtonBox.Apply):
@ -935,9 +938,9 @@ class MetadataBulkDialog(ResizableDialog, Ui_MetadataBulkDialog):
languages = self.languages.lang_codes
pubdate = adddate = None
if self.apply_pubdate.isChecked():
pubdate = qt_to_dt(self.pubdate.date())
pubdate = qt_to_dt(self.pubdate.dateTime())
if self.apply_adddate.isChecked():
adddate = qt_to_dt(self.adddate.date())
adddate = qt_to_dt(self.adddate.dateTime())
cover_action = None
if self.cover_remove.isChecked():

View File

@ -366,7 +366,7 @@ from the value in the box</string>
<item row="9" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QDateEdit" name="adddate">
<widget class="QDateTimeEdit" name="adddate">
<property name="displayFormat">
<string>d MMM yyyy</string>
</property>
@ -411,7 +411,7 @@ from the value in the box</string>
<item row="10" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QDateEdit" name="pubdate">
<widget class="QDateTimeEdit" name="pubdate">
<property name="displayFormat">
<string>MMM yyyy</string>
</property>

View File

@ -12,9 +12,9 @@ from PyQt4.Qt import (QColor, Qt, QModelIndex, QSize, QApplication,
QPen, QStyle, QPainter, QStyleOptionViewItemV4,
QIcon, QDoubleSpinBox, QVariant, QSpinBox,
QStyledItemDelegate, QComboBox, QTextDocument,
QAbstractTextDocumentLayout)
QAbstractTextDocumentLayout, QDateTime)
from calibre.gui2 import UNDEFINED_QDATE, error_dialog
from calibre.gui2 import UNDEFINED_QDATETIME, error_dialog
from calibre.gui2.widgets import EnLineEdit
from calibre.gui2.complete import MultiCompleteLineEdit, MultiCompleteComboBox
from calibre.utils.date import now, format_date
@ -107,25 +107,23 @@ class RatingDelegate(QStyledItemDelegate): # {{{
class DateDelegate(QStyledItemDelegate): # {{{
def __init__(self, parent, tweak_name='gui_timestamp_display_format',
default_format='dd MMM yyyy', editor_format='dd MMM yyyy'):
default_format='dd MMM yyyy'):
QStyledItemDelegate.__init__(self, parent)
self.tweak_name = tweak_name
self.default_format = default_format
self.editor_format = editor_format
self.format = tweaks[self.tweak_name]
if self.format is None:
format = default_format
def displayText(self, val, locale):
d = val.toDate()
if d <= UNDEFINED_QDATE:
d = val.toDateTime()
if d <= UNDEFINED_QDATETIME:
return ''
format = tweaks[self.tweak_name]
if format is None:
format = self.default_format
return format_date(d.toPyDate(), format)
return format_date(d.toPyDateTime(), self.format)
def createEditor(self, parent, option, index):
qde = QStyledItemDelegate.createEditor(self, parent, option, index)
qde.setDisplayFormat(self.editor_format)
qde.setMinimumDate(UNDEFINED_QDATE)
qde.setDisplayFormat(self.format)
qde.setMinimumDateTime(UNDEFINED_QDATETIME)
qde.setSpecialValueText(_('Undefined'))
qde.setCalendarPopup(True)
return qde
@ -134,18 +132,18 @@ class DateDelegate(QStyledItemDelegate): # {{{
class PubDateDelegate(QStyledItemDelegate): # {{{
def displayText(self, val, locale):
d = val.toDate()
if d <= UNDEFINED_QDATE:
d = val.toDateTime()
if d <= UNDEFINED_QDATETIME:
return ''
format = tweaks['gui_pubdate_display_format']
if format is None:
format = 'MMM yyyy'
return format_date(d.toPyDate(), format)
self.format = tweaks['gui_pubdate_display_format']
if self.format is None:
self.format = 'MMM yyyy'
return format_date(d.toPyDateTime(), self.format)
def createEditor(self, parent, option, index):
qde = QStyledItemDelegate.createEditor(self, parent, option, index)
qde.setDisplayFormat('MM yyyy')
qde.setMinimumDate(UNDEFINED_QDATE)
qde.setDisplayFormat(self.format)
qde.setMinimumDateTime(UNDEFINED_QDATETIME)
qde.setSpecialValueText(_('Undefined'))
qde.setCalendarPopup(True)
return qde
@ -259,15 +257,15 @@ class CcDateDelegate(QStyledItemDelegate): # {{{
self.format = format
def displayText(self, val, locale):
d = val.toDate()
if d <= UNDEFINED_QDATE:
d = val.toDateTime()
if d <= UNDEFINED_QDATETIME:
return ''
return format_date(d.toPyDate(), self.format)
return format_date(d.toPyDateTime(), self.format)
def createEditor(self, parent, option, index):
qde = QStyledItemDelegate.createEditor(self, parent, option, index)
qde.setDisplayFormat(self.format)
qde.setMinimumDate(UNDEFINED_QDATE)
qde.setMinimumDateTime(UNDEFINED_QDATETIME)
qde.setSpecialValueText(_('Undefined'))
qde.setCalendarPopup(True)
return qde
@ -279,11 +277,11 @@ class CcDateDelegate(QStyledItemDelegate): # {{{
val = m.db.data[index.row()][m.custom_columns[m.column_map[index.column()]]['rec_index']]
if val is None:
val = now()
editor.setDate(val)
editor.setDateTime(val)
def setModelData(self, editor, model, index):
val = editor.date()
if val <= UNDEFINED_QDATE:
val = editor.dateTime()
if val <= UNDEFINED_QDATETIME:
val = None
model.setData(index, QVariant(val), Qt.EditRole)

View File

@ -9,9 +9,9 @@ import functools, re, os, traceback
from collections import defaultdict
from PyQt4.Qt import (QAbstractTableModel, Qt, pyqtSignal, QIcon, QImage,
QModelIndex, QVariant, QDate, QColor)
QModelIndex, QVariant, QDateTime, QColor)
from calibre.gui2 import NONE, UNDEFINED_QDATE
from calibre.gui2 import NONE, UNDEFINED_QDATETIME
from calibre.utils.pyparsing import ParseException
from calibre.ebooks.metadata import fmt_sidx, authors_to_string, string_to_authors
from calibre.ebooks.metadata.book.base import SafeFormat
@ -580,9 +580,9 @@ class BooksModel(QAbstractTableModel): # {{{
def datetime_type(r, idx=-1):
val = self.db.data[r][idx]
if val is not None:
return QVariant(QDate(val))
return QVariant(QDateTime(val))
else:
return QVariant(UNDEFINED_QDATE)
return QVariant(UNDEFINED_QDATETIME)
def bool_type(r, idx=-1):
return None # displayed using a decorator
@ -815,7 +815,7 @@ class BooksModel(QAbstractTableModel): # {{{
if not val:
val = None
elif typ == 'datetime':
val = value.toDate()
val = value.toDateTime()
if val.isNull():
val = None
else:
@ -860,7 +860,7 @@ class BooksModel(QAbstractTableModel): # {{{
if column not in self.editable_cols:
return False
val = int(value.toInt()[0]) if column == 'rating' else \
value.toDate() if column in ('timestamp', 'pubdate') else \
value.toDateTime() if column in ('timestamp', 'pubdate') else \
unicode(value.toString()).strip()
id = self.db.id(row)
books_to_refresh = set([id])

View File

@ -9,7 +9,7 @@ __docformat__ = 'restructuredtext en'
import textwrap, re, os, errno, shutil
from PyQt4.Qt import (Qt, QDateEdit, QDate, pyqtSignal, QMessageBox,
from PyQt4.Qt import (Qt, QDateTimeEdit, pyqtSignal, QMessageBox,
QIcon, QToolButton, QWidget, QLabel, QGridLayout, QApplication,
QDoubleSpinBox, QListWidgetItem, QSize, QPixmap, QDialog, QMenu,
QPushButton, QSpinBox, QLineEdit, QSizePolicy, QDialogButtonBox, QAction)
@ -21,7 +21,7 @@ from calibre.utils.config import tweaks, prefs
from calibre.ebooks.metadata import (title_sort, authors_to_string,
string_to_authors, check_isbn, authors_to_sort_string)
from calibre.ebooks.metadata.meta import get_metadata
from calibre.gui2 import (file_icon_provider, UNDEFINED_QDATE,
from calibre.gui2 import (file_icon_provider, UNDEFINED_QDATETIME,
choose_files, error_dialog, choose_images)
from calibre.utils.date import (local_tz, qt_to_dt, as_local_time,
UNDEFINED_DATE)
@ -1377,25 +1377,24 @@ class PublisherEdit(MultiCompleteComboBox): # {{{
# }}}
class DateEdit(QDateEdit): # {{{
class DateEdit(QDateTimeEdit): # {{{
TOOLTIP = ''
LABEL = _('&Date:')
FMT = 'd MMM yyyy'
FMT = 'dd MMM yyyy hh:mm:ss'
ATTR = 'timestamp'
TWEAK = 'gui_timestamp_display_format'
def __init__(self, parent):
QDateEdit.__init__(self, parent)
QDateTimeEdit.__init__(self, parent)
self.setToolTip(self.TOOLTIP)
self.setWhatsThis(self.TOOLTIP)
fmt = tweaks[self.TWEAK]
if fmt is None:
fmt = self.FMT
if fmt is None:
fmt = tweaks['gui_pubdate_display_format']
if fmt is None:
fmt = 'MMM yyyy'
self.setDisplayFormat(fmt)
self.setCalendarPopup(True)
self.setMinimumDate(UNDEFINED_QDATE)
self.setMinimumDateTime(UNDEFINED_QDATETIME)
self.setSpecialValueText(_('Undefined'))
self.clear_button = QToolButton(parent)
self.clear_button.setIcon(QIcon(I('trash.png')))
@ -1408,12 +1407,12 @@ class DateEdit(QDateEdit): # {{{
@dynamic_property
def current_val(self):
def fget(self):
return qt_to_dt(self.date(), as_utc=False)
return qt_to_dt(self.dateTime(), as_utc=False)
def fset(self, val):
if val is None:
val = UNDEFINED_DATE
val = as_local_time(val)
self.setDate(QDate(val.year, val.month, val.day))
self.setDateTime(val)
return property(fget=fget, fset=fset)
def initialize(self, db, id_):
@ -1429,11 +1428,12 @@ class DateEdit(QDateEdit): # {{{
@property
def changed(self):
o, c = self.original_val, self.current_val
return o.year != c.year or o.month != c.month or o.day != c.day
return o != c
class PubdateEdit(DateEdit):
LABEL = _('Publishe&d:')
FMT = None
FMT = 'MMM yyyy'
ATTR = 'pubdate'
TWEAK = 'gui_pubdate_display_format'
# }}}

View File

@ -7,7 +7,7 @@ __copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
import re
from datetime import datetime
from datetime import datetime, time
from functools import partial
from dateutil.parser import parse
@ -161,6 +161,9 @@ def format_date(dt, format, assume_utc=False, as_utc=False):
if not format:
format = 'dd MMM yyyy'
if not isinstance(dt, datetime):
dt = datetime.combine(dt, time())
if hasattr(dt, 'tzinfo'):
if dt.tzinfo is None:
dt = dt.replace(tzinfo=_utc_tz if assume_utc else