📄 q3datetimeedit.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the Qt3Support module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "q3datetimeedit.h"#ifndef QT_NO_DATETIMEEDIT#include <private/q3richtext_p.h>#include "qevent.h"#include "q3rangecontrol.h"#include "qapplication.h"#include "qpixmap.h"#include "qlist.h"#include "qstring.h"#include "qstyle.h"#if defined(Q_WS_WIN)#include "qt_windows.h"#endif#define QDATETIMEEDIT_HIDDEN_CHAR QLatin1Char('0')class Q_COMPAT_EXPORT QNumberSection{public: QNumberSection(int selStart = 0, int selEnd = 0, bool separat = true, int actual = -1) : selstart(selStart), selend(selEnd), act(actual), sep(separat) {} int selectionStart() const { return selstart; } void setSelectionStart(int s) { selstart = s; } int selectionEnd() const { return selend; } void setSelectionEnd(int s) { selend = s; } int width() const { return selend - selstart; } int index() const { return act; } bool separator() const { return sep; } Q_DUMMY_COMPARISON_OPERATOR(QNumberSection)private: signed int selstart :12; signed int selend :12; signed int act :7; bool sep :1;};static QString *lDateSep = 0;static QString *lTimeSep = 0;static bool lAMPM = false;static QString *lAM = 0;static QString *lPM = 0;static Q3DateEdit::Order lOrder = Q3DateEdit::YMD;static int refcount = 0;static void cleanup(){ delete lDateSep; lDateSep = 0; delete lTimeSep; lTimeSep = 0; delete lAM; lAM = 0; delete lPM; lPM = 0;}/*!\internaltry to get the order of DMY and the date/time separator from the locale settings*/static void readLocaleSettings(){ int dpos, mpos, ypos; cleanup(); lDateSep = new QString(); lTimeSep = new QString();#if defined(Q_WS_WIN) QT_WA({ TCHAR data[10]; GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDATE, data, 10); *lDateSep = QString::fromUtf16((ushort*)data); GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STIME, data, 10); *lTimeSep = QString::fromUtf16((ushort*)data); GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ITIME, data, 10); lAMPM = QString::fromUtf16((ushort*)data).toInt()==0; GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_S1159, data, 10); QString am = QString::fromUtf16((ushort*)data); if (!am.isEmpty()) lAM = new QString(am); GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_S2359, data, 10); QString pm = QString::fromUtf16((ushort*)data); if (!pm.isEmpty() ) lPM = new QString(pm); } , { char data[10]; GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SDATE, (char*)&data, 10); *lDateSep = QString::fromLocal8Bit(data); GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_STIME, (char*)&data, 10); *lTimeSep = QString::fromLocal8Bit(data); GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_ITIME, (char*)&data, 10); lAMPM = QString::fromLocal8Bit(data).toInt()==0; GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_S1159, (char*)&data, 10); QString am = QString::fromLocal8Bit(data); if (!am.isEmpty()) lAM = new QString(am); GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_S2359, (char*)&data, 10); QString pm = QString::fromLocal8Bit(data); if (!pm.isEmpty()) lPM = new QString(pm); });#else *lDateSep = QLatin1Char('-'); *lTimeSep = QLatin1Char(':');#endif QString d = QDate(1999, 11, 22).toString(Qt::LocalDate); dpos = d.indexOf(QLatin1String("22")); mpos = d.indexOf(QLatin1String("11")); ypos = d.indexOf(QLatin1String("99")); if (dpos > -1 && mpos > -1 && ypos > -1) { // test for DMY, MDY, YMD, YDM if (dpos < mpos && mpos < ypos) { lOrder = Q3DateEdit::DMY; } else if (mpos < dpos && dpos < ypos) { lOrder = Q3DateEdit::MDY; } else if (ypos < mpos && mpos < dpos) { lOrder = Q3DateEdit::YMD; } else if (ypos < dpos && dpos < mpos) { lOrder = Q3DateEdit::YDM; } else { // cannot determine the dateformat - use the default return; } // this code needs to change if new formats are added#ifndef Q_WS_WIN QString sep = d.mid(qMin(dpos, mpos) + 2, QABS(dpos - mpos) - 2); if (d.count(sep) == 2) { *lDateSep = sep; }#endif }#ifndef Q_WS_WIN QString t = QTime(11, 22, 33).toString(Qt::LocalDate); dpos = t.indexOf(QLatin1String("11")); mpos = t.indexOf(QLatin1String("22")); ypos = t.indexOf(QLatin1String("33")); // We only allow hhmmss if (dpos > -1 && dpos < mpos && mpos < ypos) { QString sep = t.mid(dpos + 2, mpos - dpos - 2); if (sep == t.mid(mpos + 2, ypos - mpos - 2)) { *lTimeSep = sep; } }#endif}static Q3DateEdit::Order localOrder() { if (!lDateSep) { readLocaleSettings(); } return lOrder;}static QString localDateSep() { if (!lDateSep) { readLocaleSettings(); } return *lDateSep;}static QString localTimeSep() { if (!lTimeSep) { readLocaleSettings(); } return *lTimeSep;}class Q3DateTimeEditorPrivate{public: Q3DateTimeEditorPrivate() : frm(true), parag(new Q3TextParagraph(0, 0, 0, false)), focusSec(0) { parag->formatter()->setWrapEnabled(false); cursor = new Q3TextCursor(0); cursor->setParagraph(parag); offset = 0; sep = localDateSep(); refcount++; } ~Q3DateTimeEditorPrivate() { delete parag; delete cursor; if (!--refcount) cleanup(); } void appendSection(const QNumberSection& sec) { sections.append(sec); } void clearSections() { sections.clear(); } void setSectionSelection(int sec, int selstart, int selend) { if (sec < 0 || sec > (int)sections.count()) return; sections[sec].setSelectionStart(selstart); sections[sec].setSelectionEnd(selend); } uint sectionCount() const { return (uint)sections.count(); } void setSeparator(const QString& s) { sep = s; } QString separator() const { return sep; } void setFrame(bool f) { frm = f; } bool frame() const { return frm; } int focusSection() const { return focusSec; } int section(const QPoint& p) { cursor->place(p + QPoint(offset, 0), parag); int idx = cursor->index(); for (int i = 0; i < sections.count(); ++i) { if (idx >= sections[i].selectionStart() && idx <= sections[i].selectionEnd()) return i; } return -1; } QNumberSection section(int idx) const { return sections[idx]; } bool setFocusSection(int idx) { if (idx > (int)sections.count()-1 || idx < 0) return false; if (idx != focusSec) { focusSec = idx; applyFocusSelection(); return true; } return false; } bool inSectionSelection(int idx) { for (int i = 0; i < sections.count(); ++i) { if (idx >= sections[i].selectionStart() && idx <= sections[i].selectionEnd()) return true; } return false; } void paint(const QString& txt, bool focus, QPainter& p, const QPalette&pal, const QRect& rect, QStyle *style) { int fw = 0; if (frm) fw = style->pixelMetric(QStyle::PM_DefaultFrameWidth); parag->truncate(0); parag->append(txt); if (!focus) parag->removeSelection(Q3TextDocument::Standard); else { applyFocusSelection(); } /* color all QDATETIMEEDIT_HIDDEN_CHAR chars to background color */ Q3TextFormat *fb = parag->formatCollection()->format(p.font(), pal.base().color()); Q3TextFormat *nf = parag->formatCollection()->format(p.font(), pal.text().color()); for (int i = 0; i < txt.length(); ++i) { parag->setFormat(i, 1, nf); if (inSectionSelection(i)) continue; if (txt.at(i) == QDATETIMEEDIT_HIDDEN_CHAR) parag->setFormat(i, 1, fb); else parag->setFormat(i, 1, nf); } fb->removeRef(); nf->removeRef(); QRect r(rect.x(), rect.y(), rect.width() - 2 * (2 + fw), rect.height()); parag->pseudoDocument()->docRect = r; parag->invalidate(0); parag->format(); int xoff = 2 + fw - offset; int yoff = (rect.height() - parag->rect().height() + 1) / 2; if (yoff < 0) yoff = 0; p.translate(xoff, yoff); parag->paint(p, pal, 0, true); if (frm) p.translate(-xoff, -yoff); } void resize(const QSize& size) { sz = size; } int mapSection(int sec) { return sections[sec].index(); }protected: void applyFocusSelection() { if (focusSec > -1) { int selstart = sections[focusSec].selectionStart(); int selend = sections[focusSec].selectionEnd(); parag->setSelection(Q3TextDocument::Standard, selstart, selend); parag->format(); if (parag->at(selstart)->x < offset || parag->at(selend)->x + parag->string()->width(selend) > offset + sz.width()) { offset = parag->at(selstart)->x; } } }private: bool frm; Q3TextParagraph *parag; Q3TextCursor *cursor; QSize sz; int focusSec; QList< QNumberSection > sections; QString sep; int offset;};class Q3DateTimeEditor : public QWidget{ Q_OBJECTpublic: Q3DateTimeEditor(Q3DateTimeEditBase *widget, QWidget *parent, const char* name=0); ~Q3DateTimeEditor(); void setControlWidget(Q3DateTimeEditBase * widget); Q3DateTimeEditBase * controlWidget() const; void setSeparator(const QString& s); QString separator() const; int focusSection() const; bool setFocusSection(int s); void appendSection(const QNumberSection& sec); void clearSections(); void setSectionSelection(int sec, int selstart, int selend); bool eventFilter(QObject *o, QEvent *e); int sectionAt(const QPoint &p); int mapSection(int sec);protected: void init(); bool event(QEvent *e); void resizeEvent(QResizeEvent *); void paintEvent(QPaintEvent *); void mousePressEvent(QMouseEvent *e);private: Q3DateTimeEditBase* cw; Q3DateTimeEditorPrivate* d;};class QDateTimeSpinWidget : public Q3SpinWidget{ Q_OBJECTpublic: QDateTimeSpinWidget(QWidget *parent, const char *name) : Q3SpinWidget(parent, name) { } void changeEvent(QEvent *e) { if (e->type() == QEvent::EnabledChange && isEnabled()) { Q3DateEdit *de = ::qobject_cast<Q3DateEdit*>(parentWidget()); if (de) { setUpEnabled(de->date() < de->maxValue()); setDownEnabled(de->date() > de->minValue()); } else { setUpEnabled(true); setDownEnabled(true); } } } void enabledChange(bool notenabled) { Q3DateEdit *de = qobject_cast<Q3DateEdit*>(parentWidget()); if (de && !notenabled) { setUpEnabled(de->date() < de->maxValue()); setDownEnabled(de->date() > de->minValue()); } else { setUpEnabled(!notenabled); setDownEnabled(!notenabled); } }protected:#ifndef QT_NO_WHEELEVENT void wheelEvent(QWheelEvent *e) { Q3DateTimeEditor *editor = qobject_cast<Q3DateTimeEditor*>(editWidget()); Q_ASSERT(editor); if (!editor) return; int section = editor->sectionAt(e->pos()); editor->setFocusSection(section); if (section == -1) return; Q3SpinWidget::wheelEvent(e); }#endif};/*! Constructs an empty datetime editor with parent \a parent and called \a name.*/Q3DateTimeEditor::Q3DateTimeEditor(Q3DateTimeEditBase *widget, QWidget *parent, const char * name) : QWidget(parent, name){ d = new Q3DateTimeEditorPrivate(); cw = widget; init();}/*! Destroys the object and frees any allocated resources.*/Q3DateTimeEditor::~Q3DateTimeEditor(){ delete d;}/*! \internal*/void Q3DateTimeEditor::init(){ setBackgroundRole(QPalette::Base); setFocusSection(-1); installEventFilter(this); setFocusPolicy(Qt::WheelFocus);}/*! \reimp*/bool Q3DateTimeEditor::event(QEvent *e){ if (e->type() == QEvent::FocusIn || e->type() == QEvent::FocusOut) { if (e->type() == QEvent::FocusOut) qApp->sendEvent(cw, e); update(rect()); } else if (e->type() == QEvent::ShortcutOverride) { QKeyEvent* ke = (QKeyEvent*) e; switch (ke->key()) { case Qt::Key_Delete: case Qt::Key_Backspace: case Qt::Key_Up: case Qt::Key_Down: case Qt::Key_Left: case Qt::Key_Right: ke->accept(); default: break; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -