diff --git a/autotests/kcolorbuttontest.cpp b/autotests/kcolorbuttontest.cpp index b3bd029..22d8d9d 100644 --- a/autotests/kcolorbuttontest.cpp +++ b/autotests/kcolorbuttontest.cpp @@ -1,143 +1,143 @@ /* Copyright 2013 Albert Astals Cid This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kcolorbuttontest.h" #include #include #include #include #include QTEST_MAIN(KColorButtonTest) static void workaround() { // Workaround for Qt-5.1 bug, which assumes GTK if there's no running desktop. // (and apparently QTest::qWaitForWindowExposed doesn't work for GTK native dialogs) qputenv("XDG_CURRENT_DESKTOP", "KDE"); // TODO: it means this test will always fail with native dialogs, though. // But we can't set QColorDialog::DontUseNativeDialog from here... } Q_CONSTRUCTOR_FUNCTION(workaround) void KColorButtonTest::initTestCase() { black40Colors.setHsv(-1, 0, 0); } void KColorButtonTest::testChangeAndCancel() { KColorButton colorButton(Qt::red); colorButton.show(); QVERIFY(QTest::qWaitForWindowExposed(&colorButton)); QTest::mouseClick(&colorButton, Qt::LeftButton); QColorDialog *dialog = colorButton.findChild(); - QVERIFY(dialog != NULL); + QVERIFY(dialog != nullptr); QVERIFY(QTest::qWaitForWindowExposed(dialog)); #pragma message("port to QColorDialog") #if 0 KColorCells *cells = dialog->findChild(); QVERIFY(cells != NULL); QTest::mouseClick(cells->viewport(), Qt::LeftButton, 0, QPoint(1, 1)); QCOMPARE(dialog->color(), black40Colors); dialog->reject(); QCOMPARE(colorButton.color(), QColor(Qt::red)); #endif } void KColorButtonTest::testDoubleClickChange() { KColorButton colorButton(Qt::red); colorButton.show(); QVERIFY(QTest::qWaitForWindowExposed(&colorButton)); QTest::mouseClick(&colorButton, Qt::LeftButton); QColorDialog *dialog = colorButton.findChild(); if (!dialog) { qWarning() << "No QColorDialog was found! topLevelWidgets=" << QApplication::topLevelWidgets() << "children of colorbutton=" << colorButton.children(); } - QVERIFY(dialog != NULL); + QVERIFY(dialog != nullptr); QVERIFY(QTest::qWaitForWindowExposed(dialog)); #pragma message("port to QColorDialog") #if 0 KColorCells *cells = dialog->findChild(); QVERIFY(cells != NULL); QTest::mouseDClick(cells->viewport(), Qt::LeftButton, 0, QPoint(1, 1)); QCOMPARE(colorButton.color(), black40Colors); #endif } void KColorButtonTest::testOkChange() { KColorButton colorButton(Qt::red); colorButton.show(); QVERIFY(QTest::qWaitForWindowExposed(&colorButton)); QTest::mouseClick(&colorButton, Qt::LeftButton); QColorDialog *dialog = colorButton.findChild(); - QVERIFY(dialog != NULL); + QVERIFY(dialog != nullptr); QVERIFY(QTest::qWaitForWindowExposed(dialog)); #pragma message("port to QColorDialog") #if 0 KColorCells *cells = dialog->findChild(); QVERIFY(cells != NULL); QTest::mouseClick(cells->viewport(), Qt::LeftButton, 0, QPoint(1, 1)); QCOMPARE(dialog->color(), black40Colors); QSignalSpy okClickedSpy(dialog, SIGNAL(okClicked())); const QDialogButtonBox *buttonBox = dialog->findChild(); const QList buttons = buttonBox->buttons(); foreach (QAbstractButton *button, buttons) { if (buttonBox->buttonRole(button) == QDialogButtonBox::AcceptRole) { QTest::mouseClick(button, Qt::LeftButton); break; } } QCOMPARE(okClickedSpy.count(), 1); QCOMPARE(colorButton.color(), black40Colors); #endif } void KColorButtonTest::testRecentColorsPick() { KColorButton colorButton(Qt::red); colorButton.show(); QVERIFY(QTest::qWaitForWindowExposed(&colorButton)); QTest::mouseClick(&colorButton, Qt::LeftButton); QColorDialog *dialog = colorButton.findChild(); - QVERIFY(dialog != NULL); + QVERIFY(dialog != nullptr); QVERIFY(QTest::qWaitForWindowExposed(dialog)); #pragma message("port to QColorDialog") #if 0 QComboBox *combo = dialog->findChild(); combo->setFocus(); QTest::keyPress(combo, Qt::Key_Up); QTest::keyPress(combo, Qt::Key_Up); KColorCells *cells = dialog->findChild(); QVERIFY(cells != NULL); QTest::mouseMove(cells->viewport(), QPoint(1, 1)); QTest::mouseClick(cells->viewport(), Qt::LeftButton, 0, QPoint(30, 1)); const QColor color = dialog->color(); dialog->accept(); QCOMPARE(colorButton.color(), color); #endif } diff --git a/autotests/kdatecomboboxtest.cpp b/autotests/kdatecomboboxtest.cpp index 07bb16c..434eaa5 100644 --- a/autotests/kdatecomboboxtest.cpp +++ b/autotests/kdatecomboboxtest.cpp @@ -1,163 +1,163 @@ /* Copyright 2011 John Layt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kdatecomboboxtest.h" #include #include #include #include "kdatecombobox.h" QTEST_MAIN(KDateComboBoxTest) void KDateComboBoxTest::testDefaults() { - m_combo = new KDateComboBox(0); + m_combo = new KDateComboBox(nullptr); QCOMPARE(m_combo->date(), QDate::currentDate()); // Missing support in QLocale; //QCOMPARE(m_combo->minimumDate(), KLocale::global()->calendar()->earliestValidDate()); //QCOMPARE(m_combo->maximumDate(), KLocale::global()->calendar()->latestValidDate()); QCOMPARE(m_combo->isValid(), true); QCOMPARE(m_combo->isNull(), false); QCOMPARE(m_combo->options(), KDateComboBox::EditDate | KDateComboBox::SelectDate | KDateComboBox::DatePicker | KDateComboBox::DateKeywords); QCOMPARE(m_combo->displayFormat(), QLocale::ShortFormat); delete m_combo; } void KDateComboBoxTest::testValidNull() { - m_combo = new KDateComboBox(0); + m_combo = new KDateComboBox(nullptr); QCOMPARE(m_combo->isValid(), true); QCOMPARE(m_combo->isNull(), false); m_combo->setDate(QDate()); QCOMPARE(m_combo->isValid(), false); QCOMPARE(m_combo->isNull(), true); m_combo->setDate(QDate(2000, 1, 1)); m_combo->lineEdit()->setText(QStringLiteral("invalid")); QCOMPARE(m_combo->isValid(), false); QCOMPARE(m_combo->isNull(), false); delete m_combo; } void KDateComboBoxTest::testDateRange() { - m_combo = new KDateComboBox(0); + m_combo = new KDateComboBox(nullptr); m_combo->setDate(QDate(2000, 1, 1)); // Missing support in QLocale; //QCOMPARE(m_combo->minimumDate(), KLocale::global()->calendar()->earliestValidDate()); //QCOMPARE(m_combo->maximumDate(), KLocale::global()->calendar()->latestValidDate()); QCOMPARE(m_combo->isValid(), true); m_combo->setDateRange(QDate(2001, 1, 1), QDate(2002, 1, 1)); QCOMPARE(m_combo->minimumDate(), QDate(2001, 1, 1)); QCOMPARE(m_combo->maximumDate(), QDate(2002, 1, 1)); QCOMPARE(m_combo->isValid(), false); m_combo->setDate(QDate(2003, 1, 1)); QCOMPARE(m_combo->isValid(), false); m_combo->setDate(QDate(2001, 6, 1)); QCOMPARE(m_combo->isValid(), true); m_combo->setDate(QDate(2001, 1, 1)); QCOMPARE(m_combo->isValid(), true); m_combo->setDate(QDate(2002, 1, 1)); QCOMPARE(m_combo->isValid(), true); m_combo->setDate(QDate(2000, 12, 31)); QCOMPARE(m_combo->isValid(), false); m_combo->setDate(QDate(2002, 1, 2)); QCOMPARE(m_combo->isValid(), false); m_combo->setDateRange(QDate(1995, 1, 1), QDate(1990, 1, 1)); QCOMPARE(m_combo->minimumDate(), QDate(2001, 1, 1)); QCOMPARE(m_combo->maximumDate(), QDate(2002, 1, 1)); m_combo->setMinimumDate(QDate(2000, 1, 1)); QCOMPARE(m_combo->minimumDate(), QDate(2000, 1, 1)); QCOMPARE(m_combo->maximumDate(), QDate(2002, 1, 1)); m_combo->setMaximumDate(QDate(2003, 1, 1)); QCOMPARE(m_combo->minimumDate(), QDate(2000, 1, 1)); QCOMPARE(m_combo->maximumDate(), QDate(2003, 1, 1)); m_combo->resetDateRange(); QVERIFY(!m_combo->minimumDate().isValid()); QVERIFY(!m_combo->maximumDate().isValid()); // Check functioning when the minimum or maximum date is not already set m_combo->setMinimumDate(QDate(2000, 1, 1)); QCOMPARE(m_combo->minimumDate(), QDate(2000, 1, 1)); QVERIFY(!m_combo->maximumDate().isValid()); m_combo->resetMinimumDate(); QVERIFY(!m_combo->minimumDate().isValid()); QVERIFY(!m_combo->maximumDate().isValid()); m_combo->setMaximumDate(QDate(2003, 1, 1)); QVERIFY(!m_combo->minimumDate().isValid()); QCOMPARE(m_combo->maximumDate(), QDate(2003, 1, 1)); m_combo->resetMaximumDate(); QVERIFY(!m_combo->minimumDate().isValid()); QVERIFY(!m_combo->maximumDate().isValid()); delete m_combo; } void KDateComboBoxTest::testDateList() { - m_combo = new KDateComboBox(0); + m_combo = new KDateComboBox(nullptr); QMap map; // Test default map QCOMPARE(m_combo->dateMap(), map); // Test basic map map.clear(); map.insert(QDate(2000, 1, 1), QStringLiteral("New Years Day")); map.insert(QDate(2000, 1, 2), QString()); map.insert(QDate(2000, 1, 3), QStringLiteral("separator")); map.insert(QDate(), QStringLiteral("No Date")); m_combo->setDateMap(map); QCOMPARE(m_combo->dateMap(), map); delete m_combo; } void KDateComboBoxTest::testOptions() { - m_combo = new KDateComboBox(0); + m_combo = new KDateComboBox(nullptr); KDateComboBox::Options options = KDateComboBox::EditDate | KDateComboBox::SelectDate | KDateComboBox::DatePicker | KDateComboBox::DateKeywords; QCOMPARE(m_combo->options(), options); options = KDateComboBox::EditDate | KDateComboBox::WarnOnInvalid; m_combo->setOptions(options); QCOMPARE(m_combo->options(), options); delete m_combo; } void KDateComboBoxTest::testDisplayFormat() { - m_combo = new KDateComboBox(0); + m_combo = new KDateComboBox(nullptr); QLocale::FormatType format = QLocale::ShortFormat; QCOMPARE(m_combo->displayFormat(), format); format = QLocale::NarrowFormat; m_combo->setDisplayFormat(format); QCOMPARE(m_combo->displayFormat(), format); delete m_combo; } diff --git a/autotests/kdatetimeedittest.cpp b/autotests/kdatetimeedittest.cpp index a8b0b1f..3e6b050 100644 --- a/autotests/kdatetimeedittest.cpp +++ b/autotests/kdatetimeedittest.cpp @@ -1,257 +1,257 @@ /* Copyright 2011 John Layt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kdatetimeedittest.h" #include #include #include #include #include #include "kdatetimeedit.h" #include "kdatecombobox.h" QTEST_MAIN(KDateTimeEditTest) void KDateTimeEditTest::testDefaults() { - m_edit = new KDateTimeEdit(0); + m_edit = new KDateTimeEdit(nullptr); QCOMPARE(m_edit->dateTime(), QDateTime(QDate::currentDate(), QTime(0, 0, 0))); QCOMPARE(m_edit->date(), QDate::currentDate()); QCOMPARE(m_edit->time(), QTime(0, 0, 0)); // Missing support in QLocale //QCOMPARE(m_edit->minimumDateTime(), KDateTime(KLocale::global()->calendar()->earliestValidDate(), QTime(0, 0, 0))); //QCOMPARE(m_edit->maximumDateTime(), KDateTime(KLocale::global()->calendar()->latestValidDate(), QTime(23, 59, 59, 999))); QCOMPARE(m_edit->isValid(), true); QCOMPARE(m_edit->isNull(), false); QCOMPARE(m_edit->options(), KDateTimeEdit::ShowDate | KDateTimeEdit::EditDate | KDateTimeEdit::SelectDate | KDateTimeEdit::DatePicker | KDateTimeEdit::DateKeywords | KDateTimeEdit::ShowTime | KDateTimeEdit::EditTime | KDateTimeEdit::SelectTime); QCOMPARE(m_edit->dateDisplayFormat(), QLocale::ShortFormat); QCOMPARE(m_edit->timeListInterval(), 15); QCOMPARE(m_edit->timeDisplayFormat(), QLocale::ShortFormat); delete m_edit; } void KDateTimeEditTest::testValidNull() { - m_edit = new KDateTimeEdit(0); + m_edit = new KDateTimeEdit(nullptr); QCOMPARE(m_edit->isValid(), true); QCOMPARE(m_edit->isNull(), false); m_edit->setDateTime(QDateTime()); QCOMPARE(m_edit->isValid(), false); QCOMPARE(m_edit->isNull(), true); delete m_edit; } void KDateTimeEditTest::testDateTimeRange() { - m_edit = new KDateTimeEdit(0); + m_edit = new KDateTimeEdit(nullptr); m_edit->setDateTime(QDateTime(QDate(2000, 1, 1), QTime(12, 0, 0))); // Missing support in QLocale //QCOMPARE(m_edit->minimumDateTime(), KDateTime(KLocale::global()->calendar()->earliestValidDate(), QTime(0, 0, 0))); //QCOMPARE(m_edit->maximumDateTime(), KDateTime(KLocale::global()->calendar()->latestValidDate(), QTime(23, 59, 59, 999))); QCOMPARE(m_edit->isValid(), true); m_edit->setDateTimeRange(QDateTime(QDate(2001, 1, 1), QTime(10, 0, 0)), QDateTime(QDate(2002, 1, 1), QTime(20, 0, 0))); QCOMPARE(m_edit->minimumDateTime(), QDateTime(QDate(2001, 1, 1), QTime(10, 0, 0))); QCOMPARE(m_edit->maximumDateTime(), QDateTime(QDate(2002, 1, 1), QTime(20, 0, 0))); QCOMPARE(m_edit->isValid(), false); m_edit->setDateTime(QDateTime(QDate(2001, 1, 1), QTime(9, 59, 59, 999))); QCOMPARE(m_edit->isValid(), false); m_edit->setDateTime(QDateTime(QDate(2001, 1, 1), QTime(10, 0, 0))); QCOMPARE(m_edit->isValid(), true); m_edit->setDateTime(QDateTime(QDate(2002, 1, 1), QTime(20, 0, 0, 1))); QCOMPARE(m_edit->isValid(), false); m_edit->setDateTime(QDateTime(QDate(2002, 1, 1), QTime(20, 0, 0, 0))); QCOMPARE(m_edit->isValid(), true); m_edit->setDateTimeRange(QDateTime(QDate(1995, 1, 1), QTime(10, 0, 0)), QDateTime(QDate(1990, 1, 1), QTime(20, 0, 0))); QCOMPARE(m_edit->minimumDateTime(), QDateTime(QDate(2001, 1, 1), QTime(10, 0, 0))); QCOMPARE(m_edit->maximumDateTime(), QDateTime(QDate(2002, 1, 1), QTime(20, 0, 0))); m_edit->setMinimumDateTime(QDateTime(QDate(2000, 1, 1), QTime(0, 0, 0))); QCOMPARE(m_edit->minimumDateTime(), QDateTime(QDate(2000, 1, 1), QTime(0, 0, 0))); QCOMPARE(m_edit->maximumDateTime(), QDateTime(QDate(2002, 1, 1), QTime(20, 0, 0))); m_edit->setMaximumDateTime(QDateTime(QDate(2003, 1, 1), QTime(0, 0, 0))); QCOMPARE(m_edit->minimumDateTime(), QDateTime(QDate(2000, 1, 1), QTime(0, 0, 0))); QCOMPARE(m_edit->maximumDateTime(), QDateTime(QDate(2003, 1, 1), QTime(0, 0, 0))); delete m_edit; } void KDateTimeEditTest::testDateList() { - m_edit = new KDateTimeEdit(0); + m_edit = new KDateTimeEdit(nullptr); QMap map; // KDateTimeEditTest default map QCOMPARE(m_edit->dateMap(), map); // KDateTimeEditTest basic map map.clear(); map.insert(QDate(2000, 1, 1), QStringLiteral("New Years Day")); map.insert(QDate(2000, 1, 2), QString()); map.insert(QDate(2000, 1, 3), QStringLiteral("separator")); map.insert(QDate(), QStringLiteral("No Date")); m_edit->setDateMap(map); QCOMPARE(m_edit->dateMap(), map); delete m_edit; } void KDateTimeEditTest::testOptions() { - m_edit = new KDateTimeEdit(0); + m_edit = new KDateTimeEdit(nullptr); KDateTimeEdit::Options options = KDateTimeEdit::ShowDate | KDateTimeEdit::EditDate | KDateTimeEdit::SelectDate | KDateTimeEdit::DatePicker | KDateTimeEdit::DateKeywords | KDateTimeEdit::ShowTime | KDateTimeEdit::EditTime | KDateTimeEdit::SelectTime; QCOMPARE(m_edit->options(), options); options = KDateTimeEdit::EditDate | KDateTimeEdit::WarnOnInvalid; m_edit->setOptions(options); QCOMPARE(m_edit->options(), options); delete m_edit; } void KDateTimeEditTest::testDateDisplayFormat() { - m_edit = new KDateTimeEdit(0); + m_edit = new KDateTimeEdit(nullptr); QLocale::FormatType format = QLocale::ShortFormat; QCOMPARE(m_edit->dateDisplayFormat(), format); format = QLocale::NarrowFormat; m_edit->setDateDisplayFormat(format); QCOMPARE(m_edit->dateDisplayFormat(), format); delete m_edit; } void KDateTimeEditTest::testTimeListInterval() { m_edit = new KDateTimeEdit(); QCOMPARE(m_edit->timeListInterval(), 15); m_edit-> setTimeListInterval(60); QCOMPARE(m_edit->timeListInterval(), 60); delete m_edit; } void KDateTimeEditTest::testTimeList() { m_edit = new KDateTimeEdit(); QList list; // KDateTimeEditTest default list QTime thisTime = QTime(0, 0, 0); for (int i = 0; i < 1440; i = i + 15) { list << thisTime.addSecs(i * 60); } list << QTime(23, 59, 59, 999); QCOMPARE(m_edit->timeList(), list); // KDateTimeEditTest basic list list.clear(); list << QTime(3, 0, 0) << QTime(15, 16, 17); m_edit->setTimeList(list); QCOMPARE(m_edit->timeList(), list); delete m_edit; } void KDateTimeEditTest::testTimeDisplayFormat() { m_edit = new KDateTimeEdit(); QLocale::FormatType format = QLocale::ShortFormat; QCOMPARE(m_edit->timeDisplayFormat(), format); format = QLocale::NarrowFormat; m_edit->setTimeDisplayFormat(format); QCOMPARE(m_edit->timeDisplayFormat(), format); delete m_edit; } void KDateTimeEditTest::testCalendarSystem() { m_edit = new KDateTimeEdit(); QList calendars; calendars << QLocale(); QCOMPARE(m_edit->locale(), QLocale()); QCOMPARE(m_edit->calendarLocalesList(), calendars); m_edit->setLocale(QLocale(QLocale::Hebrew)); QCOMPARE(m_edit->locale(), QLocale(QLocale::Hebrew)); calendars.clear(); calendars.append(QLocale(QLocale::Hebrew)); calendars.append(QLocale(QLocale::Chinese)); m_edit->setCalendarLocalesList(calendars); QCOMPARE(m_edit->calendarLocalesList(), calendars); delete m_edit; } void KDateTimeEditTest::testTimeSpec() { m_edit = new KDateTimeEdit(); QCOMPARE(m_edit->timeZone(), QDateTime::currentDateTime().timeZone()); QList zones; foreach (const QByteArray &zoneId, QTimeZone::availableTimeZoneIds()) { zones << QTimeZone(zoneId); } QCOMPARE(m_edit->timeZones(), zones); QTimeZone zone(3600); m_edit->setTimeZone(zone); QCOMPARE(m_edit->timeZone(), zone); zones << zone; m_edit->setTimeZones(zones); QCOMPARE(m_edit->timeZones(), zones); delete m_edit; } template static T findVisibleChild(QWidget *parent) { foreach (T child, parent->findChildren()) { if (child->isVisible()) { return child; } } - return 0; + return nullptr; } void KDateTimeEditTest::testDateMenu() { m_edit = new KDateTimeEdit(); KDateTimeEdit::Options options = KDateTimeEdit::ShowDate | KDateTimeEdit::EditDate | KDateTimeEdit::SelectDate | KDateTimeEdit::DatePicker | KDateTimeEdit::DateKeywords; m_edit->setOptions(options); m_edit->setDate(QDate(2002, 1, 1)); m_edit->show(); QComboBox *combo = findVisibleChild(m_edit); QVERIFY(combo); combo->showPopup(); QMenu *menu = findVisibleChild(combo); QVERIFY(menu); QAction *nextMonthAction = menu->actions().at(3); QCOMPARE(nextMonthAction->text(), KDateComboBox::tr("Next Month", "@option next month")); nextMonthAction->trigger(); QCOMPARE(m_edit->date(), QDate::currentDate().addMonths(1)); } diff --git a/autotests/kdualactiontest.cpp b/autotests/kdualactiontest.cpp index ead2c9b..02a1d91 100644 --- a/autotests/kdualactiontest.cpp +++ b/autotests/kdualactiontest.cpp @@ -1,129 +1,129 @@ /* This file is part of the KDE libraries * * Copyright (c) 2010 Aurélien Gâteau * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA */ #include #include #include "kguiitem.h" static const QString INACTIVE_TEXT = QStringLiteral("Show Foo"); static const QString ACTIVE_TEXT = QStringLiteral("Hide Foo"); class KDualActionTest : public QObject { Q_OBJECT private Q_SLOTS: void initTestCase() { qRegisterMetaType("QAction*"); } void testSetGuiItem() { - KDualAction action(0); + KDualAction action(nullptr); action.setInactiveGuiItem(KGuiItem(INACTIVE_TEXT)); action.setActiveGuiItem(KGuiItem(ACTIVE_TEXT)); QCOMPARE(action.inactiveText(), INACTIVE_TEXT); QCOMPARE(action.activeText(), ACTIVE_TEXT); QCOMPARE(action.text(), INACTIVE_TEXT); } void testSetIconForStates() { QIcon icon(QPixmap(16, 16)); QVERIFY(!icon.isNull()); - KDualAction action(0); + KDualAction action(nullptr); QVERIFY(action.inactiveIcon().isNull()); QVERIFY(action.activeIcon().isNull()); action.setIconForStates(icon); QCOMPARE(action.inactiveIcon(), icon); QCOMPARE(action.activeIcon(), icon); } void testSetActive() { - KDualAction action(INACTIVE_TEXT, ACTIVE_TEXT, 0); + KDualAction action(INACTIVE_TEXT, ACTIVE_TEXT, nullptr); QVERIFY(!action.isActive()); QCOMPARE(action.text(), INACTIVE_TEXT); QSignalSpy activeChangedSpy(&action, SIGNAL(activeChanged(bool))); QSignalSpy activeChangedByUserSpy(&action, SIGNAL(activeChangedByUser(bool))); action.setActive(true); QVERIFY(action.isActive()); QCOMPARE(action.text(), ACTIVE_TEXT); QCOMPARE(activeChangedSpy.count(), 1); QCOMPARE(activeChangedSpy.takeFirst().at(0).toBool(), true); QCOMPARE(activeChangedByUserSpy.count(), 0); action.setActive(false); QVERIFY(!action.isActive()); QCOMPARE(action.text(), INACTIVE_TEXT); QCOMPARE(activeChangedSpy.count(), 1); QCOMPARE(activeChangedSpy.takeFirst().at(0).toBool(), false); QCOMPARE(activeChangedByUserSpy.count(), 0); } void testTrigger() { - KDualAction action(INACTIVE_TEXT, ACTIVE_TEXT, 0); + KDualAction action(INACTIVE_TEXT, ACTIVE_TEXT, nullptr); QVERIFY(!action.isActive()); QCOMPARE(action.text(), INACTIVE_TEXT); QSignalSpy activeChangedSpy(&action, SIGNAL(activeChanged(bool))); QSignalSpy activeChangedByUserSpy(&action, SIGNAL(activeChangedByUser(bool))); action.trigger(); QVERIFY(action.isActive()); QCOMPARE(action.text(), ACTIVE_TEXT); QCOMPARE(activeChangedSpy.count(), 1); QCOMPARE(activeChangedSpy.takeFirst().at(0).toBool(), true); QCOMPARE(activeChangedByUserSpy.count(), 1); QCOMPARE(activeChangedByUserSpy.takeFirst().at(0).toBool(), true); action.trigger(); QVERIFY(!action.isActive()); QCOMPARE(action.text(), INACTIVE_TEXT); QCOMPARE(activeChangedSpy.count(), 1); QCOMPARE(activeChangedSpy.takeFirst().at(0).toBool(), false); QCOMPARE(activeChangedByUserSpy.count(), 1); QCOMPARE(activeChangedByUserSpy.takeFirst().at(0).toBool(), false); // Turn off autoToggle, nothing should happen action.setAutoToggle(false); action.trigger(); QVERIFY(!action.isActive()); QCOMPARE(action.text(), INACTIVE_TEXT); QCOMPARE(activeChangedSpy.count(), 0); QCOMPARE(activeChangedByUserSpy.count(), 0); // Turn on autoToggle, action should change action.setAutoToggle(true); action.trigger(); QCOMPARE(action.text(), ACTIVE_TEXT); QCOMPARE(activeChangedSpy.count(), 1); QCOMPARE(activeChangedSpy.takeFirst().at(0).toBool(), true); QCOMPARE(activeChangedByUserSpy.count(), 1); QCOMPARE(activeChangedByUserSpy.takeFirst().at(0).toBool(), true); } }; QTEST_MAIN(KDualActionTest) #include "kdualactiontest.moc" diff --git a/autotests/kselectaction_unittest.cpp b/autotests/kselectaction_unittest.cpp index 9cc1e83..7cd6301 100644 --- a/autotests/kselectaction_unittest.cpp +++ b/autotests/kselectaction_unittest.cpp @@ -1,329 +1,329 @@ /* This file is part of the KDE libraries Copyright (c) 2009 Daniel Calviño Sánchez This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kselectaction_unittest.h" #include #include #include #include #include QTEST_MAIN(KSelectAction_UnitTest) void KSelectAction_UnitTest::testSetToolTipBeforeRequestingComboBoxWidget() { - KSelectAction selectAction(QStringLiteral("selectAction"), 0); + KSelectAction selectAction(QStringLiteral("selectAction"), nullptr); selectAction.setToolBarMode(KSelectAction::ComboBoxMode); selectAction.setToolTip(QStringLiteral("Test")); selectAction.setEnabled(false); // also test disabling the action QWidget parent; QWidget *widget = selectAction.requestWidget(&parent); QVERIFY(widget); QComboBox *comboBox = qobject_cast(widget); QVERIFY(comboBox); QCOMPARE(comboBox->toolTip(), QStringLiteral("Test")); QCOMPARE(comboBox->isEnabled(), false); } void KSelectAction_UnitTest::testSetToolTipAfterRequestingComboBoxWidget() { - KSelectAction selectAction(QStringLiteral("selectAction"), 0); + KSelectAction selectAction(QStringLiteral("selectAction"), nullptr); selectAction.setToolBarMode(KSelectAction::ComboBoxMode); QWidget parent; QWidget *widget = selectAction.requestWidget(&parent); selectAction.setToolTip(QStringLiteral("Test")); selectAction.setEnabled(false); // also test disabling the action QVERIFY(widget); QComboBox *comboBox = qobject_cast(widget); QVERIFY(comboBox); QCOMPARE(comboBox->toolTip(), QStringLiteral("Test")); QCOMPARE(comboBox->isEnabled(), false); } void KSelectAction_UnitTest::testSetToolTipBeforeRequestingToolButtonWidget() { - KSelectAction selectAction(QStringLiteral("selectAction"), 0); + KSelectAction selectAction(QStringLiteral("selectAction"), nullptr); selectAction.setToolBarMode(KSelectAction::MenuMode); selectAction.setToolTip(QStringLiteral("Test")); QToolBar toolBar; //Don't use requestWidget, as it needs a releaseWidget when used in MenuMode //(in ComboBoxMode the widget is released automatically when it is //destroyed). When the action is added to the QToolBar, it requests and //releases the widget as needed. toolBar.addAction(&selectAction); QWidget *widget = toolBar.widgetForAction(&selectAction); QVERIFY(widget); QToolButton *toolButton = qobject_cast(widget); QVERIFY(toolButton); QCOMPARE(toolButton->toolTip(), QStringLiteral("Test")); } void KSelectAction_UnitTest::testSetToolTipAfterRequestingToolButtonWidget() { - KSelectAction selectAction(QStringLiteral("selectAction"), 0); + KSelectAction selectAction(QStringLiteral("selectAction"), nullptr); selectAction.setToolBarMode(KSelectAction::MenuMode); QToolBar toolBar; //Don't use requestWidget, as it needs a releaseWidget when used in MenuMode //(in ComboBoxMode the widget is released automatically when it is //destroyed). When the action is added to the QToolBar, it requests and //releases the widget as needed. toolBar.addAction(&selectAction); QWidget *widget = toolBar.widgetForAction(&selectAction); selectAction.setToolTip(QStringLiteral("Test")); QVERIFY(widget); QToolButton *toolButton = qobject_cast(widget); QVERIFY(toolButton); QCOMPARE(toolButton->toolTip(), QStringLiteral("Test")); } void KSelectAction_UnitTest::testSetWhatsThisBeforeRequestingComboBoxWidget() { - KSelectAction selectAction(QStringLiteral("selectAction"), 0); + KSelectAction selectAction(QStringLiteral("selectAction"), nullptr); selectAction.setToolBarMode(KSelectAction::ComboBoxMode); selectAction.setWhatsThis(QStringLiteral("Test")); QWidget parent; QWidget *widget = selectAction.requestWidget(&parent); QVERIFY(widget); QComboBox *comboBox = qobject_cast(widget); QVERIFY(comboBox); QCOMPARE(comboBox->whatsThis(), QStringLiteral("Test")); } void KSelectAction_UnitTest::testSetWhatsThisAfterRequestingComboBoxWidget() { - KSelectAction selectAction(QStringLiteral("selectAction"), 0); + KSelectAction selectAction(QStringLiteral("selectAction"), nullptr); selectAction.setToolBarMode(KSelectAction::ComboBoxMode); QWidget parent; QWidget *widget = selectAction.requestWidget(&parent); selectAction.setWhatsThis(QStringLiteral("Test")); QVERIFY(widget); QComboBox *comboBox = qobject_cast(widget); QVERIFY(comboBox); QCOMPARE(comboBox->whatsThis(), QStringLiteral("Test")); } void KSelectAction_UnitTest::testSetWhatsThisBeforeRequestingToolButtonWidget() { - KSelectAction selectAction(QStringLiteral("selectAction"), 0); + KSelectAction selectAction(QStringLiteral("selectAction"), nullptr); selectAction.setToolBarMode(KSelectAction::MenuMode); selectAction.setWhatsThis(QStringLiteral("Test")); QToolBar toolBar; //Don't use requestWidget, as it needs a releaseWidget when used in MenuMode //(in ComboBoxMode the widget is released automatically when it is //destroyed). When the action is added to the QToolBar, it requests and //releases the widget as needed. toolBar.addAction(&selectAction); QWidget *widget = toolBar.widgetForAction(&selectAction); QVERIFY(widget); QToolButton *toolButton = qobject_cast(widget); QVERIFY(toolButton); QCOMPARE(toolButton->whatsThis(), QStringLiteral("Test")); } void KSelectAction_UnitTest::testSetWhatsThisAfterRequestingToolButtonWidget() { - KSelectAction selectAction(QStringLiteral("selectAction"), 0); + KSelectAction selectAction(QStringLiteral("selectAction"), nullptr); selectAction.setToolBarMode(KSelectAction::MenuMode); QToolBar toolBar; //Don't use requestWidget, as it needs a releaseWidget when used in MenuMode //(in ComboBoxMode the widget is released automatically when it is //destroyed). When the action is added to the QToolBar, it requests and //releases the widget as needed. toolBar.addAction(&selectAction); QWidget *widget = toolBar.widgetForAction(&selectAction); selectAction.setWhatsThis(QStringLiteral("Test")); QVERIFY(widget); QToolButton *toolButton = qobject_cast(widget); QVERIFY(toolButton); QCOMPARE(toolButton->whatsThis(), QStringLiteral("Test")); } void KSelectAction_UnitTest::testChildActionStateChangeComboMode() { - KSelectAction selectAction(QStringLiteral("selectAction"), 0); + KSelectAction selectAction(QStringLiteral("selectAction"), nullptr); selectAction.setToolBarMode(KSelectAction::ComboBoxMode); QWidget parent; QWidget *widget = selectAction.requestWidget(&parent); QComboBox *comboBox = qobject_cast(widget); QVERIFY(comboBox); const QString itemText = QStringLiteral("foo"); QAction *childAction = selectAction.addAction(itemText); QCOMPARE(comboBox->itemText(0), itemText); childAction->setEnabled(false); // There's no API for item-is-enabled, need to go via the internal model like kselectaction does... QStandardItemModel *model = qobject_cast(comboBox->model()); QVERIFY(model); QVERIFY(!model->item(0)->isEnabled()); // Now remove the action selectAction.removeAction(childAction); QCOMPARE(comboBox->count(), 0); } void KSelectAction_UnitTest::testRequestWidgetComboBoxModeWidgetParent() { - KSelectAction selectAction(QStringLiteral("selectAction"), 0); + KSelectAction selectAction(QStringLiteral("selectAction"), nullptr); selectAction.setToolBarMode(KSelectAction::ComboBoxMode); QToolBar toolBar; toolBar.addAction(&selectAction); QWidget *widget = toolBar.widgetForAction(&selectAction); QVERIFY(widget); QComboBox *comboBox = qobject_cast(widget); QVERIFY(comboBox); QVERIFY(!comboBox->isEnabled()); } void KSelectAction_UnitTest::testRequestWidgetComboBoxModeWidgetParentSeveralActions() { - KSelectAction selectAction(QStringLiteral("selectAction"), 0); + KSelectAction selectAction(QStringLiteral("selectAction"), nullptr); selectAction.setToolBarMode(KSelectAction::ComboBoxMode); selectAction.addAction(new QAction(QStringLiteral("action1"), &selectAction)); selectAction.addAction(new QAction(QStringLiteral("action2"), &selectAction)); selectAction.addAction(new QAction(QStringLiteral("action3"), &selectAction)); QToolBar toolBar; toolBar.addAction(&selectAction); QWidget *widget = toolBar.widgetForAction(&selectAction); QVERIFY(widget); QComboBox *comboBox = qobject_cast(widget); QVERIFY(comboBox); QVERIFY(comboBox->isEnabled()); } void KSelectAction_UnitTest::testRequestWidgetMenuModeWidgetParent() { - KSelectAction selectAction(QStringLiteral("selectAction"), 0); + KSelectAction selectAction(QStringLiteral("selectAction"), nullptr); selectAction.setToolBarMode(KSelectAction::MenuMode); QToolBar toolBar; toolBar.addAction(&selectAction); QWidget *widget = toolBar.widgetForAction(&selectAction); QVERIFY(widget); QToolButton *toolButton = qobject_cast(widget); QVERIFY(toolButton); QVERIFY(!toolButton->isEnabled()); QVERIFY(toolButton->autoRaise()); QCOMPARE((int)toolButton->focusPolicy(), (int)Qt::NoFocus); QCOMPARE(toolButton->defaultAction(), (QAction *)&selectAction); QCOMPARE(toolButton->actions().count(), 1); QCOMPARE(toolButton->actions().at(0)->text(), QStringLiteral("selectAction")); } void KSelectAction_UnitTest::testRequestWidgetMenuModeWidgetParentSeveralActions() { - KSelectAction selectAction(QStringLiteral("selectAction"), 0); + KSelectAction selectAction(QStringLiteral("selectAction"), nullptr); selectAction.setToolBarMode(KSelectAction::MenuMode); selectAction.addAction(new QAction(QStringLiteral("action1"), &selectAction)); selectAction.addAction(new QAction(QStringLiteral("action2"), &selectAction)); selectAction.addAction(new QAction(QStringLiteral("action3"), &selectAction)); QToolBar toolBar; toolBar.addAction(&selectAction); QWidget *widget = toolBar.widgetForAction(&selectAction); QVERIFY(widget); QToolButton *toolButton = qobject_cast(widget); QVERIFY(toolButton); QVERIFY(toolButton->isEnabled()); QVERIFY(toolButton->autoRaise()); QCOMPARE((int)toolButton->focusPolicy(), (int)Qt::NoFocus); QCOMPARE(toolButton->defaultAction(), (QAction *)&selectAction); QCOMPARE(toolButton->actions().count(), 4); QCOMPARE(toolButton->actions().at(0)->text(), QStringLiteral("selectAction")); QCOMPARE(toolButton->actions().at(1)->text(), QStringLiteral("action1")); QCOMPARE(toolButton->actions().at(2)->text(), QStringLiteral("action2")); QCOMPARE(toolButton->actions().at(3)->text(), QStringLiteral("action3")); } void KSelectAction_UnitTest::testRequestWidgetMenuModeWidgetParentAddActions() { - KSelectAction selectAction(QStringLiteral("selectAction"), 0); + KSelectAction selectAction(QStringLiteral("selectAction"), nullptr); selectAction.setToolBarMode(KSelectAction::MenuMode); QToolBar toolBar; toolBar.addAction(&selectAction); QWidget *widget = toolBar.widgetForAction(&selectAction); QVERIFY(widget); QVERIFY(!widget->isEnabled()); selectAction.addAction(new QAction(QStringLiteral("action1"), &selectAction)); selectAction.addAction(new QAction(QStringLiteral("action2"), &selectAction)); selectAction.addAction(new QAction(QStringLiteral("action3"), &selectAction)); QVERIFY(widget->isEnabled()); QCOMPARE(widget->actions().count(), 4); QCOMPARE(widget->actions().at(0)->text(), QStringLiteral("selectAction")); QCOMPARE(widget->actions().at(1)->text(), QStringLiteral("action1")); QCOMPARE(widget->actions().at(2)->text(), QStringLiteral("action2")); QCOMPARE(widget->actions().at(3)->text(), QStringLiteral("action3")); } void KSelectAction_UnitTest::testRequestWidgetMenuModeWidgetParentRemoveActions() { - KSelectAction selectAction(QStringLiteral("selectAction"), 0); + KSelectAction selectAction(QStringLiteral("selectAction"), nullptr); selectAction.setToolBarMode(KSelectAction::MenuMode); QToolBar toolBar; toolBar.addAction(&selectAction); QWidget *widget = toolBar.widgetForAction(&selectAction); QVERIFY(widget); QAction *action1 = new QAction(QStringLiteral("action1"), &selectAction); selectAction.addAction(action1); QAction *action2 = new QAction(QStringLiteral("action2"), &selectAction); selectAction.addAction(action2); QAction *action3 = new QAction(QStringLiteral("action3"), &selectAction); selectAction.addAction(action3); delete selectAction.removeAction(action1); delete selectAction.removeAction(action2); delete selectAction.removeAction(action3); QVERIFY(!widget->isEnabled()); QCOMPARE(widget->actions().count(), 1); QCOMPARE(widget->actions().at(0)->text(), QStringLiteral("selectAction")); } diff --git a/autotests/ksplittercollapserbuttontest.h b/autotests/ksplittercollapserbuttontest.h index 4c64b79..8f23621 100644 --- a/autotests/ksplittercollapserbuttontest.h +++ b/autotests/ksplittercollapserbuttontest.h @@ -1,58 +1,58 @@ /* Copyright (c) 2014 Montel Laurent This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #ifndef KSPLITTERCOLLAPSERBUTTONTEST_H #define KSPLITTERCOLLAPSERBUTTONTEST_H #include class QSplitter; class QTextEdit; class TestSplitter : public QWidget { Q_OBJECT public: - explicit TestSplitter(QWidget *parent = 0); + explicit TestSplitter(QWidget *parent = nullptr); QSplitter *splitter; QTextEdit *edit1; QTextEdit *edit2; }; class KSplitterCollapserButtonTest : public QObject { Q_OBJECT public: - explicit KSplitterCollapserButtonTest(QObject *parent = 0); + explicit KSplitterCollapserButtonTest(QObject *parent = nullptr); ~KSplitterCollapserButtonTest(); private Q_SLOTS: void shouldHaveDefaultValue(); void shouldCollapseWhenClickOnButton(); void shouldRestoreCorrectPosition(); void shouldRestoreCorrectPositionForFirstWidget(); void shouldTestVerticalSplitterFirstWidget(); void shouldTestVerticalSplitterSecondWidget(); void shouldBeVisible_data(); void shouldBeVisible(); void shouldBeVisibleWhenMovingHandle_data(); void shouldBeVisibleWhenMovingHandle(); }; #endif // KSPLITTERCOLLAPSERBUTTONTEST_H diff --git a/autotests/ktimecomboboxtest.cpp b/autotests/ktimecomboboxtest.cpp index f0cd3f4..b01b14b 100644 --- a/autotests/ktimecomboboxtest.cpp +++ b/autotests/ktimecomboboxtest.cpp @@ -1,186 +1,186 @@ /* Copyright 2011 John Layt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "ktimecomboboxtest.h" #include #include #include #include QTEST_MAIN(KTimeComboBoxTest) void KTimeComboBoxTest::testDefaults() { m_combo = new KTimeComboBox(); QCOMPARE(m_combo->time(), QTime(0, 0, 0, 0)); QCOMPARE(m_combo->minimumTime(), QTime(0, 0, 0, 0)); QCOMPARE(m_combo->maximumTime(), QTime(23, 59, 59, 999)); QCOMPARE(m_combo->isValid(), true); QCOMPARE(m_combo->options(), KTimeComboBox::EditTime | KTimeComboBox::SelectTime); QCOMPARE(m_combo->timeListInterval(), 15); QCOMPARE(m_combo->displayFormat(), QLocale::ShortFormat); delete m_combo; } void KTimeComboBoxTest::testValidNull() { - m_combo = new KTimeComboBox(0); + m_combo = new KTimeComboBox(nullptr); QCOMPARE(m_combo->isValid(), true); QCOMPARE(m_combo->isNull(), false); m_combo->setTime(QTime()); QCOMPARE(m_combo->isValid(), false); QCOMPARE(m_combo->isNull(), true); m_combo->setTime(QTime(0, 0, 0)); m_combo->lineEdit()->setText(QStringLiteral("99:99")); QCOMPARE(m_combo->isValid(), false); QCOMPARE(m_combo->isNull(), false); delete m_combo; } void KTimeComboBoxTest::testTimeRange() { m_combo = new KTimeComboBox(); m_combo->setTime(QTime(2, 0, 0, 0)); QCOMPARE(m_combo->minimumTime(), QTime(0, 0, 0, 0)); QCOMPARE(m_combo->maximumTime(), QTime(23, 59, 59, 999)); QCOMPARE(m_combo->isValid(), true); m_combo->setTimeRange(QTime(3, 0, 0, 0), QTime(22, 0, 0, 0)); QCOMPARE(m_combo->minimumTime(), QTime(3, 0, 0, 0)); QCOMPARE(m_combo->maximumTime(), QTime(22, 0, 0, 0)); QCOMPARE(m_combo->isValid(), false); m_combo->setTime(QTime(23, 0, 0, 0)); QCOMPARE(m_combo->isValid(), false); m_combo->setTime(QTime(12, 0, 0, 0)); QCOMPARE(m_combo->isValid(), true); m_combo->setTime(QTime(3, 0, 0, 0)); QCOMPARE(m_combo->isValid(), true); m_combo->setTime(QTime(22, 0, 0, 0)); QCOMPARE(m_combo->isValid(), true); m_combo->setTime(QTime(2, 59, 59, 999)); QCOMPARE(m_combo->isValid(), false); m_combo->setTime(QTime(22, 1, 0, 0)); QCOMPARE(m_combo->isValid(), false); m_combo->setTimeRange(QTime(15, 0, 0, 0), QTime(5, 0, 0, 0)); QCOMPARE(m_combo->minimumTime(), QTime(3, 0, 0, 0)); QCOMPARE(m_combo->maximumTime(), QTime(22, 0, 0, 0)); m_combo->setMinimumTime(QTime(2, 0, 0, 0)); QCOMPARE(m_combo->minimumTime(), QTime(2, 0, 0, 0)); QCOMPARE(m_combo->maximumTime(), QTime(22, 0, 0, 0)); m_combo->setMaximumTime(QTime(21, 0, 0, 0)); QCOMPARE(m_combo->minimumTime(), QTime(2, 0, 0, 0)); QCOMPARE(m_combo->maximumTime(), QTime(21, 0, 0, 0)); delete m_combo; } void KTimeComboBoxTest::testTimeListInterval() { m_combo = new KTimeComboBox(); QCOMPARE(m_combo->timeListInterval(), 15); m_combo-> setTimeListInterval(60); QCOMPARE(m_combo->timeListInterval(), 60); m_combo-> setTimeListInterval(7); QCOMPARE(m_combo->timeListInterval(), 60); m_combo-> setTimeListInterval(720); QCOMPARE(m_combo->timeListInterval(), 720); QList list; list << QTime(0, 0, 0) << QTime(12, 0, 0) << QTime(23, 59, 59, 999); QCOMPARE(m_combo->timeList(), list); m_combo->setTimeRange(QTime(4, 0, 0, 0), QTime(5, 0, 0, 0)); m_combo-> setTimeListInterval(30); list.clear(); list << QTime(4, 0, 0) << QTime(4, 30, 0) << QTime(5, 0, 0, 0); QCOMPARE(m_combo->timeList(), list); m_combo->setTimeRange(QTime(4, 0, 0, 0), QTime(4, 59, 0, 0)); m_combo-> setTimeListInterval(30); list.clear(); list << QTime(4, 0, 0) << QTime(4, 30, 0) << QTime(4, 59, 0, 0); QCOMPARE(m_combo->timeList(), list); delete m_combo; } void KTimeComboBoxTest::testTimeList() { m_combo = new KTimeComboBox(); QList list; // Test default list QTime thisTime = QTime(0, 0, 0); for (int i = 0; i < 1440; i = i + 15) { list << thisTime.addSecs(i * 60); } list << QTime(23, 59, 59, 999); QCOMPARE(m_combo->timeList(), list); // Test basic list list.clear(); list << QTime(3, 0, 0) << QTime(15, 16, 17); m_combo->setTimeList(list); QCOMPARE(m_combo->timeList(), list); QCOMPARE(m_combo->minimumTime(), QTime(3, 0, 0)); QCOMPARE(m_combo->maximumTime(), QTime(15, 16, 17)); // Test sort input times list.clear(); list << QTime(17, 16, 15) << QTime(4, 0, 0); m_combo->setTimeList(list); qSort(list); QCOMPARE(m_combo->timeList(), list); QCOMPARE(m_combo->minimumTime(), QTime(4, 0, 0)); QCOMPARE(m_combo->maximumTime(), QTime(17, 16, 15)); // Test ignore null QTime list.clear(); list << QTime(3, 0, 0) << QTime(15, 16, 17) << QTime(); m_combo->setTimeList(list); list.takeLast(); QCOMPARE(m_combo->timeList(), list); QCOMPARE(m_combo->minimumTime(), QTime(3, 0, 0)); QCOMPARE(m_combo->maximumTime(), QTime(15, 16, 17)); delete m_combo; } void KTimeComboBoxTest::testOptions() { m_combo = new KTimeComboBox(); KTimeComboBox::Options options = KTimeComboBox::EditTime | KTimeComboBox::SelectTime; QCOMPARE(m_combo->options(), options); options = KTimeComboBox::EditTime | KTimeComboBox::WarnOnInvalid; m_combo->setOptions(options); QCOMPARE(m_combo->options(), options); delete m_combo; } void KTimeComboBoxTest::testDisplayFormat() { m_combo = new KTimeComboBox(); QLocale::FormatType format = QLocale::ShortFormat; QCOMPARE(m_combo->displayFormat(), format); format = QLocale::NarrowFormat; m_combo->setDisplayFormat(format); QCOMPARE(m_combo->displayFormat(), format); delete m_combo; } diff --git a/src/fonthelpers_p.h b/src/fonthelpers_p.h index 0a1aa13..7782ef4 100644 --- a/src/fonthelpers_p.h +++ b/src/fonthelpers_p.h @@ -1,68 +1,68 @@ /* Requires the Qt widget libraries, available at no cost at http://www.troll.no Copyright (C) 2008 Chusslove Illich This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef FONTHELPERS_P_H #define FONTHELPERS_P_H // i18n-related helpers for fonts, common to KFont* widgets. #include #include #include /** * @internal * * Split the compound raw font name into family and foundry. * * @param name the raw font name reported by Qt * @param family the storage for family name * @param foundry the storage for foundry name */ void splitFontString(const QString &name, - QString *family, QString *foundry = NULL); + QString *family, QString *foundry = nullptr); /** * @internal * * Translate the font name for the user. * Primarily for generic fonts like Serif, Sans-Serif, etc. * * @param name the raw font name reported by Qt * @return translated font name */ QString translateFontName(const QString &name); /** * @internal * * Compose locale-aware sorted list of translated font names, * with generic fonts handled in a special way. * The mapping of translated to raw names can be reported too if required. * * @param names raw font names as reported by Qt * @param trToRawNames storage for mapping of translated to raw names * @return sorted list of translated font names */ QStringList translateFontNameList(const QStringList &names, - QHash *trToRawNames = NULL); + QHash *trToRawNames = nullptr); # endif diff --git a/src/kacceleratormanager.cpp b/src/kacceleratormanager.cpp index 0579d46..9a396ba 100644 --- a/src/kacceleratormanager.cpp +++ b/src/kacceleratormanager.cpp @@ -1,834 +1,834 @@ /* This file is part of the KDE project Copyright (C) 2002 Matthias Hölzer-Klüpfel This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kacceleratormanager.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kacceleratormanager_p.h" #include "loggingcategory.h" /********************************************************************* class Item - helper class containing widget information This class stores information about the widgets the need accelerators, as well as about their relationship. *********************************************************************/ bool KAcceleratorManagerPrivate::programmers_mode = false; QString KAcceleratorManagerPrivate::changed_string; QString KAcceleratorManagerPrivate::added_string; QString KAcceleratorManagerPrivate::removed_string; QMap KAcceleratorManagerPrivate::ignored_widgets; QStringList KAcceleratorManagerPrivate::standardNames; void KAcceleratorManagerPrivate::addStandardActionNames(const QStringList &list) { standardNames.append(list); } bool KAcceleratorManagerPrivate::standardName(const QString &str) { return standardNames.contains(str); } KAcceleratorManagerPrivate::Item::~Item() { if (m_children) while (!m_children->isEmpty()) { delete m_children->takeFirst(); } delete m_children; } void KAcceleratorManagerPrivate::Item::addChild(Item *item) { if (!m_children) { m_children = new ItemList; } m_children->append(item); } void KAcceleratorManagerPrivate::manage(QWidget *widget) { if (!widget) { qCDebug(KWidgetsAddonsLog) << "null pointer given to manage"; return; } if (KAcceleratorManagerPrivate::ignored_widgets.contains(widget)) { return; } if (qobject_cast(widget)) { // create a popup accel manager that can deal with dynamic menus KPopupAccelManager::manage(static_cast(widget)); return; } Item *root = new Item; manageWidget(widget, root); QString used; calculateAccelerators(root, used); delete root; } void KAcceleratorManagerPrivate::calculateAccelerators(Item *item, QString &used) { if (!item->m_children) { return; } // collect the contents KAccelStringList contents; Q_FOREACH (Item *it, *item->m_children) { contents << it->m_content; } // find the right accelerators KAccelManagerAlgorithm::findAccelerators(contents, used); // write them back into the widgets int cnt = -1; Q_FOREACH (Item *it, *item->m_children) { cnt++; QDockWidget *dock = qobject_cast(it->m_widget); if (dock) { if (checkChange(contents[cnt])) { dock->setWindowTitle(contents[cnt].accelerated()); } continue; } QTabBar *tabBar = qobject_cast(it->m_widget); if (tabBar) { if (checkChange(contents[cnt])) { tabBar->setTabText(it->m_index, contents[cnt].accelerated()); } continue; } QMenuBar *menuBar = qobject_cast(it->m_widget); if (menuBar) { if (it->m_index >= 0) { QAction *maction = menuBar->actions()[it->m_index]; if (maction) { checkChange(contents[cnt]); maction->setText(contents[cnt].accelerated()); } continue; } } // we possibly reserved an accel, but we won't set it as it looks silly QGroupBox *groupBox = qobject_cast(it->m_widget); if (groupBox && !groupBox->isCheckable()) { continue; } int tprop = it->m_widget->metaObject()->indexOfProperty("text"); if (tprop != -1) { if (checkChange(contents[cnt])) { it->m_widget->setProperty("text", contents[cnt].accelerated()); } } else { tprop = it->m_widget->metaObject()->indexOfProperty("title"); if (tprop != -1 && checkChange(contents[cnt])) { it->m_widget->setProperty("title", contents[cnt].accelerated()); } } } // calculate the accelerators for the children Q_FOREACH (Item *it, *item->m_children) { if (it->m_widget && it->m_widget->isVisibleTo(item->m_widget)) { calculateAccelerators(it, used); } } } void KAcceleratorManagerPrivate::traverseChildren(QWidget *widget, Item *item) { QList childList = widget->findChildren(); Q_FOREACH (QWidget *w, childList) { // Ignore unless we have the direct parent if (qobject_cast(w->parent()) != widget) { continue; } - if (!w->isVisibleTo(widget) || (w->isTopLevel() && qobject_cast(w) == NULL)) { + if (!w->isVisibleTo(widget) || (w->isTopLevel() && qobject_cast(w) == nullptr)) { continue; } if (KAcceleratorManagerPrivate::ignored_widgets.contains(w)) { continue; } manageWidget(w, item); } } void KAcceleratorManagerPrivate::manageWidget(QWidget *w, Item *item) { // first treat the special cases QTabBar *tabBar = qobject_cast(w); if (tabBar) { manageTabBar(tabBar, item); return; } QStackedWidget *wds = qobject_cast(w); if (wds) { QWidgetStackAccelManager::manage(wds); // return; } QDockWidget *dock = qobject_cast(w); if (dock) { //QWidgetStackAccelManager::manage( wds ); manageDockWidget(dock, item); } QMenu *popupMenu = qobject_cast(w); if (popupMenu) { // create a popup accel manager that can deal with dynamic menus KPopupAccelManager::manage(popupMenu); return; } QStackedWidget *wdst = qobject_cast(w); if (wdst) { QWidgetStackAccelManager::manage(wdst); // return; } QMenuBar *menuBar = qobject_cast(w); if (menuBar) { manageMenuBar(menuBar, item); return; } if (qobject_cast(w) || qobject_cast(w) || w->inherits("Q3TextEdit") || qobject_cast(w) || qobject_cast(w) || w->inherits("KMultiTabBar") || w->inherits("qdesigner_internal::TextPropertyEditor")) { return; } if (w->inherits("KUrlRequester")) { traverseChildren(w, item); return; } // now treat 'ordinary' widgets QLabel *label = qobject_cast(w); if (label) { if (!label->buddy()) { return; } else { if (label->textFormat() == Qt::RichText || (label->textFormat() == Qt::AutoText && Qt::mightBeRichText(label->text()))) { return; } } } if (w->focusPolicy() != Qt::NoFocus || label || qobject_cast(w) || qobject_cast(w)) { QString content; QVariant variant; int tprop = w->metaObject()->indexOfProperty("text"); if (tprop != -1) { QMetaProperty p = w->metaObject()->property(tprop); if (p.isValid() && p.isWritable()) { variant = p.read(w); } else { tprop = -1; } } if (tprop == -1) { tprop = w->metaObject()->indexOfProperty("title"); if (tprop != -1) { QMetaProperty p = w->metaObject()->property(tprop); if (p.isValid() && p.isWritable()) { variant = p.read(w); } } } if (variant.isValid()) { content = variant.toString(); } if (!content.isEmpty()) { Item *i = new Item; i->m_widget = w; // put some more weight on the usual action elements int weight = KAccelManagerAlgorithm::DEFAULT_WEIGHT; if (qobject_cast(w) || qobject_cast(w) || qobject_cast(w) || qobject_cast(w)) { weight = KAccelManagerAlgorithm::ACTION_ELEMENT_WEIGHT; } // don't put weight on non-checkable group boxes, // as usually the contents are more important QGroupBox *groupBox = qobject_cast(w); if (groupBox) { if (groupBox->isCheckable()) { weight = KAccelManagerAlgorithm::CHECKABLE_GROUP_BOX_WEIGHT; } else { weight = KAccelManagerAlgorithm::GROUP_BOX_WEIGHT; } } i->m_content = KAccelString(content, weight); item->addChild(i); } } traverseChildren(w, item); } void KAcceleratorManagerPrivate::manageTabBar(QTabBar *bar, Item *item) { // ignore QTabBar for QDockWidgets, because QDockWidget on its title change // also updates its tabbar entry, so on the next run of KCheckAccelerators // this looks like a conflict and triggers a new reset of the shortcuts -> endless loop QWidget *parentWidget = bar->parentWidget(); if (parentWidget) { QMainWindow *mainWindow = qobject_cast(parentWidget); // TODO: find better hints that this is a QTabBar for QDockWidgets if (mainWindow) { // && (mainWindow->layout()->indexOf(bar) != -1)) QMainWindowLayout lacks proper support return; } } for (int i = 0; i < bar->count(); i++) { QString content = bar->tabText(i); if (content.isEmpty()) { continue; } Item *it = new Item; item->addChild(it); it->m_widget = bar; it->m_index = i; it->m_content = KAccelString(content); } } void KAcceleratorManagerPrivate::manageDockWidget(QDockWidget *dock, Item *item) { // As of Qt 4.4.3 setting a shortcut to a QDockWidget has no effect, // because a QDockWidget does not grab it, even while displaying an underscore // in the title for the given shortcut letter. // Still it is useful to set the shortcut, because if QDockWidgets are tabbed, // the tab automatically gets the same text as the QDockWidget title, including the shortcut. // And for the QTabBar the shortcut does work, it gets grabbed as usual. // Having the QDockWidget without a shortcut and resetting the tab text with a title including // the shortcut does not work, the tab text is instantly reverted to the QDockWidget title // (see also manageTabBar()). // All in all QDockWidgets and shortcuts are a little broken for now. QString content = dock->windowTitle(); if (content.isEmpty()) { return; } Item *it = new Item; item->addChild(it); it->m_widget = dock; it->m_content = KAccelString(content, KAccelManagerAlgorithm::STANDARD_ACCEL); } void KAcceleratorManagerPrivate::manageMenuBar(QMenuBar *mbar, Item *item) { QAction *maction; QString s; for (int i = 0; i < mbar->actions().count(); ++i) { maction = mbar->actions()[i]; if (!maction) { continue; } // nothing to do for separators if (maction->isSeparator()) { continue; } s = maction->text(); if (!s.isEmpty()) { Item *it = new Item; item->addChild(it); it->m_content = KAccelString(s, // menu titles are important, so raise the weight KAccelManagerAlgorithm::MENU_TITLE_WEIGHT); it->m_widget = mbar; it->m_index = i; } // have a look at the popup as well, if present if (maction->menu()) { KPopupAccelManager::manage(maction->menu()); } } } /********************************************************************* class KAcceleratorManager - main entry point This class is just here to provide a clean public API... *********************************************************************/ void KAcceleratorManager::manage(QWidget *widget, bool programmers_mode) { KAcceleratorManagerPrivate::changed_string.clear(); KAcceleratorManagerPrivate::added_string.clear(); KAcceleratorManagerPrivate::removed_string.clear(); KAcceleratorManagerPrivate::programmers_mode = programmers_mode; KAcceleratorManagerPrivate::manage(widget); } void KAcceleratorManager::last_manage(QString &added, QString &changed, QString &removed) { added = KAcceleratorManagerPrivate::added_string; changed = KAcceleratorManagerPrivate::changed_string; removed = KAcceleratorManagerPrivate::removed_string; } /********************************************************************* class KAccelString - a string with weighted characters *********************************************************************/ KAccelString::KAccelString(const QString &input, int initialWeight) : m_pureText(input), m_weight() { m_orig_accel = m_pureText.indexOf(QStringLiteral("(!)&")); if (m_orig_accel != -1) { m_pureText.remove(m_orig_accel, 4); } m_orig_accel = m_pureText.indexOf(QStringLiteral("(&&)")); if (m_orig_accel != -1) { m_pureText.replace(m_orig_accel, 4, QStringLiteral("&")); } m_origText = m_pureText; if (m_pureText.contains(QLatin1Char('\t'))) { m_pureText = m_pureText.left(m_pureText.indexOf(QLatin1Char('\t'))); } m_orig_accel = m_accel = stripAccelerator(m_pureText); if (initialWeight == -1) { initialWeight = KAccelManagerAlgorithm::DEFAULT_WEIGHT; } calculateWeights(initialWeight); // dump(); } QString KAccelString::accelerated() const { QString result = m_origText; if (result.isEmpty()) { return result; } if (KAcceleratorManagerPrivate::programmers_mode) { if (m_accel != m_orig_accel) { int oa = m_orig_accel; if (m_accel >= 0) { result.insert(m_accel, QStringLiteral("(!)&")); if (m_accel < m_orig_accel) { oa += 4; } } if (m_orig_accel >= 0) { result.replace(oa, 1, QStringLiteral("(&&)")); } } } else { if (m_accel >= 0 && m_orig_accel != m_accel) { if (m_orig_accel != -1) { result.remove(m_orig_accel, 1); } result.insert(m_accel, QStringLiteral("&")); } } return result; } QChar KAccelString::accelerator() const { if ((m_accel < 0) || (m_accel > (int)m_pureText.length())) { return QChar(); } return m_pureText[m_accel].toLower(); } void KAccelString::calculateWeights(int initialWeight) { m_weight.resize(m_pureText.length()); int pos = 0; bool start_character = true; while (pos < m_pureText.length()) { QChar c = m_pureText[pos]; int weight = initialWeight + 1; // add special weight to first character if (pos == 0) { weight += KAccelManagerAlgorithm::FIRST_CHARACTER_EXTRA_WEIGHT; } // add weight to word beginnings if (start_character) { weight += KAccelManagerAlgorithm::WORD_BEGINNING_EXTRA_WEIGHT; start_character = false; } // add decreasing weight to left characters if (pos < 50) { weight += (50 - pos); } // try to preserve the wanted accelarators if ((int)pos == accel()) { weight += KAccelManagerAlgorithm::WANTED_ACCEL_EXTRA_WEIGHT; // qCDebug(KWidgetsAddonsLog) << "wanted " << m_pureText << " " << KAcceleratorManagerPrivate::standardName(m_origText); if (KAcceleratorManagerPrivate::standardName(m_origText)) { weight += KAccelManagerAlgorithm::STANDARD_ACCEL; } } // skip non typeable characters if (!c.isLetterOrNumber()) { weight = 0; start_character = true; } m_weight[pos] = weight; ++pos; } } int KAccelString::stripAccelerator(QString &text) { // Note: this code is derived from QAccel::shortcutKey int p = 0; while (p >= 0) { p = text.indexOf(QLatin1Char('&'), p) + 1; if (p <= 0 || p >= (int)text.length()) { break; } if (text[p] != QLatin1Char('&')) { QChar c = text[p]; if (c.isPrint()) { text.remove(p - 1, 1); return p - 1; } } p++; } return -1; } int KAccelString::maxWeight(int &index, const QString &used) const { int max = 0; index = -1; for (int pos = 0; pos < m_pureText.length(); ++pos) if (used.indexOf(m_pureText[pos], 0, Qt::CaseInsensitive) == -1 && m_pureText[pos].toLatin1() != 0) if (m_weight[pos] > max) { max = m_weight[pos]; index = pos; } return max; } void KAccelString::dump() { QString s; for (int i = 0; i < m_weight.count(); ++i) { s += QStringLiteral("%1(%2) ").arg(pure()[i]).arg(m_weight[i]); } qCDebug(KWidgetsAddonsLog) << "s " << s; } /********************************************************************* findAccelerators - the algorithm determining the new accelerators The algorithm is very crude: * each character in each widget text is assigned a weight * the character with the highest weight over all is picked * that widget is removed from the list * the weights are recalculated * the process is repeated until no more accelerators can be found The algorithm has some advantages: * it favors 'nice' accelerators (first characters in a word, etc.) * it is quite fast, O(N²) * it is easy to understand :-) The disadvantages: * it does not try to find as many accelerators as possible TODO: * The result is always correct, but not necessarily optimal. Perhaps it would be a good idea to add another algorithm with higher complexity that gets used when this one fails, i.e. leaves widgets without accelerators. * The weights probably need some tweaking so they make more sense. *********************************************************************/ void KAccelManagerAlgorithm::findAccelerators(KAccelStringList &result, QString &used) { KAccelStringList accel_strings = result; // initially remove all accelerators for (KAccelStringList::Iterator it = result.begin(); it != result.end(); ++it) { (*it).setAccel(-1); } // pick the highest bids for (int cnt = 0; cnt < accel_strings.count(); ++cnt) { int max = 0, index = -1, accel = -1; // find maximum weight for (int i = 0; i < accel_strings.count(); ++i) { int a; int m = accel_strings[i].maxWeight(a, used); if (m > max) { max = m; index = i; accel = a; } } // stop if no more accelerators can be found if (index < 0) { return; } // insert the accelerator if (accel >= 0) { result[index].setAccel(accel); used.append(result[index].accelerator()); } // make sure we don't visit this one again accel_strings[index] = KAccelString(); } } /********************************************************************* class KPopupAccelManager - managing QPopupMenu widgets dynamically *********************************************************************/ KPopupAccelManager::KPopupAccelManager(QMenu *popup) : QObject(popup), m_popup(popup), m_count(-1) { aboutToShow(); // do one check and then connect to show connect(popup, &QMenu::aboutToShow, this, &KPopupAccelManager::aboutToShow); } void KPopupAccelManager::aboutToShow() { // Note: we try to be smart and avoid recalculating the accelerators // whenever possible. Unfortunately, there is no way to know if an // item has been added or removed, so we can not do much more than // to compare the items each time the menu is shown :-( if (m_count != (int)m_popup->actions().count()) { findMenuEntries(m_entries); calculateAccelerators(); m_count = m_popup->actions().count(); } else { KAccelStringList entries; findMenuEntries(entries); if (entries != m_entries) { m_entries = entries; calculateAccelerators(); } } } void KPopupAccelManager::calculateAccelerators() { // find the new accelerators QString used; KAccelManagerAlgorithm::findAccelerators(m_entries, used); // change the menu entries setMenuEntries(m_entries); } void KPopupAccelManager::findMenuEntries(KAccelStringList &list) { QString s; list.clear(); // read out the menu entries Q_FOREACH (QAction *maction, m_popup->actions()) { if (maction->isSeparator()) { continue; } s = maction->text(); // in full menus, look at entries with global accelerators last int weight = 50; if (s.contains(QLatin1Char('\t'))) { weight = 0; } list.append(KAccelString(s, weight)); // have a look at the popup as well, if present if (maction->menu()) { KPopupAccelManager::manage(maction->menu()); } } } void KPopupAccelManager::setMenuEntries(const KAccelStringList &list) { uint cnt = 0; Q_FOREACH (QAction *maction, m_popup->actions()) { if (maction->isSeparator()) { continue; } if (KAcceleratorManagerPrivate::checkChange(list[cnt])) { maction->setText(list[cnt].accelerated()); } cnt++; } } void KPopupAccelManager::manage(QMenu *popup) { // don't add more than one manager to a popup - if (popup->findChild(QString()) == 0) { + if (popup->findChild(QString()) == nullptr) { new KPopupAccelManager(popup); } } void QWidgetStackAccelManager::manage(QStackedWidget *stack) { - if (stack->findChild(QString()) == 0) { + if (stack->findChild(QString()) == nullptr) { new QWidgetStackAccelManager(stack); } } QWidgetStackAccelManager::QWidgetStackAccelManager(QStackedWidget *stack) : QObject(stack), m_stack(stack) { currentChanged(stack->currentIndex()); // do one check and then connect to show connect(stack, &QStackedWidget::currentChanged, this, &QWidgetStackAccelManager::currentChanged); } bool QWidgetStackAccelManager::eventFilter(QObject *watched, QEvent *e) { if (e->type() == QEvent::Show && qApp->activeWindow()) { KAcceleratorManager::manage(qApp->activeWindow()); watched->removeEventFilter(this); } return false; } void QWidgetStackAccelManager::currentChanged(int child) { if (child < 0 || child >= static_cast(parent())->count()) { // NOTE: QStackedWidget emits currentChanged(-1) when it is emptied return; } static_cast(parent())->widget(child)->installEventFilter(this); } void KAcceleratorManager::setNoAccel(QWidget *widget) { KAcceleratorManagerPrivate::ignored_widgets[widget] = 1; } void KAcceleratorManager::addStandardActionNames(const QStringList &names) { KAcceleratorManagerPrivate::addStandardActionNames(names); } #include "moc_kacceleratormanager_p.cpp" diff --git a/src/kacceleratormanager_p.h b/src/kacceleratormanager_p.h index 3d98d61..9a1eb4f 100644 --- a/src/kacceleratormanager_p.h +++ b/src/kacceleratormanager_p.h @@ -1,274 +1,274 @@ /* This file is part of the KDE project Copyright (C) 2002 Matthias H�zer-Klpfel This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KACCELERATORMANAGER_PRIVATE_H #define KACCELERATORMANAGER_PRIVATE_H #include #include #include class QStackedWidget; class QMenuBar; class QTabBar; class QDockWidget; /** * A string class handling accelerators. * * This class contains a string and knowledge about accelerators. * It keeps a list weights, telling how valuable each character * would be as an accelerator. * * @author Matthias H�zer-Klpfel */ class KAccelString { public: KAccelString() : m_pureText(), m_accel(-1) {} explicit KAccelString(const QString &input, int initalWeight = -1); void calculateWeights(int initialWeight); const QString &pure() const { return m_pureText; } QString accelerated() const; int accel() const { return m_accel; } void setAccel(int accel) { m_accel = accel; } int originalAccel() const { return m_orig_accel; } QString originalText() const { return m_origText; } QChar accelerator() const; int maxWeight(int &index, const QString &used) const; bool operator == (const KAccelString &c) const { return m_pureText == c.m_pureText && m_accel == c.m_accel && m_orig_accel == c.m_orig_accel; } private: int stripAccelerator(QString &input); void dump(); QString m_pureText, m_origText; int m_accel, m_orig_accel; QVector m_weight; }; typedef QList KAccelStringList; /** * This class encapsulates the algorithm finding the 'best' * distribution of accelerators in a hierarchy of widgets. * * @author Matthias H�zer-Klpfel */ class KAccelManagerAlgorithm { public: enum { // Default control weight DEFAULT_WEIGHT = 50, // Additional weight for first character in string FIRST_CHARACTER_EXTRA_WEIGHT = 50, // Additional weight for the beginning of a word WORD_BEGINNING_EXTRA_WEIGHT = 50, // Additional weight for the dialog buttons (large, we basically never want these reassigned) DIALOG_BUTTON_EXTRA_WEIGHT = 300, // Additional weight for a 'wanted' accelerator WANTED_ACCEL_EXTRA_WEIGHT = 150, // Default weight for an 'action' widget (ie, pushbuttons) ACTION_ELEMENT_WEIGHT = 50, // Default weight for group boxes (lowest priority) GROUP_BOX_WEIGHT = -2000, // Default weight for checkable group boxes (low priority) CHECKABLE_GROUP_BOX_WEIGHT = 20, // Default weight for menu titles MENU_TITLE_WEIGHT = 250, // Additional weight for KDE standard accelerators STANDARD_ACCEL = 300 }; static void findAccelerators(KAccelStringList &result, QString &used); }; /** * This class manages a popup menu. It will notice if entries have been * added or changed, and will recalculate the accelerators accordingly. * * This is necessary for dynamic menus like for example in kicker. * * @author Matthias H�zer-Klpfel */ class KPopupAccelManager : public QObject { Q_OBJECT public: static void manage(QMenu *popup); protected: KPopupAccelManager(QMenu *popup); private Q_SLOTS: void aboutToShow(); private: void calculateAccelerators(); void findMenuEntries(KAccelStringList &list); void setMenuEntries(const KAccelStringList &list); QMenu *m_popup; KAccelStringList m_entries; int m_count; }; class QWidgetStackAccelManager : public QObject { Q_OBJECT public: static void manage(QStackedWidget *popup); protected: QWidgetStackAccelManager(QStackedWidget *popup); private Q_SLOTS: void currentChanged(int child); bool eventFilter(QObject *watched, QEvent *e) Q_DECL_OVERRIDE; private: void calculateAccelerators(); QStackedWidget *m_stack; KAccelStringList m_entries; }; /********************************************************************* class KAcceleratorManagerPrivate - internal helper class This class does all the work to find accelerators for a hierarchy of widgets. *********************************************************************/ class KAcceleratorManagerPrivate { public: static void manage(QWidget *widget); static bool programmers_mode; static void addStandardActionNames(const QStringList &strList); static bool standardName(const QString &str); static bool checkChange(const KAccelString &as) { QString t2 = as.accelerated(); QString t1 = as.originalText(); if (t1 != t2) { if (as.accel() == -1) { removed_string += QLatin1String("") + t1.toHtmlEscaped() + QLatin1String(""); } else if (as.originalAccel() == -1) { added_string += QLatin1String("") + t2.toHtmlEscaped() + QLatin1String(""); } else { changed_string += QLatin1String("") + t1.toHtmlEscaped() + QLatin1String(""); changed_string += QLatin1String("") + t2.toHtmlEscaped() + QLatin1String(""); } return true; } return false; } static QString changed_string; static QString added_string; static QString removed_string; static QMap ignored_widgets; static QStringList standardNames; private: class Item; public: typedef QList ItemList; private: static void traverseChildren(QWidget *widget, Item *item); static void manageWidget(QWidget *widget, Item *item); static void manageMenuBar(QMenuBar *mbar, Item *item); static void manageTabBar(QTabBar *bar, Item *item); static void manageDockWidget(QDockWidget *dock, Item *item); static void calculateAccelerators(Item *item, QString &used); class Item { public: - Item() : m_widget(0), m_children(0), m_index(-1) {} + Item() : m_widget(nullptr), m_children(nullptr), m_index(-1) {} ~Item(); void addChild(Item *item); QWidget *m_widget; KAccelString m_content; ItemList *m_children; int m_index; }; }; #endif // KACCELERATORMANAGER_PRIVATE_H diff --git a/src/kactionselector.h b/src/kactionselector.h index 41b7061..c0c4510 100644 --- a/src/kactionselector.h +++ b/src/kactionselector.h @@ -1,354 +1,354 @@ /* This file is part of the KDE project Copyright (C) 2002 Anders Lund This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _KACTION_SELECTOR_H_ #define _KACTION_SELECTOR_H_ #include #include class QListWidget; class QListWidgetItem; class QKeyEvent; class QEvent; class QIcon; class KActionSelectorPrivate; /** @short A widget for selecting and arranging actions/objects This widget allows the user to select from a set of objects and arrange the order of the selected ones using two list boxes labeled "Available" and "Used" with horizontal arrows in between to move selected objects between the two, and vertical arrows on the right to arrange the order of the selected objects. The widget moves objects to the other listbox when doubleclicked if the property moveOnDoubleClick is set to true (default). See moveOnDoubleClick() and setMoveOnDoubleClick(). The user control the widget using the keyboard if enabled (default), see keyboardEnabled. Note that this may conflict with keyboard selection in the selected list box, if you set that to anything else than QListWidget::Single (which is the default). To use it, simply construct an instance and then add items to the two listboxes, available through lbAvailable() and lbSelected(). Whenever you want, you can retrieve the selected options using QListWidget methods on lbSelected(). This way, you can use your own QListWidgetItem class, allowing you to easily store object data in those. When an item is moved to a listbox, it is placed below the current item of that listbox. Standard arrow icons are used, but you can use icons of your own choice if desired, see setButtonIcon(). It is also possible to set tooltips and whatsthis help for the buttons. See setButtonTooltip() and setButtonWhatsThis(). To set whatsthis or tooltips for the listboxes, access them through availableListWidget() and selectedListWidget(). All the moving buttons are automatically set enabled as expected. Signals are sent each time an item is moved, allowing you to follow the users actions if you need to. See addedToSelection(), removedFromSelection(), movedUp() and movedDown() \image html kactionselector.png "KDE Action Selector" @author Anders Lund */ class KWIDGETSADDONS_EXPORT KActionSelector : public QWidget { Q_OBJECT Q_PROPERTY(bool moveOnDoubleClick READ moveOnDoubleClick WRITE setMoveOnDoubleClick) Q_PROPERTY(bool keyboardEnabled READ keyboardEnabled WRITE setKeyboardEnabled) Q_PROPERTY(QString availableLabel READ availableLabel WRITE setAvailableLabel) Q_PROPERTY(QString selectedLabel READ selectedLabel WRITE setSelectedLabel) Q_PROPERTY(InsertionPolicy availableInsertionPolicy READ availableInsertionPolicy WRITE setAvailableInsertionPolicy) Q_PROPERTY(InsertionPolicy selectedInsertionPolicy READ selectedInsertionPolicy WRITE setSelectedInsertionPolicy) Q_PROPERTY(bool showUpDownButtons READ showUpDownButtons WRITE setShowUpDownButtons) public: - explicit KActionSelector(QWidget *parent = 0); + explicit KActionSelector(QWidget *parent = nullptr); ~KActionSelector(); /** @return The QListWidget holding the available actions */ QListWidget *availableListWidget() const; /** @return The QListWidget holding the selected actions */ QListWidget *selectedListWidget() const; /** This enum identifies the moving buttons */ enum MoveButton { ButtonAdd, ButtonRemove, ButtonUp, ButtonDown }; Q_ENUM(MoveButton) /** This enum defines policies for where to insert moved items in a listbox. The following policies are currently defined: @li BelowCurrent - The item is inserted below the listbox' currentItem() or at the end if there is no current item. @li Sorted - The listbox is sort()ed after one or more items are inserted. @li AtTop - The item is inserted at index 0 in the listbox. @li AtBottom - The item is inserted at the end of the listbox. @sa availableInsertionPolicy(), setAvailableInsertionPolicy(), selectedInsertionPolicy(), setSelectedInsertionPolicy(). */ enum InsertionPolicy { BelowCurrent, Sorted, AtTop, AtBottom }; Q_ENUM(InsertionPolicy) /** @return Whether moveOnDoubleClcik is enabled. If enabled, an item in any listbox will be moved to the other one whenever double-clicked. This feature is enabled by default. @sa setMoveOnDoubleClick() */ bool moveOnDoubleClick() const; /** Sets moveOnDoubleClick to @p enable @sa moveOnDoubleClick() */ void setMoveOnDoubleClick(bool enable); /** @return Whether keyboard control is enabled. When Keyboard control is enabled, the widget will react to the following keyboard actions: @li CTRL + Right - simulate clicking the add button @li CTRL + Left - simulate clicking the remove button @li CTRL + Up - simulate clicking the up button @li CTRL + Down - simulate clicking the down button Additionally, pressing RETURN or ENTER on one of the list boxes will cause the current item of that listbox to be moved to the other listbox. The keyboard actions are enabled by default. @sa setKeyboardEnabled() */ bool keyboardEnabled() const; /** Sets the keyboard enabled depending on @p enable. @sa keyboardEnabled() */ void setKeyboardEnabled(bool enable); /** @return The text of the label for the available items listbox. */ QString availableLabel() const; /** Sets the label for the available items listbox to @p text. Note that this label has the listbox as its @e buddy, so that if you have a single ampersand in the text, the following character will become the accelerator to focus the listbox. */ void setAvailableLabel(const QString &text); /** @return the label of the selected items listbox. */ QString selectedLabel() const; /** Sets the label for the selected items listbox to @p text. Note that this label has the listbox as its @e buddy, so that if you have a single ampersand in the text, the following character will become the accelerator to focus the listbox. */ void setSelectedLabel(const QString &text); /** @return The current insertion policy for the available listbox. The default policy for the available listbox is Sorted. See also InsertionPolicy, setAvailableInsertionPolicy(). */ InsertionPolicy availableInsertionPolicy() const; /** Sets the insertion policy for the available listbox. See also InsertionPolicy, availableInsertionPolicy(). */ void setAvailableInsertionPolicy(InsertionPolicy policy); /** @return The current insertion policy for the selected listbox. The default policy for the selected listbox is BelowCurrent. See also InsertionPolicy, setSelectedInsertionPolicy(). */ InsertionPolicy selectedInsertionPolicy() const; /** Sets the insertion policy for the selected listbox. See also InsertionPolicy, selectedInsertionPolicy(). */ void setSelectedInsertionPolicy(InsertionPolicy policy); /** @return whether the Up and Down buttons should be displayed. */ bool showUpDownButtons() const; /** Sets whether the Up and Down buttons should be displayed according to @p show */ void setShowUpDownButtons(bool show); /** Sets the pixmap of the button @p button to @p icon. It calls SmallIconSet(pm) to generate the icon set. */ void setButtonIcon(const QString &icon, MoveButton button); /** Sets the iconset for button @p button to @p iconset. You can use this method to set a custom icon set. Either created by QIconSet, or use the application instance of KIconLoader (recommended). */ void setButtonIconSet(const QIcon &iconset, MoveButton button); /** Sets the tooltip for the button @p button to @p tip. */ void setButtonTooltip(const QString &tip, MoveButton button); /** Sets the whatsthis help for button @p button to @p text. */ void setButtonWhatsThis(const QString &text, MoveButton button); Q_SIGNALS: /** Emitted when an item is moved to the "selected" listbox. */ void added(QListWidgetItem *item); /** Emitted when an item is moved out of the "selected" listbox. */ void removed(QListWidgetItem *item); /** Emitted when an item is moved upwards in the "selected" listbox. */ void movedUp(QListWidgetItem *item); /** Emitted when an item is moved downwards in the "selected" listbox. */ void movedDown(QListWidgetItem *item); /** Emitted when an item is moved to the "selected" listbox. */ // void addedToSelection( QListWidgetItem *item ); public Q_SLOTS: /** Sets the enabled state of all moving buttons to reflect the current options. Be sure to call this if you add or removes items to either listbox after the widget is shown */ void setButtonsEnabled(); protected: /** Reimplemented for internal reasons. */ void keyPressEvent(QKeyEvent *) Q_DECL_OVERRIDE; /** Reimplemented for internal reasons. */ bool eventFilter(QObject *, QEvent *) Q_DECL_OVERRIDE; private: /** Move selected item from available box to the selected box */ Q_PRIVATE_SLOT(d, void buttonAddClicked()) /** Move selected item from selected box to available box */ Q_PRIVATE_SLOT(d, void buttonRemoveClicked()) /** Move selected item in selected box upwards */ Q_PRIVATE_SLOT(d, void buttonUpClicked()) /** Move seleted item in selected box downwards */ Q_PRIVATE_SLOT(d, void buttonDownClicked()) /** Moves the item @p item to the other listbox if moveOnDoubleClick is enabled. */ Q_PRIVATE_SLOT(d, void itemDoubleClicked(QListWidgetItem *item)) /** connected to both list boxes to set the buttons enabled */ Q_PRIVATE_SLOT(d, void slotCurrentChanged(QListWidgetItem *)) private: /** @private Private data storage */ friend class KActionSelectorPrivate; KActionSelectorPrivate *const d; Q_DISABLE_COPY(KActionSelector) }; #endif // _KACTION_SELECTOR_H_ diff --git a/src/kanimatedbutton.cpp b/src/kanimatedbutton.cpp index 76b8ba7..1ccfe29 100644 --- a/src/kanimatedbutton.cpp +++ b/src/kanimatedbutton.cpp @@ -1,203 +1,203 @@ /* This file is part of the KDE libraries Copyright (C) 2000 Kurt Granroth Copyright (C) 2006 Hamish Rodda Copyright (C) 2008 Pino Toscano This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include class KAnimatedButtonPrivate { public: KAnimatedButtonPrivate(KAnimatedButton *qq) - : q(qq), movie(0) + : q(qq), movie(nullptr) { } void updateIcons(); void updateCurrentIcon(); void _k_movieFrameChanged(int number); void _k_movieFinished(); void _k_timerUpdate(); KAnimatedButton *q; QMovie *movie; int frames; int current_frame; QPixmap pixmap; QTimer timer; QString icon_path; QVector framesCache; // We keep copies of each frame so that // the icon code can properly cache them in QPixmapCache, // and not fill it up with dead copies }; KAnimatedButton::KAnimatedButton(QWidget *parent) : QToolButton(parent), d(new KAnimatedButtonPrivate(this)) { connect(&d->timer, SIGNAL(timeout()), this, SLOT(_k_timerUpdate())); } KAnimatedButton::~KAnimatedButton() { d->timer.stop(); qDeleteAll(d->framesCache); delete d->movie; delete d; } void KAnimatedButton::start() { if (d->movie) { d->movie->start(); } else { d->current_frame = 0; d->timer.start(50); } } void KAnimatedButton::stop() { if (d->movie) { d->movie->stop(); d->movie->jumpToFrame(0); d->_k_movieFrameChanged(0); } else { d->current_frame = 0; d->timer.stop(); d->updateCurrentIcon(); } } void KAnimatedButton::setAnimationPath(const QString &path) { if (d->icon_path == path) { return; } d->timer.stop(); d->icon_path = path; d->updateIcons(); } QString KAnimatedButton::animationPath() const { return d->icon_path; } void KAnimatedButtonPrivate::_k_timerUpdate() { if (!q->isVisible()) { return; } current_frame++; if (current_frame == frames) { current_frame = 0; } updateCurrentIcon(); } void KAnimatedButtonPrivate::updateCurrentIcon() { if (pixmap.isNull()) { return; } QPixmap *frame = framesCache[current_frame]; if (!frame) { const int icon_size = qMin(pixmap.width(), pixmap.height()); const int row_size = pixmap.width() / icon_size; const int row = current_frame / row_size; const int column = current_frame % row_size; frame = new QPixmap(icon_size, icon_size); frame->fill(Qt::transparent); QPainter p(frame); p.drawPixmap(QPoint(0, 0), pixmap, QRect(column * icon_size, row * icon_size, icon_size, icon_size)); p.end(); framesCache[current_frame] = frame; } q->setIcon(QIcon(*frame)); } void KAnimatedButtonPrivate::_k_movieFrameChanged(int number) { Q_UNUSED(number); q->setIcon(QIcon(movie->currentPixmap())); } void KAnimatedButtonPrivate::_k_movieFinished() { // if not running, make it loop if (movie->state() == QMovie::NotRunning) { movie->start(); } } void KAnimatedButtonPrivate::updateIcons() { pixmap = QPixmap(); - QMovie *newMovie = 0; + QMovie *newMovie = nullptr; QImageReader reader(icon_path); if (QMovie::supportedFormats().contains(reader.format())) { newMovie = new QMovie(icon_path); frames = 0; newMovie->setCacheMode(QMovie::CacheAll); QObject::connect(newMovie, SIGNAL(frameChanged(int)), q, SLOT(_k_movieFrameChanged(int))); QObject::connect(newMovie, SIGNAL(finished()), q, SLOT(_k_movieFinished())); } else { const QPixmap pix(icon_path); if (pix.isNull()) { return; } const int icon_size = qMin(pix.width(), pix.height()); if ((pix.height() % icon_size != 0) || (pix.width() % icon_size != 0)) { return; } frames = (pix.height() / icon_size) * (pix.width() / icon_size); pixmap = pix; } current_frame = 0; qDeleteAll(framesCache); - framesCache.fill(0); + framesCache.fill(nullptr); framesCache.resize(frames); delete movie; movie = newMovie; if (movie) { movie->jumpToFrame(0); _k_movieFrameChanged(0); } else { updateCurrentIcon(); } } #include "moc_kanimatedbutton.cpp" diff --git a/src/kanimatedbutton.h b/src/kanimatedbutton.h index 9d9e0e8..106657f 100644 --- a/src/kanimatedbutton.h +++ b/src/kanimatedbutton.h @@ -1,87 +1,87 @@ /* This file is part of the KDE libraries Copyright (C) 2000 Kurt Granroth Copyright (C) 2006 Hamish Rodda This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KANIMATEDBUTTON_H #define KANIMATEDBUTTON_H #include #include /** * @short An extended version of QToolButton which can display an animation. * * This widget extends QToolButton with the ability to display an animation. * All you need to do is pass along a path to a file containing an animation, * it can be anything supported by QMovie, or a picture containing all the * frames of the animation next to each other (each frame being assumed of * having the same size). * * @author Kurt Granroth */ class KWIDGETSADDONS_EXPORT KAnimatedButton : public QToolButton { Q_OBJECT Q_PROPERTY(QString animationPath READ animationPath WRITE setAnimationPath) public: /** * Construct an animated tool button. * * @param parent The parent widget */ - explicit KAnimatedButton(QWidget *parent = 0); + explicit KAnimatedButton(QWidget *parent = nullptr); /** * Destructor */ virtual ~KAnimatedButton(); /** * Returns the path used to load the animation */ QString animationPath() const; /** * Sets the path to the file which contains the animation to load. * * @param path The path of the file containing the animation */ void setAnimationPath(const QString &path); public Q_SLOTS: /** * Starts the animation from frame 1 */ void start(); /** * Stops the animation. This will also reset the widget to frame 1. */ void stop(); private: class KAnimatedButtonPrivate *const d; Q_PRIVATE_SLOT(d, void _k_movieFrameChanged(int)) Q_PRIVATE_SLOT(d, void _k_movieFinished()) Q_PRIVATE_SLOT(d, void _k_timerUpdate()) Q_DISABLE_COPY(KAnimatedButton) }; #endif // KANIMATEDBUTTON_H diff --git a/src/kassistantdialog.h b/src/kassistantdialog.h index 529f5cd..62f41c2 100644 --- a/src/kassistantdialog.h +++ b/src/kassistantdialog.h @@ -1,154 +1,154 @@ /* This file is part of the KDE libraries Copyright (C) 2006 Olivier Goffart This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KASSISTANTDIALOG_H #define KASSISTANTDIALOG_H #include #include /** * This class provides a framework for assistant dialogs. * * An assistant dialog consists of a sequence of pages. * Its purpose is to guide the user (assist) through a process step by step. * Assistant dialogs are useful for complex or infrequently occurring tasks * that people may find difficult to learn or do. * Sometimes a task requires too many input fields to fit them on a single dialog. * * Create and populate dialog pages that inherit from QWidget and add them * to the assistant dialog using addPage(). * * The functions next() and back() are virtual and may be reimplemented to * override the default actions of the next and back buttons. * * \image html kassistantdialog.png "KDE Assistant Dialog" * * @author Olivier Goffart */ class KWIDGETSADDONS_EXPORT KAssistantDialog : public KPageDialog { Q_OBJECT public: /** * Construct a new assistant dialog with @p parent as parent. * @param parent is the parent of the widget. * @flags the window flags to give to the assistant dialog. The * default of zero is usually what you want. */ - explicit KAssistantDialog(QWidget *parent = 0, Qt::WindowFlags flags = 0); + explicit KAssistantDialog(QWidget *parent = nullptr, Qt::WindowFlags flags = nullptr); virtual ~KAssistantDialog(); /** * Specify if the content of the page is valid, and if the next button may be enabled on this page. * By default all pages are valid. * * This will disable or enable the next button on the specified page * * @param page the page on which the next button will be enabled/disable * @param enable if true the next button will be enabled, if false it will be disabled */ void setValid(KPageWidgetItem *page, bool enable); /** * return if a page is valid * @see setValid * @param page the page to check the validity of */ bool isValid(KPageWidgetItem *page) const; /** * Specify whether a page is appropriate. * * A page is considered inappropriate if it should not be shown due to * the contents of other pages making it inappropriate. * * A page which is inappropriate will not be shown. * * The last page in an assistant dialog should always be appropriate * @param page the page to set as appropriate * @param appropriate flag indicating the appropriateness of the page. * If @p appropriate is true, then @p page is appropriate and will be * shown in the assistant dialog. If false, @p page will not be shown. */ void setAppropriate(KPageWidgetItem *page, bool appropriate); /** * Check if a page is appropriate for use in the assistant dialog. * @param page is the page to check the appropriateness of. * @return true if @p page is appropriate, false if it is not */ bool isAppropriate(KPageWidgetItem *page) const; /** * @returns the next button */ QPushButton* nextButton() const; /** * @returns the finish button */ QPushButton* backButton() const; /** * @returns the finish button */ QPushButton* finishButton() const; public Q_SLOTS: /** * Called when the user clicks the Back button. * * This function will show the preceding relevant page in the sequence. * Do nothing if the current page is the first page in the sequence. */ virtual void back(); /** * Called when the user clicks the Next/Finish button. * * This function will show the next relevant page in the sequence. * If the current page is the last page, it will call accept() */ virtual void next(); protected: /** * Construct an assistant dialog from a single widget. * @param widget the widget to construct the dialog with * @param parent the parent of the assistant dialog * @flags the window flags to use when creating the widget. The default * of zero is usually fine. * * Calls the KPageDialog(KPageWidget *widget, QWidget *parent, Qt::WindowFlags flags) constructor */ - explicit KAssistantDialog(KPageWidget *widget, QWidget *parent = 0, Qt::WindowFlags flags = 0); + explicit KAssistantDialog(KPageWidget *widget, QWidget *parent = nullptr, Qt::WindowFlags flags = nullptr); void showEvent(QShowEvent *event) Q_DECL_OVERRIDE; private: class Private; Private *const d; Q_PRIVATE_SLOT(d, void _k_slotUpdateButtons()) Q_DISABLE_COPY(KAssistantDialog) }; #endif diff --git a/src/kcapacitybar.h b/src/kcapacitybar.h index 6ebd35e..2e5ed9a 100644 --- a/src/kcapacitybar.h +++ b/src/kcapacitybar.h @@ -1,236 +1,236 @@ /* * This file is part of the KDE project * Copyright (C) 2008 Rafael Fernández López * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KCAPACITYBAR_H #define KCAPACITYBAR_H #include #include class QPaintEvent; /** * @brief This widget shows a bar which is filled to show the level of usage of * a certain device. * * This widget represents a bar which goal is to show the level of usage of a * device. Its look is similar to a progress bar, but different, because this * widget does not want to give a notion of progress. * * @since 4.2 * * \image html kcapacitybar.png "KDE Capacity Bar" * * @author Rafael Fernández López */ class KWIDGETSADDONS_EXPORT KCapacityBar : public QWidget { Q_OBJECT Q_PROPERTY(int value READ value WRITE setValue) Q_PROPERTY(QString text READ text WRITE setText) Q_PROPERTY(DrawTextMode drawTextMode READ drawTextMode WRITE setDrawTextMode) Q_PROPERTY(bool fillFullBlocks READ fillFullBlocks WRITE setFillFullBlocks) Q_PROPERTY(bool continuous READ continuous WRITE setContinuous) Q_PROPERTY(int barHeight READ barHeight WRITE setBarHeight) Q_PROPERTY(Qt::Alignment horizontalTextAlignment READ horizontalTextAlignment WRITE setHorizontalTextAlignment) public: enum DrawTextMode { DrawTextInline = 0, ///< If any text set, draw it into the capacity bar DrawTextOutline ///< If any text set, draw it out of the capacity bar }; Q_ENUM(DrawTextMode) /** * Constructs a capacity bar with DrawTextOutline as draw text mode. * @param parent The parent of the widget. * @since 5.24 */ explicit KCapacityBar(QWidget *parent = Q_NULLPTR); /** * Capacity bar constructor. * * @param drawTextMode If any text set, whether to draw it into the capacity bar * or not. * @param parent The parent of the widget. */ - explicit KCapacityBar(DrawTextMode drawTextMode, QWidget *parent = 0); + explicit KCapacityBar(DrawTextMode drawTextMode, QWidget *parent = nullptr); ~KCapacityBar(); /** * Capacity bar fill value. * * @param value This parameter can take values from 0 to 100. * * @note Its value is 0 by default. */ void setValue(int value); /** * @return The fill value of the capacity bar. */ int value() const; /** * Sets the text for the capacity bar. * * @param text The text that the capacity bar will show. * * @note This is an empty string by default. */ void setText(const QString &text); /** * @return The text that the capacity bar will show. */ QString text() const; /** * When the capacity bar is non-continuous, sets whether the last block * shown should be drawn full or can be cut off (depending on the capacity * bar width, and the value set on it). * * @param fillFullBlocks If true, the last block drawn will be fully filled, * on other case, the last block drawn could be cut off. * * @note This method is only relevant if the capacity bar is in * non-continuous mode. * * @note Its value is true by default. * * @see setContinuous, continuous */ void setFillFullBlocks(bool fillFullBlocks); /** * @return Whether the last block shown can be cut off when necessary. */ bool fillFullBlocks() const; /** * Sets whether the fill of the capacity bar should be continuous or in * block mode. * * @param continuous If true, the fill of the capacity bar is done in a * continuous way. In other case, the fill is done with * separated blocks. * * @note Its value is true by default. */ void setContinuous(bool continuous); /** * @return Whether the fill of the capacity bar should be continuous or * block-based. */ bool continuous() const; /** * Sets the height (in pixels) of the bar. * * @param barHeight The preferred height (in pixels) of the capacity bar. * * @note If you set a certain text and the capacity bar is in inline mode, * the height of the bar will be the maximum of the font height and * this value. * * @note If you set a certain text and the capacity bar is in outline mode, * the height of the whole capacity bar will be bigger than this * value. Take in count the height of this widget is got from adding * the bar height, the font metrics height and a small separator * between the bar and the outline text. * * @note Its value is 12 pixels by default. */ void setBarHeight(int barHeight); /** * @return The preferred height of the capacity bar. */ int barHeight() const; /** * If the capacity bar is in outline text mode, draw the text with * @p textAlignment alignment. * * @param textAlignment Sets the horizontal alignment for the text if * the capacity bar is in outline text mode. * * @note If @p textAlignemt contains vertical alignment flags, they will be * ignored. * * @note If the capacity bar is in inline text mode, the text is always * centered, and both vertical and horizontal flags set through this * method are ignored. * * @note Its value is centered by default. */ void setHorizontalTextAlignment(Qt::Alignment textAlignment); /** * @return The horizontal alignment for the text that will be drawn. */ Qt::Alignment horizontalTextAlignment() const; /** * Set the way text is drawn if any is set * * @param drawTextMode If any text set, whether to draw it into the capacity bar * or not. */ void setDrawTextMode(DrawTextMode mode); /** * The way text is drawn, inside the capacity bar or outside of it */ DrawTextMode drawTextMode() const; /** * This method allows you to draw the widget, directly, for example on * item delegates. You only need the painter object and the rect where * this widget should be drawn. */ void drawCapacityBar(QPainter *p, const QRect &rect) const; // Reimplemented from QWidget QSize minimumSizeHint() const Q_DECL_OVERRIDE; protected: // Reimplemented from QWidget void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; // Reimplemented from QWidget void changeEvent(QEvent *event) Q_DECL_OVERRIDE; private: /** * @internal */ class Private; Private *const d; }; #endif diff --git a/src/kcharselect.cpp b/src/kcharselect.cpp index d0bc5b3..cee6efc 100644 --- a/src/kcharselect.cpp +++ b/src/kcharselect.cpp @@ -1,1100 +1,1100 @@ /* This file is part of the KDE libraries Copyright (C) 1999 Reginald Stadlbauer This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kcharselect.h" #include "kcharselect_p.h" #include "loggingcategory.h" #include #include #include #include #include #include #include #include #include #include #include #include #include Q_GLOBAL_STATIC(KCharSelectData, s_data) class KCharSelectTablePrivate { public: - KCharSelectTablePrivate(KCharSelectTable *q): q(q), model(0) + KCharSelectTablePrivate(KCharSelectTable *q): q(q), model(nullptr) {} KCharSelectTable *q; QFont font; KCharSelectItemModel *model; QVector chars; uint chr; void _k_resizeCells(); void _k_doubleClicked(const QModelIndex &index); void _k_slotSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected); }; class KCharSelect::KCharSelectPrivate { public: struct HistoryItem { uint c; bool fromSearch; QString searchString; }; enum { MaxHistoryItems = 100 }; KCharSelectPrivate(KCharSelect *q) : q(q) - , searchLine(0) + , searchLine(nullptr) , searchMode(false) , historyEnabled(false) , allPlanesEnabled(false) , inHistory(0) - , actionParent(0) + , actionParent(nullptr) { } QString tr(const char *str) { return KCharSelect::tr(str); } KCharSelect *q; QToolButton *backButton; QToolButton *forwardButton; QLineEdit *searchLine; QFontComboBox *fontCombo; QSpinBox *fontSizeSpinBox; QComboBox *sectionCombo; QComboBox *blockCombo; KCharSelectTable *charTable; QTextBrowser *detailBrowser; bool searchMode; //a search is active bool historyEnabled; bool allPlanesEnabled; int inHistory; //index of current char in history QList history; QObject *actionParent; QString createLinks(QString s); void historyAdd(uint c, bool fromSearch, const QString &searchString); void showFromHistory(int index); void updateBackForwardButtons(); void _k_activateSearchLine(); void _k_back(); void _k_forward(); void _k_fontSelected(); void _k_charSelected(uint c); void _k_updateCurrentChar(uint c); void _k_slotUpdateUnicode(uint c); void _k_sectionSelected(int index); void _k_blockSelected(int index); void _k_searchEditChanged(); void _k_search(); void _k_linkClicked(QUrl url); }; /******************************************************************/ /* Class: KCharSelectTable */ /******************************************************************/ KCharSelectTable::KCharSelectTable(QWidget *parent, const QFont &_font) : QTableView(parent), d(new KCharSelectTablePrivate(this)) { d->font = _font; setTabKeyNavigation(false); setSelectionMode(QAbstractItemView::SingleSelection); QPalette _palette; _palette.setColor(backgroundRole(), palette().color(QPalette::Base)); setPalette(_palette); verticalHeader()->setVisible(false); verticalHeader()->setSectionResizeMode(QHeaderView::Custom); horizontalHeader()->setVisible(false); horizontalHeader()->setSectionResizeMode(QHeaderView::Custom); setFocusPolicy(Qt::StrongFocus); setDragEnabled(true); setAcceptDrops(true); setDropIndicatorShown(false); setDragDropMode(QAbstractItemView::DragDrop); connect(this, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(_k_doubleClicked(QModelIndex))); d->_k_resizeCells(); } KCharSelectTable::~KCharSelectTable() { delete d; } void KCharSelectTable::setFont(const QFont &_font) { QTableView::setFont(_font); d->font = _font; if (d->model) { d->model->setFont(_font); } d->_k_resizeCells(); } uint KCharSelectTable::chr() { return d->chr; } QFont KCharSelectTable::font() const { return d->font; } QVector KCharSelectTable::displayedChars() const { return d->chars; } void KCharSelectTable::setChar(uint c) { int pos = d->chars.indexOf(c); if (pos != -1) { setCurrentIndex(model()->index(pos / model()->columnCount(), pos % model()->columnCount())); } } void KCharSelectTable::setContents(const QVector &chars) { d->chars = chars; KCharSelectItemModel *m = d->model; d->model = new KCharSelectItemModel(chars, d->font, this); setModel(d->model); d->_k_resizeCells(); QItemSelectionModel *selectionModel = new QItemSelectionModel(d->model); setSelectionModel(selectionModel); setSelectionBehavior(QAbstractItemView::SelectItems); setSelectionMode(QAbstractItemView::SingleSelection); connect(selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(_k_slotSelectionChanged(QItemSelection,QItemSelection))); connect(d->model, &KCharSelectItemModel::showCharRequested, this, &KCharSelectTable::showCharRequested); delete m; // this should hopefully delete aold selection models too, since it is the parent of them (didn't track, if there are setParent calls somewhere. Check that (jowenn) } void KCharSelectTable::scrollTo(const QModelIndex &index, ScrollHint hint) { // this prevents horizontal scrolling when selecting a character in the last column if (index.isValid() && index.column() != 0) { QTableView::scrollTo(d->model->index(index.row(), 0), hint); } else { QTableView::scrollTo(index, hint); } } void KCharSelectTablePrivate::_k_slotSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected) { Q_UNUSED(deselected); if (!model || selected.indexes().isEmpty()) { return; } QVariant temp = model->data(selected.indexes().at(0), KCharSelectItemModel::CharacterRole); if (temp.type() != QVariant::UInt) { return; } uint c = temp.toUInt(); chr = c; emit q->focusItemChanged(c); } void KCharSelectTable::resizeEvent(QResizeEvent *e) { QTableView::resizeEvent(e); if (e->size().width() != e->oldSize().width()) { d->_k_resizeCells(); } } void KCharSelectTablePrivate::_k_resizeCells() { KCharSelectItemModel *model = static_cast(q->model()); if (!model) return; const int viewportWidth = q->viewport()->size().width(); QFontMetrics fontMetrics(font); // Determine the max width of the displayed characters // fontMetrics.maxWidth() doesn't help because of font fallbacks // (testcase: Malayalam characters) int maxCharWidth = 0; const QVector chars = model->chars(); for (int i = 0; i < chars.size(); ++i) { uint thisChar = chars.at(i); if(s_data()->isPrint(thisChar)) { maxCharWidth = qMax(maxCharWidth, fontMetrics.boundingRect(QString::fromUcs4(&thisChar, 1)).width()); } } // Avoid too narrow cells maxCharWidth = qMax(maxCharWidth, 2 * fontMetrics.xHeight()); maxCharWidth = qMax(maxCharWidth, fontMetrics.height()); // Add the necessary padding, trying to match the delegate - const int textMargin = q->style()->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, q) + 1; + const int textMargin = q->style()->pixelMetric(QStyle::PM_FocusFrameHMargin, nullptr, q) + 1; maxCharWidth += 2 * textMargin; const int columns = qMax(1, viewportWidth / maxCharWidth); model->setColumnCount(columns); const uint oldChar = q->chr(); const int new_w = viewportWidth / columns; const int rows = model->rowCount(); q->setUpdatesEnabled(false); QHeaderView *hHeader = q->horizontalHeader(); const int spaceLeft = viewportWidth - new_w * columns; for (int i = 0; i <= columns; ++i) { if (i < spaceLeft) { hHeader->resizeSection(i, new_w + 1); } else { hHeader->resizeSection(i, new_w); } } QHeaderView *vHeader = q->verticalHeader(); #ifdef Q_OS_WIN int new_h = fontMetrics.lineSpacing() + 1; #else int new_h = fontMetrics.xHeight() * 3; #endif const int fontHeight = fontMetrics.height(); if (new_h < 5 || new_h < 4 + fontHeight) { new_h = qMax(5, 4 + fontHeight); } for (int i = 0; i < rows; ++i) { vHeader->resizeSection(i, new_h); } q->setUpdatesEnabled(true); q->setChar(oldChar); } void KCharSelectTablePrivate::_k_doubleClicked(const QModelIndex &index) { uint c = model->data(index, KCharSelectItemModel::CharacterRole).toUInt(); if (s_data()->isPrint(c)) { emit q->activated(c); } } void KCharSelectTable::keyPressEvent(QKeyEvent *e) { if (d->model) { switch (e->key()) { case Qt::Key_Space: emit activated(QChar::Space); return; case Qt::Key_Enter: case Qt::Key_Return: { if (!currentIndex().isValid()) { return; } uint c = d->model->data(currentIndex(), KCharSelectItemModel::CharacterRole).toUInt(); if (s_data()->isPrint(c)) { emit activated(c); } return; } default: break; } } QTableView::keyPressEvent(e); } /******************************************************************/ /* Class: KCharSelect */ /******************************************************************/ #ifndef KWIDGETSADDONS_NO_DEPRECATED KCharSelect::KCharSelect(QWidget *parent, const Controls controls) : QWidget(parent), d(new KCharSelectPrivate(this)) { - initWidget(controls, NULL); + initWidget(controls, nullptr); } #endif KCharSelect::KCharSelect( QWidget *parent , QObject *actionParent , const Controls controls) : QWidget(parent), d(new KCharSelectPrivate(this)) { initWidget(controls, actionParent); } void attachToActionParent(QAction *action, QObject *actionParent, const QList &shortcuts) { if (!action || !actionParent) { return; } action->setParent(actionParent); if (actionParent->inherits("KActionCollection")) { QMetaObject::invokeMethod(actionParent, "addAction", Q_ARG(QString, action->objectName()), Q_ARG(QAction *, action)); QMetaObject::invokeMethod(actionParent, "setDefaultShortcuts", Q_ARG(QAction *, action), Q_ARG(QList, shortcuts)); } else { action->setShortcuts(shortcuts); } } void KCharSelect::initWidget(const Controls controls, QObject *actionParent) { d->actionParent = actionParent; QVBoxLayout *mainLayout = new QVBoxLayout(this); mainLayout->setMargin(0); if (SearchLine & controls) { QHBoxLayout *searchLayout = new QHBoxLayout(); mainLayout->addLayout(searchLayout); d->searchLine = new QLineEdit(this); searchLayout->addWidget(d->searchLine); d->searchLine->setPlaceholderText(tr("Enter a search term or character here")); d->searchLine->setClearButtonEnabled(true); d->searchLine->setToolTip(tr("Enter a search term or character here")); QAction *findAction = new QAction(this); connect(findAction, SIGNAL(triggered(bool)), this, SLOT(_k_activateSearchLine())); findAction->setObjectName(QStringLiteral("edit_find")); findAction->setText(tr("&Find...")); findAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-find"))); attachToActionParent(findAction, actionParent, QKeySequence::keyBindings(QKeySequence::Find)); connect(d->searchLine, SIGNAL(textChanged(QString)), this, SLOT(_k_searchEditChanged())); connect(d->searchLine, SIGNAL(returnPressed()), this, SLOT(_k_search())); } if ((SearchLine & controls) && ((FontCombo & controls) || (FontSize & controls) || (BlockCombos & controls))) { QFrame *line = new QFrame(this); line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Sunken); mainLayout->addWidget(line); } QHBoxLayout *comboLayout = new QHBoxLayout(); d->backButton = new QToolButton(this); comboLayout->addWidget(d->backButton); d->backButton->setEnabled(false); d->backButton->setText(tr("Previous in History", "Goes to previous character")); d->backButton->setIcon(QIcon::fromTheme(QStringLiteral("go-previous"))); d->backButton->setToolTip(tr("Previous Character in History")); d->forwardButton = new QToolButton(this); comboLayout->addWidget(d->forwardButton); d->forwardButton->setEnabled(false); d->forwardButton->setText(tr("Next in History", "Goes to next character")); d->forwardButton->setIcon(QIcon::fromTheme(QStringLiteral("go-next"))); d->forwardButton->setToolTip(tr("Next Character in History")); QAction *backAction = new QAction(this); connect(backAction, &QAction::triggered, d->backButton, &QAbstractButton::animateClick); backAction->setObjectName(QStringLiteral("go_back")); backAction->setText(tr("&Back", "go back")); backAction->setIcon(QIcon::fromTheme(QStringLiteral("go-previous"))); attachToActionParent(backAction, actionParent, QKeySequence::keyBindings(QKeySequence::Back)); QAction *forwardAction = new QAction(this); connect(forwardAction, &QAction::triggered, d->forwardButton, &QAbstractButton::animateClick); forwardAction->setObjectName(QStringLiteral("go_forward")); forwardAction->setText(tr("&Forward", "go forward")); forwardAction->setIcon(QIcon::fromTheme(QStringLiteral("go-next"))); attachToActionParent(forwardAction, actionParent, QKeySequence::keyBindings(QKeySequence::Forward)); if (QApplication::isRightToLeft()) { // swap the back/forward icons QIcon tmp = backAction->icon(); backAction->setIcon(forwardAction->icon()); forwardAction->setIcon(tmp); } connect(d->backButton, SIGNAL(clicked()), this, SLOT(_k_back())); connect(d->forwardButton, SIGNAL(clicked()), this, SLOT(_k_forward())); d->sectionCombo = new QComboBox(this); d->sectionCombo->setToolTip(tr("Select a category")); comboLayout->addWidget(d->sectionCombo); d->blockCombo = new QComboBox(this); d->blockCombo->setToolTip(tr("Select a block to be displayed")); d->blockCombo->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); comboLayout->addWidget(d->blockCombo, 1); d->sectionCombo->addItems(s_data()->sectionList()); d->blockCombo->setMinimumWidth(QFontMetrics(QWidget::font()).averageCharWidth() * 25); connect(d->sectionCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(_k_sectionSelected(int))); connect(d->blockCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(_k_blockSelected(int))); d->fontCombo = new QFontComboBox(this); comboLayout->addWidget(d->fontCombo); d->fontCombo->setEditable(true); d->fontCombo->resize(d->fontCombo->sizeHint()); d->fontCombo->setToolTip(tr("Set font")); d->fontSizeSpinBox = new QSpinBox(this); comboLayout->addWidget(d->fontSizeSpinBox); d->fontSizeSpinBox->setValue(QWidget::font().pointSize()); d->fontSizeSpinBox->setRange(1, 400); d->fontSizeSpinBox->setSingleStep(1); d->fontSizeSpinBox->setToolTip(tr("Set font size")); connect(d->fontCombo, SIGNAL(currentIndexChanged(QString)), this, SLOT(_k_fontSelected())); connect(d->fontSizeSpinBox, SIGNAL(valueChanged(int)), this, SLOT(_k_fontSelected())); if ((HistoryButtons & controls) || (FontCombo & controls) || (FontSize & controls) || (BlockCombos & controls)) { mainLayout->addLayout(comboLayout); } if (!(HistoryButtons & controls)) { d->backButton->hide(); d->forwardButton->hide(); } if (!(FontCombo & controls)) { d->fontCombo->hide(); } if (!(FontSize & controls)) { d->fontSizeSpinBox->hide(); } if (!(BlockCombos & controls)) { d->sectionCombo->hide(); d->blockCombo->hide(); } QSplitter *splitter = new QSplitter(this); if ((CharacterTable & controls) || (DetailBrowser & controls)) { mainLayout->addWidget(splitter); } else { splitter->hide(); } d->charTable = new KCharSelectTable(this, QFont()); if (CharacterTable & controls) { splitter->addWidget(d->charTable); d->charTable->setFocus(Qt::OtherFocusReason); } else { d->charTable->hide(); } const QSize sz(200, 200); d->charTable->resize(sz); d->charTable->setMinimumSize(sz); d->charTable->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setCurrentFont(QFont()); connect(d->charTable, SIGNAL(focusItemChanged(uint)), this, SLOT(_k_updateCurrentChar(uint))); connect(d->charTable, SIGNAL(activated(uint)), this, SLOT(_k_charSelected(uint))); connect(d->charTable, SIGNAL(showCharRequested(uint)), this, SLOT(setCurrentCodePoint(uint))); d->detailBrowser = new QTextBrowser(this); if (DetailBrowser & controls) { splitter->addWidget(d->detailBrowser); } else { d->detailBrowser->hide(); } d->detailBrowser->setOpenLinks(false); connect(d->detailBrowser, SIGNAL(anchorClicked(QUrl)), this, SLOT(_k_linkClicked(QUrl))); setFocusPolicy(Qt::StrongFocus); setFocusProxy(d->charTable); d->_k_sectionSelected(0); d->_k_blockSelected(0); setCurrentCodePoint(QChar::Null); d->historyEnabled = true; } KCharSelect::~KCharSelect() { delete d; } QSize KCharSelect::sizeHint() const { return QWidget::sizeHint(); } void KCharSelect::setCurrentFont(const QFont &_font) { d->fontCombo->setCurrentFont(_font); d->fontSizeSpinBox->setValue(_font.pointSize()); d->_k_fontSelected(); } void KCharSelect::setAllPlanesEnabled(bool all) { d->allPlanesEnabled = all; } bool KCharSelect::allPlanesEnabled() const { return d->allPlanesEnabled; } QChar KCharSelect::currentChar() const { if (d->allPlanesEnabled) { qFatal("You must use KCharSelect::currentCodePoint instead of KCharSelect::currentChar"); } return QChar(d->charTable->chr()); } uint KCharSelect::currentCodePoint() const { return d->charTable->chr(); } QFont KCharSelect::currentFont() const { return d->charTable->font(); } QList KCharSelect::displayedChars() const { if (d->allPlanesEnabled) { qFatal("You must use KCharSelect::displayedCodePoints instead of KCharSelect::displayedChars"); } QList result; foreach (uint c, d->charTable->displayedChars()) { result.append(QChar(c)); } return result; } QVector KCharSelect::displayedCodePoints() const { return d->charTable->displayedChars(); } void KCharSelect::setCurrentChar(const QChar &c) { if (d->allPlanesEnabled) { qCritical("You should use KCharSelect::setCurrentCodePoint instead of KCharSelect::setCurrentChar"); } setCurrentCodePoint(c.unicode()); } void KCharSelect::setCurrentCodePoint(uint c) { if (!d->allPlanesEnabled && QChar::requiresSurrogates(c)) { qCritical("You must setAllPlanesEnabled(true) to use non-BMP characters"); c = QChar::ReplacementCharacter; } if (c > QChar::LastValidCodePoint) { qCWarning(KWidgetsAddonsLog, "Code point outside Unicode range"); c = QChar::LastValidCodePoint; } bool oldHistoryEnabled = d->historyEnabled; d->historyEnabled = false; int block = s_data()->blockIndex(c); int section = s_data()->sectionIndex(block); d->sectionCombo->setCurrentIndex(section); int index = d->blockCombo->findData(block); if (index != -1) { d->blockCombo->setCurrentIndex(index); } d->historyEnabled = oldHistoryEnabled; d->charTable->setChar(c); } void KCharSelect::KCharSelectPrivate::historyAdd(uint c, bool fromSearch, const QString &searchString) { //qCDebug(KWidgetsAddonsLog) << "about to add char" << c << "fromSearch" << fromSearch << "searchString" << searchString; if (!historyEnabled) { return; } if (!history.isEmpty() && c == history.last().c) { //avoid duplicates return; } //behave like a web browser, i.e. if user goes back from B to A then clicks C, B is forgotten while (!history.isEmpty() && inHistory != history.count() - 1) { history.removeLast(); } while (history.size() >= MaxHistoryItems) { history.removeFirst(); } HistoryItem item; item.c = c; item.fromSearch = fromSearch; item.searchString = searchString; history.append(item); inHistory = history.count() - 1; updateBackForwardButtons(); } void KCharSelect::KCharSelectPrivate::showFromHistory(int index) { Q_ASSERT(index >= 0 && index < history.count()); Q_ASSERT(index != inHistory); inHistory = index; updateBackForwardButtons(); const HistoryItem &item = history[index]; //qCDebug(KWidgetsAddonsLog) << "index" << index << "char" << item.c << "fromSearch" << item.fromSearch // << "searchString" << item.searchString; //avoid adding an item from history into history again bool oldHistoryEnabled = historyEnabled; historyEnabled = false; if (item.fromSearch) { if (searchLine->text() != item.searchString) { searchLine->setText(item.searchString); _k_search(); } charTable->setChar(item.c); } else { searchLine->clear(); q->setCurrentCodePoint(item.c); } historyEnabled = oldHistoryEnabled; } void KCharSelect::KCharSelectPrivate::updateBackForwardButtons() { backButton->setEnabled(inHistory > 0); forwardButton->setEnabled(inHistory < history.count() - 1); } void KCharSelect::KCharSelectPrivate::_k_activateSearchLine() { searchLine->setFocus(); searchLine->selectAll(); } void KCharSelect::KCharSelectPrivate::_k_back() { Q_ASSERT(inHistory > 0); showFromHistory(inHistory - 1); } void KCharSelect::KCharSelectPrivate::_k_forward() { Q_ASSERT(inHistory + 1 < history.count()); showFromHistory(inHistory + 1); } void KCharSelect::KCharSelectPrivate::_k_fontSelected() { QFont font = fontCombo->currentFont(); font.setPointSize(fontSizeSpinBox->value()); charTable->setFont(font); emit q->currentFontChanged(font); } void KCharSelect::KCharSelectPrivate::_k_charSelected(uint c) { if (!allPlanesEnabled) { emit q->charSelected(QChar(c)); } emit q->codePointSelected(c); } void KCharSelect::KCharSelectPrivate::_k_updateCurrentChar(uint c) { if (!allPlanesEnabled) { emit q->currentCharChanged(QChar(c)); } emit q->currentCodePointChanged(c); if (searchMode) { //we are in search mode. make the two comboboxes show the section & block for this character. //(when we are not in search mode the current character always belongs to the current section & block.) int block = s_data()->blockIndex(c); int section = s_data()->sectionIndex(block); sectionCombo->setCurrentIndex(section); int index = blockCombo->findData(block); if (index != -1) { blockCombo->setCurrentIndex(index); } } if (searchLine) { historyAdd(c, searchMode, searchLine->text()); } _k_slotUpdateUnicode(c); } void KCharSelect::KCharSelectPrivate::_k_slotUpdateUnicode(uint c) { QString html = QStringLiteral("

") + tr("Character:") + QLatin1Char(' ') + s_data()->display(c, charTable->font()) + QLatin1Char(' ') + s_data()->formatCode(c) + QStringLiteral("
"); QString name = s_data()->name(c); if (!name.isEmpty()) { //is name ever empty?

should always be there... html += tr("Name: ") + name.toHtmlEscaped() + QStringLiteral("

"); } QStringList aliases = s_data()->aliases(c); QStringList notes = s_data()->notes(c); QVector seeAlso = s_data()->seeAlso(c); QStringList equivalents = s_data()->equivalents(c); QStringList approxEquivalents = s_data()->approximateEquivalents(c); if (!(aliases.isEmpty() && notes.isEmpty() && seeAlso.isEmpty() && equivalents.isEmpty() && approxEquivalents.isEmpty())) { html += QStringLiteral("

") + tr("Annotations and Cross References") + QStringLiteral("

"); } if (!aliases.isEmpty()) { html += QStringLiteral("

") + tr("Alias names:") + QStringLiteral("

    "); foreach (const QString &alias, aliases) { html += QStringLiteral("
  • ") + alias.toHtmlEscaped() + QStringLiteral("
  • "); } html += QStringLiteral("
"); } if (!notes.isEmpty()) { html += QStringLiteral("

") + tr("Notes:") + QStringLiteral("

    "); foreach (const QString ¬e, notes) { html += QStringLiteral("
  • ") + createLinks(note.toHtmlEscaped()) + QStringLiteral("
  • "); } html += QStringLiteral("
"); } if (!seeAlso.isEmpty()) { html += QStringLiteral("

") + tr("See also:") + QStringLiteral("

"); } if (!equivalents.isEmpty()) { html += QStringLiteral("

") + tr("Equivalents:") + QStringLiteral("

    "); foreach (const QString &equivalent, equivalents) { html += QStringLiteral("
  • ") + createLinks(equivalent.toHtmlEscaped()) + QStringLiteral("
  • "); } html += QStringLiteral("
"); } if (!approxEquivalents.isEmpty()) { html += QStringLiteral("

") + tr("Approximate equivalents:") + QStringLiteral("

    "); foreach (const QString &approxEquivalent, approxEquivalents) { html += QStringLiteral("
  • ") + createLinks(approxEquivalent.toHtmlEscaped()) + QStringLiteral("
  • "); } html += QStringLiteral("
"); } QStringList unihan = s_data()->unihanInfo(c); if (unihan.count() == 7) { html += QStringLiteral("

") + tr("CJK Ideograph Information") + QStringLiteral("

"); bool newline = true; if (!unihan[0].isEmpty()) { html += tr("Definition in English: ") + unihan[0]; newline = false; } if (!unihan[2].isEmpty()) { if (!newline) { html += QStringLiteral("
"); } html += tr("Mandarin Pronunciation: ") + unihan[2]; newline = false; } if (!unihan[1].isEmpty()) { if (!newline) { html += QStringLiteral("
"); } html += tr("Cantonese Pronunciation: ") + unihan[1]; newline = false; } if (!unihan[6].isEmpty()) { if (!newline) { html += QStringLiteral("
"); } html += tr("Japanese On Pronunciation: ") + unihan[6]; newline = false; } if (!unihan[5].isEmpty()) { if (!newline) { html += QStringLiteral("
"); } html += tr("Japanese Kun Pronunciation: ") + unihan[5]; newline = false; } if (!unihan[3].isEmpty()) { if (!newline) { html += QStringLiteral("
"); } html += tr("Tang Pronunciation: ") + unihan[3]; newline = false; } if (!unihan[4].isEmpty()) { if (!newline) { html += QStringLiteral("
"); } html += tr("Korean Pronunciation: ") + unihan[4]; newline = false; } html += QStringLiteral("

"); } html += QStringLiteral("

") + tr("General Character Properties") + QStringLiteral("
"); html += tr("Block: ") + s_data()->block(c) + QStringLiteral("
"); html += tr("Unicode category: ") + s_data()->categoryText(s_data()->category(c)) + QStringLiteral("

"); QByteArray utf8 = QString::fromUcs4(&c, 1).toUtf8(); html += QStringLiteral("

") + tr("Various Useful Representations") + QStringLiteral("
"); html += tr("UTF-8:"); foreach (unsigned char c, utf8) { html += QLatin1Char(' ') + s_data()->formatCode(c, 2, QStringLiteral("0x")); } html += QStringLiteral("
") + tr("UTF-16: "); if (QChar::requiresSurrogates(c)) { html += s_data()->formatCode(QChar::highSurrogate(c), 4, QStringLiteral("0x")); html += QLatin1Char(' ') + s_data->formatCode(QChar::lowSurrogate(c), 4, QStringLiteral("0x")); } else { html += s_data()->formatCode(c, 4, QStringLiteral("0x")); } html += QStringLiteral("
") + tr("C octal escaped UTF-8: "); foreach (unsigned char c, utf8) { html += s_data()->formatCode(c, 3, QStringLiteral("\\"), 8); } html += QStringLiteral("
") + tr("XML decimal entity:") + QStringLiteral(" &#") + QString::number(c) + QStringLiteral(";

"); detailBrowser->setHtml(html); } QString KCharSelect::KCharSelectPrivate::createLinks(QString s) { QRegExp rx(QStringLiteral("\\b([\\dABCDEF]{4,5})\\b")); QStringList chars; int pos = 0; while ((pos = rx.indexIn(s, pos)) != -1) { chars << rx.cap(1); pos += rx.matchedLength(); } QSet chars2 = QSet::fromList(chars); foreach (const QString &c, chars2) { - int unicode = c.toInt(0, 16); + int unicode = c.toInt(nullptr, 16); if (!allPlanesEnabled && QChar::requiresSurrogates(unicode)) { continue; } QString link = QStringLiteral(""); if (s_data()->isPrint(unicode)) { link += QStringLiteral("‎&#") + QString::number(unicode) + QStringLiteral("; "); } link += QStringLiteral("U+") + c + QLatin1Char(' '); link += s_data()->name(unicode).toHtmlEscaped() + QStringLiteral(""); s.replace(c, link); } return s; } void KCharSelect::KCharSelectPrivate::_k_sectionSelected(int index) { blockCombo->clear(); QVector blocks = s_data()->sectionContents(index); foreach (int block, blocks) { if (!allPlanesEnabled) { const QVector contents = s_data()->blockContents(block); if (!contents.isEmpty() && QChar::requiresSurrogates(contents.at(0))) { continue; } } blockCombo->addItem(s_data()->blockName(block), QVariant(block)); } blockCombo->setCurrentIndex(0); } void KCharSelect::KCharSelectPrivate::_k_blockSelected(int index) { if (index == -1) { //the combo box has been cleared and is about to be filled again (because the section has changed) return; } if (searchMode) { //we are in search mode, so don't fill the table with this block. return; } int block = blockCombo->itemData(index).toInt(); const QVector contents = s_data()->blockContents(block); charTable->setContents(contents); emit q->displayedCharsChanged(); charTable->setChar(contents[0]); } void KCharSelect::KCharSelectPrivate::_k_searchEditChanged() { if (searchLine->text().isEmpty()) { sectionCombo->setEnabled(true); blockCombo->setEnabled(true); //upon leaving search mode, keep the same character selected searchMode = false; uint c = charTable->chr(); bool oldHistoryEnabled = historyEnabled; historyEnabled = false; _k_blockSelected(blockCombo->currentIndex()); historyEnabled = oldHistoryEnabled; q->setCurrentCodePoint(c); } else { sectionCombo->setEnabled(false); blockCombo->setEnabled(false); int length = searchLine->text().length(); if (length >= 3) { _k_search(); } } } void KCharSelect::KCharSelectPrivate::_k_search() { if (searchLine->text().isEmpty()) { return; } searchMode = true; QVector contents = s_data()->find(searchLine->text()); if (!allPlanesEnabled) { QVector::iterator it = contents.begin(); while (it != contents.end()) { if (QChar::requiresSurrogates(*it)) { it = contents.erase(it); } else { ++it; } } } charTable->setContents(contents); emit q->displayedCharsChanged(); if (!contents.isEmpty()) { charTable->setChar(contents[0]); } } void KCharSelect::KCharSelectPrivate::_k_linkClicked(QUrl url) { QString hex = url.toString(); if (hex.size() > 6) { return; } - int unicode = hex.toInt(0, 16); + int unicode = hex.toInt(nullptr, 16); if (unicode > QChar::LastValidCodePoint) { return; } searchLine->clear(); q->setCurrentCodePoint(unicode); } //// QVariant KCharSelectItemModel::data(const QModelIndex &index, int role) const { int pos = m_columns * (index.row()) + index.column(); if (!index.isValid() || pos < 0 || pos >= m_chars.size() || index.row() < 0 || index.column() < 0) { if (role == Qt::BackgroundColorRole) { return QVariant(qApp->palette().color(QPalette::Button)); } return QVariant(); } uint c = m_chars[pos]; if (role == Qt::ToolTipRole) { QString result = s_data()->display(c, m_font) + QStringLiteral("
") + s_data()->name(c).toHtmlEscaped() + QStringLiteral("
") + tr("Unicode code point:") + QLatin1Char(' ') + s_data()->formatCode(c) + QStringLiteral("
") + tr("In decimal", "Character") + QLatin1Char(' ') + QString::number(c); return QVariant(result); } else if (role == Qt::TextAlignmentRole) { return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); } else if (role == Qt::DisplayRole) { if (s_data()->isPrint(c)) { return QVariant(QString::fromUcs4(&c, 1)); } return QVariant(); } else if (role == Qt::BackgroundColorRole) { QFontMetrics fm = QFontMetrics(m_font); if (fm.inFontUcs4(c) && s_data()->isPrint(c)) { return QVariant(qApp->palette().color(QPalette::Base)); } else { return QVariant(qApp->palette().color(QPalette::Button)); } } else if (role == Qt::FontRole) { return QVariant(m_font); } else if (role == CharacterRole) { return QVariant(c); } return QVariant(); } bool KCharSelectItemModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) { Q_UNUSED(row) Q_UNUSED(parent) if (action == Qt::IgnoreAction) { return true; } if (!data->hasText()) { return false; } if (column > 0) { return false; } QString text = data->text(); if (text.isEmpty()) { return false; } emit showCharRequested(text.toUcs4().at(0)); return true; } void KCharSelectItemModel::setColumnCount(int columns) { emit layoutAboutToBeChanged(); m_columns = columns; emit layoutChanged(); } #include "moc_kcharselect.cpp" #include "moc_kcharselect_p.cpp" diff --git a/src/kcharselect_p.h b/src/kcharselect_p.h index 466c1c7..cf4b743 100644 --- a/src/kcharselect_p.h +++ b/src/kcharselect_p.h @@ -1,188 +1,188 @@ /* This file is part of the KDE libraries Copyright (C) 2005 Joseph Wenninger This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KCHARSELECT_P_H #define KCHARSELECT_P_H #include #include #include #include #include "kcharselectdata_p.h" class KCharSelectTablePrivate; /** * @short Character selection table * * A table widget which displays the characters of a font. Internally * used by KCharSelect. See the KCharSelect documentation for further * details. * * @author Reginald Stadlbauer * @author Daniel Laidig */ class KCharSelectTable : public QTableView { Q_OBJECT public: /** * Constructor. Using @p _font, draw a table of chars. * @sa setContents */ KCharSelectTable(QWidget *parent, const QFont &_font); ~KCharSelectTable(); void resizeEvent(QResizeEvent *) Q_DECL_OVERRIDE; /** Set the font to be displayed to @p _font . */ void setFont(const QFont &_font); /** Set the highlighted character to @p c . */ void setChar(uint c); /** Set the contents of the table to @p chars . */ void setContents(const QVector &chars); /** @return Currently highlighted character. */ uint chr(); /** * Returns the currently displayed font. */ QFont font() const; /** * Returns a list of currently displayed characters. */ QVector displayedChars() const; /** * Reimplemented. */ virtual void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible) Q_DECL_OVERRIDE; protected: /** * Reimplemented. */ virtual void keyPressEvent(QKeyEvent *e) Q_DECL_OVERRIDE; Q_SIGNALS: /** Emitted to indicate that character @p c is activated (such as by double-clicking it). */ void activated(uint c); void focusItemChanged(uint c); void showCharRequested(uint c); private: Q_PRIVATE_SLOT(d, void _k_slotSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected)) Q_PRIVATE_SLOT(d, void _k_resizeCells()) Q_PRIVATE_SLOT(d, void _k_doubleClicked(const QModelIndex &index)) private: friend class KCharSelectTablePrivate; KCharSelectTablePrivate *const d; Q_DISABLE_COPY(KCharSelectTable) }; // NO D-Pointer needed, private internal class, no public API class KCharSelectItemModel: public QAbstractTableModel { Q_OBJECT public: KCharSelectItemModel(QVector chars, const QFont &font, QObject *parent): QAbstractTableModel(parent), m_chars(chars), m_font(font) { if (chars.count()) { m_columns = chars.count(); } else { m_columns = 1; } } enum internalRoles {CharacterRole = Qt::UserRole}; int rowCount(const QModelIndex & = QModelIndex()) const Q_DECL_OVERRIDE { if (m_chars.count() % m_columns == 0) { return m_chars.count() / m_columns; } else { return m_chars.count() / m_columns + 1; } } int columnCount(const QModelIndex & = QModelIndex()) const Q_DECL_OVERRIDE { return m_columns; } void setFont(const QFont &font) { beginResetModel(); m_font = font; endResetModel(); } Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE { int pos = m_columns * (index.row()) + index.column(); if (pos >= m_chars.size() || index.row() < 0 || index.column() < 0) { return Qt::ItemIsDropEnabled; } return (Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsSelectable | Qt::ItemIsEnabled); } QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; QMimeData *mimeData(const QModelIndexList &indexes) const Q_DECL_OVERRIDE { if (indexes.size() != 1) { - return 0; + return nullptr; } QMimeData *mimeData = new QMimeData(); uint character = data(indexes[0], CharacterRole).toUInt(); mimeData->setText(QString::fromUcs4(&character, 1)); return mimeData; } Qt::DropActions supportedDropActions() const Q_DECL_OVERRIDE { return Qt::CopyAction; } QStringList mimeTypes() const Q_DECL_OVERRIDE { QStringList types; types << QStringLiteral("text/plain"); return types; } bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) Q_DECL_OVERRIDE; void setColumnCount(int columns); QVector chars() const { return m_chars; } private: QVector m_chars; QFont m_font; int m_columns; Q_SIGNALS: void showCharRequested(uint c); }; #endif // KCHARSELECT_P_H diff --git a/src/kcharselectdata.cpp b/src/kcharselectdata.cpp index 92c1c79..724a374 100644 --- a/src/kcharselectdata.cpp +++ b/src/kcharselectdata.cpp @@ -1,1027 +1,1027 @@ /* This file is part of the KDE libraries Copyright (C) 2007 Daniel Laidig This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kcharselectdata_p.h" #include #include #include #include #include #include #include #include #include #include /* constants for hangul (de)composition, see UAX #15 */ #define SBase 0xAC00 #define LBase 0x1100 #define VBase 0x1161 #define TBase 0x11A7 #define LCount 19 #define VCount 21 #define TCount 28 #define NCount (VCount * TCount) #define SCount (LCount * NCount) class RunIndexCreation : public QFutureInterface, public QRunnable { public: RunIndexCreation(KCharSelectData *data, const QByteArray &dataFile) : m_data(data), m_dataFile(dataFile) { } QFuture start() { setRunnable(this); reportStarted(); QFuture f = this->future(); QThreadPool::globalInstance()->start(this); return f; } void run() Q_DECL_OVERRIDE { Index index = m_data->createIndex(m_dataFile); reportResult(index); reportFinished(); } private: KCharSelectData *m_data; QByteArray m_dataFile; }; static const char JAMO_L_TABLE[][4] = { "G", "GG", "N", "D", "DD", "R", "M", "B", "BB", "S", "SS", "", "J", "JJ", "C", "K", "T", "P", "H" }; static const char JAMO_V_TABLE[][4] = { "A", "AE", "YA", "YAE", "EO", "E", "YEO", "YE", "O", "WA", "WAE", "OE", "YO", "U", "WEO", "WE", "WI", "YU", "EU", "YI", "I" }; static const char JAMO_T_TABLE[][4] = { "", "G", "GG", "GS", "N", "NJ", "NH", "D", "L", "LG", "LM", "LB", "LS", "LT", "LP", "LH", "M", "B", "BS", "S", "SS", "NG", "J", "C", "K", "T", "P", "H" }; bool KCharSelectData::openDataFile() { if (!dataFile.isEmpty()) { return true; } else { QFile file(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kf5/kcharselect/kcharselect-data"))); if (!file.open(QIODevice::ReadOnly)) { return false; } dataFile = file.readAll(); file.close(); if (dataFile.size() < 40) { dataFile.clear(); return false; } const uchar *data = reinterpret_cast(dataFile.constData()); const quint32 offsetBegin = qFromLittleEndian(data + 20); const quint32 offsetEnd = qFromLittleEndian(data + 24); uint blocks = (offsetEnd - offsetBegin) / 4; if (blocks <= 167) { // maximum possible number of blocks in BMP // no remapping remapType = -1; } else if (blocks == 174) { // remapping introduced in 5.25 remapType = 0; } else { // unknown remapping, abort dataFile.clear(); return false; } futureIndex = (new RunIndexCreation(this, dataFile))->start(); return true; } } // Temporary remapping code points <-> 16 bit database codes // See kcharselect-generate-datafile.py for details quint16 KCharSelectData::mapCodePointToDataBase(uint code) const { if (remapType == 0) { if (code >= 0xE000 && code <= 0xEFFF) { return 0xFFFF; } if (code >= 0xF000 && code <= 0xFFFF) { return code - 0x1000; } if (code >= 0x1F000 && code <= 0x1FFFF) { return code - 0x10000; } } if (code >= 0x10000) { return 0xFFFF; } return code; } uint KCharSelectData::mapDataBaseToCodePoint(quint16 code) const { if (remapType == 0) { if (code >= 0xE000 && code <= 0xEFFF) { return code + 0x1000; } if (code >= 0xF000 && code <= 0xFFFF) { return code + 0x10000; } } return code; } quint32 KCharSelectData::getDetailIndex(uint c) const { const uchar *data = reinterpret_cast(dataFile.constData()); // Convert from little-endian, so that this code works on PPC too. // http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=482286 const quint32 offsetBegin = qFromLittleEndian(data + 12); const quint32 offsetEnd = qFromLittleEndian(data + 16); int min = 0; int mid; int max = ((offsetEnd - offsetBegin) / 27) - 1; quint16 unicode = mapCodePointToDataBase(c); if (unicode == 0xFFFF) { return 0; } static quint16 most_recent_searched; static quint32 most_recent_result; if (unicode == most_recent_searched) { return most_recent_result; } most_recent_searched = unicode; while (max >= min) { mid = (min + max) / 2; const quint16 midUnicode = qFromLittleEndian(data + offsetBegin + mid * 27); if (unicode > midUnicode) { min = mid + 1; } else if (unicode < midUnicode) { max = mid - 1; } else { most_recent_result = offsetBegin + mid * 27; return most_recent_result; } } most_recent_result = 0; return 0; } QString KCharSelectData::formatCode(uint code, int length, const QString &prefix, int base) { QString s = QString::number(code, base).toUpper(); while (s.size() < length) { s.prepend(QLatin1Char('0')); } s.prepend(prefix); return s; } QVector KCharSelectData::blockContents(int block) { if (!openDataFile()) { return QVector(); } const uchar *data = reinterpret_cast(dataFile.constData()); const quint32 offsetBegin = qFromLittleEndian(data + 20); const quint32 offsetEnd = qFromLittleEndian(data + 24); int max = ((offsetEnd - offsetBegin) / 4) - 1; QVector res; if (block > max) { return res; } quint16 unicodeBegin = qFromLittleEndian(data + offsetBegin + block * 4); quint16 unicodeEnd = qFromLittleEndian(data + offsetBegin + block * 4 + 2); while (unicodeBegin < unicodeEnd) { res.append(mapDataBaseToCodePoint(unicodeBegin)); unicodeBegin++; } res.append(mapDataBaseToCodePoint(unicodeBegin)); // Be carefull when unicodeEnd==0xffff return res; } QVector KCharSelectData::sectionContents(int section) { if (!openDataFile()) { return QVector(); } const uchar *data = reinterpret_cast(dataFile.constData()); const quint32 offsetBegin = qFromLittleEndian(data + 28); const quint32 offsetEnd = qFromLittleEndian(data + 32); int max = ((offsetEnd - offsetBegin) / 4) - 1; QVector res; if (section > max) { return res; } for (int i = 0; i <= max; i++) { const quint16 currSection = qFromLittleEndian(data + offsetBegin + i * 4); if (currSection == section) { res.append(qFromLittleEndian(data + offsetBegin + i * 4 + 2)); } } return res; } QStringList KCharSelectData::sectionList() { if (!openDataFile()) { return QStringList(); } const uchar *udata = reinterpret_cast(dataFile.constData()); const quint32 stringBegin = qFromLittleEndian(udata + 24); const quint32 stringEnd = qFromLittleEndian(udata + 28); const char *data = dataFile.constData(); QStringList list; quint32 i = stringBegin; while (i < stringEnd) { list.append(QCoreApplication::translate("KCharSelectData", data + i, "KCharSelect section name")); i += strlen(data + i) + 1; } return list; } QString KCharSelectData::block(uint c) { return blockName(blockIndex(c)); } QString KCharSelectData::section(uint c) { return sectionName(sectionIndex(blockIndex(c))); } QString KCharSelectData::name(uint c) { if (!openDataFile()) { return QString(); } if ((c & 0xFFFE) == 0xFFFE || (c >= 0xFDD0 && c <= 0xFDEF)) { return QCoreApplication::translate("KCharSelectData", ""); } else if ((c >= 0x3400 && c <= 0x4DBF) || (c >= 0x4E00 && c <= 0x9FFF) || (c >= 0x20000 && c <= 0x2F7FF)) { return QStringLiteral("CJK UNIFIED IDEOGRAPH-") + formatCode(c, 4, QString()); } else if (c >= 0xAC00 && c <= 0xD7AF) { /* compute hangul syllable name as per UAX #15 */ int SIndex = c - SBase; int LIndex, VIndex, TIndex; if (SIndex < 0 || SIndex >= SCount) { return QString(); } LIndex = SIndex / NCount; VIndex = (SIndex % NCount) / TCount; TIndex = SIndex % TCount; return QLatin1String("HANGUL SYLLABLE ") + QLatin1String(JAMO_L_TABLE[LIndex]) + QLatin1String(JAMO_V_TABLE[VIndex]) + QLatin1String(JAMO_T_TABLE[TIndex]); } else if (c >= 0xD800 && c <= 0xDB7F) { return QCoreApplication::translate("KCharSelectData", ""); } else if (c >= 0xDB80 && c <= 0xDBFF) { return QCoreApplication::translate("KCharSelectData", ""); } else if (c >= 0xDC00 && c <= 0xDFFF) { return QCoreApplication::translate("KCharSelectData", ""); } else if ((c >= 0xE000 && c <= 0xF8FF) || c >= 0xF0000) { return QCoreApplication::translate("KCharSelectData", ""); } else if ((c >= 0xF900 && c <= 0xFAFF) || (c >= 0x2F800 && c <= 0x2FFFF)) { return QStringLiteral("CJK COMPATIBILITY IDEOGRAPH-") + formatCode(c, 4, QString()); } quint16 unicode = mapCodePointToDataBase(c); if (unicode == 0xFFFF) { return QStringLiteral("NON-BMP-CHARACTER-") + formatCode(c, 4, QString()); } else { const uchar *data = reinterpret_cast(dataFile.constData()); const quint32 offsetBegin = qFromLittleEndian(data + 4); const quint32 offsetEnd = qFromLittleEndian(data + 8); int min = 0; int mid; int max = ((offsetEnd - offsetBegin) / 6) - 1; QString s; while (max >= min) { mid = (min + max) / 2; const quint16 midUnicode = qFromLittleEndian(data + offsetBegin + mid * 6); if (unicode > midUnicode) { min = mid + 1; } else if (unicode < midUnicode) { max = mid - 1; } else { quint32 offset = qFromLittleEndian(data + offsetBegin + mid * 6 + 2); s = QString::fromUtf8(dataFile.constData() + offset + 1); break; } } if (s.isNull()) { return QCoreApplication::translate("KCharSelectData", ""); } else { return s; } } } int KCharSelectData::blockIndex(uint c) { if (!openDataFile()) { return 0; } const uchar *data = reinterpret_cast(dataFile.constData()); const quint32 offsetBegin = qFromLittleEndian(data + 20); const quint32 offsetEnd = qFromLittleEndian(data + 24); const quint16 unicode = mapCodePointToDataBase(c); if (unicode == 0xFFFF) { return 0; } int max = ((offsetEnd - offsetBegin) / 4) - 1; int i = 0; while (unicode > qFromLittleEndian(data + offsetBegin + i * 4 + 2) && i < max) { i++; } return i; } int KCharSelectData::sectionIndex(int block) { if (!openDataFile()) { return 0; } const uchar *data = reinterpret_cast(dataFile.constData()); const quint32 offsetBegin = qFromLittleEndian(data + 28); const quint32 offsetEnd = qFromLittleEndian(data + 32); int max = ((offsetEnd - offsetBegin) / 4) - 1; for (int i = 0; i <= max; i++) { if (qFromLittleEndian(data + offsetBegin + i * 4 + 2) == block) { return qFromLittleEndian(data + offsetBegin + i * 4); } } return 0; } QString KCharSelectData::blockName(int index) { if (!openDataFile()) { return QString(); } const uchar *udata = reinterpret_cast(dataFile.constData()); const quint32 stringBegin = qFromLittleEndian(udata + 16); const quint32 stringEnd = qFromLittleEndian(udata + 20); quint32 i = stringBegin; int currIndex = 0; const char *data = dataFile.constData(); while (i < stringEnd && currIndex < index) { i += strlen(data + i) + 1; currIndex++; } return QCoreApplication::translate("KCharSelectData", data + i, "KCharselect unicode block name"); } QString KCharSelectData::sectionName(int index) { if (!openDataFile()) { return QString(); } const uchar *udata = reinterpret_cast(dataFile.constData()); const quint32 stringBegin = qFromLittleEndian(udata + 24); const quint32 stringEnd = qFromLittleEndian(udata + 28); quint32 i = stringBegin; int currIndex = 0; const char *data = dataFile.constData(); while (i < stringEnd && currIndex < index) { i += strlen(data + i) + 1; currIndex++; } return QCoreApplication::translate("KCharSelectData", data + i, "KCharselect unicode section name"); } QStringList KCharSelectData::aliases(uint c) { if (!openDataFile()) { return QStringList(); } const uchar *udata = reinterpret_cast(dataFile.constData()); const int detailIndex = getDetailIndex(c); if (detailIndex == 0) { return QStringList(); } const quint8 count = * (quint8 *)(udata + detailIndex + 6); quint32 offset = qFromLittleEndian(udata + detailIndex + 2); QStringList aliases; const char *data = dataFile.constData(); for (int i = 0; i < count; i++) { aliases.append(QString::fromUtf8(data + offset)); offset += strlen(data + offset) + 1; } return aliases; } QStringList KCharSelectData::notes(uint c) { if (!openDataFile()) { return QStringList(); } const int detailIndex = getDetailIndex(c); if (detailIndex == 0) { return QStringList(); } const uchar *udata = reinterpret_cast(dataFile.constData()); const quint8 count = * (quint8 *)(udata + detailIndex + 11); quint32 offset = qFromLittleEndian(udata + detailIndex + 7); QStringList notes; const char *data = dataFile.constData(); for (int i = 0; i < count; i++) { notes.append(QString::fromUtf8(data + offset)); offset += strlen(data + offset) + 1; } return notes; } QVector KCharSelectData::seeAlso(uint c) { if (!openDataFile()) { return QVector(); } const int detailIndex = getDetailIndex(c); if (detailIndex == 0) { return QVector(); } const uchar *udata = reinterpret_cast(dataFile.constData()); const quint8 count = * (quint8 *)(udata + detailIndex + 26); quint32 offset = qFromLittleEndian(udata + detailIndex + 22); QVector seeAlso; for (int i = 0; i < count; i++) { seeAlso.append(mapDataBaseToCodePoint(qFromLittleEndian (udata + offset))); offset += 2; } return seeAlso; } QStringList KCharSelectData::equivalents(uint c) { if (!openDataFile()) { return QStringList(); } const int detailIndex = getDetailIndex(c); if (detailIndex == 0) { return QStringList(); } const uchar *udata = reinterpret_cast(dataFile.constData()); const quint8 count = * (quint8 *)(udata + detailIndex + 21); quint32 offset = qFromLittleEndian(udata + detailIndex + 17); QStringList equivalents; const char *data = dataFile.constData(); for (int i = 0; i < count; i++) { equivalents.append(QString::fromUtf8(data + offset)); offset += strlen(data + offset) + 1; } return equivalents; } QStringList KCharSelectData::approximateEquivalents(uint c) { if (!openDataFile()) { return QStringList(); } const int detailIndex = getDetailIndex(c); if (detailIndex == 0) { return QStringList(); } const uchar *udata = reinterpret_cast(dataFile.constData()); const quint8 count = * (quint8 *)(udata + detailIndex + 16); quint32 offset = qFromLittleEndian(udata + detailIndex + 12); QStringList approxEquivalents; const char *data = dataFile.constData(); for (int i = 0; i < count; i++) { approxEquivalents.append(QString::fromUtf8(data + offset)); offset += strlen(data + offset) + 1; } return approxEquivalents; } QStringList KCharSelectData::unihanInfo(uint c) { if (!openDataFile()) { return QStringList(); } quint16 unicode = mapCodePointToDataBase(c); if (unicode == 0xFFFF) { return QStringList(); } const char *data = dataFile.constData(); const uchar *udata = reinterpret_cast(data); const quint32 offsetBegin = qFromLittleEndian(udata + 36); const quint32 offsetEnd = dataFile.size(); int min = 0; int mid; int max = ((offsetEnd - offsetBegin) / 30) - 1; while (max >= min) { mid = (min + max) / 2; const quint16 midUnicode = qFromLittleEndian(udata + offsetBegin + mid * 30); if (unicode > midUnicode) { min = mid + 1; } else if (unicode < midUnicode) { max = mid - 1; } else { QStringList res; for (int i = 0; i < 7; i++) { quint32 offset = qFromLittleEndian(udata + offsetBegin + mid * 30 + 2 + i * 4); if (offset != 0) { res.append(QString::fromUtf8(data + offset)); } else { res.append(QString()); } } return res; } } return QStringList(); } QChar::Category KCharSelectData::category(uint c) { if (!openDataFile()) { return QChar::category(c); } ushort unicode = mapCodePointToDataBase(c); if (unicode == 0xFFFF) { return QChar::category(c); } const uchar *data = reinterpret_cast(dataFile.constData()); const quint32 offsetBegin = qFromLittleEndian(data + 4); const quint32 offsetEnd = qFromLittleEndian(data + 8); int min = 0; int mid; int max = ((offsetEnd - offsetBegin) / 6) - 1; QString s; while (max >= min) { mid = (min + max) / 2; const quint16 midUnicode = qFromLittleEndian(data + offsetBegin + mid * 6); if (unicode > midUnicode) { min = mid + 1; } else if (unicode < midUnicode) { max = mid - 1; } else { quint32 offset = qFromLittleEndian(data + offsetBegin + mid * 6 + 2); uchar categoryCode = *(data + offset); Q_ASSERT(categoryCode > 0); categoryCode--; /* Qt5 changed QChar::Category enum to start from 0 instead of 1 See QtBase commit d17c76feee9eece4 */ return QChar::Category(categoryCode); } } return QChar::category(c); } bool KCharSelectData::isPrint(uint c) { QChar::Category cat = category(c); return !(cat == QChar::Other_Control || cat == QChar::Other_NotAssigned); } bool KCharSelectData::isDisplayable(uint c) { // Qt internally uses U+FDD0 and U+FDD1 to mark the beginning and the end of frames. // They should be seen as non-printable characters, as trying to display them leads // to a crash caused by a Qt "noBlockInString" assertion. if (c == 0xFDD0 || c == 0xFDD1) { return false; } return !isIgnorable(c) && isPrint(c); } bool KCharSelectData::isIgnorable(uint c) { /* * According to the Unicode standard, Default Ignorable Code Points * should be ignored unless explicitly supported. For example, U+202E * RIGHT-TO-LEFT-OVERRIDE ir printable according to Qt, but displaying * it gives the undesired effect of all text being turned RTL. We do not * have a way to "explicitly" support it, so we will treat it as * non-printable. * * There is a list of these on * http://unicode.org/Public/UNIDATA/DerivedCoreProperties.txt under the * property Default_Ignorable_Code_Point. */ //NOTE: not very nice to hardcode these here; is it worth it to modify // the binary data file to hold them? return c == 0x00AD || c == 0x034F || c == 0x115F || c == 0x1160 || c == 0x17B4 || c == 0x17B5 || (c >= 0x180B && c <= 0x180D) || (c >= 0x200B && c <= 0x200F) || (c >= 0x202A && c <= 0x202E) || (c >= 0x2060 && c <= 0x206F) || c == 0x3164 || (c >= 0xFE00 && c <= 0xFE0F) || c == 0xFEFF || c == 0xFFA0 || (c >= 0xFFF0 && c <= 0xFFF8); } bool KCharSelectData::isCombining(uint c) { return section(c) == QCoreApplication::translate("KCharSelectData", "Combining Diacritics", "KCharSelect section name"); //FIXME: this is an imperfect test. There are many combining characters // that are outside of this section. See Grapheme_Extend in // http://www.unicode.org/Public/UNIDATA/DerivedCoreProperties.txt } QString KCharSelectData::display(uint c, const QFont &font) { if (!isDisplayable(c)) { return QStringLiteral("") + QCoreApplication::translate("KCharSelectData", "Non-printable") + QStringLiteral(""); } else { QString s = QStringLiteral(""); if (isCombining(c)) { s += displayCombining(c); } else { s += QStringLiteral("&#") + QString::number(c) + QLatin1Char(';'); } s += QStringLiteral(""); return s; } } QString KCharSelectData::displayCombining(uint c) { /* * The purpose of this is to make it easier to see how a combining * character affects the text around it. * The initial plan was to use U+25CC DOTTED CIRCLE for this purpose, * as seen in pdfs from Unicode, but there seem to be a lot of alignment * problems with that. * * Eventually, it would be nice to determine whether the character * combines to the left or to the right, etc. */ QString s = QStringLiteral(" &#") + QString::number(c) + QStringLiteral("; ") + QStringLiteral(" (ab&#") + QString::number(c) + QStringLiteral(";c)"); return s; } QString KCharSelectData::categoryText(QChar::Category category) { switch (category) { case QChar::Other_Control: return QCoreApplication::translate("KCharSelectData", "Other, Control"); case QChar::Other_Format: return QCoreApplication::translate("KCharSelectData", "Other, Format"); case QChar::Other_NotAssigned: return QCoreApplication::translate("KCharSelectData", "Other, Not Assigned"); case QChar::Other_PrivateUse: return QCoreApplication::translate("KCharSelectData", "Other, Private Use"); case QChar::Other_Surrogate: return QCoreApplication::translate("KCharSelectData", "Other, Surrogate"); case QChar::Letter_Lowercase: return QCoreApplication::translate("KCharSelectData", "Letter, Lowercase"); case QChar::Letter_Modifier: return QCoreApplication::translate("KCharSelectData", "Letter, Modifier"); case QChar::Letter_Other: return QCoreApplication::translate("KCharSelectData", "Letter, Other"); case QChar::Letter_Titlecase: return QCoreApplication::translate("KCharSelectData", "Letter, Titlecase"); case QChar::Letter_Uppercase: return QCoreApplication::translate("KCharSelectData", "Letter, Uppercase"); case QChar::Mark_SpacingCombining: return QCoreApplication::translate("KCharSelectData", "Mark, Spacing Combining"); case QChar::Mark_Enclosing: return QCoreApplication::translate("KCharSelectData", "Mark, Enclosing"); case QChar::Mark_NonSpacing: return QCoreApplication::translate("KCharSelectData", "Mark, Non-Spacing"); case QChar::Number_DecimalDigit: return QCoreApplication::translate("KCharSelectData", "Number, Decimal Digit"); case QChar::Number_Letter: return QCoreApplication::translate("KCharSelectData", "Number, Letter"); case QChar::Number_Other: return QCoreApplication::translate("KCharSelectData", "Number, Other"); case QChar::Punctuation_Connector: return QCoreApplication::translate("KCharSelectData", "Punctuation, Connector"); case QChar::Punctuation_Dash: return QCoreApplication::translate("KCharSelectData", "Punctuation, Dash"); case QChar::Punctuation_Close: return QCoreApplication::translate("KCharSelectData", "Punctuation, Close"); case QChar::Punctuation_FinalQuote: return QCoreApplication::translate("KCharSelectData", "Punctuation, Final Quote"); case QChar::Punctuation_InitialQuote: return QCoreApplication::translate("KCharSelectData", "Punctuation, Initial Quote"); case QChar::Punctuation_Other: return QCoreApplication::translate("KCharSelectData", "Punctuation, Other"); case QChar::Punctuation_Open: return QCoreApplication::translate("KCharSelectData", "Punctuation, Open"); case QChar::Symbol_Currency: return QCoreApplication::translate("KCharSelectData", "Symbol, Currency"); case QChar::Symbol_Modifier: return QCoreApplication::translate("KCharSelectData", "Symbol, Modifier"); case QChar::Symbol_Math: return QCoreApplication::translate("KCharSelectData", "Symbol, Math"); case QChar::Symbol_Other: return QCoreApplication::translate("KCharSelectData", "Symbol, Other"); case QChar::Separator_Line: return QCoreApplication::translate("KCharSelectData", "Separator, Line"); case QChar::Separator_Paragraph: return QCoreApplication::translate("KCharSelectData", "Separator, Paragraph"); case QChar::Separator_Space: return QCoreApplication::translate("KCharSelectData", "Separator, Space"); default: return QCoreApplication::translate("KCharSelectData", "Unknown"); } } QVector KCharSelectData::find(const QString &needle) { QSet result; QVector returnRes; QString simplified = needle.simplified(); QStringList searchStrings; QRegularExpression octalExp(QStringLiteral("^\\\\[0-7][0-7\\\\]*$")); QRegularExpressionMatch match = octalExp.match(simplified); if (match.hasMatch()) { // search for C octal escaped UTF-8 QByteArray utf8; int byte = -1; for (int i = 0; i <= simplified.length(); ++i) { int c = simplified.at(i).unicode(); if (c >= '0' && c <= '7') { byte = 8 * byte + c - '0'; } else if (byte == -1) { byte = 0; } else if (byte >= 0x00 && byte <= 0xFF) { utf8.append((char) byte); byte = 0; } } simplified = QString::fromUtf8(utf8); } if (simplified.length() <= 2) { QVector ucs4 = simplified.toUcs4(); if (ucs4.size() == 1) { // search for hex representation of the character searchStrings = QStringList(formatCode(ucs4.at(0))); } } else { searchStrings = splitString(simplified); } if (searchStrings.count() == 0) { return returnRes; } QRegularExpression hexExp(QStringLiteral("^(|u\\+|U\\+|0x|0X)([A-Fa-f0-9]{4,5})$")); foreach (const QString &s, searchStrings) { QRegularExpressionMatch match = hexExp.match(s); if (match.hasMatch()) { - returnRes.append(match.captured(2).toInt(0, 16)); + returnRes.append(match.captured(2).toInt(nullptr, 16)); // search for "1234" instead of "0x1234" if (s.length() == 6 || s.length() == 7) { searchStrings[searchStrings.indexOf(s)] = match.captured(2); } } // try to parse string as decimal number bool ok; int unicode = s.toInt(&ok); if (ok && unicode >= 0 && unicode <= QChar::LastValidCodePoint) { returnRes.append(unicode); } } bool firstSubString = true; foreach (const QString &s, searchStrings) { QSet partResult = getMatchingChars(s.toLower()); if (firstSubString) { result = partResult; firstSubString = false; } else { result = result.intersect(partResult); } } // remove results found by matching the code point to prevent duplicate results // while letting these characters stay at the beginning foreach (uint c, returnRes) { result.remove(c); } QVector sortedResult; sortedResult.reserve(result.count()); QSet::const_iterator it = result.begin(); const QSet::const_iterator end = result.end(); for ( ; it != end ; ++it ) { sortedResult.append(*it); } qSort(sortedResult); returnRes += sortedResult; return returnRes; } QSet KCharSelectData::getMatchingChars(const QString &s) { if (dataFile.isEmpty()) { return QSet(); } futureIndex.waitForFinished(); const Index index = futureIndex; Index::const_iterator pos = index.lowerBound(s); QSet result; while (pos != index.constEnd() && pos.key().startsWith(s)) { foreach (quint16 c, pos.value()) { result.insert(mapDataBaseToCodePoint(c)); } ++pos; } return result; } QStringList KCharSelectData::splitString(const QString &s) { QStringList result; int start = 0; int end = 0; int length = s.length(); while (end < length) { while (end < length && (s[end].isLetterOrNumber() || s[end] == QLatin1Char('+'))) { end++; } if (start != end) { result.append(s.mid(start, end - start)); } start = end; while (end < length && !(s[end].isLetterOrNumber() || s[end] == QLatin1Char('+'))) { end++; start++; } } return result; } void KCharSelectData::appendToIndex(Index *index, quint16 unicode, const QString &s) { const QStringList strings = splitString(s); foreach (const QString &s, strings) { (*index)[s.toLower()].append(unicode); } } Index KCharSelectData::createIndex(const QByteArray &dataFile) { Index i; // character names const uchar *udata = reinterpret_cast(dataFile.constData()); const char *data = dataFile.constData(); const quint32 nameOffsetBegin = qFromLittleEndian(udata + 4); const quint32 nameOffsetEnd = qFromLittleEndian(udata + 8); int max = ((nameOffsetEnd - nameOffsetBegin) / 6) - 1; for (int pos = 0; pos <= max; pos++) { const quint16 unicode = qFromLittleEndian(udata + nameOffsetBegin + pos * 6); quint32 offset = qFromLittleEndian(udata + nameOffsetBegin + pos * 6 + 2); appendToIndex(&i, unicode, QString::fromUtf8(data + offset + 1)); } // details const quint32 detailsOffsetBegin = qFromLittleEndian(udata + 12); const quint32 detailsOffsetEnd = qFromLittleEndian(udata + 16); max = ((detailsOffsetEnd - detailsOffsetBegin) / 27) - 1; for (int pos = 0; pos <= max; pos++) { const quint16 unicode = qFromLittleEndian(udata + detailsOffsetBegin + pos * 27); // aliases const quint8 aliasCount = * (quint8 *)(udata + detailsOffsetBegin + pos * 27 + 6); quint32 aliasOffset = qFromLittleEndian(udata + detailsOffsetBegin + pos * 27 + 2); for (int j = 0; j < aliasCount; j++) { appendToIndex(&i, unicode, QString::fromUtf8(data + aliasOffset)); aliasOffset += strlen(data + aliasOffset) + 1; } // notes const quint8 notesCount = * (quint8 *)(udata + detailsOffsetBegin + pos * 27 + 11); quint32 notesOffset = qFromLittleEndian(udata + detailsOffsetBegin + pos * 27 + 7); for (int j = 0; j < notesCount; j++) { appendToIndex(&i, unicode, QString::fromUtf8(data + notesOffset)); notesOffset += strlen(data + notesOffset) + 1; } // approximate equivalents const quint8 apprCount = * (quint8 *)(udata + detailsOffsetBegin + pos * 27 + 16); quint32 apprOffset = qFromLittleEndian(udata + detailsOffsetBegin + pos * 27 + 12); for (int j = 0; j < apprCount; j++) { appendToIndex(&i, unicode, QString::fromUtf8(data + apprOffset)); apprOffset += strlen(data + apprOffset) + 1; } // equivalents const quint8 equivCount = * (quint8 *)(udata + detailsOffsetBegin + pos * 27 + 21); quint32 equivOffset = qFromLittleEndian(udata + detailsOffsetBegin + pos * 27 + 17); for (int j = 0; j < equivCount; j++) { appendToIndex(&i, unicode, QString::fromUtf8(data + equivOffset)); equivOffset += strlen(data + equivOffset) + 1; } // see also - convert to string (hex) const quint8 seeAlsoCount = * (quint8 *)(udata + detailsOffsetBegin + pos * 27 + 26); quint32 seeAlsoOffset = qFromLittleEndian(udata + detailsOffsetBegin + pos * 27 + 22); for (int j = 0; j < seeAlsoCount; j++) { quint16 seeAlso = qFromLittleEndian (udata + seeAlsoOffset); appendToIndex(&i, unicode, formatCode(seeAlso, 4, QString())); equivOffset += strlen(data + equivOffset) + 1; } } // unihan data // temporary disabled due to the huge amount of data // const quint32 unihanOffsetBegin = qFromLittleEndian(udata+36); // const quint32 unihanOffsetEnd = dataFile.size(); // max = ((unihanOffsetEnd - unihanOffsetBegin) / 30) - 1; // // for (int pos = 0; pos <= max; pos++) { // const quint16 unicode = qFromLittleEndian(udata + unihanOffsetBegin + pos*30); // for(int j = 0; j < 7; j++) { // quint32 offset = qFromLittleEndian(udata + unihanOffsetBegin + pos*30 + 2 + j*4); // if(offset != 0) { // appendToIndex(&i, unicode, QString::fromUtf8(data + offset)); // } // } // } return i; } diff --git a/src/kcollapsiblegroupbox.h b/src/kcollapsiblegroupbox.h index 1567a3b..f4eb8b8 100644 --- a/src/kcollapsiblegroupbox.h +++ b/src/kcollapsiblegroupbox.h @@ -1,120 +1,120 @@ /* * This file is part of the KDE project * Copyright (C) 2015 David Edmundson * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KCOLLAPSIBLEGROUPBOX_H #define KCOLLAPSIBLEGROUPBOX_H #include #include class KCollapsibleGroupBoxPrivate; /** * @class KCollapsibleGroupBox * * A groupbox featuring a clickable header and arrow indicator that can be * expanded and collapsed to reveal the contents. * * When expanded, the widget will resize to fit the sizeHint of child items. * * @since 5.16 */ class KWIDGETSADDONS_EXPORT KCollapsibleGroupBox : public QWidget { Q_OBJECT Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged) Q_PROPERTY(bool expanded READ isExpanded WRITE setExpanded NOTIFY expandedChanged) public: - explicit KCollapsibleGroupBox(QWidget *parent = 0); + explicit KCollapsibleGroupBox(QWidget *parent = nullptr); virtual ~KCollapsibleGroupBox(); /** * Set the title that will be permanently shown at the top of the collapsing box * Mnemonics are supported */ void setTitle(const QString &title); /** * The title */ QString title() const; /** * Set whether contents are shown * * The default is false until the user clicks */ void setExpanded(bool expanded); /** * Whether contents are shown * During animations, this will reflect the target state at the end of the animation */ bool isExpanded() const; QSize sizeHint() const Q_DECL_OVERRIDE; QSize minimumSizeHint() const Q_DECL_OVERRIDE; public Q_SLOTS: /** * Expands if collapsed and vice versa */ void toggle(); /** * Equivalent to setExpanded(true) */ void expand(); /** * Equivalent to setExpanded(false) */ void collapse(); Q_SIGNALS: /** * Emitted when the title is changed */ void titleChanged(); /** * Emitted when the widget expands or collapsed */ void expandedChanged(); protected: void paintEvent(QPaintEvent*) Q_DECL_OVERRIDE; bool event(QEvent*) Q_DECL_OVERRIDE; void mousePressEvent(QMouseEvent*) Q_DECL_OVERRIDE; void mouseMoveEvent(QMouseEvent*) Q_DECL_OVERRIDE; void leaveEvent(QEvent*) Q_DECL_OVERRIDE; void keyPressEvent(QKeyEvent*) Q_DECL_OVERRIDE; void resizeEvent(QResizeEvent*) Q_DECL_OVERRIDE; private: KCollapsibleGroupBoxPrivate *const d; Q_DISABLE_COPY(KCollapsibleGroupBox) }; #endif diff --git a/src/kcolorbutton.cpp b/src/kcolorbutton.cpp index 3db3c6a..e5cb5e7 100644 --- a/src/kcolorbutton.cpp +++ b/src/kcolorbutton.cpp @@ -1,335 +1,335 @@ /* This file is part of the KDE libraries Copyright (C) 1997 Martin Jones (mjones@kde.org) Copyright (C) 1999 Cristian Tibirna (ctibirna@kde.org) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kcolorbutton.h" #include #include #include #include #include #include #include #include #include #include #include class KColorButton::KColorButtonPrivate { public: KColorButtonPrivate(KColorButton *q); void _k_chooseColor(); void _k_colorChosen(); KColorButton *q; QColor m_defaultColor; bool m_bdefaultColor : 1; bool m_alphaChannel : 1; QColor col; QPoint mPos; QPointer dialogPtr; void initStyleOption(QStyleOptionButton *opt) const; }; ///////////////////////////////////////////////////////////////////// // Functions duplicated from KColorMimeData // Should be kept in sync void _k_populateMimeData(QMimeData *mimeData, const QColor &color) { mimeData->setColorData(color); mimeData->setText(color.name()); } bool _k_canDecode(const QMimeData *mimeData) { if (mimeData->hasColor()) { return true; } if (mimeData->hasText()) { const QString colorName = mimeData->text(); if ((colorName.length() >= 4) && (colorName[0] == QLatin1Char('#'))) { return true; } } return false; } QColor _k_fromMimeData(const QMimeData *mimeData) { if (mimeData->hasColor()) { return mimeData->colorData().value(); } if (_k_canDecode(mimeData)) { return QColor(mimeData->text()); } return QColor(); } QDrag *_k_createDrag(const QColor &color, QObject *dragsource) { QDrag *drag = new QDrag(dragsource); QMimeData *mime = new QMimeData; _k_populateMimeData(mime, color); drag->setMimeData(mime); QPixmap colorpix(25, 20); colorpix.fill(color); QPainter p(&colorpix); p.setPen(Qt::black); p.drawRect(0, 0, 24, 19); p.end(); drag->setPixmap(colorpix); drag->setHotSpot(QPoint(-5, -7)); return drag; } ///////////////////////////////////////////////////////////////////// KColorButton::KColorButtonPrivate::KColorButtonPrivate(KColorButton *q) : q(q) { m_bdefaultColor = false; m_alphaChannel = false; q->setAcceptDrops(true); connect(q, SIGNAL(clicked()), q, SLOT(_k_chooseColor())); } KColorButton::KColorButton(QWidget *parent) : QPushButton(parent) , d(new KColorButtonPrivate(this)) { } KColorButton::KColorButton(const QColor &c, QWidget *parent) : QPushButton(parent) , d(new KColorButtonPrivate(this)) { d->col = c; } KColorButton::KColorButton(const QColor &c, const QColor &defaultColor, QWidget *parent) : QPushButton(parent) , d(new KColorButtonPrivate(this)) { d->col = c; setDefaultColor(defaultColor); } KColorButton::~KColorButton() { delete d; } QColor KColorButton::color() const { return d->col; } void KColorButton::setColor(const QColor &c) { if (d->col != c) { d->col = c; update(); emit changed(d->col); } } void KColorButton::setAlphaChannelEnabled(bool alpha) { d->m_alphaChannel = alpha; } bool KColorButton::isAlphaChannelEnabled() const { return d->m_alphaChannel; } QColor KColorButton::defaultColor() const { return d->m_defaultColor; } void KColorButton::setDefaultColor(const QColor &c) { d->m_bdefaultColor = c.isValid(); d->m_defaultColor = c; } void KColorButton::KColorButtonPrivate::initStyleOption(QStyleOptionButton *opt) const { opt->initFrom(q); opt->state |= q->isDown() ? QStyle::State_Sunken : QStyle::State_Raised; opt->features = QStyleOptionButton::None; if (q->isDefault()) { opt->features |= QStyleOptionButton::DefaultButton; } opt->text.clear(); opt->icon = QIcon(); } void KColorButton::paintEvent(QPaintEvent *) { QPainter painter(this); QStyle *style = QWidget::style(); //First, we need to draw the bevel. QStyleOptionButton butOpt; d->initStyleOption(&butOpt); style->drawControl(QStyle::CE_PushButtonBevel, &butOpt, &painter, this); //OK, now we can muck around with drawing out pretty little color box //First, sort out where it goes QRect labelRect = style->subElementRect(QStyle::SE_PushButtonContents, &butOpt, this); int shift = style->pixelMetric(QStyle::PM_ButtonMargin, &butOpt, this) / 2; labelRect.adjust(shift, shift, -shift, -shift); int x, y, w, h; labelRect.getRect(&x, &y, &w, &h); if (isChecked() || isDown()) { x += style->pixelMetric(QStyle::PM_ButtonShiftHorizontal, &butOpt, this); y += style->pixelMetric(QStyle::PM_ButtonShiftVertical, &butOpt, this); } QColor fillCol = isEnabled() ? d->col : palette().color(backgroundRole()); - qDrawShadePanel(&painter, x, y, w, h, palette(), true, 1, NULL); + qDrawShadePanel(&painter, x, y, w, h, palette(), true, 1, nullptr); if (fillCol.isValid()) { const QRect rect(x + 1, y + 1, w - 2, h - 2); if (fillCol.alpha() < 255) { QPixmap chessboardPattern(16, 16); QPainter patternPainter(&chessboardPattern); patternPainter.fillRect(0, 0, 8, 8, Qt::black); patternPainter.fillRect(8, 8, 8, 8, Qt::black); patternPainter.fillRect(0, 8, 8, 8, Qt::white); patternPainter.fillRect(8, 0, 8, 8, Qt::white); patternPainter.end(); painter.fillRect(rect, QBrush(chessboardPattern)); } painter.fillRect(rect, fillCol); } if (hasFocus()) { QRect focusRect = style->subElementRect(QStyle::SE_PushButtonFocusRect, &butOpt, this); QStyleOptionFocusRect focusOpt; focusOpt.init(this); focusOpt.rect = focusRect; focusOpt.backgroundColor = palette().background().color(); style->drawPrimitive(QStyle::PE_FrameFocusRect, &focusOpt, &painter, this); } } QSize KColorButton::sizeHint() const { QStyleOptionButton opt; d->initStyleOption(&opt); return style()->sizeFromContents(QStyle::CT_PushButton, &opt, QSize(40, 15), this). expandedTo(QApplication::globalStrut()); } QSize KColorButton::minimumSizeHint() const { QStyleOptionButton opt; d->initStyleOption(&opt); return style()->sizeFromContents(QStyle::CT_PushButton, &opt, QSize(3, 3), this). expandedTo(QApplication::globalStrut()); } void KColorButton::dragEnterEvent(QDragEnterEvent *event) { event->setAccepted(_k_canDecode(event->mimeData()) && isEnabled()); } void KColorButton::dropEvent(QDropEvent *event) { QColor c = _k_fromMimeData(event->mimeData()); if (c.isValid()) { setColor(c); } } void KColorButton::keyPressEvent(QKeyEvent *e) { int key = e->key() | e->modifiers(); if (QKeySequence::keyBindings(QKeySequence::Copy).contains(key)) { QMimeData *mime = new QMimeData; _k_populateMimeData(mime, color()); QApplication::clipboard()->setMimeData(mime, QClipboard::Clipboard); } else if (QKeySequence::keyBindings(QKeySequence::Paste).contains(key)) { QColor color = _k_fromMimeData(QApplication::clipboard()->mimeData(QClipboard::Clipboard)); setColor(color); } else { QPushButton::keyPressEvent(e); } } void KColorButton::mousePressEvent(QMouseEvent *e) { d->mPos = e->pos(); QPushButton::mousePressEvent(e); } void KColorButton::mouseMoveEvent(QMouseEvent *e) { if ((e->buttons() & Qt::LeftButton) && (e->pos() - d->mPos).manhattanLength() > QApplication::startDragDistance()) { _k_createDrag(color(), this)->start(); setDown(false); } } void KColorButton::KColorButtonPrivate::_k_chooseColor() { QColorDialog *dialog = dialogPtr.data(); if (dialog) { dialog->show(); dialog->raise(); dialog->activateWindow(); return; } dialog = new QColorDialog(q); dialog->setCurrentColor(q->color()); dialog->setOption(QColorDialog::ShowAlphaChannel, m_alphaChannel); dialog->setAttribute(Qt::WA_DeleteOnClose); connect(dialog, SIGNAL(accepted()), q, SLOT(_k_colorChosen())); dialogPtr = dialog; dialog->show(); } void KColorButton::KColorButtonPrivate::_k_colorChosen() { QColorDialog *dialog = dialogPtr.data(); if (!dialog) { return; } if (dialog->selectedColor().isValid()) { q->setColor(dialog->selectedColor()); } else if (m_bdefaultColor) { q->setColor(m_defaultColor); } } #include "moc_kcolorbutton.cpp" diff --git a/src/kcolorbutton.h b/src/kcolorbutton.h index 93902ba..6232e9a 100644 --- a/src/kcolorbutton.h +++ b/src/kcolorbutton.h @@ -1,123 +1,123 @@ /* This file is part of the KDE libraries Copyright (C) 1997 Martin Jones (mjones@kde.org) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KCOLORBUTTON_H #define KCOLORBUTTON_H #include #include class KColorButtonPrivate; /** * @short A pushbutton to display or allow user selection of a color. * * This widget can be used to display or allow user selection of a color. * * @see QColorDialog * * \image html kcolorbutton.png "KDE Color Button" */ class KWIDGETSADDONS_EXPORT KColorButton : public QPushButton { Q_OBJECT Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY changed USER true) Q_PROPERTY(QColor defaultColor READ defaultColor WRITE setDefaultColor) Q_PROPERTY(bool alphaChannelEnabled READ isAlphaChannelEnabled WRITE setAlphaChannelEnabled) public: /** * Creates a color button. */ - explicit KColorButton(QWidget *parent = 0); + explicit KColorButton(QWidget *parent = nullptr); /** * Creates a color button with an initial color @p c. */ - explicit KColorButton(const QColor &c, QWidget *parent = 0); + explicit KColorButton(const QColor &c, QWidget *parent = nullptr); /** * Creates a color button with an initial color @p c and default color @p defaultColor. */ - KColorButton(const QColor &c, const QColor &defaultColor, QWidget *parent = 0); + KColorButton(const QColor &c, const QColor &defaultColor, QWidget *parent = nullptr); virtual ~KColorButton(); /** * Returns the currently chosen color. */ QColor color() const; /** * Sets the current color to @p c. */ void setColor(const QColor &c); /** * When set to true, allow the user to change the alpha component * of the color. The default value is false. * @since 4.5 */ void setAlphaChannelEnabled(bool alpha); /** * Returns true if the user is allowed to change the alpha component. * @since 4.5 */ bool isAlphaChannelEnabled() const; /** * Returns the default color or an invalid color * if no default color is set. */ QColor defaultColor() const; /** * Sets the default color to @p c. */ void setDefaultColor(const QColor &c); QSize sizeHint() const Q_DECL_OVERRIDE; QSize minimumSizeHint() const Q_DECL_OVERRIDE; Q_SIGNALS: /** * Emitted when the color of the widget * is changed, either with setColor() or via user selection. */ void changed(const QColor &newColor); protected: void paintEvent(QPaintEvent *pe) Q_DECL_OVERRIDE; void dragEnterEvent(QDragEnterEvent *) Q_DECL_OVERRIDE; void dropEvent(QDropEvent *) Q_DECL_OVERRIDE; void mousePressEvent(QMouseEvent *e) Q_DECL_OVERRIDE; void mouseMoveEvent(QMouseEvent *e) Q_DECL_OVERRIDE; void keyPressEvent(QKeyEvent *e) Q_DECL_OVERRIDE; private: class KColorButtonPrivate; KColorButtonPrivate *const d; Q_PRIVATE_SLOT(d, void _k_chooseColor()) Q_PRIVATE_SLOT(d, void _k_colorChosen()) }; #endif diff --git a/src/kcolorcombo.cpp b/src/kcolorcombo.cpp index 92bf403..91bff87 100644 --- a/src/kcolorcombo.cpp +++ b/src/kcolorcombo.cpp @@ -1,354 +1,354 @@ /* This file is part of the KDE libraries Copyright (C) 1997 Martin Jones (mjones@kde.org) Copyright (C) 2007 Pino Toscano (pino@kde.org) Copyright (c) 2007 David Jarvie (software@astrojar.org.uk) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kcolorcombo.h" #include #include #include #include class KColorComboDelegate : public QAbstractItemDelegate { public: enum ItemRoles { ColorRole = Qt::UserRole + 1 }; enum LayoutMetrics { FrameMargin = 3 }; - KColorComboDelegate(QObject *parent = 0); + KColorComboDelegate(QObject *parent = nullptr); virtual ~KColorComboDelegate(); void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE; QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE; }; static QBrush k_colorcombodelegate_brush(const QModelIndex &index, int role) { QBrush brush; QVariant v = index.data(role); if (v.type() == QVariant::Brush) { brush = v.value(); } else if (v.type() == QVariant::Color) { brush = QBrush(v.value()); } return brush; } KColorComboDelegate::KColorComboDelegate(QObject *parent) : QAbstractItemDelegate(parent) { } KColorComboDelegate::~KColorComboDelegate() { } void KColorComboDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { // background QColor innercolor(Qt::white); bool isSelected = (option.state & QStyle::State_Selected); bool paletteBrush = (k_colorcombodelegate_brush(index, Qt::BackgroundRole).style() == Qt::NoBrush); if (isSelected) { innercolor = option.palette.color(QPalette::Highlight); } else { innercolor = option.palette.color(QPalette::Base); } // highlight selected item QStyleOptionViewItem opt(option); opt.showDecorationSelected = true; QStyle *style = opt.widget ? opt.widget->style() : QApplication::style(); style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget); QRect innerrect = option.rect.adjusted(FrameMargin, FrameMargin, -FrameMargin, -FrameMargin); // inner color QVariant cv = index.data(ColorRole); if (cv.type() == QVariant::Color) { QColor tmpcolor = cv.value(); if (tmpcolor.isValid()) { innercolor = tmpcolor; paletteBrush = false; painter->setPen(Qt::transparent); painter->setBrush(innercolor); QPainter::RenderHints tmpHint = painter->renderHints(); painter->setRenderHint(QPainter::Antialiasing); painter->drawRoundedRect(innerrect, 2, 2); painter->setRenderHints(tmpHint); painter->setBrush(Qt::NoBrush); } } // text QVariant tv = index.data(Qt::DisplayRole); if (tv.type() == QVariant::String) { QString text = tv.toString(); QColor textColor; if (paletteBrush) { if (isSelected) { textColor = option.palette.color(QPalette::HighlightedText); } else { textColor = option.palette.color(QPalette::Text); } } else { int unused, v; innercolor.getHsv(&unused, &unused, &v); if (v > 128) { textColor = Qt::black; } else { textColor = Qt::white; } } painter->setPen(textColor); painter->drawText(innerrect.adjusted(1, 1, -1, -1), text); } } QSize KColorComboDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { Q_UNUSED(index) // the width does not matter, as the view will always use the maximum width available return QSize(100, option.fontMetrics.height() + 2 * FrameMargin); } static const uchar standardPalette[][4] = { { 255, 255, 255 }, // white { 192, 192, 192 }, // light gray { 160, 160, 160 }, // gray { 128, 128, 128 }, // dark gray { 0, 0, 0 }, // black { 255, 128, 128 }, //light red { 255, 192, 128 }, //light orange { 255, 255, 128 }, //light yellow { 128, 255, 128 }, //light green { 128, 255, 255 }, //cyan blue { 128, 128, 255 }, //light blue { 255, 128, 255 }, //light violet { 255, 0, 0 }, //red { 255, 128, 0 }, //orange { 255, 255, 0 }, //yellow { 0, 255, 0 }, //green { 0, 255, 255 }, //light blue { 0, 0, 255 }, //blue { 255, 0, 255 }, //violet { 128, 0, 0 }, //dark red { 128, 64, 0 }, //dark orange { 128, 128, 0 }, //dark yellow { 0, 128, 0 }, //dark green { 0, 128, 128 }, //dark light blue { 0, 0, 128 }, //dark blue { 128, 0, 128 } //dark violet }; #define STANDARD_PALETTE_SIZE (int(sizeof(standardPalette) / sizeof(*standardPalette))) static inline QColor standardColor(int i) { const uchar *entry = standardPalette[i]; return QColor(entry[0], entry[1], entry[2]); } class KColorComboPrivate { public: KColorComboPrivate(KColorCombo *qq); void addColors(); void setCustomColor(const QColor &color, bool lookupInPresets = true); // slots void _k_slotActivated(int index); void _k_slotHighlighted(int index); KColorCombo *q; QList colorList; QColor customColor; QColor internalcolor; }; KColorComboPrivate::KColorComboPrivate(KColorCombo *qq) : q(qq), customColor(Qt::white) { } void KColorComboPrivate::setCustomColor(const QColor &color, bool lookupInPresets) { if (lookupInPresets) { if (colorList.isEmpty()) { for (int i = 0; i < STANDARD_PALETTE_SIZE; ++i) { if (standardColor(i) == color) { q->setCurrentIndex(i + 1); internalcolor = color; return; } } } else { int i = colorList.indexOf(color); if (i >= 0) { q->setCurrentIndex(i + 1); internalcolor = color; return; } } } internalcolor = color; customColor = color; q->setItemData(0, customColor, KColorComboDelegate::ColorRole); } KColorCombo::KColorCombo(QWidget *parent) : QComboBox(parent), d(new KColorComboPrivate(this)) { setItemDelegate(new KColorComboDelegate(this)); d->addColors(); connect(this, SIGNAL(activated(int)), SLOT(_k_slotActivated(int))); connect(this, SIGNAL(highlighted(int)), SLOT(_k_slotHighlighted(int))); // select the white color setCurrentIndex(1); d->_k_slotActivated(1); setMaxVisibleItems(13); } KColorCombo::~KColorCombo() { delete d; } void KColorCombo::setColors(const QList &colors) { clear(); d->colorList = colors; d->addColors(); } QList KColorCombo::colors() const { if (d->colorList.isEmpty()) { QList list; for (int i = 0; i < STANDARD_PALETTE_SIZE; ++i) { list += standardColor(i); } return list; } else { return d->colorList; } } void KColorCombo::setColor(const QColor &col) { if (!col.isValid()) { return; } if (count() == 0) { d->addColors(); } d->setCustomColor(col, true); } QColor KColorCombo::color() const { return d->internalcolor; } bool KColorCombo::isCustomColor() const { return d->internalcolor == d->customColor; } void KColorCombo::paintEvent(QPaintEvent *event) { Q_UNUSED(event) QStylePainter painter(this); painter.setPen(palette().color(QPalette::Text)); QStyleOptionComboBox opt; initStyleOption(&opt); painter.drawComplexControl(QStyle::CC_ComboBox, opt); QRect frame = style()->subControlRect(QStyle::CC_ComboBox, &opt, QStyle::SC_ComboBoxEditField, this); painter.setRenderHint(QPainter::Antialiasing); painter.setPen(Qt::transparent); painter.setBrush(QBrush(d->internalcolor)); painter.drawRoundedRect(frame.adjusted(1, 1, -1, -1), 2, 2); } void KColorCombo::showEmptyList() { clear(); } void KColorComboPrivate::_k_slotActivated(int index) { if (index == 0) { QColor c = QColorDialog::getColor(customColor, q); if (c.isValid()) { customColor = c; setCustomColor(customColor, false); } } else if (colorList.isEmpty()) { internalcolor = standardColor(index - 1); } else { internalcolor = colorList[index - 1]; } emit q->activated(internalcolor); } void KColorComboPrivate::_k_slotHighlighted(int index) { if (index == 0) { internalcolor = customColor; } else if (colorList.isEmpty()) { internalcolor = standardColor(index - 1); } else { internalcolor = colorList[index - 1]; } emit q->highlighted(internalcolor); } void KColorComboPrivate::addColors() { q->addItem(KColorCombo::tr("Custom...", "Custom color")); if (colorList.isEmpty()) { for (int i = 0; i < STANDARD_PALETTE_SIZE; ++i) { q->addItem(QString()); q->setItemData(i + 1, standardColor(i), KColorComboDelegate::ColorRole); } } else { for (int i = 0, count = colorList.count(); i < count; ++i) { q->addItem(QString()); q->setItemData(i + 1, colorList[i], KColorComboDelegate::ColorRole); } } } #include "moc_kcolorcombo.cpp" diff --git a/src/kcolorcombo.h b/src/kcolorcombo.h index 98fb0eb..e437e87 100644 --- a/src/kcolorcombo.h +++ b/src/kcolorcombo.h @@ -1,115 +1,115 @@ /* This file is part of the KDE libraries Copyright (C) 1997 Martin Jones (mjones@kde.org) Copyright (c) 2007 David Jarvie (software@astrojar.org.uk) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ //----------------------------------------------------------------------------- // KDE color selection combo box // layout management added Oct 1997 by Mario Weilguni // #ifndef KCOLORCOMBO_H #define KCOLORCOMBO_H #include #include #include class KColorComboPrivate; /** * Combobox for colors. * * The combobox provides some preset colors to be selected, and an entry to * select a custom color using a color dialog. * * \image html kcolorcombo.png "KDE Color Combo Box" */ class KWIDGETSADDONS_EXPORT KColorCombo : public QComboBox { Q_OBJECT Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY activated USER true) Q_PROPERTY(QList colors READ colors WRITE setColors) public: /** * Constructs a color combo box. */ - explicit KColorCombo(QWidget *parent = 0); + explicit KColorCombo(QWidget *parent = nullptr); ~KColorCombo(); /** * Selects the color @p col. */ void setColor(const QColor &col); /** * Returns the currently selected color. **/ QColor color() const; /** * Find whether the currently selected color is a custom color selected * using a color dialog. **/ bool isCustomColor() const; /** * Set a custom list of colors to choose from, in place of the standard * list. * @param cols list of colors. If empty, the selection list reverts to * the standard list. **/ void setColors(const QList &colors); /** * Return the list of colors available for selection. * @return list of colors **/ QList colors() const; /** * Clear the color list and don't show it, till the next setColor() call **/ void showEmptyList(); Q_SIGNALS: /** * Emitted when a new color box has been selected. */ void activated(const QColor &col); /** * Emitted when a new item has been highlighted. */ void highlighted(const QColor &col); protected: void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; private: friend class KColorComboPrivate; KColorComboPrivate *const d; Q_DISABLE_COPY(KColorCombo) Q_PRIVATE_SLOT(d, void _k_slotActivated(int)) Q_PRIVATE_SLOT(d, void _k_slotHighlighted(int)) }; #endif // KCOLORCOMBO_H diff --git a/src/kcolumnresizer.h b/src/kcolumnresizer.h index 6855f57..83aeb6d 100644 --- a/src/kcolumnresizer.h +++ b/src/kcolumnresizer.h @@ -1,126 +1,126 @@ /* This file is part of the KDE frameworks * * Copyright (c) 2014 Aurélien Gâteau * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA */ #ifndef KCOLUMNRESIZER_H #define KCOLUMNRESIZER_H #include #include #include class QEvent; class QGridLayout; class QLayout; class QWidget; class KColumnResizerPrivate; /** * @short Maintains consistent column sizes across layouts * * KColumnResizer is a helper class which can force columns of different layouts * to keep the same width. It is useful to keep label columns consistent. * * It works with QGridLayout and QFormLayout. * * @image html kcolumnresizer.png "left: without KColumnResizer - right: with KColumnResizer" * * Here is a typical example: * * @code * void Window::createWidgets() * { * QVBoxLayout *layout = new QVBoxLayout(this); * * QGroupBox *box1 = new QGroupBox(); * // Fill box1 * // ... * layout->addWidget(box1); * * QGroupBox *box2 = new QGroupBox(); * // Fill box2 * // ... * layout->addWidget(box2); * * KColumnResizer *resizer = new KColumnResizer(this); * resizer->addWidgetsFromLayout(box1->layout(), 0); * resizer->addWidgetsFromLayout(box2->layout(), 0); * } * @endcode * * In this example box1 and box2 children can be organized using QGridLayout or * QFormLayout, resizer will ensure the first columns of the two QGroupBox stay * the same width. * * @author Aurélien Gâteau * * @since 5.1 */ class KWIDGETSADDONS_EXPORT KColumnResizer : public QObject { Q_OBJECT public: /** * Constructs a KColumnResizer. */ - explicit KColumnResizer(QObject *parent = 0); + explicit KColumnResizer(QObject *parent = nullptr); ~KColumnResizer(); /** * Add all widgets from @p layout which are in column @p column to the list * of widgets to manage. * * @param layout The layout containing the widgets to add. KColumnResizer * supports QGridLayout and QFormLayout. * @param column The column number which contains the widgets. If layout is * a QFormLayout, column should not be higher than QFormLayout::SpanningRole */ void addWidgetsFromLayout(QLayout *layout, int column = 0); /** * Add a single widget to the list of widgets whose width is monitored. * * It is more common to use addWidgetsFromLayout(), but adding single * widgets can be useful if you want to keep a single button the same width * as a column in a layout. * * @param widget The widget to add */ void addWidget(QWidget *widget); /** * Remove a widget previously added by addWidget or addWidgetsFromLayout. * * @param widget The widget to remove */ void removeWidget(QWidget *widget); protected: bool eventFilter(QObject *, QEvent *event) Q_DECL_OVERRIDE; private: KColumnResizerPrivate *const d; Q_DISABLE_COPY(KColumnResizer) Q_PRIVATE_SLOT(d, void updateWidth()) }; #endif /* KCOLUMNRESIZER_H */ diff --git a/src/kcursor.cpp b/src/kcursor.cpp index 22bff24..41fea34 100644 --- a/src/kcursor.cpp +++ b/src/kcursor.cpp @@ -1,274 +1,274 @@ /* This file is part of the KDE libraries Copyright (C) 1998 Kurt Granroth (granroth@kde.org) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kcursor.h" #include "kcursor_p.h" #include #include #include #include #include #include void KCursor::setAutoHideCursor(QWidget *w, bool enable, bool customEventFilter) { KCursorPrivate::self()->setAutoHideCursor(w, enable, customEventFilter); } void KCursor::autoHideEventFilter(QObject *o, QEvent *e) { KCursorPrivate::self()->eventFilter(o, e); } void KCursor::setHideCursorDelay(int ms) { KCursorPrivate::self()->hideCursorDelay = ms; } int KCursor::hideCursorDelay() { return KCursorPrivate::self()->hideCursorDelay; } // ************************************************************************** KCursorPrivateAutoHideEventFilter::KCursorPrivateAutoHideEventFilter(QWidget *widget) : m_widget(widget) , m_wasMouseTracking(m_widget->hasMouseTracking()) , m_isCursorHidden(false) , m_isOwnCursor(false) { mouseWidget()->setMouseTracking(true); connect(&m_autoHideTimer, &QTimer::timeout, this, &KCursorPrivateAutoHideEventFilter::hideCursor); } KCursorPrivateAutoHideEventFilter::~KCursorPrivateAutoHideEventFilter() { - if (m_widget != NULL) { + if (m_widget != nullptr) { mouseWidget()->setMouseTracking(m_wasMouseTracking); } } void KCursorPrivateAutoHideEventFilter::resetWidget() { - m_widget = NULL; + m_widget = nullptr; } void KCursorPrivateAutoHideEventFilter::hideCursor() { m_autoHideTimer.stop(); if (m_isCursorHidden) { return; } m_isCursorHidden = true; QWidget *w = mouseWidget(); m_isOwnCursor = w->testAttribute(Qt::WA_SetCursor); if (m_isOwnCursor) { m_oldCursor = w->cursor(); } w->setCursor(QCursor(Qt::BlankCursor)); } void KCursorPrivateAutoHideEventFilter::unhideCursor() { m_autoHideTimer.stop(); if (!m_isCursorHidden) { return; } m_isCursorHidden = false; QWidget *w = mouseWidget(); if (w->cursor().shape() != Qt::BlankCursor) { // someone messed with the cursor already return; } if (m_isOwnCursor) { w->setCursor(m_oldCursor); } else { w->unsetCursor(); } } // The widget which gets mouse events, and that shows the cursor // (that is the viewport, for a QAbstractScrollArea) QWidget *KCursorPrivateAutoHideEventFilter::mouseWidget() const { QWidget *w = m_widget; // Is w a QAbstractScrollArea ? Call setCursor on the viewport in that case. QAbstractScrollArea *sv = qobject_cast(w); if (sv) { w = sv->viewport(); } return w; } bool KCursorPrivateAutoHideEventFilter::eventFilter(QObject *o, QEvent *e) { Q_UNUSED(o); // o is m_widget or its viewport //Q_ASSERT( o == m_widget ); switch (e->type()) { case QEvent::Leave: case QEvent::FocusOut: case QEvent::WindowDeactivate: unhideCursor(); break; case QEvent::KeyPress: case QEvent::ShortcutOverride: hideCursor(); break; case QEvent::Enter: case QEvent::FocusIn: case QEvent::MouseButtonPress: case QEvent::MouseButtonRelease: case QEvent::MouseButtonDblClick: case QEvent::MouseMove: case QEvent::Show: case QEvent::Hide: case QEvent::Wheel: unhideCursor(); if (m_widget->hasFocus()) { m_autoHideTimer.setSingleShot(true); m_autoHideTimer.start(KCursorPrivate::self()->hideCursorDelay); } break; default: break; } return false; } -KCursorPrivate *KCursorPrivate::s_self = 0L; +KCursorPrivate *KCursorPrivate::s_self = nullptr; KCursorPrivate *KCursorPrivate::self() { if (!s_self) { s_self = new KCursorPrivate; } // WABA: Don't delete KCursorPrivate, it serves no real purpose. // Even worse it causes crashes because it seems to get deleted // during ~QApplication and ~QApplication doesn't seem to like it // when we delete a QCursor. No idea if that is a bug itself. return s_self; } KCursorPrivate::KCursorPrivate() { hideCursorDelay = 5000; // 5s default value enabled = true; } KCursorPrivate::~KCursorPrivate() { } void KCursorPrivate::setAutoHideCursor(QWidget *w, bool enable, bool customEventFilter) { if (!w || !enabled) { return; } - QWidget *viewport = 0; + QWidget *viewport = nullptr; QAbstractScrollArea *sv = qobject_cast(w); if (sv) { viewport = sv->viewport(); } if (enable) { if (m_eventFilters.contains(w)) { return; } KCursorPrivateAutoHideEventFilter *filter = new KCursorPrivateAutoHideEventFilter(w); m_eventFilters.insert(w, filter); if (viewport) { m_eventFilters.insert(viewport, filter); connect(viewport, &QObject::destroyed, this, &KCursorPrivate::slotViewportDestroyed); } if (!customEventFilter) { w->installEventFilter(filter); // for key events if (viewport) { viewport->installEventFilter(filter); // for mouse events } } connect(w, &QObject::destroyed, this, &KCursorPrivate::slotWidgetDestroyed); } else { KCursorPrivateAutoHideEventFilter *filter = m_eventFilters.take(w); - if (filter == 0) { + if (filter == nullptr) { return; } w->removeEventFilter(filter); if (viewport) { m_eventFilters.remove(viewport); disconnect(viewport, &QObject::destroyed, this, &KCursorPrivate::slotViewportDestroyed); viewport->removeEventFilter(filter); } delete filter; disconnect(w, &QObject::destroyed, this, &KCursorPrivate::slotWidgetDestroyed); } } bool KCursorPrivate::eventFilter(QObject *o, QEvent *e) { if (!enabled || e->type() == QEvent::ChildAdded) { return false; } KCursorPrivateAutoHideEventFilter *filter = m_eventFilters.value(o); - Q_ASSERT(filter != 0); - if (filter == 0) { + Q_ASSERT(filter != nullptr); + if (filter == nullptr) { return false; } return filter->eventFilter(o, e); } void KCursorPrivate::slotViewportDestroyed(QObject *o) { m_eventFilters.remove(o); } void KCursorPrivate::slotWidgetDestroyed(QObject *o) { KCursorPrivateAutoHideEventFilter *filter = m_eventFilters.take(o); - Q_ASSERT(filter != 0); + Q_ASSERT(filter != nullptr); filter->resetWidget(); // so that dtor doesn't access it delete filter; } #include "moc_kcursor_p.cpp" diff --git a/src/kdatecombobox.h b/src/kdatecombobox.h index 3979600..b2c042a 100644 --- a/src/kdatecombobox.h +++ b/src/kdatecombobox.h @@ -1,311 +1,311 @@ /* Copyright 2011 John Layt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KDATECOMBOBOX_H #define KDATECOMBOBOX_H #include #include #include class KDateComboBoxPrivate; class KWIDGETSADDONS_EXPORT KDateComboBox : public QComboBox { Q_OBJECT Q_PROPERTY(QDate date READ date WRITE setDate NOTIFY dateChanged USER true) Q_PROPERTY(QDate minimumDate READ minimumDate WRITE setMinimumDate RESET resetMinimumDate) Q_PROPERTY(QDate maximumDate READ maximumDate WRITE setMaximumDate RESET resetMaximumDate) Q_PROPERTY(Options options READ options WRITE setOptions) public: /** * Options provided by the widget * @see options() * @see setOptions() */ enum Option { EditDate = 0x0001, /**< Allow the user to manually edit the date in the combo line edit */ SelectDate = 0x0002, /**< Allow the user to select the date from a drop-down menu */ DatePicker = 0x0004, /**< Show a date picker in the drop-down */ DateKeywords = 0x0008, /**< Show date keywords in the drop-down */ WarnOnInvalid = 0x0010 /**< Show a warning on focus out if the date is invalid */ }; Q_DECLARE_FLAGS(Options, Option) Q_FLAG(Options) /** * Create a new KDateComboBox widget * * By default the EditDate, SelectDate, DatePicker and DateKeywords options * are enabled, the ShortDate format is used and the date is set to the * current date. */ - explicit KDateComboBox(QWidget *parent = 0); + explicit KDateComboBox(QWidget *parent = nullptr); /** * Destroy the widget */ virtual ~KDateComboBox(); /** * Return the currently selected date * * @return the currently selected date */ QDate date() const; /** * Return if the current user input is valid * * If the user input is null then it is not valid * * @see isNull() * @return if the current user input is valid */ bool isValid() const; /** * Return if the current user input is null * * @see isValid() * @return if the current user input is null */ bool isNull() const; /** * Return the currently set widget options * * @return the currently set widget options */ Options options() const; /** * Return the currently set date display format * * By default this is the Short Format * * @return the currently set date format */ QLocale::FormatType displayFormat() const; /** * Return the current minimum date * * @return the current minimum date */ QDate minimumDate() const; /** * Return the current maximum date * * @return the current maximum date */ QDate maximumDate() const; /** * Return the map of dates listed in the drop-down and their displayed * string forms. * * @see setDateMap() * @return the select date map */ QMap dateMap() const; Q_SIGNALS: /** * Signal if the date has been manually entered or selected by the user. * * The returned date may be invalid. * * @param date the new date */ void dateEntered(const QDate &date); /** * Signal if the date has been changed either manually by the user * or programatically. * * The returned date may be invalid. * * @param date the new date */ void dateChanged(const QDate &date); /** * Signal if the date is being manually edited by the user. * * The returned date may be invalid. * * @param date the new date */ void dateEdited(const QDate &date); public Q_SLOTS: /** * Set the currently selected date * * You can set an invalid date or a date outside the valid range, validity * checking is only done via isValid(). * * @param date the new date */ void setDate(const QDate &date); /** * Set the new widget options * * @param options the new widget options */ void setOptions(Options options); /** * Sets the date format to display. * * By default is the Short Format. * * @param format the date format to use */ void setDisplayFormat(QLocale::FormatType format); /** * Set the valid date range to be applied by isValid(). * * Both dates must be valid and the minimum date must be less than or equal * to the maximum date, otherwise the date range will not be set. * * @param minDate the minimum date * @param maxDate the maximum date * @param minWarnMsg the minimum warning message * @param maxWarnMsg the maximum warning message */ void setDateRange(const QDate &minDate, const QDate &maxDate, const QString &minWarnMsg = QString(), const QString &maxWarnMsg = QString()); /** * Reset the minimum and maximum date to the default values. * @see setDateRange() */ void resetDateRange(); /** * Set the minimum allowed date. * * If the date is invalid, or greater than current maximum, * then the minimum will not be set. * * @see minimumDate() * @see maximumDate() * @see setMaximumDate() * @see setDateRange() * @param minDate the minimum date * @param minWarnMsg the minimum warning message */ void setMinimumDate(const QDate &minTime, const QString &minWarnMsg = QString()); /** * Reset the minimum date to the default. * * The default is to have no minimum date. */ void resetMinimumDate(); /** * Set the maximum allowed date. * * If the date is invalid, or less than current minimum, * then the maximum will not be set. * * @see minimumDate() * @see maximumDate() * @see setMaximumDate() * @see setDateRange() * @param maxDate the maximum date * @param maxWarnMsg the maximum warning message */ void setMaximumDate(const QDate &maxDate, const QString &maxWarnMsg = QString()); /** * Reset the maximum date to the default * * The default is to have no maximum date. */ void resetMaximumDate(); /** * Set the list of dates able to be selected from the drop-down and the * string form to display for those dates, e.g. "2010-01-01" and "Yesterday". * * Any invalid or duplicate dates will be used, the list will NOT be * sorted, and the minimum and maximum date will not be affected. * * The @p dateMap is keyed by the date to be listed and the value is the * string to be displayed. If you want the date to be displayed in the * default date format then the string should be null. If you want a * separator to be displayed then set the string to "separator". * * @see dateMap() * @param dateMap the map of dates able to be selected */ void setDateMap(QMap dateMap); protected: bool eventFilter(QObject *object, QEvent *event) Q_DECL_OVERRIDE; void showPopup() Q_DECL_OVERRIDE; void hidePopup() Q_DECL_OVERRIDE; void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE; void focusInEvent(QFocusEvent *event) Q_DECL_OVERRIDE; void focusOutEvent(QFocusEvent *event) Q_DECL_OVERRIDE; void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; /** * Assign the date for the widget. * * Virtual to allow sub-classes to apply extra validation rules. * * @param date the new date */ virtual void assignDate(const QDate &date); private: friend class KDateComboBoxPrivate; KDateComboBoxPrivate *const d; Q_PRIVATE_SLOT(d, void clickDate()) Q_PRIVATE_SLOT(d, void selectDate(QAction *)) Q_PRIVATE_SLOT(d, void editDate(const QString &)) Q_PRIVATE_SLOT(d, void enterDate(const QDate &)) Q_PRIVATE_SLOT(d, void parseDate()) }; Q_DECLARE_OPERATORS_FOR_FLAGS(KDateComboBox::Options) #endif // KDATECOMBOBOX_H diff --git a/src/kdatepicker.cpp b/src/kdatepicker.cpp index 712cb9b..6196fa8 100644 --- a/src/kdatepicker.cpp +++ b/src/kdatepicker.cpp @@ -1,657 +1,657 @@ /* -*- C++ -*- This file is part of the KDE libraries Copyright (C) 1997 Tim D. Gilman (tdgilman@best.org) (C) 1998-2001 Mirko Boehm (mirko@kde.org) (C) 2007 John Layt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kdatepicker.h" #include "kdatepicker_p.h" #include "kdatetable_p.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "moc_kdatepicker.cpp" #include "moc_kdatepicker_p.cpp" class DatePickerValidator : public QValidator { public: DatePickerValidator(KDatePicker *parent) : QValidator(parent), picker(parent) {} State validate(QString &text, int &) const Q_DECL_OVERRIDE { QLocale::FormatType formats[] = { QLocale::LongFormat, QLocale::ShortFormat, QLocale::NarrowFormat }; QLocale locale = picker->locale(); for (int i = 0; i < 3; i++) { QDate tmp = locale.toDate(text, formats[i]); if (tmp.isValid()) { return Acceptable; } } return QValidator::Intermediate; } private: KDatePicker *picker; }; // Week numbers are defined by ISO 8601 // See http://www.merlyn.demon.co.uk/weekinfo.htm for details KDatePickerPrivateYearSelector::KDatePickerPrivateYearSelector( const QDate ¤tDate, QWidget *parent) : QLineEdit(parent), val(new QIntValidator(this)), result(0) { oldDate = currentDate; setFont(QFontDatabase::systemFont(QFontDatabase::GeneralFont)); setFrame(false); // TODO: Find a way to get that from QLocale //val->setRange( calendar->year( calendar->earliestValidDate() ), // calendar->year( calendar->latestValidDate() ) ); setValidator(val); connect(this, &QLineEdit::returnPressed, this, &KDatePickerPrivateYearSelector::yearEnteredSlot); } void KDatePickerPrivateYearSelector::yearEnteredSlot() { bool ok; int newYear; // check if entered value is a number newYear = text().toInt(&ok); if (!ok) { QApplication::beep(); return; } // check if new year will lead to a valid date if (QDate(newYear, oldDate.month(), oldDate.day()).isValid()) { result = newYear; emit(closeMe(1)); } else { QApplication::beep(); } } int KDatePickerPrivateYearSelector::year() { return result; } void KDatePickerPrivateYearSelector::setYear(int year) { setText(QString::number(year)); } class KDatePicker::KDatePickerPrivate { public: KDatePickerPrivate(KDatePicker *q) : - q(q), closeButton(0L), selectWeek(0L), todayButton(0), navigationLayout(0) + q(q), closeButton(nullptr), selectWeek(nullptr), todayButton(nullptr), navigationLayout(nullptr) { } void fillWeeksCombo(); QDate validDateInYearMonth(int year, int month); /// the date table KDatePicker *q; QToolButton *closeButton; QComboBox *selectWeek; QToolButton *todayButton; QBoxLayout *navigationLayout; /// the year forward button QToolButton *yearForward; /// the year backward button QToolButton *yearBackward; /// the month forward button QToolButton *monthForward; /// the month backward button QToolButton *monthBackward; /// the button for selecting the month directly QToolButton *selectMonth; /// the button for selecting the year directly QToolButton *selectYear; /// the line edit to enter the date directly QLineEdit *line; /// the validator for the line edit: DatePickerValidator *val; /// the date table KDateTable *table; /// the widest month string in pixels: QSize maxMonthRect; /// the font size for the widget int fontsize; }; void KDatePicker::KDatePickerPrivate::fillWeeksCombo() { // every year can have a different number of weeks // it could be that we had 53,1..52 and now 1..53 which is the same number but different // so always fill with new values // We show all week numbers for all weeks between first day of year to last day of year // This of course can be a list like 53,1,2..52 const QDate thisDate = q->date(); const int thisYear = thisDate.year(); QDate day(thisDate.year(), 1, 1); const QDate lastDayOfYear = QDate(thisDate.year() + 1, 1, 1).addDays(-1); selectWeek->clear(); // Starting from the first day in the year, loop through the year a week at a time // adding an entry to the week combo for each week in the year for (; day.isValid() && day <= lastDayOfYear; day = day.addDays(7)) { // Get the ISO week number for the current day and what year that week is in // e.g. 1st day of this year may fall in week 53 of previous year int weekYear = thisYear; const int week = day.weekNumber(&weekYear); QString weekString = tr("Week %1").arg(QString::number(week)); // show that this is a week from a different year if (weekYear != thisYear) { weekString += QLatin1Char('*'); } // when the week is selected, go to the same weekday as the one // that is currently selected in the date table QDate targetDate = day.addDays(thisDate.dayOfWeek() - day.dayOfWeek()); selectWeek->addItem(weekString, targetDate); // make sure that the week of the lastDayOfYear is always inserted: in Chinese calendar // system, this is not always the case if (day < lastDayOfYear && day.daysTo(lastDayOfYear) < 7 && lastDayOfYear.weekNumber() != day.weekNumber()) { day = lastDayOfYear.addDays(-7); } } } QDate KDatePicker::KDatePickerPrivate::validDateInYearMonth(int year, int month) { QDate newDate; // Try to create a valid date in this year and month // First try the first of the month, then try last of month if (QDate(year, month, 1).isValid()) { newDate = QDate(year, month, 1); } else if (QDate(year, month + 1, 1).isValid()) { newDate = QDate(year, month + 1, 1).addDays(-1); } else { newDate = QDate::fromJulianDay(0); } return newDate; } KDatePicker::KDatePicker(QWidget *parent) : QFrame(parent), d(new KDatePickerPrivate(this)) { initWidget(QDate::currentDate()); } KDatePicker::KDatePicker(const QDate &date_, QWidget *parent) : QFrame(parent), d(new KDatePickerPrivate(this)) { initWidget(date_); } void KDatePicker::initWidget(const QDate &date_) { const int spacingHint = style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing); QBoxLayout *topLayout = new QVBoxLayout(this); topLayout->setSpacing(0); topLayout->setMargin(0); d->navigationLayout = new QHBoxLayout(); d->navigationLayout->setSpacing(0); d->navigationLayout->setMargin(0); topLayout->addLayout(d->navigationLayout); d->navigationLayout->addStretch(); d->yearBackward = new QToolButton(this); d->yearBackward->setAutoRaise(true); d->navigationLayout->addWidget(d->yearBackward); d->monthBackward = new QToolButton(this); d->monthBackward ->setAutoRaise(true); d->navigationLayout->addWidget(d->monthBackward); d->navigationLayout->addSpacing(spacingHint); d->selectMonth = new QToolButton(this); d->selectMonth ->setAutoRaise(true); d->navigationLayout->addWidget(d->selectMonth); d->selectYear = new QToolButton(this); d->selectYear->setCheckable(true); d->selectYear->setAutoRaise(true); d->navigationLayout->addWidget(d->selectYear); d->navigationLayout->addSpacing(spacingHint); d->monthForward = new QToolButton(this); d->monthForward ->setAutoRaise(true); d->navigationLayout->addWidget(d->monthForward); d->yearForward = new QToolButton(this); d->yearForward ->setAutoRaise(true); d->navigationLayout->addWidget(d->yearForward); d->navigationLayout->addStretch(); d->line = new QLineEdit(this); d->val = new DatePickerValidator(this); d->table = new KDateTable(this); setFocusProxy(d->table); d->fontsize = QFontDatabase::systemFont(QFontDatabase::GeneralFont).pointSize(); if (d->fontsize == -1) { d->fontsize = QFontInfo(QFontDatabase::systemFont(QFontDatabase::GeneralFont)).pointSize(); } d->fontsize++; // Make a little bigger d->selectWeek = new QComboBox(this); // read only week selection d->selectWeek->setFocusPolicy(Qt::NoFocus); d->todayButton = new QToolButton(this); d->todayButton->setIcon(QIcon::fromTheme(QStringLiteral("go-jump-today"))); d->yearForward->setToolTip(tr("Next year")); d->yearBackward->setToolTip(tr("Previous year")); d->monthForward->setToolTip(tr("Next month")); d->monthBackward->setToolTip(tr("Previous month")); d->selectWeek->setToolTip(tr("Select a week")); d->selectMonth->setToolTip(tr("Select a month")); d->selectYear->setToolTip(tr("Select a year")); d->todayButton->setToolTip(tr("Select the current day")); // ----- setFontSize(d->fontsize); d->line->setValidator(d->val); d->line->installEventFilter(this); if (QApplication::isRightToLeft()) { d->yearForward->setIcon(QIcon::fromTheme(QStringLiteral("arrow-left-double"))); d->yearBackward->setIcon(QIcon::fromTheme(QStringLiteral("arrow-right-double"))); d->monthForward->setIcon(QIcon::fromTheme(QStringLiteral("arrow-left"))); d->monthBackward->setIcon(QIcon::fromTheme(QStringLiteral("arrow-right"))); } else { d->yearForward->setIcon(QIcon::fromTheme(QStringLiteral("arrow-right-double"))); d->yearBackward->setIcon(QIcon::fromTheme(QStringLiteral("arrow-left-double"))); d->monthForward->setIcon(QIcon::fromTheme(QStringLiteral("arrow-right"))); d->monthBackward->setIcon(QIcon::fromTheme(QStringLiteral("arrow-left"))); } connect(d->table, SIGNAL(dateChanged(QDate)), SLOT(dateChangedSlot(QDate))); connect(d->table, &KDateTable::tableClicked, this, &KDatePicker::tableClickedSlot); connect(d->monthForward, &QAbstractButton::clicked, this, &KDatePicker::monthForwardClicked); connect(d->monthBackward, &QAbstractButton::clicked, this, &KDatePicker::monthBackwardClicked); connect(d->yearForward, &QAbstractButton::clicked, this, &KDatePicker::yearForwardClicked); connect(d->yearBackward, &QAbstractButton::clicked, this, &KDatePicker::yearBackwardClicked); connect(d->selectWeek, SIGNAL(activated(int)), SLOT(weekSelected(int))); connect(d->todayButton, &QAbstractButton::clicked, this, &KDatePicker::todayButtonClicked); connect(d->selectMonth, &QAbstractButton::clicked, this, &KDatePicker::selectMonthClicked); connect(d->selectYear, &QAbstractButton::toggled, this, &KDatePicker::selectYearClicked); connect(d->line, &QLineEdit::returnPressed, this, &KDatePicker::lineEnterPressed); topLayout->addWidget(d->table); QBoxLayout *bottomLayout = new QHBoxLayout(); bottomLayout->setMargin(0); bottomLayout->setSpacing(0); topLayout->addLayout(bottomLayout); bottomLayout->addWidget(d->todayButton); bottomLayout->addWidget(d->line); bottomLayout->addWidget(d->selectWeek); d->table->setDate(date_); dateChangedSlot(date_); // needed because table emits changed only when newDate != oldDate } KDatePicker::~KDatePicker() { delete d; } bool KDatePicker::eventFilter(QObject *o, QEvent *e) { if (e->type() == QEvent::KeyPress) { QKeyEvent *k = (QKeyEvent *)e; if ((k->key() == Qt::Key_PageUp) || (k->key() == Qt::Key_PageDown) || (k->key() == Qt::Key_Up) || (k->key() == Qt::Key_Down)) { QApplication::sendEvent(d->table, e); d->table->setFocus(); return true; // eat event } } return QFrame::eventFilter(o, e); } void KDatePicker::resizeEvent(QResizeEvent *e) { QWidget::resizeEvent(e); } void KDatePicker::dateChangedSlot(const QDate &date_) { d->line->setText(locale().toString(date_, QLocale::ShortFormat)); d->selectMonth->setText(locale().standaloneMonthName(date_.month(), QLocale::LongFormat)); d->fillWeeksCombo(); // calculate the item num in the week combo box; normalize selected day so as if 1.1. is the first day of the week QDate firstDay(date_.year(), 1, 1); // If we cannot successfully create the 1st of the year, this can only mean that // the 1st is before the earliest valid date in the current calendar system, so use // the earliestValidDate as the first day. // In particular covers the case of Gregorian where 1/1/-4713 is not a valid QDate d->selectWeek->setCurrentIndex((date_.dayOfYear() + firstDay.dayOfWeek() - 2) / 7); d->selectYear->setText(QString::number(date_.year()).rightJustified(4, QLatin1Char('0'))); emit(dateChanged(date_)); } void KDatePicker::tableClickedSlot() { emit(dateSelected(date())); emit(tableClicked()); } const QDate &KDatePicker::date() const { return d->table->date(); } bool KDatePicker::setDate(const QDate &date_) { // the table setDate does validity checking for us // this also emits dateChanged() which then calls our dateChangedSlot() return d->table->setDate(date_); } void KDatePicker::monthForwardClicked() { if (! setDate(date().addMonths(1))) { QApplication::beep(); } d->table->setFocus(); } void KDatePicker::monthBackwardClicked() { if (! setDate(date().addMonths(-1))) { QApplication::beep(); } d->table->setFocus(); } void KDatePicker::yearForwardClicked() { if (! setDate(d->table->date().addYears(1))) { QApplication::beep(); } d->table->setFocus(); } void KDatePicker::yearBackwardClicked() { if (! setDate(d->table->date().addYears(-1))) { QApplication::beep(); } d->table->setFocus(); } void KDatePicker::weekSelected(int index) { QDate targetDay = d->selectWeek->itemData(index).toDateTime().date(); if (! setDate(targetDay)) { QApplication::beep(); } d->table->setFocus(); } void KDatePicker::selectMonthClicked() { QDate thisDate(date()); d->table->setFocus(); QMenu popup(d->selectMonth); // Populate the pick list with all the month names, this may change by year // JPL do we need to do somethng here for months that fall outside valid range? const int monthsInYear = QDate(thisDate.year() + 1, 1, 1).addDays(-1).month(); for (int m = 1; m <= monthsInYear; m++) { popup.addAction(locale().standaloneMonthName(m))->setData(m); } QAction *item = popup.actions()[ thisDate.month() - 1 ]; // if this happens the above should already given an assertion if (item) { popup.setActiveAction(item); } // cancelled - if ((item = popup.exec(d->selectMonth->mapToGlobal(QPoint(0, 0)), item)) == 0) { + if ((item = popup.exec(d->selectMonth->mapToGlobal(QPoint(0, 0)), item)) == nullptr) { return; } // We need to create a valid date in the month selected so we can find out how many days are // in the month. QDate newDate(thisDate.year(), item->data().toInt(), 1); // If we have succeeded in creating a date in the new month, then try to create the new date, // checking we don't set a day after the last day of the month newDate.setDate(newDate.year(), newDate.month(), qMin(thisDate.day(), newDate.daysInMonth())); // Set the date, if it's invalid in any way then alert user and don't update if (! setDate(newDate)) { QApplication::beep(); } } void KDatePicker::selectYearClicked() { if (!d->selectYear->isChecked()) { return; } QDate thisDate(date()); KPopupFrame *popup = new KPopupFrame(this); KDatePickerPrivateYearSelector *picker = new KDatePickerPrivateYearSelector(date(), popup); picker->resize(picker->sizeHint()); picker->setYear(thisDate.year()); picker->selectAll(); popup->setMainWidget(picker); connect(picker, SIGNAL(closeMe(int)), popup, SLOT(close(int))); picker->setFocus(); if (popup->exec(d->selectYear->mapToGlobal(QPoint(0, d->selectMonth->height())))) { // We need to create a valid date in the year/month selected so we can find out how many // days are in the month. QDate newDate(picker->year(), thisDate.month(), 1); // If we have succeeded in creating a date in the new month, then try to create the new // date, checking we don't set a day after the last day of the month newDate = QDate(newDate.year(), newDate.month(), qMin(thisDate.day(), newDate.daysInMonth())); // Set the date, if it's invalid in any way then alert user and don't update if (! setDate(newDate)) { QApplication::beep(); } } delete popup; d->selectYear->setChecked(false); } void KDatePicker::uncheckYearSelector() { d->selectYear->setChecked(false); d->selectYear->update(); } void KDatePicker::changeEvent(QEvent *event) { if (event && event->type() == QEvent::EnabledChange) { if (isEnabled()) { d->table->setFocus(); } } } KDateTable *KDatePicker::dateTable() const { return d->table; } void KDatePicker::lineEnterPressed() { QDate newDate = QDate::fromString(d->line->text(), locale().dateFormat()); if (newDate.isValid()) { emit(dateEntered(newDate)); setDate(newDate); d->table->setFocus(); } else { QApplication::beep(); } } void KDatePicker::todayButtonClicked() { setDate(QDate::currentDate()); d->table->setFocus(); } QSize KDatePicker::sizeHint() const { return QWidget::sizeHint(); } void KDatePicker::setFontSize(int s) { QWidget *const buttons[] = { d->selectMonth, d->selectYear, }; const int NoOfButtons = sizeof(buttons) / sizeof(buttons[0]); int count; QFont font; QRect r; // ----- d->fontsize = s; for (count = 0; count < NoOfButtons; ++count) { font = buttons[count]->font(); font.setPointSize(s); buttons[count]->setFont(font); } d->table->setFontSize(s); QFontMetrics metrics(d->selectMonth->fontMetrics()); QString longestMonth; for (int i = 1;; ++i) { QString str = locale().standaloneMonthName(i, QLocale::LongFormat); if (str.isNull()) { break; } r = metrics.boundingRect(str); if (r.width() > d->maxMonthRect.width()) { d->maxMonthRect.setWidth(r.width()); longestMonth = str; } if (r.height() > d->maxMonthRect.height()) { d->maxMonthRect.setHeight(r.height()); } } QStyleOptionToolButton opt; opt.initFrom(d->selectMonth); opt.text = longestMonth; // stolen from QToolButton QSize textSize = metrics.size(Qt::TextShowMnemonic, longestMonth); textSize.setWidth(textSize.width() + metrics.width(QLatin1Char(' ')) * 2); int w = textSize.width(); int h = textSize.height(); opt.rect.setHeight(h); // PM_MenuButtonIndicator depends on the height QSize metricBound = style()->sizeFromContents( QStyle::CT_ToolButton, &opt, QSize(w, h), d->selectMonth ).expandedTo(QApplication::globalStrut()); d->selectMonth->setMinimumSize(metricBound); } int KDatePicker::fontSize() const { return d->fontsize; } void KDatePicker::setCloseButton(bool enable) { - if (enable == (d->closeButton != 0L)) { + if (enable == (d->closeButton != nullptr)) { return; } if (enable) { d->closeButton = new QToolButton(this); d->closeButton->setAutoRaise(true); const int spacingHint = style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing); d->navigationLayout->addSpacing(spacingHint); d->navigationLayout->addWidget(d->closeButton); d->closeButton->setToolTip(tr("Close", "@action:button")); d->closeButton->setIcon(QIcon::fromTheme(QStringLiteral("window-close"))); connect(d->closeButton, &QAbstractButton::clicked, topLevelWidget(), &QWidget::close); } else { delete d->closeButton; - d->closeButton = 0L; + d->closeButton = nullptr; } updateGeometry(); } bool KDatePicker::hasCloseButton() const { return (d->closeButton); } diff --git a/src/kdatepicker.h b/src/kdatepicker.h index 4511f8f..f53b2a3 100644 --- a/src/kdatepicker.h +++ b/src/kdatepicker.h @@ -1,183 +1,183 @@ /* -*- C++ -*- This file is part of the KDE libraries Copyright (C) 1997 Tim D. Gilman (tdgilman@best.org) (C) 1998-2001 Mirko Boehm (mirko@kde.org) (C) 2007 John Layt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KDATEPICKER_H #define KDATEPICKER_H #include #include #include class QLineEdit; class KDateTable; /** * @short A date selection widget. * * Provides a widget for calendar date input. * * Different from the * previous versions, it now emits two types of signals, either * dateSelected() or dateEntered() (see documentation for both * signals). * * A line edit has been added in the newer versions to allow the user * to select a date directly by entering numbers like 19990101 * or 990101. * * \image html kdatepicker.png "KDE Date Widget" * * @author Tim Gilman, Mirko Boehm * **/ class KWIDGETSADDONS_EXPORT KDatePicker: public QFrame { Q_OBJECT Q_PROPERTY(QDate date READ date WRITE setDate NOTIFY dateChanged USER true) Q_PROPERTY(bool closeButton READ hasCloseButton WRITE setCloseButton) Q_PROPERTY(int fontSize READ fontSize WRITE setFontSize) public: /** * The constructor. The current date will be displayed initially. **/ - explicit KDatePicker(QWidget *parent = 0); + explicit KDatePicker(QWidget *parent = nullptr); /** * The constructor. The given date will be displayed initially. **/ - explicit KDatePicker(const QDate &dt, QWidget *parent = 0); + explicit KDatePicker(const QDate &dt, QWidget *parent = nullptr); /** * The destructor. **/ virtual ~KDatePicker(); /** The size hint for date pickers. The size hint recommends the * minimum size of the widget so that all elements may be placed * without clipping. This sometimes looks ugly, so when using the * size hint, try adding 28 to each of the reported numbers of * pixels. **/ QSize sizeHint() const Q_DECL_OVERRIDE; /** * Sets the date. * * @returns @p false and does not change anything if the date given is invalid. **/ bool setDate(const QDate &date); /** * @returns the selected date. */ const QDate &date() const; /** * @returns the KDateTable widget child of this KDatePicker * widget. */ /** * Sets the font size of the widgets elements. **/ void setFontSize(int); /** * Returns the font size of the widget elements. */ int fontSize() const; /** * By calling this method with @p enable = true, KDatePicker will show * a little close-button in the upper button-row. Clicking the * close-button will cause the KDatePicker's topLevelWidget()'s close() * method being called. This is mostly useful for toplevel datepickers * without a window manager decoration. * @see hasCloseButton */ void setCloseButton(bool enable); /** * @returns true if a KDatePicker shows a close-button. * @see setCloseButton */ bool hasCloseButton() const; protected: /// to catch move keyEvents when QLineEdit has keyFocus bool eventFilter(QObject *o, QEvent *e) Q_DECL_OVERRIDE; /// the resize event void resizeEvent(QResizeEvent *) Q_DECL_OVERRIDE; void changeEvent(QEvent *event) Q_DECL_OVERRIDE; protected Q_SLOTS: void dateChangedSlot(const QDate &date); void tableClickedSlot(); void monthForwardClicked(); void monthBackwardClicked(); void yearForwardClicked(); void yearBackwardClicked(); void selectMonthClicked(); void selectYearClicked(); void uncheckYearSelector(); void lineEnterPressed(); void todayButtonClicked(); void weekSelected(int); Q_SIGNALS: /** This signal is emitted each time the selected date is changed. * Usually, this does not mean that the date has been entered, * since the date also changes, for example, when another month is * selected. * @see dateSelected */ void dateChanged(const QDate &date); /** This signal is emitted each time a day has been selected by * clicking on the table (hitting a day in the current month). It * has the same meaning as dateSelected() in older versions of * KDatePicker. */ void dateSelected(const QDate &date); /** This signal is emitted when enter is pressed and a VALID date * has been entered before into the line edit. Connect to both * dateEntered() and dateSelected() to receive all events where the * user really enters a date. */ void dateEntered(const QDate &date); /** This signal is emitted when the day has been selected by * clicking on it in the table. */ void tableClicked(); private: KDateTable *dateTable() const; void initWidget(const QDate &date); class KDatePickerPrivate; friend class KDatePickerPrivate; KDatePickerPrivate *const d; }; #endif // KDATEPICKER_H diff --git a/src/kdatepicker_p.h b/src/kdatepicker_p.h index 2f071d3..7645f83 100644 --- a/src/kdatepicker_p.h +++ b/src/kdatepicker_p.h @@ -1,59 +1,59 @@ /* -*- C++ -*- This file is part of the KDE libraries Copyright (C) 1997 Tim D. Gilman (tdgilman@best.org) (C) 1998-2001 Mirko Boehm (mirko@kde.org) (C) 1998-2001 Mirko Boehm (john@layt.net) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KDATEPICKER_P_H #define KDATEPICKER_P_H #include #include #include /** Year selection widget. * @internal * @author Tim Gilman, Mirko Boehm, John Layt */ class KDatePickerPrivateYearSelector : public QLineEdit { Q_OBJECT public: - KDatePickerPrivateYearSelector(const QDate ¤tDate, QWidget *parent = 0); + KDatePickerPrivateYearSelector(const QDate ¤tDate, QWidget *parent = nullptr); int year(); void setYear(int year); public Q_SLOTS: void yearEnteredSlot(); Q_SIGNALS: void closeMe(int); protected: QIntValidator *val; int result; private: QDate oldDate; Q_DISABLE_COPY(KDatePickerPrivateYearSelector) }; #endif // KDATEPICKER_P_H diff --git a/src/kdatetable_p.h b/src/kdatetable_p.h index a371426..5dd32d6 100644 --- a/src/kdatetable_p.h +++ b/src/kdatetable_p.h @@ -1,193 +1,193 @@ /* -*- C++ -*- This file is part of the KDE libraries Copyright (C) 1997 Tim D. Gilman (tdgilman@best.org) (C) 1998-2001 Mirko Boehm (mirko@kde.org) (C) 2007 John Layt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KDATETABLE_H #define KDATETABLE_H #include #include class QMenu; /** * Date selection table. * This is a support class for the KDatePicker class. It just * draws the calendar table without titles, but could theoretically * be used as a standalone. * * When a date is selected by the user, it emits a signal: * dateSelected(QDate) * * \image html kdatetable.png "KDE Date Selection Table" * * @internal * @author Tim Gilman, Mirko Boehm */ class KDateTable : public QWidget { Q_OBJECT Q_PROPERTY(QDate date READ date WRITE setDate) Q_PROPERTY(bool popupMenu READ popupMenuEnabled WRITE setPopupMenuEnabled) public: /** * The constructor. */ - explicit KDateTable(QWidget *parent = 0); + explicit KDateTable(QWidget *parent = nullptr); /** * The constructor. */ - explicit KDateTable(const QDate &, QWidget *parent = 0); + explicit KDateTable(const QDate &, QWidget *parent = nullptr); /** * The destructor. */ ~KDateTable(); /** * Returns a recommended size for the widget. * To save some time, the size of the largest used cell content is * calculated in each paintCell() call, since all calculations have * to be done there anyway. The size is stored in maxCell. The * sizeHint() simply returns a multiple of maxCell. */ QSize sizeHint() const Q_DECL_OVERRIDE; /** * Set the font size of the date table. */ void setFontSize(int size); /** * Select and display this date. */ bool setDate(const QDate &date); // KDE5 remove the const & from the returned QDate /** * @returns the selected date. */ const QDate &date() const; /** * Enables a popup menu when right clicking on a date. * * When it's enabled, this object emits a aboutToShowContextMenu signal * where you can fill in the menu items. */ void setPopupMenuEnabled(bool enable); /** * Returns if the popup menu is enabled or not */ bool popupMenuEnabled() const; enum BackgroundMode { NoBgMode = 0, RectangleMode, CircleMode }; /** * Makes a given date be painted with a given foregroundColor, and background * (a rectangle, or a circle/ellipse) in a given color. */ void setCustomDatePainting(const QDate &date, const QColor &fgColor, BackgroundMode bgMode = NoBgMode, const QColor &bgColor = QColor()); /** * Unsets the custom painting of a date so that the date is painted as usual. */ void unsetCustomDatePainting(const QDate &date); protected: /** * calculate the position of the cell in the matrix for the given date. * The result is the 0-based index. */ virtual int posFromDate(const QDate &date); /** * calculate the date that is displayed at a given cell in the matrix. pos is the * 0-based index in the matrix. Inverse function to posForDate(). */ virtual QDate dateFromPos(int pos); void paintEvent(QPaintEvent *e) Q_DECL_OVERRIDE; /** * React on mouse clicks that select a date. */ void mousePressEvent(QMouseEvent *e) Q_DECL_OVERRIDE; void wheelEvent(QWheelEvent *e) Q_DECL_OVERRIDE; void keyPressEvent(QKeyEvent *e) Q_DECL_OVERRIDE; void focusInEvent(QFocusEvent *e) Q_DECL_OVERRIDE; void focusOutEvent(QFocusEvent *e) Q_DECL_OVERRIDE; /** * Cell highlight on mouse hovering */ bool event(QEvent *e) Q_DECL_OVERRIDE; Q_SIGNALS: /** * The selected date changed. */ void dateChanged(const QDate &date); /** * This function behaves essentially like the one above. * The selected date changed. * @param cur The current date * @param old The date before the date was changed */ void dateChanged(const QDate &cur, const QDate &old); /** * A date has been selected by clicking on the table. */ void tableClicked(); /** * A popup menu for a given date is about to be shown (as when the user * right clicks on that date and the popup menu is enabled). Connect * the slot where you fill the menu to this signal. */ void aboutToShowContextMenu(QMenu *menu, const QDate &date); private: Q_PRIVATE_SLOT(d, void nextMonth()) Q_PRIVATE_SLOT(d, void previousMonth()) Q_PRIVATE_SLOT(d, void beginningOfMonth()) Q_PRIVATE_SLOT(d, void endOfMonth()) Q_PRIVATE_SLOT(d, void beginningOfWeek()) Q_PRIVATE_SLOT(d, void endOfWeek()) private: class KDateTablePrivate; friend class KDateTablePrivate; KDateTablePrivate *const d; void initWidget(const QDate &date); void initAccels(); void paintCell(QPainter *painter, int row, int col); Q_DISABLE_COPY(KDateTable) }; #endif // KDATETABLE_H diff --git a/src/kdatetimeedit.h b/src/kdatetimeedit.h index 6e809cc..a989806 100644 --- a/src/kdatetimeedit.h +++ b/src/kdatetimeedit.h @@ -1,600 +1,600 @@ /* Copyright 2011 John Layt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KDATETIMEEDIT_H #define KDATETIMEEDIT_H #include #include #include #include class KDateTimeEditPrivate; class KWIDGETSADDONS_EXPORT KDateTimeEdit : public QWidget { Q_OBJECT Q_PROPERTY(QDate date READ date WRITE setDate NOTIFY dateChanged USER true) Q_PROPERTY(QTime time READ time WRITE setTime NOTIFY timeChanged USER true) Q_PROPERTY(int timeListInterval READ timeListInterval WRITE setTimeListInterval) Q_PROPERTY(Options options READ options WRITE setOptions) public: /** * Options provided by the widget * @see options * @see setOptions */ enum Option { ShowCalendar = 0x00001, /**< If the Calendar System edit is displayed */ ShowDate = 0x00002, /**< If the Date is displayed */ ShowTime = 0x00004, /**< If the Time is displayed */ ShowTimeZone = 0x00008, /**< If the Time Zone is displayed */ //EditCalendar = 0x00010, /**< Allow the user to manually edit the calendar */ EditDate = 0x00020, /**< Allow the user to manually edit the date */ EditTime = 0x00040, /**< Allow the user to manually edit the time */ //EditTimeZone = 0x00080, /**< Allow the user to manually edit the time zone */ SelectCalendar = 0x00100, /**< Allow the user to select a calendar */ SelectDate = 0x00200, /**< Allow the user to select a date */ SelectTime = 0x00400, /**< Allow the user to select a time */ SelectTimeZone = 0x00800, /**< Allow the user to select a time zone */ DatePicker = 0x01000, /**< Show a date picker */ DateKeywords = 0x02000, /**< Show date keywords */ ForceTime = 0x04000, /**< The entered time can only be a selected time */ WarnOnInvalid = 0x08000 /**< Show a warning on focus out if the date or time is invalid */ }; Q_DECLARE_FLAGS(Options, Option) Q_FLAG(Options) /** * Create a new KDateTimeEdit widget */ - explicit KDateTimeEdit(QWidget *parent = 0); + explicit KDateTimeEdit(QWidget *parent = nullptr); /** * Destroy the widget */ virtual ~KDateTimeEdit(); /** * Return the currently set widget options * * @return the currently set widget options */ Options options() const; /** * Return the currently selected date, time and time zone * * @return the currently selected date, time and time zone */ QDateTime dateTime() const; /** * Return the currently selected date * * @return the currently selected date */ QDate date() const; /** * Return the currently selected time * * @return the currently selected time */ QTime time() const; /** * Return the currently selected time zone * * @return the currently selected time zone */ QTimeZone timeZone() const; /** * Returns the list of Calendar Systems displayed. * * @param calendars the list of calendar systems to display */ QList calendarLocalesList() const; /** * Return the current minimum date and time * * @return the current minimum date and time */ QDateTime minimumDateTime() const; /** * Return the current maximum date and time * * @return the current maximum date and time */ QDateTime maximumDateTime() const; /** * Return the currently set date display format * * By default this is the Short Format * * @return the currently set date format */ QLocale::FormatType dateDisplayFormat() const; /** * Return the map of dates listed in the drop-down and their displayed * string forms. * * @see setDateMap() * @return the select date map */ QMap dateMap() const; /** * Return the currently set time format * * By default this is the Short Format * * @return the currently set time format */ QLocale::FormatType timeDisplayFormat() const; /** * Return the time list interval able to be selected * * @return the select time intervals in minutes */ int timeListInterval() const; /** * Return the list of times able to be selected in the drop-down. * * @see setTimeList() * @see timeListInterval() * @see setTimeListInterval() * @return the select time list */ QList timeList() const; /** * Return the list of time zones able to be selected * * @param zones the time zones to display */ QList timeZones() const; /** * Return if the current user input is valid * * If the user input is null then it is not valid * * @see isNull() * @return if the current user input is valid */ bool isValid() const; /** * Return if the current user input is null * * @see isValid() * @return if the current user input is null */ bool isNull() const; /** * Return if the current user input date is valid * * If the user input date is null then it is not valid * * @see isNullDate() * @return if the current user input date is valid */ bool isValidDate() const; /** * Return if the current user input date is null * * @see isValidDate() * @return if the current user input date is null */ bool isNullDate() const; /** * Return if the current user input time is valid * * If the user input time is null then it is not valid * * @see isNullTime() * @return if the current user input time is valid */ bool isValidTime() const; /** * Return if the current user input time is null * * @see isValidTime() * @return if the current user input time is null */ bool isNullTime() const; Q_SIGNALS: /** * Signal if the date or time has been manually entered by the user. * * The returned date and time may be invalid. * * @param dateTime the new date, time and time zone */ void dateTimeEntered(const QDateTime &dateTime); /** * Signal if the date or time has been changed either manually by the user * or programatically. * * The returned date and time may be invalid. * * @param dateTime the new date, time and time zone */ void dateTimeChanged(const QDateTime &dateTime); /** * Signal if the date or time is being manually edited by the user. * * The returned date and time may be invalid. * * @param dateTime the new date, time and time zone */ void dateTimeEdited(const QDateTime &dateTime); /** * Signal if the Calendar Locale has been manually entered by the user. * * @param calendarLocale the new calendar locale */ void calendarEntered(const QLocale &calendarLocale); /** * Signal if the Calendar Locale has been changed either manually by the user * or programatically. * * @param calendarLocale the new calendar locale */ void calendarChanged(const QLocale &calendarLocale); /** * Signal if the date has been manually entered by the user. * * The returned date may be invalid. * * @param date the new date */ void dateEntered(const QDate &date); /** * Signal if the date has been changed either manually by the user * or programatically. * * The returned date may be invalid. * * @param date the new date */ void dateChanged(const QDate &date); /** * Signal if the date is being manually edited by the user. * * The returned date may be invalid. * * @param date the new date */ void dateEdited(const QDate &date); /** * Signal if the time has been manually entered by the user. * * The returned time may be invalid. * * @param time the new time */ void timeEntered(const QTime &time); /** * Signal if the time has been changed either manually by the user * or programatically. * * The returned time may be invalid. * * @param time the new time */ void timeChanged(const QTime &time); /** * Signal if the time is being manually edited by the user. * * The returned time may be invalid. * * @param time the new time */ void timeEdited(const QTime &time); /** * Signal if the time zone has been changed manually by the user. * * @param timeZone the new time zone */ void timeZoneEntered(const QTimeZone &zone); /** * Signal if the time zone has been changed either manually by the user * or programatically. * * @param timeZone the new time zone */ void timeZoneChanged(const QTimeZone &zone); public Q_SLOTS: /** * Set the new widget options * * @param options the new widget options */ void setOptions(Options options); /** * Set the currently selected date, time and time zone * * @param dateTime the new date, time and time zone */ void setDateTime(const QDateTime &dateTime); /** * Set the currently selected date * * @param date the new date */ void setDate(const QDate &date); /** * Set the currently selected time * * @param time the new time */ void setTime(const QTime &time); /** * Set the current time zone * * @param zone the new zone */ void setTimeZone(const QTimeZone &zone); /** * Set the minimum and maximum date and time range * * To enable range checking provide two valid dates. * To disable range checking provide two invalid dates, or call * clearDateRange; * * @param minDateTime the minimum date and time * @param maxDateTime the maximum date and time * @param minWarnMsg the minimum warning message * @param maxWarnMsg the maximum warning message */ void setDateTimeRange(const QDateTime &minDateTime, const QDateTime &maxDateTime, const QString &minWarnMsg = QString(), const QString &maxWarnMsg = QString()); /** * Reset the minimum and maximum date and time to the default */ void resetDateTimeRange(); /** * Set the minimum allowed date. * * If the date is invalid, or more than current maximum, * then the minimum will not be set. * * @see setMaximumDateTime() * @see setDateRange() * @param maxDate the minimum date * @param maxWarnMsg the minimum warning message */ void setMinimumDateTime(const QDateTime &minDateTime, const QString &minWarnMsg = QString()); /** * Reset the minimum date and time to the default */ void resetMinimumDateTime(); /** * Set the maximum allowed date. * * If the date is invalid, or less than current minimum, * then the maximum will not be set. * * @see setMinimumDateTime() * @see setDateRange() * @param maxDate the maximum date * @param maxWarnMsg the maximum warning message */ void setMaximumDateTime(const QDateTime &maxDateTime, const QString &maxWarnMsg = QString()); /** * Reset the minimum date and time to the default */ void resetMaximumDateTime(); /** * Sets the date format to display. * * By default is the Short Format. * * @param format the date format to use */ void setDateDisplayFormat(QLocale::FormatType format); /** * Set the list of Calendar Locales to display. * * @param calendarLocales the list of calendar locales to display */ void setCalendarLocalesList(const QList &calendarLocales); /** * Set the list of dates able to be selected from the drop-down and the * string form to display for those dates, e.g. "2010-01-01" and "Yesterday". * * Any invalid or duplicate dates will be used, the list will NOT be * sorted, and the minimum and maximum date will not be affected. * * The @p dateMap is keyed by the date to be listed and the value is the * string to be displayed. If you want the date to be displayed in the * default date format then the string should be null. If you want a * separator to be displayed then set the string to "separator". * * @see dateMap() * @param dateMap the map of dates able to be selected */ void setDateMap(QMap dateMap); /** * Sets the time format to display. * * By default is the Short Format. * * @param format the time format to use */ void setTimeDisplayFormat(QLocale::FormatType formatOptions); /** * Set the interval between times able to be selected from the drop-down. * * The combo drop-down will be populated with times every @param minutes * apart, starting from the minimumTime() and ending at maximumTime(). * * If the ForceInterval option is set then any time manually typed into the * combo line edit will be forced to the nearest interval. * * This interval must be an exact divisor of the valid time range hours. * For example with the default 24 hour range @p interval must divide 1440 * minutes exactly, meaning 1, 6 and 90 are valid but 7, 31 and 91 are not. * * Setting the time list interval will override any time list previously set * via setTimeList(). * * @see timeListInterval() * @param minutes the time list interval to display */ void setTimeListInterval(int minutes); /** * Set the list of times able to be selected from the drop-down. * * Setting the time list will override any time interval previously set via * setTimeListInterval(). * * Any invalid or duplicate times will be ignored, and the list will be * sorted. * * The minimum and maximum time will automatically be set to the earliest * and latest value in the list. * * @see timeList() * @param timeList the list of times able to be selected * @param minWarnMsg the minimum warning message * @param maxWarnMsg the maximum warning message */ void setTimeList(QList timeList, const QString &minWarnMsg = QString(), const QString &maxWarnMsg = QString()); /** * Set the time zones able to be selected * * @param zones the time zones to display */ void setTimeZones(const QList &zones); protected: bool eventFilter(QObject *object, QEvent *event) Q_DECL_OVERRIDE; void focusInEvent(QFocusEvent *event) Q_DECL_OVERRIDE; void focusOutEvent(QFocusEvent *event) Q_DECL_OVERRIDE; void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; /** * Assign the date, time and time zone for the widget. * * Virtual to allow sub-classes to apply extra validation rules, * but reimplementations must call the parent method at the end. * * @param datetime the new date and time */ virtual void assignDateTime(const QDateTime &dateTime); /** * Assign the date for the widget. * * Virtual to allow sub-classes to apply extra validation rules, * but reimplementations must call the parent method at the end. * * @param date the new date */ virtual void assignDate(const QDate &date); /** * Assign the time for the widget. * * Virtual to allow sub-classes to apply extra validation rules, * but reimplementations must call the parent method at the end. * * @param time the new time */ virtual void assignTime(const QTime &time); /** * Assign the time zone for the widget. * * Virtual to allow sub-classes to apply extra validation rules, * but reimplementations must call the parent method at the end. * * @param zone the new time zone */ void assignTimeZone(const QTimeZone &zone); private: friend class KDateTimeEditPrivate; KDateTimeEditPrivate *const d; Q_PRIVATE_SLOT(d, void selectCalendar(int)) Q_PRIVATE_SLOT(d, void enterCalendar(const QLocale &)) Q_PRIVATE_SLOT(d, void selectTimeZone(int)) Q_PRIVATE_SLOT(d, void enterTimeZone(const QByteArray &)) }; Q_DECLARE_OPERATORS_FOR_FLAGS(KDateTimeEdit::Options) #endif // KDATETIMEEDIT_H diff --git a/src/kdragwidgetdecorator.cpp b/src/kdragwidgetdecorator.cpp index 5e18fd9..9ff121b 100644 --- a/src/kdragwidgetdecorator.cpp +++ b/src/kdragwidgetdecorator.cpp @@ -1,108 +1,108 @@ /* This file is part of the KDE libraries Copyright (C) 2000 Carsten Pfeiffer This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kdragwidgetdecorator.h" #include #include #include #include class KDragWidgetDecoratorBasePrivate { public: KDragWidgetDecoratorBasePrivate() : dragEnabled(true), - decoratedWidget(0) + decoratedWidget(nullptr) { } bool dragEnabled; QWidget *decoratedWidget; QPoint startPos; }; KDragWidgetDecoratorBase::KDragWidgetDecoratorBase(QWidget *parent) : QObject(parent), d(new KDragWidgetDecoratorBasePrivate) { parent->installEventFilter(this); d->decoratedWidget = parent; } KDragWidgetDecoratorBase::~KDragWidgetDecoratorBase() { delete d; } bool KDragWidgetDecoratorBase::isDragEnabled() const { return d->dragEnabled; } void KDragWidgetDecoratorBase::setDragEnabled(bool enable) { d->dragEnabled = enable; } bool KDragWidgetDecoratorBase::eventFilter(QObject *watched, QEvent *event) { Q_UNUSED(watched) // except in Q_ASSERT Q_ASSERT(watched == d->decoratedWidget); if (!d->dragEnabled) { return false; } if (event->type() == QEvent::MouseButtonPress) { QMouseEvent *e = static_cast(event); d->startPos = e->pos(); } else if (event->type() == QEvent::MouseMove) { QMouseEvent *e = static_cast(event); if ((e->buttons() & Qt::LeftButton) && (e->pos() - d->startPos).manhattanLength() > QApplication::startDragDistance()) { startDrag(); d->decoratedWidget->setProperty("down", false); return true; } } return false; } QWidget *KDragWidgetDecoratorBase::decoratedWidget() const { return d->decoratedWidget; } QDrag *KDragWidgetDecoratorBase::dragObject() { - return 0; + return nullptr; } void KDragWidgetDecoratorBase::startDrag() { QDrag *drag = dragObject(); if (drag) { drag->exec(Qt::CopyAction); } } diff --git a/src/kdragwidgetdecorator.h b/src/kdragwidgetdecorator.h index 620823f..c923c91 100644 --- a/src/kdragwidgetdecorator.h +++ b/src/kdragwidgetdecorator.h @@ -1,148 +1,148 @@ /* This file is part of the KDE libraries Copyright (C) 2000 Carsten Pfeiffer Copyright (C) 2012 Kevin Ottens This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KDRAGWIDGETDECORATOR_H #define KDRAGWIDGETDECORATOR_H #include #include class QDrag; class KDragWidgetDecoratorBasePrivate; /** * @brief A decorator which adds drag-support to widgets * * This is a decorator using an event filter to implement drag-support * in widgets. * You must override the virtual method dragObject() to specify the * QDrag to be used. * * @author Carsten Pfeiffer */ class KWIDGETSADDONS_EXPORT KDragWidgetDecoratorBase : public QObject { Q_OBJECT Q_PROPERTY(bool isDragEnabled READ isDragEnabled WRITE setDragEnabled) public: /** * Default constructor. */ - explicit KDragWidgetDecoratorBase(QWidget *parent = 0); + explicit KDragWidgetDecoratorBase(QWidget *parent = nullptr); /** * Destructs the decorator. */ ~KDragWidgetDecoratorBase(); /** * Enables/disables drag-support. Default is enabled. */ void setDragEnabled(bool enable); /** * @returns if drag support is enabled or not. */ bool isDragEnabled() const; protected: /** * @return the widget this decorator is attached to */ QWidget *decoratedWidget() const; /** * Reimplement this and return the QDrag object that should be used * for the drag. Remember to give it "decoratedWidget()" as parent. * * Default implementation returns 0, so that no drag is initiated. */ virtual QDrag *dragObject(); /** * Reimplemented to add drag-support */ bool eventFilter(QObject *watched, QEvent *event) Q_DECL_OVERRIDE; /** * Starts a drag (Copy by default) using dragObject() */ virtual void startDrag(); private: KDragWidgetDecoratorBasePrivate *const d; }; /** * @brief A decorator which adds drag-support to widgets * * This is a decorator using an event filter to implement drag-support * in widgets. * You must set the dragObjectFactory to specify the QDrag to be used. * * @author Kevin Ottens */ template class KDragWidgetDecorator : public KDragWidgetDecoratorBase { public: typedef QDrag *(*DragObjectFactory)(Widget *); KDragWidgetDecorator(Widget *parent = 0) : KDragWidgetDecoratorBase(parent), m_factory(0) {} /** * @return the QDrag factory used by this decorator */ DragObjectFactory dragObjectFactory() const { return m_factory; } /** * Set a factory to be used by this decorator * * @param factory the new QDrag factory to use */ void setDragObjectFactory(DragObjectFactory factory) { m_factory = factory; } private: /** * Reimplemented to use the QDrag factory */ QDrag *dragObject() Q_DECL_OVERRIDE { if (m_factory) { Widget *w = static_cast(decoratedWidget()); return m_factory(w); } else { return KDragWidgetDecoratorBase::dragObject(); } } DragObjectFactory m_factory; }; #endif // KDRAGWIDGETDECORATOR_H diff --git a/src/keditlistwidget.cpp b/src/keditlistwidget.cpp index 9669127..14b31c7 100644 --- a/src/keditlistwidget.cpp +++ b/src/keditlistwidget.cpp @@ -1,653 +1,653 @@ /* This file is part of the KDE libraries Copyright (C) 2000 David Faure , Alexander Neundorf (C) 2000, 2002 Carsten Pfeiffer (C) 2010 Sebastian Trueg This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "keditlistwidget.h" #include #include #include #include #include #include #include #include #include #include class KEditListWidgetPrivate { public: KEditListWidgetPrivate(KEditListWidget *parent) - : lineEdit(0), - editingWidget(0), + : lineEdit(nullptr), + editingWidget(nullptr), q(parent) { } QListView *listView; QPushButton *servUpButton, *servDownButton; QPushButton *servNewButton, *servRemoveButton; QLineEdit *lineEdit; QWidget *editingWidget; QVBoxLayout *mainLayout; QVBoxLayout *btnsLayout; QStringListModel *model; bool checkAtEntering; KEditListWidget::Buttons buttons; void init(bool check = false, KEditListWidget::Buttons buttons = KEditListWidget::All, - QWidget *representationWidget = 0); - void setEditor(QLineEdit *lineEdit, QWidget *representationWidget = 0); + QWidget *representationWidget = nullptr); + void setEditor(QLineEdit *lineEdit, QWidget *representationWidget = nullptr); void updateButtonState(); QModelIndex selectedIndex(); private: KEditListWidget *q; }; void KEditListWidgetPrivate::init(bool check, KEditListWidget::Buttons newButtons, QWidget *representationWidget) { checkAtEntering = check; - servNewButton = servRemoveButton = servUpButton = servDownButton = 0L; + servNewButton = servRemoveButton = servUpButton = servDownButton = nullptr; q->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred)); mainLayout = new QVBoxLayout(q); mainLayout->setMargin(0); QHBoxLayout *subLayout = new QHBoxLayout; btnsLayout = new QVBoxLayout; btnsLayout->addStretch(); model = new QStringListModel(); listView = new QListView(q); listView->setModel(model); subLayout->addWidget(listView); subLayout->addLayout(btnsLayout); mainLayout->insertLayout(1, subLayout); setEditor(lineEdit, representationWidget); - buttons = 0; + buttons = nullptr; q->setButtons(newButtons); q->connect(listView->selectionModel(), &QItemSelectionModel::selectionChanged, q, &KEditListWidget::slotSelectionChanged); } void KEditListWidgetPrivate::setEditor(QLineEdit *newLineEdit, QWidget *representationWidget) { if (editingWidget != lineEdit && editingWidget != representationWidget) { delete editingWidget; } if (lineEdit != newLineEdit) { delete lineEdit; } lineEdit = newLineEdit ? newLineEdit : new QLineEdit(q); editingWidget = representationWidget ? representationWidget : lineEdit; if (representationWidget) { representationWidget->setParent(q); } mainLayout->insertWidget(0, editingWidget); lineEdit->installEventFilter(q); q->connect(lineEdit, &QLineEdit::textChanged, q, &KEditListWidget::typedSomething); q->connect(lineEdit, &QLineEdit::returnPressed, q, &KEditListWidget::addItem); // maybe supplied lineedit has some text already q->typedSomething(lineEdit->text()); // fix tab ordering q->setTabOrder(editingWidget, listView); QWidget *w = listView; if (servNewButton) { q->setTabOrder(w, servNewButton); w = servNewButton; } if (servRemoveButton) { q->setTabOrder(w, servRemoveButton); w = servRemoveButton; } if (servUpButton) { q->setTabOrder(w, servUpButton); w = servUpButton; } if (servDownButton) { q->setTabOrder(w, servDownButton); w = servDownButton; } } void KEditListWidgetPrivate::updateButtonState() { QModelIndex index = selectedIndex(); if (servUpButton) { servUpButton->setEnabled(index.isValid()); } if (servDownButton) { servDownButton->setEnabled(index.isValid()); } if (servRemoveButton) { servRemoveButton->setEnabled(index.isValid()); } } QModelIndex KEditListWidgetPrivate::selectedIndex() { QItemSelectionModel *selection = listView->selectionModel(); const QModelIndexList selectedIndexes = selection->selectedIndexes(); if (!selectedIndexes.isEmpty() && selectedIndexes[0].isValid()) { return selectedIndexes[0]; } else { return QModelIndex(); } } class KEditListWidget::CustomEditorPrivate { public: CustomEditorPrivate(KEditListWidget::CustomEditor *q): q(q), - representationWidget(0), - lineEdit(0) {} + representationWidget(nullptr), + lineEdit(nullptr) {} KEditListWidget::CustomEditor *q; QWidget *representationWidget; QLineEdit *lineEdit; }; KEditListWidget::CustomEditor::CustomEditor() : d(new CustomEditorPrivate(this)) { } KEditListWidget::CustomEditor::CustomEditor(QWidget *repWidget, QLineEdit *edit) : d(new CustomEditorPrivate(this)) { d->representationWidget = repWidget; d->lineEdit = edit; } KEditListWidget::CustomEditor::CustomEditor(QComboBox *combo) : d(new CustomEditorPrivate(this)) { d->representationWidget = combo; d->lineEdit = qobject_cast(combo->lineEdit()); Q_ASSERT(d->lineEdit); } KEditListWidget::CustomEditor::~CustomEditor() { delete d; } void KEditListWidget::CustomEditor::setRepresentationWidget(QWidget *repWidget) { d->representationWidget = repWidget; } void KEditListWidget::CustomEditor::setLineEdit(QLineEdit *edit) { d->lineEdit = edit; } QWidget *KEditListWidget::CustomEditor::representationWidget() const { return d->representationWidget; } QLineEdit *KEditListWidget::CustomEditor::lineEdit() const { return d->lineEdit; } KEditListWidget::KEditListWidget(QWidget *parent) : QWidget(parent), d(new KEditListWidgetPrivate(this)) { d->init(); } KEditListWidget::KEditListWidget(const CustomEditor &custom, QWidget *parent, bool checkAtEntering, Buttons buttons) : QWidget(parent), d(new KEditListWidgetPrivate(this)) { d->lineEdit = custom.lineEdit(); d->init(checkAtEntering, buttons, custom.representationWidget()); } KEditListWidget::~KEditListWidget() { delete d; } void KEditListWidget::setCustomEditor(const CustomEditor &editor) { d->setEditor(editor.lineEdit(), editor.representationWidget()); } QListView *KEditListWidget::listView() const { return d->listView; } QLineEdit *KEditListWidget::lineEdit() const { return d->lineEdit; } QPushButton *KEditListWidget::addButton() const { return d->servNewButton; } QPushButton *KEditListWidget::removeButton() const { return d->servRemoveButton; } QPushButton *KEditListWidget::upButton() const { return d->servUpButton; } QPushButton *KEditListWidget::downButton() const { return d->servDownButton; } int KEditListWidget::count() const { return int(d->model->rowCount()); } void KEditListWidget::setButtons(Buttons buttons) { if (d->buttons == buttons) { return; } if ((buttons & Add) && !d->servNewButton) { d->servNewButton = new QPushButton(QIcon::fromTheme(QStringLiteral("list-add")), tr("&Add"), this); d->servNewButton->setEnabled(false); d->servNewButton->show(); connect(d->servNewButton, &QAbstractButton::clicked, this, &KEditListWidget::addItem); d->btnsLayout->insertWidget(0, d->servNewButton); } else if ((buttons & Add) == 0 && d->servNewButton) { delete d->servNewButton; - d->servNewButton = 0; + d->servNewButton = nullptr; } if ((buttons & Remove) && !d->servRemoveButton) { d->servRemoveButton = new QPushButton(QIcon::fromTheme(QStringLiteral("list-remove")), tr("&Remove"), this); d->servRemoveButton->setEnabled(false); d->servRemoveButton->show(); connect(d->servRemoveButton, &QAbstractButton::clicked, this, &KEditListWidget::removeItem); d->btnsLayout->insertWidget(1, d->servRemoveButton); } else if ((buttons & Remove) == 0 && d->servRemoveButton) { delete d->servRemoveButton; - d->servRemoveButton = 0; + d->servRemoveButton = nullptr; } if ((buttons & UpDown) && !d->servUpButton) { d->servUpButton = new QPushButton(QIcon::fromTheme(QStringLiteral("arrow-up")), tr("Move &Up"), this); d->servUpButton->setEnabled(false); d->servUpButton->show(); connect(d->servUpButton, &QAbstractButton::clicked, this, &KEditListWidget::moveItemUp); d->servDownButton = new QPushButton(QIcon::fromTheme(QStringLiteral("arrow-down")), tr("Move &Down"), this); d->servDownButton->setEnabled(false); d->servDownButton->show(); connect(d->servDownButton, &QAbstractButton::clicked, this, &KEditListWidget::moveItemDown); d->btnsLayout->insertWidget(2, d->servUpButton); d->btnsLayout->insertWidget(3, d->servDownButton); } else if ((buttons & UpDown) == 0 && d->servUpButton) { - delete d->servUpButton; d->servUpButton = 0; - delete d->servDownButton; d->servDownButton = 0; + delete d->servUpButton; d->servUpButton = nullptr; + delete d->servDownButton; d->servDownButton = nullptr; } d->buttons = buttons; } void KEditListWidget::setCheckAtEntering(bool check) { d->checkAtEntering = check; } bool KEditListWidget::checkAtEntering() { return d->checkAtEntering; } void KEditListWidget::typedSomething(const QString &text) { if (currentItem() >= 0) { if (currentText() != d->lineEdit->text()) { // IMHO changeItem() shouldn't do anything with the value // of currentItem() ... like changing it or emitting signals ... // but TT disagree with me on this one (it's been that way since ages ... grrr) bool block = d->listView->signalsBlocked(); d->listView->blockSignals(true); QModelIndex currentIndex = d->selectedIndex(); if (currentIndex.isValid()) { d->model->setData(currentIndex, text); } d->listView->blockSignals(block); emit changed(); } } if (!d->servNewButton) { return; } if (!d->lineEdit->hasAcceptableInput()) { d->servNewButton->setEnabled(false); return; } if (!d->checkAtEntering) { d->servNewButton->setEnabled(!text.isEmpty()); } else { if (text.isEmpty()) { d->servNewButton->setEnabled(false); } else { QStringList list = d->model->stringList(); bool enable = !list.contains(text, Qt::CaseSensitive); d->servNewButton->setEnabled(enable); } } } void KEditListWidget::moveItemUp() { if (!d->listView->isEnabled()) { QApplication::beep(); return; } QModelIndex index = d->selectedIndex(); if (index.isValid()) { if (index.row() == 0) { QApplication::beep(); return; } QModelIndex aboveIndex = d->model->index(index.row() - 1, index.column()); QString tmp = d->model->data(aboveIndex, Qt::DisplayRole).toString(); d->model->setData(aboveIndex, d->model->data(index, Qt::DisplayRole)); d->model->setData(index, tmp); d->listView->selectionModel()->select(index, QItemSelectionModel::Deselect); d->listView->selectionModel()->select(aboveIndex, QItemSelectionModel::Select); } emit changed(); } void KEditListWidget::moveItemDown() { if (!d->listView->isEnabled()) { QApplication::beep(); return; } QModelIndex index = d->selectedIndex(); if (index.isValid()) { if (index.row() == d->model->rowCount() - 1) { QApplication::beep(); return; } QModelIndex belowIndex = d->model->index(index.row() + 1, index.column()); QString tmp = d->model->data(belowIndex, Qt::DisplayRole).toString(); d->model->setData(belowIndex, d->model->data(index, Qt::DisplayRole)); d->model->setData(index, tmp); d->listView->selectionModel()->select(index, QItemSelectionModel::Deselect); d->listView->selectionModel()->select(belowIndex, QItemSelectionModel::Select); } emit changed(); } void KEditListWidget::addItem() { // when checkAtEntering is true, the add-button is disabled, but this // slot can still be called through Key_Return/Key_Enter. So we guard // against this. if (!d->servNewButton || !d->servNewButton->isEnabled()) { return; } QModelIndex currentIndex = d->selectedIndex(); const QString ¤tTextLE = d->lineEdit->text(); bool alreadyInList(false); //if we didn't check for dupes at the inserting we have to do it now if (!d->checkAtEntering) { // first check current item instead of dumb iterating the entire list if (currentIndex.isValid()) { if (d->model->data(currentIndex, Qt::DisplayRole).toString() == currentTextLE) { alreadyInList = true; } } else { alreadyInList = d->model->stringList().contains(currentTextLE, Qt::CaseSensitive); } } if (d->servNewButton) { d->servNewButton->setEnabled(false); } bool block = d->lineEdit->signalsBlocked(); d->lineEdit->blockSignals(true); d->lineEdit->clear(); d->lineEdit->blockSignals(block); d->listView->selectionModel()->setCurrentIndex(currentIndex, QItemSelectionModel::Deselect); if (!alreadyInList) { block = d->listView->signalsBlocked(); if (currentIndex.isValid()) { d->model->setData(currentIndex, currentTextLE); } else { QStringList lst; lst << currentTextLE; lst << d->model->stringList(); d->model->setStringList(lst); } emit changed(); emit added(currentTextLE); // TODO: pass the index too } d->updateButtonState(); } int KEditListWidget::currentItem() const { QModelIndex selectedIndex = d->selectedIndex(); if (selectedIndex.isValid()) { return selectedIndex.row(); } else { return -1; } } void KEditListWidget::removeItem() { QModelIndex currentIndex = d->selectedIndex(); if (!currentIndex.isValid()) { return; } if (currentIndex.row() >= 0) { QString removedText = d->model->data(currentIndex, Qt::DisplayRole).toString(); d->model->removeRows(currentIndex.row(), 1); d->listView->selectionModel()->clear(); emit changed(); emit removed(removedText); } d->updateButtonState(); } void KEditListWidget::enableMoveButtons(const QModelIndex &newIndex, const QModelIndex &) { int index = newIndex.row(); // Update the lineEdit when we select a different line. if (currentText() != d->lineEdit->text()) { d->lineEdit->setText(currentText()); } bool moveEnabled = d->servUpButton && d->servDownButton; if (moveEnabled) { if (d->model->rowCount() <= 1) { d->servUpButton->setEnabled(false); d->servDownButton->setEnabled(false); } else if (index == (d->model->rowCount() - 1)) { d->servUpButton->setEnabled(true); d->servDownButton->setEnabled(false); } else if (index == 0) { d->servUpButton->setEnabled(false); d->servDownButton->setEnabled(true); } else { d->servUpButton->setEnabled(true); d->servDownButton->setEnabled(true); } } if (d->servRemoveButton) { d->servRemoveButton->setEnabled(true); } } void KEditListWidget::clear() { d->lineEdit->clear(); d->model->setStringList(QStringList()); emit changed(); } void KEditListWidget::insertStringList(const QStringList &list, int index) { QStringList content = d->model->stringList(); if (index < 0) { content += list; } else for (int i = 0, j = index; i < list.count(); ++i, ++j) { content.insert(j, list[ i ]); } d->model->setStringList(content); } void KEditListWidget::insertItem(const QString &text, int index) { QStringList list = d->model->stringList(); if (index < 0) { list.append(text); } else { list.insert(index, text); } d->model->setStringList(list); } QString KEditListWidget::text(int index) const { const QStringList list = d->model->stringList(); return list[ index ]; } QString KEditListWidget::currentText() const { QModelIndex index = d->selectedIndex(); if (!index.isValid()) { return QString(); } else { return text(index.row()); } } QStringList KEditListWidget::items() const { return d->model->stringList(); } void KEditListWidget::setItems(const QStringList &items) { d->model->setStringList(items); } KEditListWidget::Buttons KEditListWidget::buttons() const { return d->buttons; } void KEditListWidget::slotSelectionChanged(const QItemSelection &, const QItemSelection &) { d->updateButtonState(); QModelIndex index = d->selectedIndex(); enableMoveButtons(index, QModelIndex()); if (index.isValid()) { d->lineEdit->setFocus(Qt::OtherFocusReason); } } bool KEditListWidget::eventFilter(QObject *o, QEvent *e) { if (o == d->lineEdit && e->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = (QKeyEvent *)e; if (keyEvent->key() == Qt::Key_Down || keyEvent->key() == Qt::Key_Up) { return ((QObject *)d->listView)->event(e); } else if (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) { return true; } } return false; } diff --git a/src/keditlistwidget.h b/src/keditlistwidget.h index 85bfc34..1f74021 100644 --- a/src/keditlistwidget.h +++ b/src/keditlistwidget.h @@ -1,270 +1,270 @@ /* This file is part of the KDE libraries Copyright (C) 2000 David Faure , Alexander Neundorf (C) 2010 Sebastian Trueg This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KEDITLISTWIDGET_H #define KEDITLISTWIDGET_H #include #include class QLineEdit; class QComboBox; class QListView; class QPushButton; class QItemSelection; class KEditListWidgetPrivate; /** * An editable listbox * * This class provides an editable listbox, this means * a listbox which is accompanied by a line edit to enter new * items into the listbox and pushbuttons to add and remove * items from the listbox and two buttons to move items up and down. * * \image html keditlistbox.png "KDE Edit List Box Widget" * * @since 4.6 */ class KWIDGETSADDONS_EXPORT KEditListWidget : public QWidget { Q_OBJECT Q_PROPERTY(Buttons buttons READ buttons WRITE setButtons) Q_PROPERTY(QStringList items READ items WRITE setItems NOTIFY changed USER true) Q_PROPERTY(bool checkAtEntering READ checkAtEntering WRITE setCheckAtEntering) public: class CustomEditorPrivate; /** * Custom editor class **/ class KWIDGETSADDONS_EXPORT CustomEditor { public: CustomEditor(); CustomEditor(QWidget *repWidget, QLineEdit *edit); CustomEditor(QComboBox *combo); virtual ~CustomEditor(); void setRepresentationWidget(QWidget *repWidget); void setLineEdit(QLineEdit *edit); virtual QWidget *representationWidget() const; virtual QLineEdit *lineEdit() const; private: friend class CustomEditorPrivate; CustomEditorPrivate *const d; Q_DISABLE_COPY(CustomEditor) }; public: /** * Enumeration of the buttons, the listbox offers. Specify them in the * constructor in the buttons parameter, or in setButtons. */ enum Button { Add = 0x0001, Remove = 0x0002, UpDown = 0x0004, All = Add | Remove | UpDown }; Q_DECLARE_FLAGS(Buttons, Button) Q_FLAG(Buttons) /** * Create an editable listbox. */ - explicit KEditListWidget(QWidget *parent = 0); + explicit KEditListWidget(QWidget *parent = nullptr); /** * Constructor which allows to use a custom editing widget * instead of the standard QLineEdit widget. E.g. you can use a * KUrlRequester or a QComboBox as input widget. The custom * editor must consist of a lineedit and optionally another widget that * is used as representation. A QComboBox or a KUrlRequester have a * QLineEdit as child-widget for example, so the QComboBox is used as * the representation widget. * * @see KUrlRequester::customEditor(), setCustomEditor */ KEditListWidget(const CustomEditor &customEditor, - QWidget *parent = 0, + QWidget *parent = nullptr, bool checkAtEntering = false, Buttons buttons = All); virtual ~KEditListWidget(); /** * @returns a pointer to the embedded QListView. */ QListView *listView() const; /** * @returns a pointer to the embedded QLineEdit. */ QLineEdit *lineEdit() const; /** * @returns a pointer to the Add button */ QPushButton *addButton() const; /** * @returns a pointer to the Remove button */ QPushButton *removeButton() const; /** * @returns a pointer to the Up button */ QPushButton *upButton() const; /** * @returns a pointer to the Down button */ QPushButton *downButton() const; /** * @returns the count of elements in the list */ int count() const; /** * Inserts a @p list of elements from the @p index element * If @p index is negative, the elements will be appended */ void insertStringList(const QStringList &list, int index = -1); /** * Inserts a @p text element at the @p index position * If @p index is negative, the element will be appended */ void insertItem(const QString &text, int index = -1); /** * Clears both the listbox and the line edit. */ void clear(); /** * @returns the text at the @p index position */ QString text(int index) const; /** * @returns the currently selected item */ int currentItem() const; /** * @returns the currently selected item's text */ QString currentText() const; /** * @returns a list with the text of all items in the listbox */ QStringList items() const; /** * Clears the listbox and sets the contents to @p items */ void setItems(const QStringList &items); /** * @returns which buttons are visible */ Buttons buttons() const; /** * Specifies which @p buttons are visible */ void setButtons(Buttons buttons); /** * If @p check is true, after every character you type * in the line edit KEditListWidget will enable or disable * the Add-button, depending whether the current content of the * line edit is already in the listbox. Maybe this can become a * performance hit with large lists on slow machines. * If @p check is false, * it will be checked if you press the Add-button. It is not * possible to enter items twice into the listbox. * Default is false. */ void setCheckAtEntering(bool check); /** * @returns true if check at entering is enabled. */ bool checkAtEntering(); /** * Allows to use a custom editing widget * instead of the standard QLineEdit widget. E.g. you can use a * KUrlRequester or a QComboBox as input widget. The custom * editor must consist of a lineedit and optionally another widget that * is used as representation. A QComboBox or a KUrlRequester have a * QLineEdit as child-widget for example, so the QComboBox is used as * the representation widget. */ void setCustomEditor(const CustomEditor &editor); /** * Reimplented for interal reasons. The API is not affected. */ bool eventFilter(QObject *o, QEvent *e) Q_DECL_OVERRIDE; Q_SIGNALS: void changed(); /** * This signal is emitted when the user adds a new string to the list, * the parameter is the added string. */ void added(const QString &text); /** * This signal is emitted when the user removes a string from the list, * the parameter is the removed string. */ void removed(const QString &text); private Q_SLOTS: void moveItemUp(); void moveItemDown(); void addItem(); void removeItem(); void enableMoveButtons(const QModelIndex &, const QModelIndex &); void typedSomething(const QString &text); void slotSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected); private: friend class KEditListWidgetPrivate; KEditListWidgetPrivate *const d; Q_DISABLE_COPY(KEditListWidget) }; Q_DECLARE_OPERATORS_FOR_FLAGS(KEditListWidget::Buttons) #endif diff --git a/src/kfontchooser.cpp b/src/kfontchooser.cpp index 94e5764..787ec4b 100644 --- a/src/kfontchooser.cpp +++ b/src/kfontchooser.cpp @@ -1,1021 +1,1021 @@ /* Copyright (C) 1996 Bernd Johannes Wuebben Copyright (c) 1999 Preston Brown Copyright (c) 1999 Mario Weilguni This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kfontchooser.h" #include "fonthelpers_p.h" #include #include #include #include #include #include #include #include #include #include #include #include #include // When message extraction needs to be avoided. #define TR_NOX tr static int minimumListWidth(const QListWidget *list) { int w = 0; for (int i = 0; i < list->count(); i++) { int itemWidth = list->visualItemRect(list->item(i)).width(); // ...and add a space on both sides for not too tight look. itemWidth += list->fontMetrics().width(QLatin1Char(' ')) * 2; w = qMax(w, itemWidth); } if (w == 0) { w = 40; } w += list->frameWidth() * 2; w += list->verticalScrollBar()->sizeHint().width(); return w; } static int minimumListHeight(const QListWidget *list, int numVisibleEntry) { int w = list->count() > 0 ? list->visualItemRect(list->item(0)).height() : list->fontMetrics().lineSpacing(); if (w < 0) { w = 10; } if (numVisibleEntry <= 0) { numVisibleEntry = 4; } return (w * numVisibleEntry + 2 * list->frameWidth()); } static QString formatFontSize(qreal size) { return QLocale::system().toString(size, 'f', (size == floor(size)) ? 0 : 1); } class KFontChooser::Private { public: Private(KFontChooser *qq) : q(qq) { m_palette.setColor(QPalette::Active, QPalette::Text, Qt::black); m_palette.setColor(QPalette::Active, QPalette::Base, Qt::white); signalsAllowed = true; selectedSize = -1; customSizeRow = -1; } // pointer to an optinally supplied list of fonts to // inserted into the fontdialog font-family combo-box // QStringList fontList; void setFamilyBoxItems(const QStringList &fonts); void fillFamilyListBox(bool onlyFixedFonts = false); int nearestSizeRow(qreal val, bool customize); qreal fillSizeList(const QList &sizes = QList()); qreal setupSizeListBox(const QString &family, const QString &style); void setupDisplay(); QString styleIdentifier(const QFont &font); void _k_toggled_checkbox(); void _k_family_chosen_slot(const QString &); void _k_size_chosen_slot(const QString &); void _k_style_chosen_slot(const QString &); void _k_displaySample(const QFont &font); void _k_size_value_slot(double); KFontChooser *q; QPalette m_palette; QDoubleSpinBox *sizeOfFont; QTextEdit *sampleEdit; QLabel *familyLabel; QLabel *styleLabel; QCheckBox *familyCheckbox; QCheckBox *styleCheckbox; QCheckBox *sizeCheckbox; QLabel *sizeLabel; QListWidget *familyListBox; QListWidget *styleListBox; QListWidget *sizeListBox; QCheckBox *sizeIsRelativeCheckBox; QFont selFont; QString selectedStyle; qreal selectedSize; QString standardSizeAtCustom; int customSizeRow; bool signalsAllowed: 1; bool usingFixed: 1; // Mappings of translated to Qt originated family and style strings. QHash qtFamilies; QHash qtStyles; // Mapping of translated style strings to internal style identifiers. QHash styleIDs; }; KFontChooser::KFontChooser(QWidget *parent, const DisplayFlags &flags, const QStringList &fontList, int visibleListSize, Qt::CheckState *sizeIsRelativeState) : QWidget(parent), d(new KFontChooser::Private(this)) { d->usingFixed = flags & FixedFontsOnly; setWhatsThis(KFontChooser::tr("Here you can choose the font to be used.", "@info:whatsthis")); // The top layout is divided vertically into a splitter with font // attribute widgets and preview on the top, and XLFD data at the bottom. QVBoxLayout *topLayout = new QVBoxLayout(this); topLayout->setMargin(0); const int spacingHint = style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing); int checkBoxGap = spacingHint / 2; // The splitter contains font attribute widgets in the top part, // and the font preview in the bottom part. // The splitter is there to allow the user to resize the font preview. QSplitter *splitter = new QSplitter(Qt::Vertical, this); splitter->setChildrenCollapsible(false); topLayout->addWidget(splitter); // Build the grid of font attribute widgets for the upper splitter part. // QWidget *page; QGridLayout *gridLayout; int row = 0; if (flags & DisplayFrame) { page = new QGroupBox(KFontChooser::tr("Requested Font"), this); splitter->addWidget(page); gridLayout = new QGridLayout(page); row = 1; } else { page = new QWidget(this); splitter->addWidget(page); gridLayout = new QGridLayout(page); gridLayout->setMargin(0); } // // first, create the labels across the top // QHBoxLayout *familyLayout = new QHBoxLayout(); familyLayout->addSpacing(checkBoxGap); if (flags & ShowDifferences) { d->familyCheckbox = new QCheckBox(KFontChooser::tr("Font", "@option:check"), page); connect(d->familyCheckbox, SIGNAL(toggled(bool)), this, SLOT(_k_toggled_checkbox())); familyLayout->addWidget(d->familyCheckbox, 0, Qt::AlignLeft); d->familyCheckbox->setWhatsThis(KFontChooser::tr("Enable this checkbox to change the font family settings.", "@info:whatsthis")); d->familyCheckbox->setToolTip(KFontChooser::tr("Change font family?", "@info:tooltip")); - d->familyLabel = 0; + d->familyLabel = nullptr; } else { - d->familyCheckbox = 0; + d->familyCheckbox = nullptr; d->familyLabel = new QLabel(KFontChooser::tr("Font:", "@label"), page); familyLayout->addWidget(d->familyLabel, 1, Qt::AlignLeft); } gridLayout->addLayout(familyLayout, row, 0); QHBoxLayout *styleLayout = new QHBoxLayout(); if (flags & ShowDifferences) { d->styleCheckbox = new QCheckBox(KFontChooser::tr("Font style", "@option:check"), page); connect(d->styleCheckbox, SIGNAL(toggled(bool)), this, SLOT(_k_toggled_checkbox())); styleLayout->addWidget(d->styleCheckbox, 0, Qt::AlignLeft); d->styleCheckbox->setWhatsThis(KFontChooser::tr("Enable this checkbox to change the font style settings.", "@info:whatsthis")); d->styleCheckbox->setToolTip(KFontChooser::tr("Change font style?", "@info:tooltip")); - d->styleLabel = 0; + d->styleLabel = nullptr; } else { - d->styleCheckbox = 0; + d->styleCheckbox = nullptr; d->styleLabel = new QLabel(KFontChooser::tr("Font style:"), page); styleLayout->addWidget(d->styleLabel, 1, Qt::AlignLeft); } styleLayout->addSpacing(checkBoxGap); gridLayout->addLayout(styleLayout, row, 1); QHBoxLayout *sizeLayout = new QHBoxLayout(); if (flags & ShowDifferences) { d->sizeCheckbox = new QCheckBox(KFontChooser::tr("Size", "@option:check"), page); connect(d->sizeCheckbox, SIGNAL(toggled(bool)), this, SLOT(_k_toggled_checkbox())); sizeLayout->addWidget(d->sizeCheckbox, 0, Qt::AlignLeft); d->sizeCheckbox->setWhatsThis(KFontChooser::tr("Enable this checkbox to change the font size settings.", "@info:whatsthis")); d->sizeCheckbox->setToolTip(KFontChooser::tr("Change font size?", "@info:tooltip")); - d->sizeLabel = 0; + d->sizeLabel = nullptr; } else { - d->sizeCheckbox = 0; + d->sizeCheckbox = nullptr; d->sizeLabel = new QLabel(KFontChooser::tr("Size:", "@label:listbox Font size"), page); sizeLayout->addWidget(d->sizeLabel, 1, Qt::AlignLeft); } sizeLayout->addSpacing(checkBoxGap); sizeLayout->addSpacing(checkBoxGap); // prevent label from eating border gridLayout->addLayout(sizeLayout, row, 2); row ++; // // now create the actual boxes that hold the info // d->familyListBox = new QListWidget(page); d->familyListBox->setEnabled(flags ^ ShowDifferences); gridLayout->addWidget(d->familyListBox, row, 0); QString fontFamilyWhatsThisText( KFontChooser::tr("Here you can choose the font family to be used.", "@info:whatsthis")); d->familyListBox->setWhatsThis(fontFamilyWhatsThisText); if (flags & ShowDifferences) { d->familyCheckbox->setWhatsThis(fontFamilyWhatsThisText); } else { d->familyLabel->setWhatsThis(fontFamilyWhatsThisText); } connect(d->familyListBox, SIGNAL(currentTextChanged(QString)), this, SLOT(_k_family_chosen_slot(QString))); if (!fontList.isEmpty()) { d->setFamilyBoxItems(fontList); } else { d->fillFamilyListBox(flags & FixedFontsOnly); } d->familyListBox->setMinimumWidth(minimumListWidth(d->familyListBox)); d->familyListBox->setMinimumHeight( minimumListHeight(d->familyListBox, visibleListSize)); d->styleListBox = new QListWidget(page); d->styleListBox->setEnabled(flags ^ ShowDifferences); gridLayout->addWidget(d->styleListBox, row, 1); d->styleListBox->setWhatsThis(KFontChooser::tr("Here you can choose the font style to be used.", "@info:whatsthis")); if (flags & ShowDifferences) { ((QWidget *)d->styleCheckbox)->setWhatsThis(fontFamilyWhatsThisText); } else { ((QWidget *)d->styleLabel)->setWhatsThis(fontFamilyWhatsThisText); } // Populate usual styles, to determine minimum list width; // will be replaced later with correct styles. d->styleListBox->addItem(KFontChooser::tr("Normal", "QFontDatabase")); d->styleListBox->addItem(KFontChooser::tr("Italic", "@item font")); d->styleListBox->addItem(KFontChooser::tr("Oblique", "@item font")); d->styleListBox->addItem(KFontChooser::tr("Bold", "@item font")); d->styleListBox->addItem(KFontChooser::tr("Bold Italic", "@item font")); d->styleListBox->setMinimumWidth(minimumListWidth(d->styleListBox)); d->styleListBox->setMinimumHeight( minimumListHeight(d->styleListBox, visibleListSize)); connect(d->styleListBox, SIGNAL(currentTextChanged(QString)), this, SLOT(_k_style_chosen_slot(QString))); d->sizeListBox = new QListWidget(page); d->sizeOfFont = new QDoubleSpinBox(page); d->sizeOfFont->setMinimum(4); d->sizeOfFont->setMaximum(999); d->sizeOfFont->setDecimals(1); d->sizeOfFont->setSingleStep(1); d->sizeListBox->setEnabled(flags ^ ShowDifferences); d->sizeOfFont->setEnabled(flags ^ ShowDifferences); if (sizeIsRelativeState) { QString sizeIsRelativeCBText = KFontChooser::tr("Relative", "@item font size"); QString sizeIsRelativeCBToolTipText = KFontChooser::tr("Font size
fixed or relative
to environment"); QString sizeIsRelativeCBWhatsThisText = KFontChooser::tr("Here you can switch between fixed font size and font size " "to be calculated dynamically and adjusted to changing " "environment (e.g. widget dimensions, paper size)."); d->sizeIsRelativeCheckBox = new QCheckBox(sizeIsRelativeCBText, page); d->sizeIsRelativeCheckBox->setTristate(flags & ShowDifferences); QGridLayout *sizeLayout2 = new QGridLayout(); sizeLayout2->setSpacing(spacingHint / 2); gridLayout->addLayout(sizeLayout2, row, 2); sizeLayout2->setColumnStretch(1, 1); // to prevent text from eating the right border sizeLayout2->addWidget(d->sizeOfFont, 0, 0, 1, 2); sizeLayout2->addWidget(d->sizeListBox, 1, 0, 1, 2); sizeLayout2->addWidget(d->sizeIsRelativeCheckBox, 2, 0, Qt::AlignLeft); d->sizeIsRelativeCheckBox->setWhatsThis(sizeIsRelativeCBWhatsThisText); d->sizeIsRelativeCheckBox->setToolTip(sizeIsRelativeCBToolTipText); } else { - d->sizeIsRelativeCheckBox = 0L; + d->sizeIsRelativeCheckBox = nullptr; QGridLayout *sizeLayout2 = new QGridLayout(); sizeLayout2->setSpacing(spacingHint / 2); gridLayout->addLayout(sizeLayout2, row, 2); sizeLayout2->addWidget(d->sizeOfFont, 0, 0); sizeLayout2->addWidget(d->sizeListBox, 1, 0); } QString fontSizeWhatsThisText = KFontChooser::tr("Here you can choose the font size to be used."); d->sizeListBox->setWhatsThis(fontSizeWhatsThisText); if (flags & ShowDifferences) { ((QWidget *)d->sizeCheckbox)->setWhatsThis(fontSizeWhatsThisText); } else { ((QWidget *)d->sizeLabel)->setWhatsThis(fontSizeWhatsThisText); } // Populate with usual sizes, to determine minimum list width; // will be replaced later with correct sizes. d->fillSizeList(); d->sizeListBox->setMinimumWidth(minimumListWidth(d->sizeListBox) + d->sizeListBox->fontMetrics().maxWidth()); d->sizeListBox->setMinimumHeight( minimumListHeight(d->sizeListBox, visibleListSize)); connect(d->sizeOfFont, SIGNAL(valueChanged(double)), this, SLOT(_k_size_value_slot(double))); connect(d->sizeListBox, SIGNAL(currentTextChanged(QString)), this, SLOT(_k_size_chosen_slot(QString))); row ++; // // Completed the font attribute grid. // Add the font preview into the lower part of the splitter. // d->sampleEdit = new QTextEdit(page); d->sampleEdit->setAcceptRichText(false); QFont tmpFont(font().family(), 64, QFont::Black); d->sampleEdit->setFont(tmpFont); d->sampleEdit->setMinimumHeight(d->sampleEdit->fontMetrics().lineSpacing()); // tr: A classical test phrase, with all letters of the English alphabet. // Replace it with a sample text in your language, such that it is // representative of language's writing system. // If you wish, you can input several lines of text separated by \n. setSampleText(KFontChooser::tr("The Quick Brown Fox Jumps Over The Lazy Dog")); d->sampleEdit->setTextCursor(QTextCursor(d->sampleEdit->document())); QString sampleEditWhatsThisText = KFontChooser::tr("This sample text illustrates the current settings. " "You may edit it to test special characters."); d->sampleEdit->setWhatsThis(sampleEditWhatsThisText); connect(this, SIGNAL(fontSelected(QFont)), this, SLOT(_k_displaySample(QFont))); splitter->addWidget(d->sampleEdit); // // Finished setting up the splitter. // // Finished setting up the chooser layout. // lets initialize the display if possible if (d->usingFixed) { setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont), d->usingFixed); } else { setFont(QGuiApplication::font(), d->usingFixed); } // check or uncheck or gray out the "relative" checkbox if (sizeIsRelativeState && d->sizeIsRelativeCheckBox) { setSizeIsRelative(*sizeIsRelativeState); } // Set focus to the size list as this is the most commonly changed property d->sizeListBox->setFocus(); } KFontChooser::~KFontChooser() { delete d; } void KFontChooser::setColor(const QColor &col) { d->m_palette.setColor(QPalette::Active, QPalette::Text, col); QPalette pal = d->sampleEdit->palette(); pal.setColor(QPalette::Active, QPalette::Text, col); d->sampleEdit->setPalette(pal); QTextCursor cursor = d->sampleEdit->textCursor(); d->sampleEdit->selectAll(); d->sampleEdit->setTextColor(col); d->sampleEdit->setTextCursor(cursor); } QColor KFontChooser::color() const { return d->m_palette.color(QPalette::Active, QPalette::Text); } void KFontChooser::setBackgroundColor(const QColor &col) { d->m_palette.setColor(QPalette::Active, QPalette::Base, col); QPalette pal = d->sampleEdit->palette(); pal.setColor(QPalette::Active, QPalette::Base, col); d->sampleEdit->setPalette(pal); } QColor KFontChooser::backgroundColor() const { return d->m_palette.color(QPalette::Active, QPalette::Base); } void KFontChooser::setSizeIsRelative(Qt::CheckState relative) { // check or uncheck or gray out the "relative" checkbox if (d->sizeIsRelativeCheckBox) { if (Qt::PartiallyChecked == relative) { d->sizeIsRelativeCheckBox->setCheckState(Qt::PartiallyChecked); } else { d->sizeIsRelativeCheckBox->setCheckState((Qt::Checked == relative) ? Qt::Checked : Qt::Unchecked); } } } Qt::CheckState KFontChooser::sizeIsRelative() const { return d->sizeIsRelativeCheckBox ? d->sizeIsRelativeCheckBox->checkState() : Qt::PartiallyChecked; } QString KFontChooser::sampleText() const { return d->sampleEdit->toPlainText(); } void KFontChooser::setSampleText(const QString &text) { d->sampleEdit->setPlainText(text); } void KFontChooser::setSampleBoxVisible(bool visible) { d->sampleEdit->setVisible(visible); } QSize KFontChooser::sizeHint(void) const { return minimumSizeHint(); } void KFontChooser::enableColumn(int column, bool state) { if (column & FamilyList) { d->familyListBox->setEnabled(state); } if (column & StyleList) { d->styleListBox->setEnabled(state); } if (column & SizeList) { d->sizeListBox->setEnabled(state); d->sizeOfFont->setEnabled(state); } } void KFontChooser::setFont(const QFont &aFont, bool onlyFixed) { d->selFont = aFont; d->selectedSize = aFont.pointSizeF(); if (d->selectedSize == -1) { d->selectedSize = QFontInfo(aFont).pointSizeF(); } if (onlyFixed != d->usingFixed) { d->usingFixed = onlyFixed; d->fillFamilyListBox(d->usingFixed); } d->setupDisplay(); } KFontChooser::FontDiffFlags KFontChooser::fontDiffFlags() const { FontDiffFlags diffFlags = NoFontDiffFlags; if (d->familyCheckbox && d->familyCheckbox->isChecked()) { diffFlags |= FontDiffFamily; } if (d->styleCheckbox && d->styleCheckbox->isChecked()) { diffFlags |= FontDiffStyle; } if (d->sizeCheckbox && d->sizeCheckbox->isChecked()) { diffFlags |= FontDiffSize; } return diffFlags; } QFont KFontChooser::font() const { return d->selFont; } void KFontChooser::Private::_k_toggled_checkbox() { familyListBox->setEnabled(familyCheckbox->isChecked()); styleListBox->setEnabled(styleCheckbox->isChecked()); sizeListBox->setEnabled(sizeCheckbox->isChecked()); sizeOfFont->setEnabled(sizeCheckbox->isChecked()); } void KFontChooser::Private::_k_family_chosen_slot(const QString &family) { if (!signalsAllowed) { return; } signalsAllowed = false; QString currentFamily; if (family.isEmpty()) { Q_ASSERT(familyListBox->currentItem()); if (familyListBox->currentItem()) { currentFamily = qtFamilies[familyListBox->currentItem()->text()]; } } else { currentFamily = qtFamilies[family]; } // Get the list of styles available in this family. QFontDatabase dbase; QStringList styles = dbase.styles(currentFamily); if (styles.isEmpty()) { // Avoid extraction, it is in kdeqt.po styles.append(TR_NOX("Normal", "QFontDatabase")); } // Filter style strings and add to the listbox. QString pureFamily; splitFontString(family, &pureFamily); QStringList filteredStyles; qtStyles.clear(); styleIDs.clear(); Q_FOREACH (const QString &style, styles) { // Sometimes the font database will report an invalid style, // that falls back back to another when set. // Remove such styles, by checking set/get round-trip. QFont testFont = dbase.font(currentFamily, style, 10); if (dbase.styleString(testFont) != style) { styles.removeAll(style); continue; } QString fstyle = tr("%1", "@item Font style").arg(style); if (!filteredStyles.contains(fstyle)) { filteredStyles.append(fstyle); qtStyles.insert(fstyle, style); styleIDs.insert(fstyle, styleIdentifier(testFont)); } } styleListBox->clear(); styleListBox->addItems(filteredStyles); // Try to set the current style in the listbox to that previous. int listPos = filteredStyles.indexOf(selectedStyle.isEmpty() ? TR_NOX("Normal", "QFontDatabase") : selectedStyle); if (listPos < 0) { // Make extra effort to have Italic selected when Oblique was chosen, // and vice versa, as that is what the user would probably want. QString styleIt = tr("Italic", "@item font"); QString styleOb = tr("Oblique", "@item font"); for (int i = 0; i < 2; ++i) { int pos = selectedStyle.indexOf(styleIt); if (pos >= 0) { QString style = selectedStyle; style.replace(pos, styleIt.length(), styleOb); listPos = filteredStyles.indexOf(style); if (listPos >= 0) { break; } } qSwap(styleIt, styleOb); } } styleListBox->setCurrentRow(listPos >= 0 ? listPos : 0); QString currentStyle = qtStyles[styleListBox->currentItem()->text()]; // Recompute the size listbox for this family/style. qreal currentSize = setupSizeListBox(currentFamily, currentStyle); sizeOfFont->setValue(currentSize); selFont = dbase.font(currentFamily, currentStyle, int(currentSize)); if (dbase.isSmoothlyScalable(currentFamily, currentStyle) && selFont.pointSize() == floor(currentSize)) { selFont.setPointSizeF(currentSize); } emit q->fontSelected(selFont); signalsAllowed = true; } void KFontChooser::Private::_k_style_chosen_slot(const QString &style) { if (!signalsAllowed) { return; } signalsAllowed = false; QFontDatabase dbase; QString currentFamily = qtFamilies[familyListBox->currentItem()->text()]; QString currentStyle; if (style.isEmpty()) { currentStyle = qtStyles[styleListBox->currentItem()->text()]; } else { currentStyle = qtStyles[style]; } // Recompute the size listbox for this family/style. qreal currentSize = setupSizeListBox(currentFamily, currentStyle); sizeOfFont->setValue(currentSize); selFont = dbase.font(currentFamily, currentStyle, int(currentSize)); if (dbase.isSmoothlyScalable(currentFamily, currentStyle) && selFont.pointSize() == floor(currentSize)) { selFont.setPointSizeF(currentSize); } emit q->fontSelected(selFont); if (!style.isEmpty()) { selectedStyle = currentStyle; } signalsAllowed = true; } void KFontChooser::Private::_k_size_chosen_slot(const QString &size) { if (!signalsAllowed) { return; } signalsAllowed = false; qreal currentSize; if (size.isEmpty()) { currentSize = QLocale::system().toDouble(sizeListBox->currentItem()->text()); } else { currentSize = QLocale::system().toDouble(size); } // Reset the customized size slot in the list if not needed. if (customSizeRow >= 0 && selFont.pointSizeF() != currentSize) { sizeListBox->item(customSizeRow)->setText(standardSizeAtCustom); customSizeRow = -1; } sizeOfFont->setValue(currentSize); selFont.setPointSizeF(currentSize); emit q->fontSelected(selFont); if (!size.isEmpty()) { selectedSize = currentSize; } signalsAllowed = true; } void KFontChooser::Private::_k_size_value_slot(double dval) { if (!signalsAllowed) { return; } signalsAllowed = false; // We compare with qreal, so convert for platforms where qreal != double. qreal val = qreal(dval); QFontDatabase dbase; QString family = qtFamilies[familyListBox->currentItem()->text()]; QString style = qtStyles[styleListBox->currentItem()->text()]; // Reset current size slot in list if it was customized. if (customSizeRow >= 0 && sizeListBox->currentRow() == customSizeRow) { sizeListBox->item(customSizeRow)->setText(standardSizeAtCustom); customSizeRow = -1; } bool canCustomize = true; // For Qt-bad-sizes workaround: skip this block unconditionally if (!dbase.isSmoothlyScalable(family, style)) { // Bitmap font, allow only discrete sizes. // Determine the nearest in the direction of change. canCustomize = false; int nrows = sizeListBox->count(); int row = sizeListBox->currentRow(); int nrow; if (val - selFont.pointSizeF() > 0) { for (nrow = row + 1; nrow < nrows; ++nrow) if (QLocale::system().toDouble(sizeListBox->item(nrow)->text()) >= val) { break; } } else { for (nrow = row - 1; nrow >= 0; --nrow) if (QLocale::system().toDouble(sizeListBox->item(nrow)->text()) <= val) { break; } } // Make sure the new row is not out of bounds. nrow = nrow < 0 ? 0 : nrow >= nrows ? nrows - 1 : nrow; // Get the size from the new row and set the spinbox to that size. val = QLocale::system().toDouble(sizeListBox->item(nrow)->text()); sizeOfFont->setValue(val); } // Set the current size in the size listbox. int row = nearestSizeRow(val, canCustomize); sizeListBox->setCurrentRow(row); selectedSize = val; selFont.setPointSizeF(val); emit q->fontSelected(selFont); signalsAllowed = true; } void KFontChooser::Private::_k_displaySample(const QFont &font) { sampleEdit->setFont(font); //sampleEdit->setCursorPosition(0); //QFontInfo a = QFontInfo(font); //qCDebug(KWidgetsAddonsLog) << "font: " << a.family () << ", " << a.pointSize (); //qCDebug(KWidgetsAddonsLog) << " (" << font.toString() << ")\n"; } int KFontChooser::Private::nearestSizeRow(qreal val, bool customize) { qreal diff = 1000; int row = 0; for (int r = 0; r < sizeListBox->count(); ++r) { qreal cval = QLocale::system().toDouble(sizeListBox->item(r)->text()); if (qAbs(cval - val) < diff) { diff = qAbs(cval - val); row = r; } } // For Qt-bad-sizes workaround: ignore value of customize, use true if (customize && diff > 0) { customSizeRow = row; standardSizeAtCustom = sizeListBox->item(row)->text(); sizeListBox->item(row)->setText(formatFontSize(val)); } return row; } qreal KFontChooser::Private::fillSizeList(const QList &sizes_) { if (!sizeListBox) { return 0; //assertion. } QList sizes = sizes_; bool canCustomize = false; if (sizes.count() == 0) { static const int c[] = { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 24, 26, 28, 32, 48, 64, 72, 80, 96, 128, 0 }; for (int i = 0; c[i]; ++i) { sizes.append(c[i]); } // Since sizes were not supplied, this is a vector font, // and size slot customization is allowed. canCustomize = true; } // Insert sizes into the listbox. sizeListBox->clear(); qSort(sizes); Q_FOREACH (qreal size, sizes) { sizeListBox->addItem(formatFontSize(size)); } // Return the nearest to selected size. // If the font is vector, the nearest size is always same as selected, // thus size slot customization is allowed. // If the font is bitmap, the nearest size need not be same as selected, // thus size slot customization is not allowed. customSizeRow = -1; int row = nearestSizeRow(selectedSize, canCustomize); return QLocale::system().toDouble(sizeListBox->item(row)->text()); } qreal KFontChooser::Private::setupSizeListBox(const QString &family, const QString &style) { QFontDatabase dbase; QList sizes; if (dbase.isSmoothlyScalable(family, style)) { // A vector font. //>sampleEdit->setPaletteBackgroundPixmap( VectorPixmap ); // TODO } else { // A bitmap font. //sampleEdit->setPaletteBackgroundPixmap( BitmapPixmap ); // TODO QList smoothSizes = dbase.smoothSizes(family, style); Q_FOREACH (int size, smoothSizes) { sizes.append(size); } } // Fill the listbox (uses default list of sizes if the given is empty). // Collect the best fitting size to selected size, to use if not smooth. qreal bestFitSize = fillSizeList(sizes); // Set the best fit size as current in the listbox if available. const QList selectedSizeList = sizeListBox->findItems(formatFontSize(bestFitSize), Qt::MatchExactly); if (!selectedSizeList.isEmpty()) { sizeListBox->setCurrentItem(selectedSizeList.first()); } return bestFitSize; } void KFontChooser::Private::setupDisplay() { QFontDatabase dbase; QString family = selFont.family().toLower(); QString styleID = styleIdentifier(selFont); qreal size = selFont.pointSizeF(); if (size == -1) { size = QFontInfo(selFont).pointSizeF(); } int numEntries, i; // Direct family match. numEntries = familyListBox->count(); for (i = 0; i < numEntries; ++i) { if (family == qtFamilies[familyListBox->item(i)->text()].toLower()) { familyListBox->setCurrentRow(i); break; } } // 1st family fallback. if (i == numEntries) { if (family.contains(QLatin1Char('['))) { family = family.left(family.indexOf(QLatin1Char('['))).trimmed(); for (i = 0; i < numEntries; ++i) { if (family == qtFamilies[familyListBox->item(i)->text()].toLower()) { familyListBox->setCurrentRow(i); break; } } } } // 2nd family fallback. if (i == numEntries) { QString fallback = family + QStringLiteral(" ["); for (i = 0; i < numEntries; ++i) { if (qtFamilies[familyListBox->item(i)->text()].toLower().startsWith(fallback)) { familyListBox->setCurrentRow(i); break; } } } // 3rd family fallback. if (i == numEntries) { for (i = 0; i < numEntries; ++i) { if (qtFamilies[familyListBox->item(i)->text()].toLower().startsWith(family)) { familyListBox->setCurrentRow(i); break; } } } // Family fallback in case nothing matched. Otherwise, diff doesn't work if (i == numEntries) { familyListBox->setCurrentRow(0); } // By setting the current item in the family box, the available // styles and sizes for that family have been collected. // Try now to set the current items in the style and size boxes. // Set current style in the listbox. numEntries = styleListBox->count(); for (i = 0; i < numEntries; ++i) { if (styleID == styleIDs[styleListBox->item(i)->text()]) { styleListBox->setCurrentRow(i); break; } } if (i == numEntries) { // Style not found, fallback. styleListBox->setCurrentRow(0); } // Set current size in the listbox. // If smoothly scalable, allow customizing one of the standard size slots, // otherwise just select the nearest available size. QString currentFamily = qtFamilies[familyListBox->currentItem()->text()]; QString currentStyle = qtStyles[styleListBox->currentItem()->text()]; bool canCustomize = dbase.isSmoothlyScalable(currentFamily, currentStyle); sizeListBox->setCurrentRow(nearestSizeRow(size, canCustomize)); // Set current size in the spinbox. sizeOfFont->setValue(QLocale::system().toDouble(sizeListBox->currentItem()->text())); } void KFontChooser::getFontList(QStringList &list, uint fontListCriteria) { QFontDatabase dbase; QStringList lstSys(dbase.families()); // if we have criteria; then check fonts before adding if (fontListCriteria) { QStringList lstFonts; for (QStringList::const_iterator it = lstSys.constBegin(); it != lstSys.constEnd(); ++it) { if ((fontListCriteria & FixedWidthFonts) > 0 && !dbase.isFixedPitch(*it)) { continue; } if (((fontListCriteria & (SmoothScalableFonts | ScalableFonts)) == ScalableFonts) && !dbase.isBitmapScalable(*it)) { continue; } if ((fontListCriteria & SmoothScalableFonts) > 0 && !dbase.isSmoothlyScalable(*it)) { continue; } lstFonts.append(*it); } if ((fontListCriteria & FixedWidthFonts) > 0) { // Fallback.. if there are no fixed fonts found, it's probably a // bug in the font server or Qt. In this case, just use 'fixed' if (lstFonts.count() == 0) { lstFonts.append(QStringLiteral("fixed")); } } lstSys = lstFonts; } lstSys.sort(); list = lstSys; } void KFontChooser::Private::setFamilyBoxItems(const QStringList &fonts) { signalsAllowed = false; QStringList trfonts = translateFontNameList(fonts, &qtFamilies); familyListBox->clear(); familyListBox->addItems(trfonts); signalsAllowed = true; } void KFontChooser::Private::fillFamilyListBox(bool onlyFixedFonts) { QStringList fontList; getFontList(fontList, onlyFixedFonts ? FixedWidthFonts : 0); setFamilyBoxItems(fontList); } // Human-readable style identifiers returned by QFontDatabase::styleString() // do not always survive round trip of QFont serialization/deserialization, // causing wrong style in the style box to be highlighted when // the chooser dialog is opened. This will cause the style to be changed // when the dialog is closed and the user did not touch the style box. // Hence, construct custom style identifiers sufficient for the purpose. QString KFontChooser::Private::styleIdentifier(const QFont &font) { const QChar comma(QLatin1Char(',')); return QString::number(font.weight()) + comma + QString::number((int)font.style()) + comma + QString::number(font.stretch()); } #include "moc_kfontchooser.cpp" diff --git a/src/kfontchooser.h b/src/kfontchooser.h index d3b777b..482875b 100644 --- a/src/kfontchooser.h +++ b/src/kfontchooser.h @@ -1,271 +1,271 @@ /* Requires the Qt widget libraries, available at no cost at http://www.troll.no Copyright (C) 1997 Bernd Johannes Wuebben Copyright (c) 1999 Preston Brown Copyright (c) 1999 Mario Weilguni This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef K_FONT_CHOOSER_H #define K_FONT_CHOOSER_H #include #include class QFont; class QStringList; /** * @short A font selection widget. * * While KFontChooser as an ordinary widget can be embedded in * custom dialogs and therefore is very flexible, in most cases * it is preferable to use the convenience functions in * QFontDialog. * * \image html kfontchooser.png "KDE Font Chooser Widget" * * @see KFontRequester * * @author Preston Brown , Bernd Wuebben */ class KWIDGETSADDONS_EXPORT KFontChooser : public QWidget { Q_OBJECT Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontSelected USER true) Q_PROPERTY(QColor color READ color WRITE setColor) Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor) Q_PROPERTY(Qt::CheckState sizeIsRelative READ sizeIsRelative WRITE setSizeIsRelative) Q_PROPERTY(QString sampleText READ sampleText WRITE setSampleText) public: /** * @li @p FamilyList - Identifies the family (leftmost) list. * @li @p StyleList - Identifies the style (center) list. * @li @p SizeList - Identifies the size (rightmost) list. */ enum FontColumn { FamilyList = 0x01, StyleList = 0x02, SizeList = 0x04}; /** * @li @p FontDiffFamily - Identifies a requested change in the font family. * @li @p FontDiffStyle - Identifies a requested change in the font style. * @li @p FontDiffSize - Identifies a requested change in the font size. */ enum FontDiff { NoFontDiffFlags = 0, FontDiffFamily = 1, FontDiffStyle = 2, FontDiffSize = 4, AllFontDiffs = FontDiffFamily | FontDiffStyle | FontDiffSize }; Q_DECLARE_FLAGS(FontDiffFlags, FontDiff) /** * @li @p FixedFontsOnly only show fixed fonts, excluding proportional fonts * @li @p DisplayFrame show a visual frame around the chooser * @li @p ShowDifferences display the font differences interfaces */ enum DisplayFlag { NoDisplayFlags = 0, FixedFontsOnly = 1, DisplayFrame = 2, ShowDifferences = 4 }; Q_DECLARE_FLAGS(DisplayFlags, DisplayFlag) /** * Constructs a font picker widget. * It normally comes up with all font families present on the system; the * getFont method below does allow some more fine-tuning of the selection of fonts * that will be displayed in the dialog. *

Consider the following code snippet; * \code * QStringList list; * KFontChooser::getFontList(list, KFontChooser::SmoothScalableFonts); * KFontChooser *chooseFont = new KFontChooser(0, NoDisplayFlags, list); * \endcode *

* The above creates a font chooser dialog with only SmoothScaleble fonts. * * @param parent The parent widget. * @param flags Defines how the font chooser is displayed. @see DisplayFlags * @param fontList A list of fonts to display, in XLFD format. If * no list is formatted, the internal KDE font list is used. * If that has not been created, X is queried, and all fonts * available on the system are displayed. * @param visibleListSize The minimum number of visible entries in the * fontlists. * @param sizeIsRelativeState If not zero the widget will show a * checkbox where the user may choose whether the font size * is to be interpreted as relative size. * Initial state of this checkbox will be set according to * *sizeIsRelativeState, user choice may be retrieved by * calling sizeIsRelative(). */ - explicit KFontChooser(QWidget *parent = 0L, + explicit KFontChooser(QWidget *parent = nullptr, const DisplayFlags &flags = DisplayFrame, const QStringList &fontList = QStringList(), int visibleListSize = 8, - Qt::CheckState *sizeIsRelativeState = 0L); + Qt::CheckState *sizeIsRelativeState = nullptr); /** * Destructs the font chooser. */ virtual ~KFontChooser(); /** * Enables or disable a font column in the chooser. * * Use this * function if your application does not need or supports all font * properties. * * @param column Specify the columns. An or'ed combination of * @p FamilyList, @p StyleList and @p SizeList is possible. * @param state If @p false the columns are disabled. */ void enableColumn(int column, bool state); /** * Sets the currently selected font in the chooser. * * @param font The font to select. * @param onlyFixed Readjust the font list to display only fixed * width fonts if @p true, or vice-versa. */ void setFont(const QFont &font, bool onlyFixed = false); /** * @return The bitmask corresponding to the attributes the user * wishes to change. */ FontDiffFlags fontDiffFlags() const; /** * @return The currently selected font in the chooser. */ QFont font() const; /** * Sets the color to use in the preview. */ void setColor(const QColor &col); /** * @return The color currently used in the preview (default: the text * color of the active color group) */ QColor color() const; /** * Sets the background color to use in the preview. */ void setBackgroundColor(const QColor &col); /** * @return The background color currently used in the preview (default: * the base color of the active colorgroup) */ QColor backgroundColor() const; /** * Sets the state of the checkbox indicating whether the font size * is to be interpreted as relative size. * NOTE: If parameter sizeIsRelative was not set in the constructor * of the widget this setting will be ignored. */ void setSizeIsRelative(Qt::CheckState relative); /** * @return Whether the font size is to be interpreted as relative size * (default: QButton:Off) */ Qt::CheckState sizeIsRelative() const; /** * @return The current text in the sample text input area. */ QString sampleText() const; /** * Sets the sample text. * * Normally you should not change this * text, but it can be better to do this if the default text is * too large for the edit area when using the default font of your * application. * * @param text The new sample text. The current will be removed. */ void setSampleText(const QString &text); /** * Shows or hides the sample text box. * * @param visible Set it to true to show the box, to false to hide it. */ void setSampleBoxVisible(bool visible); /** * The selection criteria for the font families shown in the dialog. * @li @p FixedWidthFont when included only fixed-width fonts are returned. * The fonts where the width of every character is equal. * @li @p ScalableFont when included only scalable fonts are returned; * certain configurations allow bitmap fonts to remain unscaled and * thus these fonts have limited number of sizes. * @li @p SmoothScalableFont when included only return smooth scalable fonts. * this will return only non-bitmap fonts which are scalable to any size requested. * Setting this option to true will mean the "scalable" flag is irrelavant. */ enum FontListCriteria { FixedWidthFonts = 0x01, ScalableFonts = 0x02, SmoothScalableFonts = 0x04 }; /** * Creates a list of font strings. * * @param list The list is returned here. * @param fontListCriteria should contain all the restrictions for font selection as OR-ed values * @see KFontChooser::FontListCriteria for the individual values */ static void getFontList(QStringList &list, uint fontListCriteria); /** * Reimplemented for internal reasons. */ QSize sizeHint(void) const Q_DECL_OVERRIDE; Q_SIGNALS: /** * Emitted whenever the selected font changes. */ void fontSelected(const QFont &font); private: class Private; Private *const d; Q_DISABLE_COPY(KFontChooser) Q_PRIVATE_SLOT(d, void _k_toggled_checkbox()) Q_PRIVATE_SLOT(d, void _k_family_chosen_slot(const QString &)) Q_PRIVATE_SLOT(d, void _k_size_chosen_slot(const QString &)) Q_PRIVATE_SLOT(d, void _k_style_chosen_slot(const QString &)) Q_PRIVATE_SLOT(d, void _k_displaySample(const QFont &font)) Q_PRIVATE_SLOT(d, void _k_size_value_slot(double)) }; Q_DECLARE_OPERATORS_FOR_FLAGS(KFontChooser::DisplayFlags) #endif diff --git a/src/kfontrequester.cpp b/src/kfontrequester.cpp index 6cca672..3c97813 100644 --- a/src/kfontrequester.cpp +++ b/src/kfontrequester.cpp @@ -1,234 +1,234 @@ /* Copyright (C) 2003 Nadeem Hasan This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kfontrequester.h" #include "fonthelpers_p.h" #include #include #include #include #include #include #include #include // Determine if the font with given properties is available on the system, // otherwise find and return the best fitting combination. static QFont nearestExistingFont(const QFont &font) { QFontDatabase dbase; // Initialize font data accoring to given font object. QString family = font.family(); QString style = dbase.styleString(font); qreal size = font.pointSizeF(); // Check if the family exists. const QStringList families = dbase.families(); if (!families.contains(family)) { // Chose another family. family = families.count() ? families[0] : QStringLiteral("fixed"); // TODO: Try to find nearest match? } // Check if the family has the requested style. // Easiest by piping it through font selection in the database. QString retStyle = dbase.styleString(dbase.font(family, style, 10)); style = retStyle; // Check if the family has the requested size. // Only for bitmap fonts. if (!dbase.isSmoothlyScalable(family, style)) { QList sizes = dbase.smoothSizes(family, style); if (!sizes.contains(size)) { // Find nearest available size. int mindiff = 1000; int refsize = size; Q_FOREACH (int lsize, sizes) { int diff = qAbs(refsize - lsize); if (mindiff > diff) { mindiff = diff; size = lsize; } } } } // Select the font with confirmed properties. QFont result = dbase.font(family, style, int(size)); if (dbase.isSmoothlyScalable(family, style) && result.pointSize() == floor(size)) { result.setPointSizeF(size); } return result; } class KFontRequester::KFontRequesterPrivate { public: KFontRequesterPrivate(KFontRequester *q): q(q) {} void displaySampleText(); void setToolTip(); void _k_buttonClicked(); KFontRequester *q; bool m_onlyFixed; QString m_sampleText, m_title; QLabel *m_sampleLabel; QPushButton *m_button; QFont m_selFont; }; KFontRequester::KFontRequester(QWidget *parent, bool onlyFixed) : QWidget(parent), d(new KFontRequesterPrivate(this)) { d->m_onlyFixed = onlyFixed; QHBoxLayout *layout = new QHBoxLayout(this); layout->setMargin(0); d->m_sampleLabel = new QLabel(this); d->m_button = new QPushButton(tr("Choose..."), this); d->m_sampleLabel->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); setFocusProxy(d->m_button); setFocusPolicy(d->m_button->focusPolicy()); layout->addWidget(d->m_sampleLabel, 1); layout->addWidget(d->m_button); connect(d->m_button, SIGNAL(clicked()), SLOT(_k_buttonClicked())); d->displaySampleText(); d->setToolTip(); } KFontRequester::~KFontRequester() { delete d; } QFont KFontRequester::font() const { return d->m_selFont; } bool KFontRequester::isFixedOnly() const { return d->m_onlyFixed; } QString KFontRequester::sampleText() const { return d->m_sampleText; } QString KFontRequester::title() const { return d->m_title; } QLabel *KFontRequester::label() const { return d->m_sampleLabel; } QPushButton *KFontRequester::button() const { return d->m_button; } void KFontRequester::setFont(const QFont &font, bool onlyFixed) { d->m_selFont = nearestExistingFont(font); d->m_onlyFixed = onlyFixed; d->displaySampleText(); emit fontSelected(d->m_selFont); } void KFontRequester::setSampleText(const QString &text) { d->m_sampleText = text; d->displaySampleText(); } void KFontRequester::setTitle(const QString &title) { d->m_title = title; d->setToolTip(); } void KFontRequester::KFontRequesterPrivate::_k_buttonClicked() { - QFontDialog::FontDialogOptions flags = 0; + QFontDialog::FontDialogOptions flags = nullptr; if (m_onlyFixed) { flags = QFontDialog::MonospacedFonts; } bool ok = false; QFont font = QFontDialog::getFont(&ok, m_selFont, q->parentWidget(), QString(), flags); if (ok) { m_selFont = font; displaySampleText(); emit q->fontSelected(m_selFont); } } void KFontRequester::KFontRequesterPrivate::displaySampleText() { m_sampleLabel->setFont(m_selFont); qreal size = m_selFont.pointSizeF(); if (size == -1) { size = m_selFont.pixelSize(); } if (m_sampleText.isEmpty()) { QString family = translateFontName(m_selFont.family()); m_sampleLabel->setText(QStringLiteral("%1 %2").arg(family).arg(size)); } else { m_sampleLabel->setText(m_sampleText); } } void KFontRequester::KFontRequesterPrivate::setToolTip() { m_button->setToolTip(tr("Click to select a font")); m_sampleLabel->setToolTip(QString()); m_sampleLabel->setWhatsThis(QString()); if (m_title.isNull()) { m_sampleLabel->setToolTip(tr("Preview of the selected font")); m_sampleLabel->setWhatsThis(tr("This is a preview of the selected font. You can change it" " by clicking the \"Choose...\" button.")); } else { m_sampleLabel->setToolTip(tr("Preview of the \"%1\" font").arg(m_title)); m_sampleLabel->setWhatsThis(tr("This is a preview of the \"%1\" font. You can change it" " by clicking the \"Choose...\" button.").arg(m_title)); } } #include "moc_kfontrequester.cpp" diff --git a/src/kfontrequester.h b/src/kfontrequester.h index fe6fc8c..fbd6bf8 100644 --- a/src/kfontrequester.h +++ b/src/kfontrequester.h @@ -1,142 +1,142 @@ /* Copyright (C) 2003 Nadeem Hasan This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KFONTREQUESTER_H #define KFONTREQUESTER_H #include #include #include #include class QLabel; class QPushButton; /** * This class provides a widget with a lineedit and a button, which invokes * a font dialog (QFontDialog). * * The lineedit provides a preview of the selected font. The preview text can * be customized. You can also have the font dialog show only the fixed fonts. * * \image html kfontrequester.png "KDE Font Requester" * * @author Nadeem Hasan * */ class KWIDGETSADDONS_EXPORT KFontRequester : public QWidget { Q_OBJECT Q_PROPERTY(QString title READ title WRITE setTitle) Q_PROPERTY(QString sampleText READ sampleText WRITE setSampleText) Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontSelected USER true) public: /** * Constructs a font requester widget. * * @param parent The parent widget. * @param onlyFixed Only display fonts which have fixed-width character * sizes. */ - explicit KFontRequester(QWidget *parent = 0L, bool onlyFixed = false); + explicit KFontRequester(QWidget *parent = nullptr, bool onlyFixed = false); ~KFontRequester(); /** * @return The currently selected font in the requester. */ QFont font() const; /** * @return Returns true if only fixed fonts are displayed. */ bool isFixedOnly() const; /** * @return The current text in the sample text input area. */ QString sampleText() const; /** * @return The current title of the widget. */ QString title() const; /** * @return Pointer to the label used for preview. */ QLabel *label() const; /** * @return Pointer to the pushbutton in the widget. */ QPushButton *button() const; /** * Sets the currently selected font in the requester. * * @param font The font to select. * @param onlyFixed Display only fixed-width fonts in the font dialog * if @p true, or vice-versa. */ virtual void setFont(const QFont &font, bool onlyFixed = false); /** * Sets the sample text. * * Normally you should not change this * text, but it can be better to do this if the default text is * too large for the edit area when using the default font of your * application. Default text is current font name and size. Setting * the text to QString() will restore the default. * * @param text The new sample text. The current will be removed. */ virtual void setSampleText(const QString &text); /** * Set the title for the widget that will be used in the tooltip and * what's this text. * * @param title The title to be set. */ virtual void setTitle(const QString &title); Q_SIGNALS: /** * Emitted when a new @p font has been selected in the underlying dialog */ void fontSelected(const QFont &font); private: class KFontRequesterPrivate; friend class KFontRequesterPrivate; KFontRequesterPrivate *const d; Q_PRIVATE_SLOT(d, void _k_buttonClicked()) Q_DISABLE_COPY(KFontRequester) }; #endif // KFONTREQUESTER_H diff --git a/src/kguiitem.cpp b/src/kguiitem.cpp index 36c3277..83ed5b1 100644 --- a/src/kguiitem.cpp +++ b/src/kguiitem.cpp @@ -1,224 +1,224 @@ /* This file is part of the KDE libraries Copyright (C) 2001 Holger Freyther (freyher@yahoo.com) based on ideas from Martijn and Simon many thanks to Simon This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kguiitem.h" #include class KGuiItem::KGuiItemPrivate { public: KGuiItemPrivate() { m_enabled = true; m_hasIcon = false; } KGuiItemPrivate(const KGuiItemPrivate &rhs) { (*this) = rhs; } KGuiItemPrivate &operator=(const KGuiItemPrivate &rhs) { m_text = rhs.m_text; m_icon = rhs.m_icon; m_iconName = rhs.m_iconName; m_toolTip = rhs.m_toolTip; m_whatsThis = rhs.m_whatsThis; m_statusText = rhs.m_statusText; m_enabled = rhs.m_enabled; m_hasIcon = rhs.m_hasIcon; return *this; } QString m_text; QString m_toolTip; QString m_whatsThis; QString m_statusText; QString m_iconName; QIcon m_icon; bool m_hasIcon : 1; bool m_enabled : 1; }; KGuiItem::KGuiItem() { d = new KGuiItemPrivate; } KGuiItem::KGuiItem(const QString &text, const QString &iconName, const QString &toolTip, const QString &whatsThis) { d = new KGuiItemPrivate; d->m_text = text; d->m_toolTip = toolTip; d->m_whatsThis = whatsThis; setIconName(iconName); } KGuiItem::KGuiItem(const QString &text, const QIcon &icon, const QString &toolTip, const QString &whatsThis) { d = new KGuiItemPrivate; d->m_text = text; d->m_toolTip = toolTip; d->m_whatsThis = whatsThis; setIcon(icon); } KGuiItem::KGuiItem(const KGuiItem &rhs) - : d(0) + : d(nullptr) { (*this) = rhs; } KGuiItem &KGuiItem::operator=(const KGuiItem &rhs) { if (d == rhs.d) { return *this; } Q_ASSERT(rhs.d); delete d; d = new KGuiItemPrivate(*rhs.d); return *this; } KGuiItem::~KGuiItem() { delete d; } QString KGuiItem::text() const { return d->m_text; } QString KGuiItem::plainText() const { const int len = d->m_text.length(); if (len == 0) { return d->m_text; } //Can assume len >= 1 from now on. QString stripped; int resultLength = 0; stripped.resize(len); const QChar *data = d->m_text.unicode(); for (int pos = 0; pos < len; ++pos) { if (data[ pos ] != QLatin1Char('&')) { stripped[ resultLength++ ] = data[ pos ]; } else if (pos + 1 < len && data[ pos + 1 ] == QLatin1Char('&')) { stripped[ resultLength++ ] = data[ pos++ ]; } } stripped.truncate(resultLength); return stripped; } QIcon KGuiItem::icon() const { if (d->m_hasIcon) { if (!d->m_iconName.isEmpty()) { return QIcon::fromTheme(d->m_iconName); } else { return d->m_icon; } } return QIcon(); } QString KGuiItem::iconName() const { return d->m_iconName; } QString KGuiItem::toolTip() const { return d->m_toolTip; } QString KGuiItem::whatsThis() const { return d->m_whatsThis; } bool KGuiItem::isEnabled() const { return d->m_enabled; } bool KGuiItem::hasIcon() const { return d->m_hasIcon; } void KGuiItem::setText(const QString &text) { d->m_text = text; } void KGuiItem::setIcon(const QIcon &icon) { d->m_icon = icon; d->m_iconName.clear(); d->m_hasIcon = !icon.isNull(); } void KGuiItem::setIconName(const QString &iconName) { d->m_iconName = iconName; d->m_icon = QIcon(); d->m_hasIcon = !iconName.isEmpty(); } void KGuiItem::setToolTip(const QString &toolTip) { d->m_toolTip = toolTip; } void KGuiItem::setWhatsThis(const QString &whatsThis) { d->m_whatsThis = whatsThis; } void KGuiItem::setEnabled(bool enabled) { d->m_enabled = enabled; } void KGuiItem::assign(QPushButton *button, const KGuiItem &item) { button->setText(item.d->m_text); button->setIcon(item.icon()); button->setToolTip(item.d->m_toolTip); button->setWhatsThis(item.d->m_whatsThis); } diff --git a/src/kled.h b/src/kled.h index 97f8720..9ca717f 100644 --- a/src/kled.h +++ b/src/kled.h @@ -1,262 +1,262 @@ /* This file is part of the KDE libraries Copyright (C) 1998 Jörg Habenicht (j.habenicht@europemail.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KLED_H #define KLED_H #include #include class QColor; /** * @short An LED widget. * * Displays a round or rectangular light emitting diode. * * It is configurable to arbitrary colors, the two on/off states and three * styles (or "looks"); * * It may display itself in a performant flat view, a round view with * light spot or a round view sunken in the screen. * * \image html kled.png "KDE LED Widget" * * @author Joerg Habenicht, Richard J. Moore (rich@kde.org) 1998, 1999 */ class KWIDGETSADDONS_EXPORT KLed : public QWidget { Q_OBJECT Q_PROPERTY(State state READ state WRITE setState) Q_PROPERTY(Shape shape READ shape WRITE setShape) Q_PROPERTY(Look look READ look WRITE setLook) Q_PROPERTY(QColor color READ color WRITE setColor) Q_PROPERTY(int darkFactor READ darkFactor WRITE setDarkFactor) public: /** * Status of the light is on/off. * @short LED on/off. */ enum State { Off, On }; Q_ENUM(State) /** * Shades of the lamp. * @short LED shape */ enum Shape { Rectangular, Circular }; Q_ENUM(Shape) /** * Displays a flat, round or sunken LED. * * @short LED look. */ enum Look { Flat, Raised, Sunken }; Q_ENUM(Look) /** * Constructs a green, round LED widget which will initially * be turned on. * * @param parent The parent widget. */ - explicit KLed(QWidget *parent = 0); + explicit KLed(QWidget *parent = nullptr); /** * Constructs a round LED widget with the supplied color which will * initially be turned on. * * @param color Initial color of the LED. * @param parent The parent widget. * @short Constructor */ - explicit KLed(const QColor &color, QWidget *parent = 0); + explicit KLed(const QColor &color, QWidget *parent = nullptr); /** * Constructor with the color, state and look. * * Differs from above only in the parameters, which configure all settings. * * @param color Initial color of the LED. * @param state Sets the State. * @param look Sets the Look. * @param shape Sets the Shape (rectangular or circular). * @param parent The parent widget. * @short Constructor */ KLed(const QColor &color, KLed::State state, KLed::Look look, KLed::Shape shape, - QWidget *parent = 0); + QWidget *parent = nullptr); /** * Destroys the LED widget. * @short Destructor */ ~KLed(); /** * Returns the current color of the widget. * * @see Color * @short Returns LED color. */ QColor color() const; /** * Returns the current state of the widget (on/off). * * @see State * @short Returns LED state. */ State state() const; /** * Returns the current look of the widget. * * @see Look * @short Returns LED look. */ Look look() const; /** * Returns the current shape of the widget. * * @see Shape * @short Returns LED shape. */ Shape shape() const; /** * Returns the factor to darken the LED. * * @see setDarkFactor() * @short Returns dark factor. */ int darkFactor() const; /** * Set the color of the widget. * * The LED is shown with Color when in the KLed::On state * or with the darken Color (@see setDarkFactor) in KLed::Off * state. * * The widget calls the update() method, so it will * be updated when entering the main event loop. * * @see Color * * @param color New color of the LED. * @short Sets the LED color. */ void setColor(const QColor &color); /** * Sets the state of the widget to On or Off. * * @see on() off() toggle() * * @param state The LED state: on or off. * @short Set LED state. */ void setState(State state); /** * Sets the look of the widget. * * The look may be Flat, Raised or Sunken. * * The widget calls the update() method, so it will * be updated when entering the main event loop. * * @see Look * * @param look New look of the LED. * @short Sets LED look. */ void setLook(Look look); /** * Set the shape of the LED. * * @param shape The LED shape. * @short Set LED shape. */ void setShape(Shape shape); /** * Sets the factor to darken the LED in KLed::Off state. * * The @param darkFactor should be greater than 100, otherwise the LED * becomes lighter in KLed::Off state. * * Defaults to 300. * * @see QColor * * @param darkFactor Sets the factor to darken the LED. * @short Sets the factor to darken the LED. */ void setDarkFactor(int darkFactor); QSize sizeHint() const Q_DECL_OVERRIDE; QSize minimumSizeHint() const Q_DECL_OVERRIDE; public Q_SLOTS: /** * Toggles the state of the led from Off to On or vice versa. */ void toggle(); /** * Sets the state of the widget to On. * * @see off() toggle() setState() */ void on(); /** * Sets the state of the widget to Off. * * @see on() toggle() setState() */ void off(); protected: void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE; void resizeEvent(QResizeEvent *) Q_DECL_OVERRIDE; /** * @internal * invalidates caches after property changes and calls update() */ void updateCachedPixmap(); private: class Private; Private *const d; void updateAccessibleName(); }; #endif diff --git a/src/kmessagebox.cpp b/src/kmessagebox.cpp index ef1c085..bae288d 100644 --- a/src/kmessagebox.cpp +++ b/src/kmessagebox.cpp @@ -1,1172 +1,1172 @@ /* This file is part of the KDE libraries Copyright (C) 1999 Waldo Bastian (bastian@kde.org) Copyright 2012 David Faure This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; version 2 of the License. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kmessagebox.h" #include "kmessagebox_p.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if 0 // NOTE waiting for the notification framework plan #include #endif #include // Some i18n filters, that standard button texts are piped through // (the new KGuiItem object with filtered text is created from the old one). // Filter for the Yes-button text in standard message dialogs, // after the message caption/text have been translated. #define I18N_FILTER_BUTTON_YES(src, dst) \ KGuiItem dst(src); \ dst.setText( QApplication::translate( "KMessageBox", src.text().toUtf8().constData(), "@action:button filter-yes" ) ); // Filter for the No-button text in standard message dialogs, // after the message caption/text have been translated. #define I18N_FILTER_BUTTON_NO(src, dst) \ KGuiItem dst(src); \ dst.setText( QApplication::translate( "KMessageBox", src.text().toUtf8().constData(), "@action:button filter-no" ) ); // Filter for the Continue-button text in standard message dialogs, // after the message caption/text have been translated. #define I18N_FILTER_BUTTON_CONTINUE(src, dst) \ KGuiItem dst(src); \ dst.setText( QApplication::translate( "KMessageBox", src.text().toUtf8().constData(), "@action:button filter-continue" ) ); // Filter for the Cancel-button text in standard message dialogs, // after the message caption/text have been translated. #define I18N_FILTER_BUTTON_CANCEL(src, dst) \ KGuiItem dst(src); \ dst.setText( QApplication::translate( "KMessageBox", src.text().toUtf8().constData(), "@action:button filter-cancel" ) ); // Called after the button texts in standard message dialogs // have been filtered by the messages above. Not visible to user. #define I18N_POST_BUTTON_FILTER \ QApplication::translate( "KMessageBox", ".", "@action:button post-filter" ); namespace KMessageBox { /* * this static is used by the createKMessageBox function to enqueue dialogs * FIXME what should we do about this static? */ -QDialogButtonBox::StandardButton KWIDGETSADDONS_EXPORT(*KMessageBox_exec_hook)(QDialog *) = 0; +QDialogButtonBox::StandardButton KWIDGETSADDONS_EXPORT(*KMessageBox_exec_hook)(QDialog *) = nullptr; static QIcon themedMessageBoxIcon(QMessageBox::Icon icon) { QString icon_name; switch (icon) { case QMessageBox::NoIcon: return QIcon(); break; case QMessageBox::Information: icon_name = QStringLiteral("dialog-information"); break; case QMessageBox::Warning: icon_name = QStringLiteral("dialog-warning"); break; case QMessageBox::Critical: icon_name = QStringLiteral("dialog-error"); break; default: break; } QIcon ret = QIcon::fromTheme(icon_name); if (ret.isNull()) { return QMessageBox::standardIcon(icon); } else { return ret; } } static void applyOptions(QDialog *dialog, KMessageBox::Options options) { if (options & KMessageBox::WindowModal) { dialog->setWindowModality(Qt::WindowModal); } dialog->setModal(true); } // This method has been copied from KWindowSystem to avoid depending on it static void setMainWindow(QWidget *subWidget, WId mainWindowId) { #ifdef Q_OS_OSX if (!QWidget::find(mainWindowId)) { return; } #endif // Set the WA_NativeWindow attribute to force the creation of the QWindow. // Without this QWidget::windowHandle() returns 0. subWidget->setAttribute(Qt::WA_NativeWindow, true); QWindow *subWindow = subWidget->windowHandle(); Q_ASSERT(subWindow); QWindow *mainWindow = QWindow::fromWinId(mainWindowId); // mainWindow is not the child of any object, so make sure it gets deleted at some point QObject::connect(subWidget, &QObject::destroyed, mainWindow, &QObject::deleteLater); subWindow->setTransientParent(mainWindow); } /** * Create a QDialog whose parent is a foreign window */ static QDialog *createWIdDialog(WId parent_id) { QWidget *parent = QWidget::find(parent_id); QDialog *dialog = new QDialog(parent, Qt::Dialog); if (!parent && parent_id) { setMainWindow(dialog, parent_id); } return dialog; } class DialogButtonsHelper : public QObject { Q_OBJECT public: DialogButtonsHelper(QDialog *dialog, QDialogButtonBox *buttons) : QObject(dialog), m_dialog(dialog), m_buttons(buttons), - m_details(0) + m_details(nullptr) { connect(m_buttons, &QDialogButtonBox::clicked, this, &DialogButtonsHelper::onButtonClicked); } void setDetailsWidget(QWidget *widget) { m_details = widget; } public Q_SLOTS: void onButtonClicked(QAbstractButton *button) { QDialogButtonBox::StandardButton code = m_buttons->standardButton(button); if (code != QDialogButtonBox::NoButton) { m_dialog->done(code); } else if (m_details && (button->objectName() == QStringLiteral("detailsButton"))) { button->setText(QApplication::translate("KMessageBox", "&Details") + (m_details->isVisible() ? QStringLiteral(" >>") : QStringLiteral(" <<"))); m_details->setVisible(!m_details->isVisible()); } } private: QDialog *const m_dialog; QDialogButtonBox *const m_buttons; QWidget *m_details; }; QDialogButtonBox::StandardButton createKMessageBox(QDialog *dialog, QDialogButtonBox *buttons, QMessageBox::Icon icon, const QString &text, const QStringList &strlist, const QString &ask, bool *checkboxReturn, Options options, const QString &details) { return createKMessageBox(dialog, buttons, themedMessageBoxIcon(icon), text, strlist, ask, checkboxReturn, options, details, icon); } QDialogButtonBox::StandardButton createKMessageBox(QDialog *dialog, QDialogButtonBox *buttons, const QIcon &icon, const QString &text, const QStringList &strlist, const QString &ask, bool *checkboxReturn, Options options, const QString &details, QMessageBox::Icon notifyType) { DialogButtonsHelper *buttonsHelper = new DialogButtonsHelper(dialog, buttons); QWidget *mainWidget = new QWidget(dialog); QVBoxLayout *mainLayout = new QVBoxLayout(mainWidget); const int spacingHint = mainWidget->style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing); mainLayout->setSpacing(spacingHint * 2); // provide extra spacing mainLayout->setMargin(0); QHBoxLayout *hLayout = new QHBoxLayout(); hLayout->setMargin(0); hLayout->setSpacing(-1); // use default spacing mainLayout->addLayout(hLayout, 5); QLabel *iconLabel = new QLabel(mainWidget); if (!icon.isNull()) { QStyleOption option; option.initFrom(mainWidget); iconLabel->setPixmap(icon.pixmap(mainWidget->style()->pixelMetric(QStyle::PM_MessageBoxIconSize, &option, mainWidget))); } QVBoxLayout *iconLayout = new QVBoxLayout(); iconLayout->addStretch(1); iconLayout->addWidget(iconLabel); iconLayout->addStretch(5); hLayout->addLayout(iconLayout, 0); hLayout->addSpacing(spacingHint); QLabel *messageLabel = new QLabel(text, mainWidget); messageLabel->setOpenExternalLinks(options & KMessageBox::AllowLink); Qt::TextInteractionFlags flags = Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard; if (options & KMessageBox::AllowLink) { flags |= Qt::LinksAccessibleByMouse | Qt::LinksAccessibleByKeyboard; } messageLabel->setTextInteractionFlags(flags); QRect desktop = QApplication::desktop()->screenGeometry(dialog); bool usingSqueezedTextLabel = false; if (messageLabel->sizeHint().width() > desktop.width() * 0.5) { // enable automatic wrapping of messages which are longer than 50% of screen width messageLabel->setWordWrap(true); // use a squeezed label if text is still too wide usingSqueezedTextLabel = messageLabel->sizeHint().width() > desktop.width() * 0.85; if (usingSqueezedTextLabel) { delete messageLabel; messageLabel = new KSqueezedTextLabel(text, mainWidget); messageLabel->setOpenExternalLinks(options & KMessageBox::AllowLink); messageLabel->setTextInteractionFlags(flags); } } QPalette messagePal(messageLabel->palette()); messagePal.setColor(QPalette::Window, Qt::transparent); messageLabel->setPalette(messagePal); bool usingScrollArea = desktop.height() / 3 < messageLabel->sizeHint().height(); if (usingScrollArea) { QScrollArea *messageScrollArea = new QScrollArea(mainWidget); messageScrollArea->setWidget(messageLabel); messageScrollArea->setFrameShape(QFrame::NoFrame); messageScrollArea->setWidgetResizable(true); QPalette scrollPal(messageScrollArea->palette()); scrollPal.setColor(QPalette::Window, Qt::transparent); messageScrollArea->viewport()->setPalette(scrollPal); hLayout->addWidget(messageScrollArea, 5); } else { hLayout->addWidget(messageLabel, 5); } const bool usingListWidget = !strlist.isEmpty(); if (usingListWidget) { // enable automatic wrapping since the listwidget has already a good initial width messageLabel->setWordWrap(true); QListWidget *listWidget = new QListWidget(mainWidget); listWidget->addItems(strlist); QStyleOptionViewItem styleOption; styleOption.initFrom(listWidget); QFontMetrics fm(styleOption.font); int w = listWidget->width(); Q_FOREACH (const QString &str, strlist) { w = qMax(w, fm.width(str)); } const int borderWidth = listWidget->width() - listWidget->viewport()->width() + listWidget->verticalScrollBar()->height(); w += borderWidth; if (w > desktop.width() * 0.85) { // limit listWidget size to 85% of screen width w = qRound(desktop.width() * 0.85); } listWidget->setMinimumWidth(w); mainLayout->addWidget(listWidget, usingScrollArea ? 10 : 50); listWidget->setSelectionMode(QListWidget::NoSelection); messageLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); } else if (!usingScrollArea) { mainLayout->addStretch(15); } - QPointer checkbox = 0; + QPointer checkbox = nullptr; if (!ask.isEmpty()) { checkbox = new QCheckBox(ask, mainWidget); mainLayout->addWidget(checkbox); if (checkboxReturn) { checkbox->setChecked(*checkboxReturn); } } QVBoxLayout *topLayout = new QVBoxLayout; dialog->setLayout(topLayout); topLayout->addWidget(mainWidget); if (!details.isEmpty()) { QGroupBox *detailsGroup = new QGroupBox(QApplication::translate("KMessageBox", "Details")); QVBoxLayout *detailsLayout = new QVBoxLayout(detailsGroup); if (details.length() < 512) { QLabel *detailsLabel = new QLabel(details); detailsLabel->setOpenExternalLinks(options & KMessageBox::AllowLink); Qt::TextInteractionFlags flags = Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard; if (options & KMessageBox::AllowLink) { flags |= Qt::LinksAccessibleByMouse | Qt::LinksAccessibleByKeyboard; }; detailsLabel->setTextInteractionFlags(flags); detailsLabel->setWordWrap(true); detailsLayout->addWidget(detailsLabel, 50); } else { QTextBrowser *detailTextEdit = new QTextBrowser(); detailTextEdit->setText(details); detailTextEdit->setReadOnly(true); detailTextEdit->setMinimumHeight(detailTextEdit->fontMetrics().lineSpacing() * 11); detailsLayout->addWidget(detailTextEdit, 50); } if (!usingListWidget) { mainLayout->setStretchFactor(hLayout, 10); } topLayout->addWidget(detailsGroup); buttonsHelper->setDetailsWidget(detailsGroup); detailsGroup->hide(); } buttons->setParent(dialog); topLayout->addWidget(buttons); if (!usingListWidget && !usingScrollArea && !usingSqueezedTextLabel && details.isEmpty()) { dialog->setFixedSize(dialog->sizeHint() + QSize(10, 10)); } else if (!details.isEmpty() && dialog->minimumHeight() < iconLabel->sizeHint().height() * 2) { //strange bug... if (!usingScrollArea) { dialog->setMinimumSize(300, qMax(150, qMax(iconLabel->sizeHint().height(), messageLabel->sizeHint().height()))); } else { dialog->setMinimumSize(300, qMax(150, iconLabel->sizeHint().height())); } } if ((options & KMessageBox::Dangerous)) { QPushButton *cancelButton = buttons->button(QDialogButtonBox::Cancel); QPushButton *noButton = buttons->button(QDialogButtonBox::No); if (cancelButton && cancelButton->isEnabled()) { cancelButton->setDefault(true); cancelButton->setFocus(); } else if (noButton && noButton->isEnabled()) { noButton->setDefault(true); noButton->setFocus(); } } #ifndef Q_OS_WIN // FIXME problems with KNotify on Windows if ((options & KMessageBox::Notify)) { QString message = text; if (!strlist.isEmpty()) { message += QLatin1Char('\n') + strlist.join(QLatin1Char('\n')); } notifyInterface()->sendNotification(notifyType, message, dialog->topLevelWidget()); } #endif if (KMessageBox_exec_hook) { return KMessageBox_exec_hook(dialog); } if ((options & KMessageBox::NoExec)) { return QDialogButtonBox::NoButton; // We have to return something. } // We use a QPointer because the dialog may get deleted // during exec() if the parent of the dialog gets deleted. // In that case the QPointer will reset to 0. QPointer guardedDialog = dialog; const QDialogButtonBox::StandardButton result = QDialogButtonBox::StandardButton(guardedDialog->exec()); if (checkbox && checkboxReturn) { *checkboxReturn = checkbox->isChecked(); } delete guardedDialog; return result; } ButtonCode questionYesNo(QWidget *parent, const QString &text, const QString &caption, const KGuiItem &buttonYes, const KGuiItem &buttonNo, const QString &dontAskAgainName, Options options) { return questionYesNoList(parent, text, QStringList(), caption, buttonYes, buttonNo, dontAskAgainName, options); } bool shouldBeShownYesNo(const QString &dontShowAgainName, ButtonCode &result) { if (dontShowAgainName.isEmpty()) { return true; } return dontAskAgainInterface()->shouldBeShownYesNo(dontShowAgainName, result); } bool shouldBeShownContinue(const QString &dontShowAgainName) { if (dontShowAgainName.isEmpty()) { return true; } return dontAskAgainInterface()->shouldBeShownContinue(dontShowAgainName); } void saveDontShowAgainYesNo(const QString &dontShowAgainName, ButtonCode result) { if (dontShowAgainName.isEmpty()) { return; } dontAskAgainInterface()->saveDontShowAgainYesNo(dontShowAgainName, result); } void saveDontShowAgainContinue(const QString &dontShowAgainName) { if (dontShowAgainName.isEmpty()) { return; } dontAskAgainInterface()->saveDontShowAgainContinue(dontShowAgainName); } void enableAllMessages() { dontAskAgainInterface()->enableAllMessages(); } void enableMessage(const QString &dontShowAgainName) { dontAskAgainInterface()->enableMessage(dontShowAgainName); } void setDontShowAgainConfig(KConfig *cfg) { dontAskAgainInterface()->setConfig(cfg); } static ButtonCode questionYesNoListInternal(QDialog *dialog, const QString &text, const QStringList &strlist, const QString &caption, const KGuiItem &buttonYes_, const KGuiItem &buttonNo_, const QString &dontAskAgainName, Options options) { ButtonCode res; if (!shouldBeShownYesNo(dontAskAgainName, res)) { delete dialog; return res; } I18N_FILTER_BUTTON_YES(buttonYes_, buttonYes) I18N_FILTER_BUTTON_NO(buttonNo_, buttonNo) I18N_POST_BUTTON_FILTER dialog->setWindowTitle(caption.isEmpty() ? QApplication::translate("KMessageBox", "Question") : caption); dialog->setObjectName(QStringLiteral("questionYesNo")); QDialogButtonBox *buttonBox = new QDialogButtonBox(dialog); buttonBox->setStandardButtons(QDialogButtonBox::Yes | QDialogButtonBox::No); KGuiItem::assign(buttonBox->button(QDialogButtonBox::Yes), buttonYes); KGuiItem::assign(buttonBox->button(QDialogButtonBox::No), buttonNo); applyOptions(dialog, options); bool checkboxResult = false; const int result = createKMessageBox(dialog, buttonBox, QMessageBox::Information, text, strlist, dontAskAgainName.isEmpty() ? QString() : QApplication::translate("KMessageBox", "Do not ask again"), &checkboxResult, options); res = (result == QDialogButtonBox::Yes ? Yes : No); if (checkboxResult) { saveDontShowAgainYesNo(dontAskAgainName, res); } return res; } ButtonCode questionYesNoList(QWidget *parent, const QString &text, const QStringList &strlist, const QString &caption, const KGuiItem &buttonYes, const KGuiItem &buttonNo, const QString &dontAskAgainName, Options options) { return questionYesNoListInternal(new QDialog(parent), text, strlist, caption, buttonYes, buttonNo, dontAskAgainName, options); } static ButtonCode questionYesNoCancelInternal(QDialog *dialog, const QString &text, const QString &caption, const KGuiItem &buttonYes_, const KGuiItem &buttonNo_, const KGuiItem &buttonCancel_, const QString &dontAskAgainName, Options options) { ButtonCode res; if (!shouldBeShownYesNo(dontAskAgainName, res)) { delete dialog; return res; } I18N_FILTER_BUTTON_YES(buttonYes_, buttonYes) I18N_FILTER_BUTTON_NO(buttonNo_, buttonNo) I18N_FILTER_BUTTON_CANCEL(buttonCancel_, buttonCancel) I18N_POST_BUTTON_FILTER dialog->setWindowTitle(caption.isEmpty() ? QApplication::translate("KMessageBox", "Question") : caption); dialog->setObjectName(QStringLiteral("questionYesNoCancel")); QDialogButtonBox *buttonBox = new QDialogButtonBox(dialog); buttonBox->setStandardButtons(QDialogButtonBox::Yes | QDialogButtonBox::No | QDialogButtonBox::Cancel); KGuiItem::assign(buttonBox->button(QDialogButtonBox::Yes), buttonYes); KGuiItem::assign(buttonBox->button(QDialogButtonBox::No), buttonNo); KGuiItem::assign(buttonBox->button(QDialogButtonBox::Cancel), buttonCancel); applyOptions(dialog, options); bool checkboxResult = false; const int result = createKMessageBox(dialog, buttonBox, QMessageBox::Information, text, QStringList(), dontAskAgainName.isEmpty() ? QString() : QApplication::translate("KMessageBox", "Do not ask again"), &checkboxResult, options); if (result == QDialogButtonBox::Yes) { res = Yes; } else if (result == QDialogButtonBox::No) { res = No; } else { return Cancel; } if (checkboxResult) { saveDontShowAgainYesNo(dontAskAgainName, res); } return res; } ButtonCode questionYesNoCancel(QWidget *parent, const QString &text, const QString &caption, const KGuiItem &buttonYes, const KGuiItem &buttonNo, const KGuiItem &buttonCancel, const QString &dontAskAgainName, Options options) { return questionYesNoCancelInternal(new QDialog(parent), text, caption, buttonYes, buttonNo, buttonCancel, dontAskAgainName, options); } ButtonCode warningYesNo(QWidget *parent, const QString &text, const QString &caption, const KGuiItem &buttonYes, const KGuiItem &buttonNo, const QString &dontAskAgainName, Options options) { return warningYesNoList(parent, text, QStringList(), caption, buttonYes, buttonNo, dontAskAgainName, options); } static ButtonCode warningYesNoListInternal(QDialog *dialog, const QString &text, const QStringList &strlist, const QString &caption, const KGuiItem &buttonYes_, const KGuiItem &buttonNo_, const QString &dontAskAgainName, Options options) { ButtonCode res; if (!shouldBeShownYesNo(dontAskAgainName, res)) { delete dialog; return res; } I18N_FILTER_BUTTON_YES(buttonYes_, buttonYes) I18N_FILTER_BUTTON_NO(buttonNo_, buttonNo) I18N_POST_BUTTON_FILTER dialog->setWindowTitle(caption.isEmpty() ? QApplication::translate("KMessageBox", "Warning") : caption); dialog->setObjectName(QStringLiteral("warningYesNoList")); QDialogButtonBox *buttonBox = new QDialogButtonBox(dialog); buttonBox->setStandardButtons(QDialogButtonBox::Yes | QDialogButtonBox::No); KGuiItem::assign(buttonBox->button(QDialogButtonBox::Yes), buttonYes); KGuiItem::assign(buttonBox->button(QDialogButtonBox::No), buttonNo); applyOptions(dialog, options); bool checkboxResult = false; const int result = createKMessageBox(dialog, buttonBox, QMessageBox::Warning, text, strlist, dontAskAgainName.isEmpty() ? QString() : QApplication::translate("KMessageBox", "Do not ask again"), &checkboxResult, options); res = (result == QDialogButtonBox::Yes ? Yes : No); if (checkboxResult) { saveDontShowAgainYesNo(dontAskAgainName, res); } return res; } ButtonCode warningYesNoList(QWidget *parent, const QString &text, const QStringList &strlist, const QString &caption, const KGuiItem &buttonYes, const KGuiItem &buttonNo, const QString &dontAskAgainName, Options options) { return warningYesNoListInternal(new QDialog(parent), text, strlist, caption, buttonYes, buttonNo, dontAskAgainName, options); } ButtonCode warningContinueCancel(QWidget *parent, const QString &text, const QString &caption, const KGuiItem &buttonContinue, const KGuiItem &buttonCancel, const QString &dontAskAgainName, Options options) { return warningContinueCancelList(parent, text, QStringList(), caption, buttonContinue, buttonCancel, dontAskAgainName, options); } static ButtonCode warningContinueCancelListInternal(QDialog *dialog, const QString &text, const QStringList &strlist, const QString &caption, const KGuiItem &buttonContinue_, const KGuiItem &buttonCancel_, const QString &dontAskAgainName, Options options) { if (!shouldBeShownContinue(dontAskAgainName)) { delete dialog; return Continue; } I18N_FILTER_BUTTON_CONTINUE(buttonContinue_, buttonContinue) I18N_FILTER_BUTTON_CANCEL(buttonCancel_, buttonCancel) I18N_POST_BUTTON_FILTER dialog->setWindowTitle(caption.isEmpty() ? QApplication::translate("KMessageBox", "Warning") : caption); dialog->setObjectName(QStringLiteral("warningYesNo")); QDialogButtonBox *buttonBox = new QDialogButtonBox(dialog); buttonBox->setStandardButtons(QDialogButtonBox::Yes | QDialogButtonBox::No); KGuiItem::assign(buttonBox->button(QDialogButtonBox::Yes), buttonContinue); KGuiItem::assign(buttonBox->button(QDialogButtonBox::No), buttonCancel); applyOptions(dialog, options); bool checkboxResult = false; const int result = createKMessageBox(dialog, buttonBox, QMessageBox::Warning, text, strlist, dontAskAgainName.isEmpty() ? QString() : QApplication::translate("KMessageBox", "Do not ask again"), &checkboxResult, options); if (result != QDialogButtonBox::Yes) { return Cancel; } if (checkboxResult) { saveDontShowAgainContinue(dontAskAgainName); } return Continue; } ButtonCode warningContinueCancelList(QWidget *parent, const QString &text, const QStringList &strlist, const QString &caption, const KGuiItem &buttonContinue, const KGuiItem &buttonCancel, const QString &dontAskAgainName, Options options) { return warningContinueCancelListInternal(new QDialog(parent), text, strlist, caption, buttonContinue, buttonCancel, dontAskAgainName, options); } ButtonCode warningYesNoCancel(QWidget *parent, const QString &text, const QString &caption, const KGuiItem &buttonYes, const KGuiItem &buttonNo, const KGuiItem &buttonCancel, const QString &dontAskAgainName, Options options) { return warningYesNoCancelList(parent, text, QStringList(), caption, buttonYes, buttonNo, buttonCancel, dontAskAgainName, options); } static ButtonCode warningYesNoCancelListInternal(QDialog *dialog, const QString &text, const QStringList &strlist, const QString &caption, const KGuiItem &buttonYes_, const KGuiItem &buttonNo_, const KGuiItem &buttonCancel_, const QString &dontAskAgainName, Options options) { ButtonCode res; if (!shouldBeShownYesNo(dontAskAgainName, res)) { delete dialog; return res; } I18N_FILTER_BUTTON_YES(buttonYes_, buttonYes) I18N_FILTER_BUTTON_NO(buttonNo_, buttonNo) I18N_FILTER_BUTTON_CANCEL(buttonCancel_, buttonCancel) I18N_POST_BUTTON_FILTER dialog->setWindowTitle(caption.isEmpty() ? QApplication::translate("KMessageBox", "Warning") : caption); dialog->setObjectName(QStringLiteral("warningYesNoCancel")); QDialogButtonBox *buttonBox = new QDialogButtonBox(dialog); buttonBox->setStandardButtons(QDialogButtonBox::Yes | QDialogButtonBox::No | QDialogButtonBox::Cancel); KGuiItem::assign(buttonBox->button(QDialogButtonBox::Yes), buttonYes); KGuiItem::assign(buttonBox->button(QDialogButtonBox::No), buttonNo); KGuiItem::assign(buttonBox->button(QDialogButtonBox::Cancel), buttonCancel); applyOptions(dialog, options); bool checkboxResult = false; const int result = createKMessageBox(dialog, buttonBox, QMessageBox::Warning, text, strlist, dontAskAgainName.isEmpty() ? QString() : QApplication::translate("KMessageBox", "Do not ask again"), &checkboxResult, options); if (result == QDialogButtonBox::Yes) { res = Yes; } else if (result == QDialogButtonBox::No) { res = No; } else { return Cancel; } if (checkboxResult) { saveDontShowAgainYesNo(dontAskAgainName, res); } return res; } ButtonCode warningYesNoCancelList(QWidget *parent, const QString &text, const QStringList &strlist, const QString &caption, const KGuiItem &buttonYes, const KGuiItem &buttonNo, const KGuiItem &buttonCancel, const QString &dontAskAgainName, Options options) { return warningYesNoCancelListInternal(new QDialog(parent), text, strlist, caption, buttonYes, buttonNo, buttonCancel, dontAskAgainName, options); } void error(QWidget *parent, const QString &text, const QString &caption, Options options) { return errorList(parent, text, QStringList(), caption, options); } static void errorListInternal(QDialog *dialog, const QString &text, const QStringList &strlist, const QString &caption, Options options) { dialog->setWindowTitle(caption.isEmpty() ? QApplication::translate("KMessageBox", "Error") : caption); dialog->setObjectName(QStringLiteral("error")); QDialogButtonBox *buttonBox = new QDialogButtonBox(dialog); buttonBox->setStandardButtons(QDialogButtonBox::Ok); applyOptions(dialog, options); - createKMessageBox(dialog, buttonBox, QMessageBox::Critical, text, strlist, QString(), 0, options); + createKMessageBox(dialog, buttonBox, QMessageBox::Critical, text, strlist, QString(), nullptr, options); } void errorList(QWidget *parent, const QString &text, const QStringList &strlist, const QString &caption, Options options) { errorListInternal(new QDialog(parent), text, strlist, caption, options); } static void detailedErrorInternal(QDialog *dialog, const QString &text, const QString &details, const QString &caption, Options options) { dialog->setWindowTitle(caption.isEmpty() ? QApplication::translate("KMessageBox", "Error") : caption); dialog->setObjectName(QStringLiteral("error")); QPushButton *detailsButton = new QPushButton; detailsButton->setObjectName(QStringLiteral("detailsButton")); detailsButton->setText(QApplication::translate("KMessageBox", "&Details") + QStringLiteral(" >>")); detailsButton->setIcon(QIcon::fromTheme(QStringLiteral("help-about"))); QDialogButtonBox *buttonBox = new QDialogButtonBox(dialog); buttonBox->addButton(detailsButton, QDialogButtonBox::HelpRole); buttonBox->addButton(QDialogButtonBox::Ok); buttonBox->button(QDialogButtonBox::Ok)->setFocus(); applyOptions(dialog, options); - createKMessageBox(dialog, buttonBox, QMessageBox::Critical, text, QStringList(), QString(), 0, options, details); + createKMessageBox(dialog, buttonBox, QMessageBox::Critical, text, QStringList(), QString(), nullptr, options, details); } void detailedError(QWidget *parent, const QString &text, const QString &details, const QString &caption, Options options) { detailedErrorInternal(new QDialog(parent), text, details, caption, options); } static void sorryInternal(QDialog *dialog, const QString &text, const QString &caption, Options options) { dialog->setWindowTitle(caption.isEmpty() ? QApplication::translate("KMessageBox", "Sorry") : caption); dialog->setObjectName(QStringLiteral("sorry")); QDialogButtonBox *buttonBox = new QDialogButtonBox(dialog); buttonBox->setStandardButtons(QDialogButtonBox::Ok); applyOptions(dialog, options); - createKMessageBox(dialog, buttonBox, QMessageBox::Warning, text, QStringList(), QString(), 0, options); + createKMessageBox(dialog, buttonBox, QMessageBox::Warning, text, QStringList(), QString(), nullptr, options); } void sorry(QWidget *parent, const QString &text, const QString &caption, Options options) { sorryInternal(new QDialog(parent), text, caption, options); } static void detailedSorryInternal(QDialog *dialog, const QString &text, const QString &details, const QString &caption, Options options) { dialog->setWindowTitle(caption.isEmpty() ? QApplication::translate("KMessageBox", "Sorry") : caption); dialog->setObjectName(QStringLiteral("sorry")); QPushButton *detailsButton = new QPushButton; detailsButton->setObjectName(QStringLiteral("detailsButton")); detailsButton->setText(QApplication::translate("KMessageBox", "&Details") + QStringLiteral(" >>")); detailsButton->setIcon(QIcon::fromTheme(QStringLiteral("help-about"))); QDialogButtonBox *buttonBox = new QDialogButtonBox(dialog); buttonBox->addButton(detailsButton, QDialogButtonBox::HelpRole); buttonBox->addButton(QDialogButtonBox::Ok); buttonBox->button(QDialogButtonBox::Ok)->setFocus(); applyOptions(dialog, options); - createKMessageBox(dialog, buttonBox, QMessageBox::Warning, text, QStringList(), QString(), 0, options, details); + createKMessageBox(dialog, buttonBox, QMessageBox::Warning, text, QStringList(), QString(), nullptr, options, details); } void detailedSorry(QWidget *parent, const QString &text, const QString &details, const QString &caption, Options options) { detailedSorryInternal(new QDialog(parent), text, details, caption, options); } void information(QWidget *parent, const QString &text, const QString &caption, const QString &dontShowAgainName, Options options) { informationList(parent, text, QStringList(), caption, dontShowAgainName, options); } static void informationListInternal(QDialog *dialog, const QString &text, const QStringList &strlist, const QString &caption, const QString &dontShowAgainName, Options options) { if (!shouldBeShownContinue(dontShowAgainName)) { delete dialog; return; } dialog->setWindowTitle(caption.isEmpty() ? QApplication::translate("KMessageBox", "Information") : caption); dialog->setObjectName(QStringLiteral("information")); QDialogButtonBox *buttonBox = new QDialogButtonBox(dialog); buttonBox->setStandardButtons(QDialogButtonBox::Ok); applyOptions(dialog, options); bool checkboxResult = false; createKMessageBox(dialog, buttonBox, QMessageBox::Information, text, strlist, dontShowAgainName.isEmpty() ? QString() : QApplication::translate("KMessageBox", "Do not show this message again"), &checkboxResult, options); if (checkboxResult) { saveDontShowAgainContinue(dontShowAgainName); } } void informationList(QWidget *parent, const QString &text, const QStringList &strlist, const QString &caption, const QString &dontShowAgainName, Options options) { informationListInternal(new QDialog(parent), text, strlist, caption, dontShowAgainName, options); } void about(QWidget *parent, const QString &text, const QString &caption, Options options) { QDialog *dialog = new QDialog(parent, Qt::Dialog); if (!caption.isEmpty()) { dialog->setWindowTitle(caption); } dialog->setObjectName(QStringLiteral("about")); QDialogButtonBox *buttonBox = new QDialogButtonBox(dialog); buttonBox->setStandardButtons(QDialogButtonBox::Ok); applyOptions(dialog, options); if (qApp->windowIcon().isNull()) { QPixmap ret = QMessageBox::standardIcon(QMessageBox::Information); dialog->setWindowIcon(ret); } - createKMessageBox(dialog, buttonBox, qApp->windowIcon(), text, QStringList(), QString(), 0, options); + createKMessageBox(dialog, buttonBox, qApp->windowIcon(), text, QStringList(), QString(), nullptr, options); } static ButtonCode messageBoxInternal(QDialog *dialog, DialogType type, const QString &text, const QString &caption, const KGuiItem &buttonYes, const KGuiItem &buttonNo, const KGuiItem &buttonCancel, const QString &dontShow, Options options) { switch (type) { case QuestionYesNo: return questionYesNoListInternal(dialog, text, QStringList(), caption, buttonYes, buttonNo, dontShow, options); case QuestionYesNoCancel: return questionYesNoCancelInternal(dialog, text, caption, buttonYes, buttonNo, buttonCancel, dontShow, options); case WarningYesNo: return warningYesNoListInternal(dialog, text, QStringList(), caption, buttonYes, buttonNo, dontShow, options); case WarningContinueCancel: return warningContinueCancelListInternal(dialog, text, QStringList(), caption, KGuiItem(buttonYes.text()), buttonCancel, dontShow, options); case WarningYesNoCancel: return warningYesNoCancelListInternal(dialog, text, QStringList(), caption, buttonYes, buttonNo, buttonCancel, dontShow, options); case Information: informationListInternal(dialog, text, QStringList(), caption, dontShow, options); return KMessageBox::Ok; case Error: errorListInternal(dialog, text, QStringList(), caption, options); return KMessageBox::Ok; case Sorry: sorryInternal(dialog, text, caption, options); return KMessageBox::Ok; } return KMessageBox::Cancel; } ButtonCode messageBox(QWidget *parent, DialogType type, const QString &text, const QString &caption, const KGuiItem &buttonYes, const KGuiItem &buttonNo, const KGuiItem &buttonCancel, const QString &dontShow, Options options) { return messageBoxInternal(new QDialog(parent), type, text, caption, buttonYes, buttonNo, buttonCancel, dontShow, options); } ButtonCode questionYesNoWId(WId parent_id, const QString &text, const QString &caption, const KGuiItem &buttonYes, const KGuiItem &buttonNo, const QString &dontAskAgainName, Options options) { return questionYesNoListWId(parent_id, text, QStringList(), caption, buttonYes, buttonNo, dontAskAgainName, options); } ButtonCode questionYesNoListWId(WId parent_id, const QString &text, const QStringList &strlist, const QString &caption, const KGuiItem &buttonYes, const KGuiItem &buttonNo, const QString &dontAskAgainName, Options options) { return questionYesNoListInternal(createWIdDialog(parent_id), text, strlist, caption, buttonYes, buttonNo, dontAskAgainName, options); } ButtonCode questionYesNoCancelWId(WId parent_id, const QString &text, const QString &caption, const KGuiItem &buttonYes, const KGuiItem &buttonNo, const KGuiItem &buttonCancel, const QString &dontAskAgainName, Options options) { return questionYesNoCancelInternal(createWIdDialog(parent_id), text, caption, buttonYes, buttonNo, buttonCancel, dontAskAgainName, options); } ButtonCode warningYesNoWId(WId parent_id, const QString &text, const QString &caption, const KGuiItem &buttonYes, const KGuiItem &buttonNo, const QString &dontAskAgainName, Options options) { return warningYesNoListWId(parent_id, text, QStringList(), caption, buttonYes, buttonNo, dontAskAgainName, options); } ButtonCode warningYesNoListWId(WId parent_id, const QString &text, const QStringList &strlist, const QString &caption, const KGuiItem &buttonYes, const KGuiItem &buttonNo, const QString &dontAskAgainName, Options options) { return warningYesNoListInternal(createWIdDialog(parent_id), text, strlist, caption, buttonYes, buttonNo, dontAskAgainName, options); } ButtonCode warningContinueCancelWId(WId parent_id, const QString &text, const QString &caption, const KGuiItem &buttonContinue, const KGuiItem &buttonCancel, const QString &dontAskAgainName, Options options) { return warningContinueCancelListWId(parent_id, text, QStringList(), caption, buttonContinue, buttonCancel, dontAskAgainName, options); } ButtonCode warningContinueCancelListWId(WId parent_id, const QString &text, const QStringList &strlist, const QString &caption, const KGuiItem &buttonContinue, const KGuiItem &buttonCancel, const QString &dontAskAgainName, Options options) { return warningContinueCancelListInternal(createWIdDialog(parent_id), text, strlist, caption, buttonContinue, buttonCancel, dontAskAgainName, options); } ButtonCode warningYesNoCancelWId(WId parent_id, const QString &text, const QString &caption, const KGuiItem &buttonYes, const KGuiItem &buttonNo, const KGuiItem &buttonCancel, const QString &dontAskAgainName, Options options) { return warningYesNoCancelListWId(parent_id, text, QStringList(), caption, buttonYes, buttonNo, buttonCancel, dontAskAgainName, options); } ButtonCode warningYesNoCancelListWId(WId parent_id, const QString &text, const QStringList &strlist, const QString &caption, const KGuiItem &buttonYes, const KGuiItem &buttonNo, const KGuiItem &buttonCancel, const QString &dontAskAgainName, Options options) { return warningYesNoCancelList(createWIdDialog(parent_id), text, strlist, caption, buttonYes, buttonNo, buttonCancel, dontAskAgainName, options); } void errorWId(WId parent_id, const QString &text, const QString &caption, Options options) { errorListWId(parent_id, text, QStringList(), caption, options); } void errorListWId(WId parent_id, const QString &text, const QStringList &strlist, const QString &caption, Options options) { errorListInternal(createWIdDialog(parent_id), text, strlist, caption, options); } void detailedErrorWId(WId parent_id, const QString &text, const QString &details, const QString &caption, Options options) { detailedErrorInternal(createWIdDialog(parent_id), text, details, caption, options); } void sorryWId(WId parent_id, const QString &text, const QString &caption, Options options) { QWidget *parent = QWidget::find(parent_id); QDialog *dialog = new QDialog(parent, Qt::Dialog); dialog->setWindowTitle(caption.isEmpty() ? QApplication::translate("KMessageBox", "Sorry") : caption); dialog->setObjectName(QStringLiteral("sorry")); QDialogButtonBox *buttonBox = new QDialogButtonBox(dialog); buttonBox->setStandardButtons(QDialogButtonBox::Ok); applyOptions(dialog, options); - if (parent == NULL && parent_id) { + if (parent == nullptr && parent_id) { setMainWindow(dialog, parent_id); } - createKMessageBox(dialog, buttonBox, QMessageBox::Warning, text, QStringList(), QString(), 0, options); + createKMessageBox(dialog, buttonBox, QMessageBox::Warning, text, QStringList(), QString(), nullptr, options); } void detailedSorryWId(WId parent_id, const QString &text, const QString &details, const QString &caption, Options options) { detailedSorryInternal(createWIdDialog(parent_id), text, details, caption, options); } void informationWId(WId parent_id, const QString &text, const QString &caption, const QString &dontShowAgainName, Options options) { informationListWId(parent_id, text, QStringList(), caption, dontShowAgainName, options); } void informationListWId(WId parent_id, const QString &text, const QStringList &strlist, const QString &caption, const QString &dontShowAgainName, Options options) { informationListInternal(createWIdDialog(parent_id), text, strlist, caption, dontShowAgainName, options); } ButtonCode messageBoxWId(WId parent_id, DialogType type, const QString &text, const QString &caption, const KGuiItem &buttonYes, const KGuiItem &buttonNo, const KGuiItem &buttonCancel, const QString &dontShow, Options options) { return messageBoxInternal(createWIdDialog(parent_id), type, text, caption, buttonYes, buttonNo, buttonCancel, dontShow, options); } } // namespace #include "kmessagebox.moc" diff --git a/src/kmessagebox_p.cpp b/src/kmessagebox_p.cpp index 3fc3989..d6375bc 100644 --- a/src/kmessagebox_p.cpp +++ b/src/kmessagebox_p.cpp @@ -1,156 +1,156 @@ /* This file is part of the KDE libraries * Copyright 2012 David Faure * Copyright 2013 Aurélien Gâteau * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License or ( at * your option ) version 3 or, at the discretion of KDE e.V. ( which shall * act as a proxy as in section 14 of the GPLv3 ), any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "kmessagebox_p.h" #include "loggingcategory.h" #include #include #include #include #include #include namespace KMessageBox { class KMessageBoxDontAskAgainQSettingsStorage : public KMessageBoxDontAskAgainInterface { public: KMessageBoxDontAskAgainQSettingsStorage() { m_filePath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1Char('/') + QCoreApplication::instance()->applicationName() + QStringLiteral(".kmessagebox"); QSettings s(m_filePath, QSettings::IniFormat); foreach (const QString &key, s.allKeys()) { m_saved.insert(key, static_cast(s.value(key).toInt())); } } virtual ~KMessageBoxDontAskAgainQSettingsStorage() { QSettings s(m_filePath, QSettings::IniFormat); for (auto it = m_saved.constBegin(); it != m_saved.constEnd(); ++it) { s.setValue(it.key(), static_cast(it.value())); } } bool shouldBeShownYesNo(const QString &dontShowAgainName, KMessageBox::ButtonCode &result) Q_DECL_OVERRIDE { KMessageBox::ButtonCode code = m_saved.value(dontShowAgainName, KMessageBox::ButtonCode(0)); if (code == KMessageBox::Yes || code == KMessageBox::No) { result = code; return false; } return true; } bool shouldBeShownContinue(const QString &dontShowAgainName) Q_DECL_OVERRIDE { KMessageBox::ButtonCode code = m_saved.value(dontShowAgainName, KMessageBox::Yes); return code == KMessageBox::Yes; } void saveDontShowAgainYesNo(const QString &dontShowAgainName, KMessageBox::ButtonCode result) Q_DECL_OVERRIDE { m_saved[dontShowAgainName] = result; } void saveDontShowAgainContinue(const QString &dontShowAgainName) Q_DECL_OVERRIDE { m_saved[dontShowAgainName] = KMessageBox::No; } void enableAllMessages() Q_DECL_OVERRIDE { m_saved.clear(); } void enableMessage(const QString &dontShowAgainName) Q_DECL_OVERRIDE { m_saved.remove(dontShowAgainName); } void setConfig(KConfig *) Q_DECL_OVERRIDE { qCWarning(KWidgetsAddonsLog) << "Using QSettings based KMessageBoxDontAskAgainInterface. KMessageBox::setDontShowAgainConfig ignored"; } private: QString m_filePath; QHash m_saved; }; class KMessageBoxNotifyDummy : public KMessageBoxNotifyInterface { public: void sendNotification(QMessageBox::Icon /*notificationType*/, const QString &/*message*/, QWidget * /*parent*/) Q_DECL_OVERRIDE {} }; Q_GLOBAL_STATIC(KMessageBoxDontAskAgainQSettingsStorage, s_defaultDontAskAgainInterface) Q_GLOBAL_STATIC(KMessageBoxNotifyDummy, s_defaultNotifyInterface) -static KMessageBoxDontAskAgainInterface *s_dontAskAgainInterface = 0; -static KMessageBoxNotifyInterface *s_notifyInterface = 0; +static KMessageBoxDontAskAgainInterface *s_dontAskAgainInterface = nullptr; +static KMessageBoxNotifyInterface *s_notifyInterface = nullptr; static void loadKMessageBoxPlugin() { static bool triedLoadingPlugin = false; if (!triedLoadingPlugin) { triedLoadingPlugin = true; QPluginLoader lib(QStringLiteral("kf5/FrameworkIntegrationPlugin")); QObject *rootObj = lib.instance(); if (rootObj) { s_dontAskAgainInterface = rootObj->property(KMESSAGEBOXDONTASKAGAIN_PROPERTY).value(); s_notifyInterface = rootObj->property(KMESSAGEBOXNOTIFY_PROPERTY).value(); } } if (!s_dontAskAgainInterface) { s_dontAskAgainInterface = s_defaultDontAskAgainInterface; } if (!s_notifyInterface) { s_notifyInterface = s_defaultNotifyInterface; } } KMessageBoxDontAskAgainInterface *dontAskAgainInterface() { if (!s_dontAskAgainInterface) { loadKMessageBoxPlugin(); } return s_dontAskAgainInterface; } KMessageBoxNotifyInterface *notifyInterface() { if (!s_notifyInterface) { loadKMessageBoxPlugin(); } return s_notifyInterface; } void setDontShowAgainInterface(KMessageBoxDontAskAgainInterface *dontAskAgainInterface) { - Q_ASSERT(dontAskAgainInterface != 0); + Q_ASSERT(dontAskAgainInterface != nullptr); s_dontAskAgainInterface = dontAskAgainInterface; } void setNotifyInterface(KMessageBoxNotifyInterface *notifyInterface) { - Q_ASSERT(notifyInterface != 0); + Q_ASSERT(notifyInterface != nullptr); s_notifyInterface = notifyInterface; } } // KMessageBox namespace diff --git a/src/kmessagewidget.cpp b/src/kmessagewidget.cpp index b0d2571..be9105d 100644 --- a/src/kmessagewidget.cpp +++ b/src/kmessagewidget.cpp @@ -1,491 +1,491 @@ /* This file is part of the KDE libraries * * Copyright (c) 2011 Aurélien Gâteau * Copyright (c) 2014 Dominik Haumann * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA */ #include "kmessagewidget.h" #include #include #include #include #include #include #include #include #include #include //--------------------------------------------------------------------- // KMessageWidgetPrivate //--------------------------------------------------------------------- class KMessageWidgetPrivate { public: void init(KMessageWidget *); KMessageWidget *q; QFrame *content; QLabel *iconLabel; QLabel *textLabel; QToolButton *closeButton; QTimeLine *timeLine; QIcon icon; KMessageWidget::MessageType messageType; bool wordWrap; QList buttons; QPixmap contentSnapShot; void createLayout(); void updateSnapShot(); void updateLayout(); void slotTimeLineChanged(qreal); void slotTimeLineFinished(); int bestContentHeight() const; }; void KMessageWidgetPrivate::init(KMessageWidget *q_ptr) { q = q_ptr; q->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); timeLine = new QTimeLine(500, q); QObject::connect(timeLine, SIGNAL(valueChanged(qreal)), q, SLOT(slotTimeLineChanged(qreal))); QObject::connect(timeLine, SIGNAL(finished()), q, SLOT(slotTimeLineFinished())); content = new QFrame(q); content->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); wordWrap = false; iconLabel = new QLabel(content); iconLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); iconLabel->hide(); textLabel = new QLabel(content); textLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); textLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); QObject::connect(textLabel, &QLabel::linkActivated, q, &KMessageWidget::linkActivated); QObject::connect(textLabel, &QLabel::linkHovered, q, &KMessageWidget::linkHovered); QAction *closeAction = new QAction(q); closeAction->setText(KMessageWidget::tr("&Close")); closeAction->setToolTip(KMessageWidget::tr("Close message")); closeAction->setIcon(q->style()->standardIcon(QStyle::SP_DialogCloseButton)); QObject::connect(closeAction, &QAction::triggered, q, &KMessageWidget::animatedHide); closeButton = new QToolButton(content); closeButton->setAutoRaise(true); closeButton->setDefaultAction(closeAction); q->setMessageType(KMessageWidget::Information); } void KMessageWidgetPrivate::createLayout() { delete content->layout(); content->resize(q->size()); qDeleteAll(buttons); buttons.clear(); Q_FOREACH (QAction *action, q->actions()) { QToolButton *button = new QToolButton(content); button->setDefaultAction(action); button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); buttons.append(button); } // AutoRaise reduces visual clutter, but we don't want to turn it on if // there are other buttons, otherwise the close button will look different // from the others. closeButton->setAutoRaise(buttons.isEmpty()); if (wordWrap) { QGridLayout *layout = new QGridLayout(content); // Set alignment to make sure icon does not move down if text wraps layout->addWidget(iconLabel, 0, 0, 1, 1, Qt::AlignHCenter | Qt::AlignTop); layout->addWidget(textLabel, 0, 1); if (buttons.isEmpty()) { // Use top-vertical alignment like the icon does. layout->addWidget(closeButton, 0, 2, 1, 1, Qt::AlignHCenter | Qt::AlignTop); } else { // Use an additional layout in row 1 for the buttons. QHBoxLayout *buttonLayout = new QHBoxLayout; buttonLayout->addStretch(); Q_FOREACH (QToolButton *button, buttons) { // For some reason, calling show() is necessary if wordwrap is true, // otherwise the buttons do not show up. It is not needed if // wordwrap is false. button->show(); buttonLayout->addWidget(button); } buttonLayout->addWidget(closeButton); layout->addItem(buttonLayout, 1, 0, 1, 2); } } else { QHBoxLayout *layout = new QHBoxLayout(content); layout->addWidget(iconLabel); layout->addWidget(textLabel); Q_FOREACH (QToolButton *button, buttons) { layout->addWidget(button); } layout->addWidget(closeButton); }; if (q->isVisible()) { q->setFixedHeight(content->sizeHint().height()); } q->updateGeometry(); } void KMessageWidgetPrivate::updateLayout() { if (content->layout()) { createLayout(); } } void KMessageWidgetPrivate::updateSnapShot() { // Attention: updateSnapShot calls QWidget::render(), which causes the whole // window layouts to be activated. Calling this method from resizeEvent() // can lead to infinite recursion, see: // https://bugs.kde.org/show_bug.cgi?id=311336 contentSnapShot = QPixmap(content->size() * q->devicePixelRatio()); contentSnapShot.setDevicePixelRatio(q->devicePixelRatio()); contentSnapShot.fill(Qt::transparent); content->render(&contentSnapShot, QPoint(), QRegion(), QWidget::DrawChildren); } void KMessageWidgetPrivate::slotTimeLineChanged(qreal value) { q->setFixedHeight(qMin(value * 2, qreal(1.0)) * content->height()); q->update(); } void KMessageWidgetPrivate::slotTimeLineFinished() { if (timeLine->direction() == QTimeLine::Forward) { // Show // We set the whole geometry here, because it may be wrong if a // KMessageWidget is shown right when the toplevel window is created. content->setGeometry(0, 0, q->width(), bestContentHeight()); // notify about finished animation emit q->showAnimationFinished(); } else { // hide and notify about finished animation q->hide(); emit q->hideAnimationFinished(); } } int KMessageWidgetPrivate::bestContentHeight() const { int height = content->heightForWidth(q->width()); if (height == -1) { height = content->sizeHint().height(); } return height; } //--------------------------------------------------------------------- // KMessageWidget //--------------------------------------------------------------------- KMessageWidget::KMessageWidget(QWidget *parent) : QFrame(parent) , d(new KMessageWidgetPrivate) { d->init(this); } KMessageWidget::KMessageWidget(const QString &text, QWidget *parent) : QFrame(parent) , d(new KMessageWidgetPrivate) { d->init(this); setText(text); } KMessageWidget::~KMessageWidget() { delete d; } QString KMessageWidget::text() const { return d->textLabel->text(); } void KMessageWidget::setText(const QString &text) { d->textLabel->setText(text); updateGeometry(); } KMessageWidget::MessageType KMessageWidget::messageType() const { return d->messageType; } static QColor darkShade(QColor c) { qreal contrast = 0.7; // taken from kcolorscheme for the dark shade qreal darkAmount; if (c.lightnessF() < 0.006) { /* too dark */ darkAmount = 0.02 + 0.40 * contrast; } else if (c.lightnessF() > 0.93) { /* too bright */ darkAmount = -0.06 - 0.60 * contrast; } else { darkAmount = (-c.lightnessF()) * (0.55 + contrast * 0.35); } qreal v = c.lightnessF() + darkAmount; v = v > 0.0 ? (v < 1.0 ? v : 1.0) : 0.0; c.setHsvF(c.hslHueF(), c.hslSaturationF(), v); return c; } void KMessageWidget::setMessageType(KMessageWidget::MessageType type) { d->messageType = type; QColor bg0, bg1, bg2, border, fg; switch (type) { case Positive: bg1.setRgb(39, 174, 96); // values taken from kcolorscheme.cpp (Positive) fg.setRgb(239, 240, 241); break; case Information: bg1 = palette().highlight().color(); fg = palette().highlightedText().color(); break; case Warning: bg1.setRgb(246, 116, 0); // values taken from kcolorscheme.cpp (Neutral) fg.setRgb(239, 240, 241); break; case Error: bg1.setRgb(218, 68, 83); // values taken from kcolorscheme.cpp (Negative) // #357210: use darker color to improve the visibility of close button. bg1 = bg1.darker(110); fg.setRgb(239, 240, 241); break; } // Colors bg0 = bg1.lighter(110); bg2 = bg1.darker(110); border = darkShade(bg1); d->content->setStyleSheet( QString::fromLatin1(".QFrame {" "background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1," " stop: 0 %1," " stop: 0.1 %2," " stop: 1.0 %3);" "border-radius: 5px;" "border: 1px solid %4;" "margin: %5px;" "}" ".QLabel { color: %6; }" ) .arg(bg0.name()) .arg(bg1.name()) .arg(bg2.name()) .arg(border.name()) // DefaultFrameWidth returns the size of the external margin + border width. We know our border is 1px, so we subtract this from the frame normal QStyle FrameWidth to get our margin - .arg(style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, this) - 1) + .arg(style()->pixelMetric(QStyle::PM_DefaultFrameWidth, nullptr, this) - 1) .arg(fg.name()) ); } QSize KMessageWidget::sizeHint() const { ensurePolished(); return d->content->sizeHint(); } QSize KMessageWidget::minimumSizeHint() const { ensurePolished(); return d->content->minimumSizeHint(); } bool KMessageWidget::event(QEvent *event) { if (event->type() == QEvent::Polish && !d->content->layout()) { d->createLayout(); } return QFrame::event(event); } void KMessageWidget::resizeEvent(QResizeEvent *event) { QFrame::resizeEvent(event); if (d->timeLine->state() == QTimeLine::NotRunning) { d->content->resize(width(), d->bestContentHeight()); } } int KMessageWidget::heightForWidth(int width) const { ensurePolished(); return d->content->heightForWidth(width); } void KMessageWidget::paintEvent(QPaintEvent *event) { QFrame::paintEvent(event); if (d->timeLine->state() == QTimeLine::Running) { QPainter painter(this); painter.setOpacity(d->timeLine->currentValue() * d->timeLine->currentValue()); painter.drawPixmap(0, 0, d->contentSnapShot); } } bool KMessageWidget::wordWrap() const { return d->wordWrap; } void KMessageWidget::setWordWrap(bool wordWrap) { d->wordWrap = wordWrap; d->textLabel->setWordWrap(wordWrap); QSizePolicy policy = sizePolicy(); policy.setHeightForWidth(wordWrap); setSizePolicy(policy); d->updateLayout(); // Without this, when user does wordWrap -> !wordWrap -> wordWrap, a minimum // height is set, causing the widget to be too high. // Mostly visible in test programs. if (wordWrap) { setMinimumHeight(0); } } bool KMessageWidget::isCloseButtonVisible() const { return d->closeButton->isVisible(); } void KMessageWidget::setCloseButtonVisible(bool show) { d->closeButton->setVisible(show); updateGeometry(); } void KMessageWidget::addAction(QAction *action) { QFrame::addAction(action); d->updateLayout(); } void KMessageWidget::removeAction(QAction *action) { QFrame::removeAction(action); d->updateLayout(); } void KMessageWidget::animatedShow() { - if (!style()->styleHint(QStyle::SH_Widget_Animate, 0, this)) { + if (!style()->styleHint(QStyle::SH_Widget_Animate, nullptr, this)) { show(); emit showAnimationFinished(); return; } if (isVisible()) { return; } QFrame::show(); setFixedHeight(0); int wantedHeight = d->bestContentHeight(); d->content->setGeometry(0, -wantedHeight, width(), wantedHeight); d->updateSnapShot(); d->timeLine->setDirection(QTimeLine::Forward); if (d->timeLine->state() == QTimeLine::NotRunning) { d->timeLine->start(); } } void KMessageWidget::animatedHide() { - if (!style()->styleHint(QStyle::SH_Widget_Animate, 0, this)) { + if (!style()->styleHint(QStyle::SH_Widget_Animate, nullptr, this)) { hide(); emit hideAnimationFinished(); return; } if (!isVisible()) { return; } d->content->move(0, -d->content->height()); d->updateSnapShot(); d->timeLine->setDirection(QTimeLine::Backward); if (d->timeLine->state() == QTimeLine::NotRunning) { d->timeLine->start(); } } bool KMessageWidget::isHideAnimationRunning() const { return (d->timeLine->direction() == QTimeLine::Backward) && (d->timeLine->state() == QTimeLine::Running); } bool KMessageWidget::isShowAnimationRunning() const { return (d->timeLine->direction() == QTimeLine::Forward) && (d->timeLine->state() == QTimeLine::Running); } QIcon KMessageWidget::icon() const { return d->icon; } void KMessageWidget::setIcon(const QIcon &icon) { d->icon = icon; if (d->icon.isNull()) { d->iconLabel->hide(); } else { const int size = style()->pixelMetric(QStyle::PM_ToolBarIconSize); d->iconLabel->setPixmap(d->icon.pixmap(size)); d->iconLabel->show(); } } #include "moc_kmessagewidget.cpp" diff --git a/src/kmessagewidget.h b/src/kmessagewidget.h index ce073ef..0059657 100644 --- a/src/kmessagewidget.h +++ b/src/kmessagewidget.h @@ -1,344 +1,344 @@ /* This file is part of the KDE libraries * * Copyright (c) 2011 Aurélien Gâteau * Copyright (c) 2014 Dominik Haumann * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA */ #ifndef KMESSAGEWIDGET_H #define KMESSAGEWIDGET_H #include #include class KMessageWidgetPrivate; /** * @short A widget to provide feedback or propose opportunistic interactions. * * KMessageWidget can be used to provide inline positive or negative * feedback, or to implement opportunistic interactions. * * As a feedback widget, KMessageWidget provides a less intrusive alternative * to "OK Only" message boxes. If you want to avoid a modal KMessageBox, * consider using KMessageWidget instead. * * Examples of KMessageWidget look as follows, all of them having an icon set * with setIcon(), and the first three show a close button: * * \image html kmessagewidget.png "KMessageWidget with different message types" * * Negative feedback * * The KMessageWidget can be used as a secondary indicator of failure: the * first indicator is usually the fact the action the user expected to happen * did not happen. * * Example: User fills a form, clicks "Submit". * * @li Expected feedback: form closes * @li First indicator of failure: form stays there * @li Second indicator of failure: a KMessageWidget appears on top of the * form, explaining the error condition * * When used to provide negative feedback, KMessageWidget should be placed * close to its context. In the case of a form, it should appear on top of the * form entries. * * KMessageWidget should get inserted in the existing layout. Space should not * be reserved for it, otherwise it becomes "dead space", ignored by the user. * KMessageWidget should also not appear as an overlay to prevent blocking * access to elements the user needs to interact with to fix the failure. * * Positive feedback * * KMessageWidget can be used for positive feedback but it shouldn't be * overused. It is often enough to provide feedback by simply showing the * results of an action. * * Examples of acceptable uses: * * @li Confirm success of "critical" transactions * @li Indicate completion of background tasks * * Example of unadapted uses: * * @li Indicate successful saving of a file * @li Indicate a file has been successfully removed * * Opportunistic interaction * * Opportunistic interaction is the situation where the application suggests to * the user an action he could be interested in perform, either based on an * action the user just triggered or an event which the application noticed. * * Example of acceptable uses: * * @li A browser can propose remembering a recently entered password * @li A music collection can propose ripping a CD which just got inserted * @li A chat application may notify the user a "special friend" just connected * * @author Aurélien Gâteau * @since 4.7 */ class KWIDGETSADDONS_EXPORT KMessageWidget : public QFrame { Q_OBJECT Q_PROPERTY(QString text READ text WRITE setText) Q_PROPERTY(bool wordWrap READ wordWrap WRITE setWordWrap) Q_PROPERTY(bool closeButtonVisible READ isCloseButtonVisible WRITE setCloseButtonVisible) Q_PROPERTY(MessageType messageType READ messageType WRITE setMessageType) Q_PROPERTY(QIcon icon READ icon WRITE setIcon) public: /** * Available message types. * The background colors are chosen depending on the message type. */ enum MessageType { Positive, Information, Warning, Error }; Q_ENUM(MessageType) /** * Constructs a KMessageWidget with the specified @p parent. */ - explicit KMessageWidget(QWidget *parent = 0); + explicit KMessageWidget(QWidget *parent = nullptr); /** * Constructs a KMessageWidget with the specified @p parent and * contents @p text. */ - explicit KMessageWidget(const QString &text, QWidget *parent = 0); + explicit KMessageWidget(const QString &text, QWidget *parent = nullptr); /** * Destructor. */ ~KMessageWidget(); /** * Get the text of this message widget. * @see setText() */ QString text() const; /** * Check whether word wrap is enabled. * * If word wrap is enabled, the message widget wraps the displayed text * as required to the available width of the widget. This is useful to * avoid breaking widget layouts. * * @see setWordWrap() */ bool wordWrap() const; /** * Check whether the close button is visible. * * @see setCloseButtonVisible() */ bool isCloseButtonVisible() const; /** * Get the type of this message. * By default, the type is set to KMessageWidget::Information. * * @see KMessageWidget::MessageType, setMessageType() */ MessageType messageType() const; /** * Add @p action to the message widget. * For each action a button is added to the message widget in the * order the actions were added. * * @param action the action to add * @see removeAction(), QWidget::actions() */ void addAction(QAction *action); /** * Remove @p action from the message widget. * * @param action the action to remove * @see KMessageWidget::MessageType, addAction(), setMessageType() */ void removeAction(QAction *action); /** * Returns the preferred size of the message widget. */ QSize sizeHint() const Q_DECL_OVERRIDE; /** * Returns the minimum size of the message widget. */ QSize minimumSizeHint() const Q_DECL_OVERRIDE; /** * Returns the required height for @p width. * @param width the width in pixels */ int heightForWidth(int width) const Q_DECL_OVERRIDE; /** * The icon shown on the left of the text. By default, no icon is shown. * @since 4.11 */ QIcon icon() const; /** * Check whether the hide animation started by calling animatedHide() * is still running. If animations are disabled, this function always * returns @e false. * * @see animatedHide(), hideAnimationFinished() * @since 5.0 */ bool isHideAnimationRunning() const; /** * Check whether the show animation started by calling animatedShow() * is still running. If animations are disabled, this function always * returns @e false. * * @see animatedShow(), showAnimationFinished() * @since 5.0 */ bool isShowAnimationRunning() const; public Q_SLOTS: /** * Set the text of the message widget to @p text. * If the message widget is already visible, the text changes on the fly. * * @param text the text to display, rich text is allowed * @see text() */ void setText(const QString &text); /** * Set word wrap to @p wordWrap. If word wrap is enabled, the text() * of the message widget is wrapped to fit the available width. * If word wrap is disabled, the message widget's minimum size is * such that the entire text fits. * * @param wordWrap disable/enable word wrap * @see wordWrap() */ void setWordWrap(bool wordWrap); /** * Set the visibility of the close button. If @p visible is @e true, * a close button is shown that calls animatedHide() if clicked. * * @see closeButtonVisible(), animatedHide() */ void setCloseButtonVisible(bool visible); /** * Set the message type to @p type. * By default, the message type is set to KMessageWidget::Information. * * @see messageType(), KMessageWidget::MessageType */ void setMessageType(KMessageWidget::MessageType type); /** * Show the widget using an animation. */ void animatedShow(); /** * Hide the widget using an animation. */ void animatedHide(); /** * Define an icon to be shown on the left of the text * @since 4.11 */ void setIcon(const QIcon &icon); Q_SIGNALS: /** * This signal is emitted when the user clicks a link in the text label. * The URL referred to by the href anchor is passed in contents. * @param contents text of the href anchor * @see QLabel::linkActivated() * @since 4.10 */ void linkActivated(const QString &contents); /** * This signal is emitted when the user hovers over a link in the text label. * The URL referred to by the href anchor is passed in contents. * @param contents text of the href anchor * @see QLabel::linkHovered() * @since 4.11 */ void linkHovered(const QString &contents); /** * This signal is emitted when the hide animation is finished, started by * calling animatedHide(). If animations are disabled, this signal is * emitted immediately after the message widget got hidden. * * @note This signal is @e not emitted if the widget was hidden by * calling hide(), so this signal is only useful in conjunction * with animatedHide(). * * @see animatedHide() * @since 5.0 */ void hideAnimationFinished(); /** * This signal is emitted when the show animation is finished, started by * calling animatedShow(). If animations are disabled, this signal is * emitted immediately after the message widget got shown. * * @note This signal is @e not emitted if the widget was shown by * calling show(), so this signal is only useful in conjunction * with animatedShow(). * * @see animatedShow() * @since 5.0 */ void showAnimationFinished(); protected: void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; bool event(QEvent *event) Q_DECL_OVERRIDE; void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; private: KMessageWidgetPrivate *const d; friend class KMessageWidgetPrivate; Q_PRIVATE_SLOT(d, void slotTimeLineChanged(qreal)) Q_PRIVATE_SLOT(d, void slotTimeLineFinished()) }; #endif /* KMESSAGEWIDGET_H */ diff --git a/src/kmimetypechooser.cpp b/src/kmimetypechooser.cpp index 3fe0fc8..d34118d 100644 --- a/src/kmimetypechooser.cpp +++ b/src/kmimetypechooser.cpp @@ -1,369 +1,369 @@ /* This file is part of the KDE libraries Copyright (C) 2001 - 2004 Anders Lund This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kmimetypechooser.h" #include "kmimetypeeditor.h" #include #include #include #include #include #include #include #include //BEGIN KMimeTypeChooserPrivate class KMimeTypeChooserPrivate { public: KMimeTypeChooserPrivate(KMimeTypeChooser *parent) : q(parent), - mimeTypeTree(0), - btnEditMimeType(0) + mimeTypeTree(nullptr), + btnEditMimeType(nullptr) { } void loadMimeTypes(const QStringList &selected = QStringList()); void _k_editMimeType(); void _k_slotCurrentChanged(QTreeWidgetItem *); void _k_slotSycocaDatabaseChanged(const QStringList &); KMimeTypeChooser *q; QTreeWidget *mimeTypeTree; QPushButton *btnEditMimeType; QString defaultgroup; QStringList groups; int visuals; }; //END static const char s_keditfiletypeExecutable[] = "keditfiletype5"; //BEGIN KMimeTypeChooser KMimeTypeChooser::KMimeTypeChooser(const QString &text, const QStringList &selMimeTypes, const QString &defaultGroup, const QStringList &groupsToShow, int visuals, QWidget *parent) : QWidget(parent), d(new KMimeTypeChooserPrivate(this)) { d->defaultgroup = defaultGroup; d->groups = groupsToShow; if (visuals & EditButton) { if (QStandardPaths::findExecutable(QString::fromLatin1(s_keditfiletypeExecutable)).isEmpty()) { visuals &= ~EditButton; } } d->visuals = visuals; QVBoxLayout *vboxLayout = new QVBoxLayout(this); vboxLayout->setMargin(0); if (!text.isEmpty()) { vboxLayout->addWidget(new QLabel(text, this)); } d->mimeTypeTree = new QTreeWidget(this); vboxLayout->addWidget(d->mimeTypeTree); QStringList headerLabels; headerLabels.append(tr("Mime Type")); if (visuals & Comments) { headerLabels.append(tr("Comment")); } if (visuals & Patterns) { headerLabels.append(tr("Patterns")); } d->mimeTypeTree->setColumnCount(headerLabels.count()); d->mimeTypeTree->setHeaderLabels(headerLabels); QFontMetrics fm(d->mimeTypeTree->fontMetrics()); d->mimeTypeTree->setColumnWidth(0, 20 * fm.height()); // big enough for most names, but not for the insanely long ones d->loadMimeTypes(selMimeTypes); if (visuals & EditButton) { QHBoxLayout *buttonLayout = new QHBoxLayout(); buttonLayout->addStretch(1); d->btnEditMimeType = new QPushButton(tr("&Edit..."), this); buttonLayout->addWidget(d->btnEditMimeType); connect(d->btnEditMimeType, SIGNAL(clicked()), this, SLOT(_k_editMimeType())); d->btnEditMimeType->setEnabled(false); connect(d->mimeTypeTree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT(_k_editMimeType())); connect(d->mimeTypeTree, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(_k_slotCurrentChanged(QTreeWidgetItem*))); d->btnEditMimeType->setWhatsThis(tr( "Click this button to display the familiar KDE mime type editor.")); vboxLayout->addLayout(buttonLayout); } setLayout(vboxLayout); } KMimeTypeChooser::~KMimeTypeChooser() { delete d; } void KMimeTypeChooserPrivate::loadMimeTypes(const QStringList &_selectedMimeTypes) { QStringList selMimeTypes; if (!_selectedMimeTypes.isEmpty()) { selMimeTypes = _selectedMimeTypes; } else { selMimeTypes = q->mimeTypes(); } mimeTypeTree->clear(); QMap groupItems; QMimeDatabase db; const QList mimetypes = db.allMimeTypes(); bool agroupisopen = false; - QTreeWidgetItem *idefault = 0; //open this, if all other fails - QTreeWidgetItem *firstChecked = 0; // make this one visible after the loop + QTreeWidgetItem *idefault = nullptr; //open this, if all other fails + QTreeWidgetItem *firstChecked = nullptr; // make this one visible after the loop foreach (const QMimeType &mt, mimetypes) { const QString mimetype = mt.name(); const int index = mimetype.indexOf(QLatin1Char('/')); const QString maj = mimetype.left(index); if (!groups.isEmpty() && !groups.contains(maj)) { continue; } QTreeWidgetItem *groupItem; QMap::Iterator mit = groupItems.find(maj); if (mit == groupItems.end()) { groupItem = new QTreeWidgetItem(mimeTypeTree, QStringList(maj)); groupItems.insert(maj, groupItem); if (maj == defaultgroup) { idefault = groupItem; } } else { groupItem = mit.value(); } const QString min = mimetype.mid(index + 1); QTreeWidgetItem *item = new QTreeWidgetItem(groupItem, QStringList(min)); item->setIcon(0, QIcon::fromTheme(mt.iconName())); int cl = 1; if (visuals & KMimeTypeChooser::Comments) { item->setText(cl, mt.comment()); cl++; } if (visuals & KMimeTypeChooser::Patterns) { item->setText(cl, mt.globPatterns().join(QStringLiteral("; "))); } if (selMimeTypes.contains(mimetype)) { item->setCheckState(0, Qt::Checked); groupItem->setExpanded(true); agroupisopen = true; if (!firstChecked) { firstChecked = item; } } else { item->setCheckState(0, Qt::Unchecked); } } if (firstChecked) { mimeTypeTree->scrollToItem(firstChecked); } if (!agroupisopen && idefault) { idefault->setExpanded(true); mimeTypeTree->scrollToItem(idefault); } mimeTypeTree->resizeColumnToContents(1); } void KMimeTypeChooserPrivate::_k_editMimeType() { QTreeWidgetItem *item = mimeTypeTree->currentItem(); if (!item || !item->parent()) { return; } QString mt = (item->parent())->text(0) + QLatin1Char('/') + item->text(0); // KF5 TODO: use a QFileSystemWatcher on one of the shared-mime-info generated files, instead. //q->connect( KSycoca::self(), SIGNAL(databaseChanged(QStringList)), // q, SLOT(_k_slotSycocaDatabaseChanged(QStringList)) ); #pragma message("KF5 TODO: use QFileSystemWatcher to be told when keditfiletype changed a mimetype") // or a better idea: a QMimeDatabaseWatcher class in Qt itself KMimeTypeEditor::editMimeType(mt, q); } void KMimeTypeChooserPrivate::_k_slotCurrentChanged(QTreeWidgetItem *item) { if (btnEditMimeType) { btnEditMimeType->setEnabled(item && item->parent()); } } // TODO: see _k_editMimeType void KMimeTypeChooserPrivate::_k_slotSycocaDatabaseChanged(const QStringList &changedResources) { if (changedResources.contains(QStringLiteral("xdgdata-mime"))) { loadMimeTypes(); } } // recursive helper for mimeTypes() static void getCheckedItems(QList &lst, QTreeWidgetItem *parent) { for (int i = 0; i < parent->childCount(); ++i) { QTreeWidgetItem *item = parent->child(i); if (item->checkState(0) == Qt::Checked) { lst.append(item); } getCheckedItems(lst, item); } } static void getCheckedItems(QList &lst, QTreeWidget *tree) { for (int i = 0; i < tree->topLevelItemCount(); ++i) { QTreeWidgetItem *topItem = tree->topLevelItem(i); //if (topItem->checkState(0) == Qt::Checked) // lst.append(topItem); getCheckedItems(lst, topItem); } } QStringList KMimeTypeChooser::mimeTypes() const { QStringList mimeList; QList checkedItems; getCheckedItems(checkedItems, d->mimeTypeTree); foreach (QTreeWidgetItem *item, checkedItems) { mimeList.append(item->parent()->text(0) + QLatin1Char('/') + item->text(0)); } return mimeList; } QStringList KMimeTypeChooser::patterns() const { QStringList patternList; QList checkedItems; getCheckedItems(checkedItems, d->mimeTypeTree); QMimeDatabase db; foreach (QTreeWidgetItem *item, checkedItems) { QMimeType mime = db.mimeTypeForName(item->parent()->text(0) + QLatin1Char('/') + item->text(0)); Q_ASSERT(mime.isValid()); patternList += mime.globPatterns(); } return patternList; } //END //BEGIN KMimeTypeChooserDialog::Private class KMimeTypeChooserDialog::Private { public: Private(KMimeTypeChooserDialog *parent) : q(parent) { } void init(); KMimeTypeChooserDialog *q; KMimeTypeChooser *m_chooser; }; //END //BEGIN KMimeTypeChooserDialog KMimeTypeChooserDialog::KMimeTypeChooserDialog( const QString &caption, const QString &text, const QStringList &selMimeTypes, const QString &defaultGroup, const QStringList &groupsToShow, int visuals, QWidget *parent) : QDialog(parent), d(new Private(this)) { setWindowTitle(caption); d->m_chooser = new KMimeTypeChooser(text, selMimeTypes, defaultGroup, groupsToShow, visuals, this); d->init(); } KMimeTypeChooserDialog::KMimeTypeChooserDialog( const QString &caption, const QString &text, const QStringList &selMimeTypes, const QString &defaultGroup, QWidget *parent) : QDialog(parent), d(new Private(this)) { setWindowTitle(caption); d->m_chooser = new KMimeTypeChooser(text, selMimeTypes, defaultGroup, QStringList(), KMimeTypeChooser::Comments | KMimeTypeChooser::Patterns | KMimeTypeChooser::EditButton, this); d->init(); } KMimeTypeChooser *KMimeTypeChooserDialog::chooser() { return d->m_chooser; } void KMimeTypeChooserDialog::Private::init() { QVBoxLayout *layout = new QVBoxLayout; q->setLayout(layout); layout->addWidget(m_chooser); QDialogButtonBox *buttonBox = new QDialogButtonBox(q); buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); QObject::connect(buttonBox, &QDialogButtonBox::accepted, q, &QDialog::accept); QObject::connect(buttonBox, &QDialogButtonBox::rejected, q, &QDialog::reject); layout->addWidget(buttonBox); } KMimeTypeChooserDialog::~KMimeTypeChooserDialog() { delete d; } //END KMimeTypeChooserDialog #include "moc_kmimetypechooser.cpp" diff --git a/src/kmimetypechooser.h b/src/kmimetypechooser.h index 2d5aeb1..5bc7582 100644 --- a/src/kmimetypechooser.h +++ b/src/kmimetypechooser.h @@ -1,160 +1,160 @@ /* This file is part of the KDE libraries Copyright (C) 2001 - 2004 Anders Lund This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KMIMETYPE_CHOOSER_H #define KMIMETYPE_CHOOSER_H #include #include #include class QTreeWidgetItem; /** * This widget provides a checkable list of all available mimetypes, * and a list of selected ones, as well as a corresponding list of file * extensions, an optional text and an optional edit button (not working yet). * Mime types is presented in a list view, with name, comment and patterns columns. * * @author Anders Lund (anders at alweb dk), jan 23, 2002 */ class KWIDGETSADDONS_EXPORT KMimeTypeChooser : public QWidget { Q_OBJECT public: /** * Buttons and data for display. */ enum Visuals { Comments = 1, ///< Show the Mimetypes Comment field in a column ("HTML Document"). Patterns = 2, ///< Show the Mimetypes Patterns field in a column ("*.html;*.htm"). EditButton = 4 ///< Show the "Edit" button, allowing to edit the selected type. }; /** * Create a new KMimeTypeChooser. * * @param text A Text to display above the list * @param selectedMimeTypes A list of mimetype names, theese will be checked * in the list if they exist. * @param visuals A OR'd Visuals enum to decide which data and buttons to display. * @param defaultGroup The group to open when no groups are selected (like * "text"). If not provided, no group is opened. If @p groupsToShow * is provided and defaultGroup is not a member of that, it is ignored. * @param groupsToShow a list of mimetype groups to show. If empty, all * groups are shown. * @param parent The parent widget to use */ explicit KMimeTypeChooser(const QString &text = QString(), const QStringList &selectedMimeTypes = QStringList(), const QString &defaultGroup = QString(), const QStringList &groupsToShow = QStringList(), int visuals = Comments | Patterns | EditButton, - QWidget *parent = 0); + QWidget *parent = nullptr); ~KMimeTypeChooser(); /** * @return a list of all selected selected mimetypes represented by their name. */ QStringList mimeTypes() const; /** * @return a list of the fileame patterns associated with all selected mimetypes. */ QStringList patterns() const; private: class KMimeTypeChooserPrivate *d; Q_PRIVATE_SLOT(d, void _k_editMimeType()) Q_PRIVATE_SLOT(d, void _k_slotCurrentChanged(QTreeWidgetItem *)) Q_PRIVATE_SLOT(d, void _k_slotSycocaDatabaseChanged(QStringList)) }; /** * @short A Dialog to choose some mimetypes. * Provides a checkable tree list of mimetypes, with icons and optinally * comments and patterns, and an (optional) button to display the KDE mimetype * editor. * * Here is an example, using the dialog to set the text of two lineedits: * * @code * QString text = i18n("Select the MimeTypes you want for this file type."); * QStringList list = QStringList::split( QRegExp("\\s*;\\s*"), leMimetypes->text() ); * KMimeTypeChooserDialog dlg( i18n("Select Mime Types"), text, list, "text", this ); * if ( dlg.exec() == KDialog::Accepted ) { * leWildcards->setText( dlg.chooser()->patterns().join(";") ); * leMimetypes->setText( dlg.chooser()->mimeTypes().join(";") ); * } * @endcode * * \image html kmimetypechooserdialog.png "KMimeTypeChooserDialog in action" * * @author Anders Lund (anders at alweb dk) dec 19, 2001 */ class KWIDGETSADDONS_EXPORT KMimeTypeChooserDialog : public QDialog { public: /** * Create a KMimeTypeChooser dialog. * * @param caption The title of the dialog * @param text A Text to display above the list * @param selectedMimeTypes A list of mimetype names, theese will be * checked in the list if they exist. * patterns will be added to the list view. * @param visuals A OR'd KMimetypeChooser::Visuals enum to decide which data * and buttons to display. * @param defaultGroup The group to open when no groups are selected (like * "text"). If not provided, no group is opened. If @p groupsToShow * is provided and defaultGroup is not a member of that, it is ignored. * @param groupsToShow a list of mimetype groups to show. If empty, all * groups are shown. * @param parent The parent widget to use */ explicit KMimeTypeChooserDialog(const QString &caption = QString(), const QString &text = QString(), const QStringList &selectedMimeTypes = QStringList(), const QString &defaultGroup = QString(), const QStringList &groupsToShow = QStringList(), int visuals = KMimeTypeChooser::Comments | KMimeTypeChooser::Patterns | KMimeTypeChooser::EditButton, - QWidget *parent = 0); + QWidget *parent = nullptr); /** * @overload */ KMimeTypeChooserDialog(const QString &caption, const QString &text, const QStringList &selectedMimeTypes, const QString &defaultGroup, - QWidget *parent = 0); + QWidget *parent = nullptr); ~KMimeTypeChooserDialog(); /** * @return a pointer to the KMimeTypeChooser widget */ KMimeTypeChooser *chooser(); private: class Private; Private *const d; }; #endif // _KMIMETYPE_CHOOSER_H_ diff --git a/src/kmultitabbar.cpp b/src/kmultitabbar.cpp index 7c4707d..2e487cd 100644 --- a/src/kmultitabbar.cpp +++ b/src/kmultitabbar.cpp @@ -1,690 +1,690 @@ /*************************************************************************** kmultitabbar.cpp - description ------------------- begin : 2001 copyright : (C) 2001,2002,2003 by Joseph Wenninger ***************************************************************************/ /*************************************************************************** This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ***************************************************************************/ #include "kmultitabbar.h" #include "kmultitabbar_p.h" #include "moc_kmultitabbar.cpp" #include "moc_kmultitabbar_p.cpp" #include #include #include #include #include #include #include /** A bit of an overview about what's going on here: There are two sorts of things that can be in the tab bar: tabs and regular buttons. The former are managed by KMultiTabBarInternal, the later by the KMultiTabBar itself. */ class KMultiTabBarPrivate { public: class KMultiTabBarInternal *m_internal; QBoxLayout *m_l; QFrame *m_btnTabSep; QList m_buttons; KMultiTabBar::KMultiTabBarPosition m_position; }; KMultiTabBarInternal::KMultiTabBarInternal(QWidget *parent, KMultiTabBar::KMultiTabBarPosition pos): QFrame(parent) { m_position = pos; if (pos == KMultiTabBar::Left || pos == KMultiTabBar::Right) { mainLayout = new QVBoxLayout(this); } else { mainLayout = new QHBoxLayout(this); } mainLayout->setMargin(0); mainLayout->setSpacing(0); mainLayout->addStretch(); setFrameStyle(NoFrame); setBackgroundRole(QPalette::Background); } KMultiTabBarInternal::~KMultiTabBarInternal() { qDeleteAll(m_tabs); m_tabs.clear(); } void KMultiTabBarInternal::setStyle(enum KMultiTabBar::KMultiTabBarStyle style) { m_style = style; for (int i = 0; i < m_tabs.count(); i++) { m_tabs.at(i)->setStyle(m_style); } updateGeometry(); } void KMultiTabBarInternal::contentsMousePressEvent(QMouseEvent *ev) { ev->ignore(); } void KMultiTabBarInternal::mousePressEvent(QMouseEvent *ev) { ev->ignore(); } KMultiTabBarTab *KMultiTabBarInternal::tab(int id) const { QListIterator it(m_tabs); while (it.hasNext()) { KMultiTabBarTab *tab = it.next(); if (tab->id() == id) { return tab; } } - return 0; + return nullptr; } int KMultiTabBarInternal::appendTab(const QIcon &icon, int id, const QString &text) { KMultiTabBarTab *tab; m_tabs.append(tab = new KMultiTabBarTab(icon, text, id, this, m_position, m_style)); // Insert before the stretch.. mainLayout->insertWidget(m_tabs.size() - 1, tab); tab->show(); return 0; } int KMultiTabBarInternal::appendTab(const QPixmap &pic, int id, const QString &text) { // reuse icon variant return appendTab(QIcon(pic), id, text); } void KMultiTabBarInternal::removeTab(int id) { for (int pos = 0; pos < m_tabs.count(); pos++) { if (m_tabs.at(pos)->id() == id) { // remove & delete the tab delete m_tabs.takeAt(pos); break; } } } void KMultiTabBarInternal::setPosition(enum KMultiTabBar::KMultiTabBarPosition pos) { m_position = pos; for (int i = 0; i < m_tabs.count(); i++) { m_tabs.at(i)->setPosition(m_position); } updateGeometry(); } // KMultiTabBarButton /////////////////////////////////////////////////////////////////////////////// KMultiTabBarButton::KMultiTabBarButton(const QIcon &icon, const QString &text, int id, QWidget *parent) - : QPushButton(icon, text, parent), m_id(id), d(0) + : QPushButton(icon, text, parent), m_id(id), d(nullptr) { connect(this, SIGNAL(clicked()), this, SLOT(slotClicked())); // we can't see the focus, so don't take focus. #45557 // If keyboard navigation is wanted, then only the bar should take focus, // and arrows could change the focused button; but generally, tabbars don't take focus anyway. setFocusPolicy(Qt::NoFocus); setAttribute(Qt::WA_LayoutUsesWidgetRect); Q_UNUSED(d); } KMultiTabBarButton::KMultiTabBarButton(const QPixmap &pic, const QString &text, int id, QWidget *parent) - : QPushButton(QIcon(pic), text, parent), m_id(id), d(0) + : QPushButton(QIcon(pic), text, parent), m_id(id), d(nullptr) { connect(this, SIGNAL(clicked()), this, SLOT(slotClicked())); // we can't see the focus, so don't take focus. #45557 // If keyboard navigation is wanted, then only the bar should take focus, // and arrows could change the focused button; but generally, tabbars don't take focus anyway. setFocusPolicy(Qt::NoFocus); setAttribute(Qt::WA_LayoutUsesWidgetRect); Q_UNUSED(d); } KMultiTabBarButton::~KMultiTabBarButton() { } void KMultiTabBarButton::setText(const QString &text) { QPushButton::setText(text); } void KMultiTabBarButton::slotClicked() { updateGeometry(); emit clicked(m_id); } int KMultiTabBarButton::id() const { return m_id; } void KMultiTabBarButton::hideEvent(QHideEvent *he) { QPushButton::hideEvent(he); KMultiTabBar *tb = dynamic_cast(parentWidget()); if (tb) { tb->updateSeparator(); } } void KMultiTabBarButton::showEvent(QShowEvent *he) { QPushButton::showEvent(he); KMultiTabBar *tb = dynamic_cast(parentWidget()); if (tb) { tb->updateSeparator(); } } void KMultiTabBarButton::paintEvent(QPaintEvent *) { QStyleOptionButton opt; opt.initFrom(this); opt.icon = icon(); opt.iconSize = iconSize(); // removes the QStyleOptionButton::HasMenu ButtonFeature opt.features = QStyleOptionButton::Flat; QPainter painter(this); style()->drawControl(QStyle::CE_PushButton, &opt, &painter, this); } // KMultiTabBarTab /////////////////////////////////////////////////////////////////////////////// KMultiTabBarTab::KMultiTabBarTab(const QIcon &icon, const QString &text, int id, QWidget *parent, KMultiTabBar::KMultiTabBarPosition pos, KMultiTabBar::KMultiTabBarStyle style) - : KMultiTabBarButton(icon, text, id, parent), m_style(style), d(0) + : KMultiTabBarButton(icon, text, id, parent), m_style(style), d(nullptr) { m_position = pos; setToolTip(text); setCheckable(true); // shrink down to icon only, but prefer to show text if it's there setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); } KMultiTabBarTab::KMultiTabBarTab(const QPixmap &pic, const QString &text, int id, QWidget *parent, KMultiTabBar::KMultiTabBarPosition pos, KMultiTabBar::KMultiTabBarStyle style) - : KMultiTabBarButton(pic, text, id, parent), m_style(style), d(0) + : KMultiTabBarButton(pic, text, id, parent), m_style(style), d(nullptr) { m_position = pos; setToolTip(text); setCheckable(true); // shrink down to icon only, but prefer to show text if it's there setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); } KMultiTabBarTab::~KMultiTabBarTab() { } void KMultiTabBarTab::setPosition(KMultiTabBar::KMultiTabBarPosition pos) { m_position = pos; updateGeometry(); } void KMultiTabBarTab::setStyle(KMultiTabBar::KMultiTabBarStyle style) { m_style = style; updateGeometry(); } QPixmap KMultiTabBarTab::iconPixmap() const { - int iconSize = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this); + int iconSize = style()->pixelMetric(QStyle::PM_SmallIconSize, nullptr, this); return icon().pixmap(iconSize); } void KMultiTabBarTab::initStyleOption(QStyleOptionToolButton *opt) const { opt->initFrom(this); // Setup icon.. if (!icon().isNull()) { opt->iconSize = iconPixmap().size(); opt->icon = icon(); } // Should we draw text? if (shouldDrawText()) { opt->text = text(); } opt->state |= QStyle::State_AutoRaise; if (underMouse()) { opt->state |= QStyle::State_MouseOver | QStyle::State_Raised; } if (isChecked()) { opt->state |= QStyle::State_Sunken | QStyle::State_On; } opt->font = font(); opt->toolButtonStyle = shouldDrawText() ? Qt::ToolButtonTextBesideIcon : Qt::ToolButtonIconOnly; opt->subControls = QStyle::SC_ToolButton; } QSize KMultiTabBarTab::sizeHint() const { return computeSizeHint(shouldDrawText()); } QSize KMultiTabBarTab::minimumSizeHint() const { return computeSizeHint(false); } void KMultiTabBarTab::computeMargins(int *hMargin, int *vMargin) const { // Unfortunately, QStyle does not give us enough information to figure out // where to place things, so we try to reverse-engineer it QStyleOptionToolButton opt; initStyleOption(&opt); QPixmap iconPix = iconPixmap(); QSize trialSize = iconPix.size() / iconPix.devicePixelRatio(); QSize expandSize = style()->sizeFromContents(QStyle::CT_ToolButton, &opt, trialSize, this); *hMargin = (expandSize.width() - trialSize.width()) / 2; *vMargin = (expandSize.height() - trialSize.height()) / 2; } QSize KMultiTabBarTab::computeSizeHint(bool withText) const { // Compute as horizontal first, then flip around if need be. QStyleOptionToolButton opt; initStyleOption(&opt); int hMargin, vMargin; computeMargins(&hMargin, &vMargin); // Compute interior size, starting from pixmap.. QPixmap iconPix = iconPixmap(); QSize size = iconPix.size() / iconPix.devicePixelRatio(); // Always include text height in computation, to avoid resizing the minor direction // when expanding text.. QSize textSize = fontMetrics().size(0, text()); size.setHeight(qMax(size.height(), textSize.height())); // Pick margins for major/minor direction, depending on orientation int majorMargin = isVertical() ? vMargin : hMargin; int minorMargin = isVertical() ? hMargin : vMargin; size.setWidth(size.width() + 2 * majorMargin); size.setHeight(size.height() + 2 * minorMargin); if (withText) // Add enough room for the text, and an extra major margin. { size.setWidth(size.width() + textSize.width() + majorMargin); } // flip time? if (isVertical()) { return QSize(size.height(), size.width()); } else { return size; } } void KMultiTabBarTab::setState(bool newState) { setChecked(newState); updateGeometry(); } void KMultiTabBarTab::setIcon(const QString &icon) { const QIcon i = QIcon::fromTheme(icon); - const int iconSize = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this); + const int iconSize = style()->pixelMetric(QStyle::PM_SmallIconSize, nullptr, this); setIcon(i.pixmap(iconSize)); } void KMultiTabBarTab::setIcon(const QPixmap &icon) { QPushButton::setIcon(icon); } bool KMultiTabBarTab::shouldDrawText() const { return (m_style == KMultiTabBar::KDEV3ICON) || isChecked(); } bool KMultiTabBarTab::isVertical() const { return m_position == KMultiTabBar::Right || m_position == KMultiTabBar::Left; } void KMultiTabBarTab::paintEvent(QPaintEvent *) { QPainter painter(this); QStyleOptionToolButton opt; initStyleOption(&opt); // Paint bevel.. if (underMouse() || isChecked()) { opt.text.clear(); opt.icon = QIcon(); style()->drawComplexControl(QStyle::CC_ToolButton, &opt, &painter, this); } int hMargin, vMargin; computeMargins(&hMargin, &vMargin); // We first figure out how much room we have for the text, based on // icon size and margin, try to fit in by eliding, and perhaps // give up on drawing the text entirely if we're too short on room QPixmap icon = iconPixmap(); int textRoom = 0; int iconRoom = 0; QString t; if (shouldDrawText()) { if (isVertical()) { iconRoom = icon.height() / icon.devicePixelRatio() + 2 * vMargin; textRoom = height() - iconRoom - vMargin; } else { iconRoom = icon.width() / icon.devicePixelRatio() + 2 * hMargin; textRoom = width() - iconRoom - hMargin; } t = painter.fontMetrics().elidedText(text(), Qt::ElideRight, textRoom); // See whether anything is left. Qt will return either // ... or the ellipsis unicode character, 0x2026 if (t == QLatin1String("...") || t == QChar(0x2026)) { t.clear(); } } // Label time.... Simple case: no text, so just plop down the icon right in the center // We only do this when the button never draws the text, to avoid jumps in icon position // when resizing if (!shouldDrawText()) { style()->drawItemPixmap(&painter, rect(), Qt::AlignCenter | Qt::AlignVCenter, icon); return; } // Now where the icon/text goes depends on text direction and tab position QRect iconArea; QRect labelArea; bool bottomIcon = false; bool rtl = layoutDirection() == Qt::RightToLeft; if (isVertical()) { if (m_position == KMultiTabBar::Left && !rtl) { bottomIcon = true; } if (m_position == KMultiTabBar::Right && rtl) { bottomIcon = true; } } //alignFlags = Qt::AlignLeading | Qt::AlignVCenter; if (isVertical()) { if (bottomIcon) { labelArea = QRect(0, vMargin, width(), textRoom); iconArea = QRect(0, vMargin + textRoom, width(), iconRoom); } else { labelArea = QRect(0, iconRoom, width(), textRoom); iconArea = QRect(0, 0, width(), iconRoom); } } else { // Pretty simple --- depends only on RTL/LTR if (rtl) { labelArea = QRect(hMargin, 0, textRoom, height()); iconArea = QRect(hMargin + textRoom, 0, iconRoom, height()); } else { labelArea = QRect(iconRoom, 0, textRoom, height()); iconArea = QRect(0, 0, iconRoom, height()); } } style()->drawItemPixmap(&painter, iconArea, Qt::AlignCenter | Qt::AlignVCenter, icon); if (t.isEmpty()) { return; } QRect labelPaintArea = labelArea; if (isVertical()) { // If we're vertical, we paint to a simple 0,0 origin rect, // and get the transformations to get us in the right place labelPaintArea = QRect(0, 0, labelArea.height(), labelArea.width()); QTransform tr; if (bottomIcon) { tr.translate(labelArea.x(), labelPaintArea.width() + labelArea.y()); tr.rotate(-90); } else { tr.translate(labelPaintArea.height() + labelArea.x(), labelArea.y()); tr.rotate(90); } painter.setTransform(tr); } opt.text = t; opt.icon = QIcon(); opt.rect = labelPaintArea; style()->drawControl(QStyle::CE_ToolButtonLabel, &opt, &painter, this); } // KMultiTabBar /////////////////////////////////////////////////////////////////////////////// KMultiTabBar::KMultiTabBar(QWidget *parent) : KMultiTabBar(Left, parent) { } KMultiTabBar::KMultiTabBar(KMultiTabBarPosition pos, QWidget *parent) : QWidget(parent), d(new KMultiTabBarPrivate) { if (pos == Left || pos == Right) { d->m_l = new QVBoxLayout(this); setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding/*, true*/); } else { d->m_l = new QHBoxLayout(this); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed/*, true*/); } d->m_l->setMargin(0); d->m_l->setSpacing(0); d->m_internal = new KMultiTabBarInternal(this, pos); setPosition(pos); setStyle(VSNET); d->m_l->insertWidget(0, d->m_internal); d->m_l->insertWidget(0, d->m_btnTabSep = new QFrame(this)); d->m_btnTabSep->setFixedHeight(4); d->m_btnTabSep->setFrameStyle(QFrame::Panel | QFrame::Sunken); d->m_btnTabSep->setLineWidth(2); d->m_btnTabSep->hide(); updateGeometry(); } KMultiTabBar::~KMultiTabBar() { qDeleteAll(d->m_buttons); d->m_buttons.clear(); delete d; } int KMultiTabBar::appendButton(const QIcon &icon, int id, QMenu *popup, const QString &) { KMultiTabBarButton *btn = new KMultiTabBarButton(icon, QString(), id, this); // a button with a QMenu can have another size. Make sure the button has always the same size. btn->setFixedWidth(btn->height()); btn->setMenu(popup); d->m_buttons.append(btn); d->m_l->insertWidget(0, btn); btn->show(); d->m_btnTabSep->show(); return 0; } #ifndef KWIDGETSADDONS_NO_DEPRECATED int KMultiTabBar::appendButton(const QPixmap &pic, int id, QMenu *popup, const QString &x) { // reuse icon variant return appendButton(QIcon(pic), id, popup, x); } #endif void KMultiTabBar::updateSeparator() { bool hideSep = true; QListIterator it(d->m_buttons); while (it.hasNext()) { if (it.next()->isVisibleTo(this)) { hideSep = false; break; } } if (hideSep) { d->m_btnTabSep->hide(); } else { d->m_btnTabSep->show(); } } int KMultiTabBar::appendTab(const QIcon &icon, int id, const QString &text) { d->m_internal->appendTab(icon, id, text); return 0; } #ifndef KWIDGETSADDONS_NO_DEPRECATED int KMultiTabBar::appendTab(const QPixmap &pic, int id, const QString &text) { d->m_internal->appendTab(pic, id, text); return 0; } #endif KMultiTabBarButton *KMultiTabBar::button(int id) const { QListIterator it(d->m_buttons); while (it.hasNext()) { KMultiTabBarButton *button = it.next(); if (button->id() == id) { return button; } } - return 0; + return nullptr; } KMultiTabBarTab *KMultiTabBar::tab(int id) const { return d->m_internal->tab(id); } void KMultiTabBar::removeButton(int id) { for (int pos = 0; pos < d->m_buttons.count(); pos++) { if (d->m_buttons.at(pos)->id() == id) { d->m_buttons.takeAt(pos)->deleteLater(); break; } } if (d->m_buttons.count() == 0) { d->m_btnTabSep->hide(); } } void KMultiTabBar::removeTab(int id) { d->m_internal->removeTab(id); } void KMultiTabBar::setTab(int id, bool state) { KMultiTabBarTab *ttab = tab(id); if (ttab) { ttab->setState(state); } } bool KMultiTabBar::isTabRaised(int id) const { KMultiTabBarTab *ttab = tab(id); if (ttab) { return ttab->isChecked(); } return false; } void KMultiTabBar::setStyle(KMultiTabBarStyle style) { d->m_internal->setStyle(style); } KMultiTabBar::KMultiTabBarStyle KMultiTabBar::tabStyle() const { return d->m_internal->m_style; } void KMultiTabBar::setPosition(KMultiTabBarPosition pos) { d->m_position = pos; d->m_internal->setPosition(pos); } KMultiTabBar::KMultiTabBarPosition KMultiTabBar::position() const { return d->m_position; } void KMultiTabBar::fontChange(const QFont & /* oldFont */) { updateGeometry(); } diff --git a/src/kmultitabbar.h b/src/kmultitabbar.h index 5549c93..dac1d54 100644 --- a/src/kmultitabbar.h +++ b/src/kmultitabbar.h @@ -1,293 +1,293 @@ /*************************************************************************** kmultitabbar.h - description ------------------- begin : 2001 copyright : (C) 2001,2002,2003 by Joseph Wenninger ***************************************************************************/ /*************************************************************************** This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ***************************************************************************/ #ifndef _KMultitabbar_h_ #define _KMultitabbar_h_ #include #include #include #include #include class QPixmap; class QPainter; class QMenu; class QStyleOptionToolButton; class KMultiTabBarPrivate; class KMultiTabBarTabPrivate; class KMultiTabBarButtonPrivate; class KMultiTabBarInternal; /** * A Widget for horizontal and vertical tabs. * (Note that in Qt4, QTabBar can be vertical as well) * * It is possible to add normal buttons to the top/left * The handling if only one tab at a time or multiple tabs * should be raisable is left to the "user". * * \image html kmultitabbar.png "KDE Multi Tab Bar Widget" * * @author Joseph Wenninger */ class KWIDGETSADDONS_EXPORT KMultiTabBar: public QWidget { Q_OBJECT Q_PROPERTY(KMultiTabBarPosition position READ position WRITE setPosition) Q_PROPERTY(KMultiTabBarStyle tabStyle READ tabStyle WRITE setStyle) public: enum KMultiTabBarPosition { Left, Right, Top, Bottom }; Q_ENUM(KMultiTabBarPosition) /** * The list of available styles for KMultiTabBar * - VSNET - Visual Studio .Net like, always shows icon, only show the text of active tabs * - KDEV3ICON - Kdevelop 3 like, always shows the text and icons */ enum KMultiTabBarStyle {VSNET = 0, KDEV3ICON = 2, STYLELAST = 0xffff}; Q_ENUM(KMultiTabBarStyle) /** * Create a KMultiTabBar with Left as KMultiTabBar position. * @param parent The parent of the widget. * @since 5.24 */ explicit KMultiTabBar(QWidget *parent = Q_NULLPTR); - explicit KMultiTabBar(KMultiTabBarPosition pos, QWidget *parent = 0); + explicit KMultiTabBar(KMultiTabBarPosition pos, QWidget *parent = nullptr); virtual ~KMultiTabBar(); /** * append a new button to the button area. The button can later on be accessed with button(ID) * eg for connecting signals to it * @param icon a icon for the button * @param id an arbitraty ID value. It will be emitted in the clicked signal for identifying the button * if more than one button is connected to a signals. * @param popup A popup menu which should be displayed if the button is clicked * @param not_used_yet will be used for a popup text in the future */ - int appendButton(const QIcon &icon, int id = -1, QMenu *popup = 0, const QString ¬_used_yet = QString()); + int appendButton(const QIcon &icon, int id = -1, QMenu *popup = nullptr, const QString ¬_used_yet = QString()); #ifndef KWIDGETSADDONS_NO_DEPRECATED /** * append a new button to the button area. The button can later on be accessed with button(ID) * eg for connecting signals to it * * @deprecated since 5.13, use the appendButton() with QIcon * * @param pic a pixmap for the button * @param id an arbitraty ID value. It will be emitted in the clicked signal for identifying the button * if more than one button is connected to a signals. * @param popup A popup menu which should be displayed if the button is clicked * @param not_used_yet will be used for a popup text in the future */ - KWIDGETSADDONS_DEPRECATED int appendButton(const QPixmap &pic, int id = -1, QMenu *popup = 0, const QString ¬_used_yet = QString()); + KWIDGETSADDONS_DEPRECATED int appendButton(const QPixmap &pic, int id = -1, QMenu *popup = nullptr, const QString ¬_used_yet = QString()); #endif /** * remove a button with the given ID */ void removeButton(int id); /** * append a new tab to the tab area. It can be accessed lateron with tabb(id); * @param icon a icon for the tab * @param id an arbitrary ID which can be used later on to identify the tab * @param text if a mode with text is used it will be the tab text, otherwise a mouse over hint */ int appendTab(const QIcon &icon, int id = -1, const QString &text = QString()); #ifndef KWIDGETSADDONS_NO_DEPRECATED /** * append a new tab to the tab area. It can be accessed lateron with tabb(id); * * @deprecated since 5.13, use the appendTab() with QIcon * * @param pic a bitmap for the tab * @param id an arbitrary ID which can be used later on to identify the tab * @param text if a mode with text is used it will be the tab text, otherwise a mouse over hint */ KWIDGETSADDONS_DEPRECATED int appendTab(const QPixmap &pic, int id = -1, const QString &text = QString()); #endif /** * remove a tab with a given ID */ void removeTab(int id); /** * set a tab to "raised" * @param id The ID of the tab to manipulate * @param state true == activated/raised, false == not active */ void setTab(int id, bool state); /** * return the state of a tab, identified by its ID */ bool isTabRaised(int id) const; /** * get a pointer to a button within the button area identified by its ID */ class KMultiTabBarButton *button(int id) const; /** * get a pointer to a tab within the tab area, identiifed by its ID */ class KMultiTabBarTab *tab(int id) const; /** * set the real position of the widget. * @param pos if the mode is horizontal, only use top, bottom, if it is vertical use left or right */ void setPosition(KMultiTabBarPosition pos); /** * get the tabbar position. * @return position */ KMultiTabBarPosition position() const; /** * set the display style of the tabs */ void setStyle(KMultiTabBarStyle style); /** * get the display style of the tabs * @return display style */ KMultiTabBarStyle tabStyle() const; protected: friend class KMultiTabBarButton; virtual void fontChange(const QFont &); void updateSeparator(); private: KMultiTabBarPrivate *const d; }; /** * Use KMultiTabBar::appendButton to append a button, which creates a KMultiTabBarButton instance */ class KWIDGETSADDONS_EXPORT KMultiTabBarButton: public QPushButton { Q_OBJECT public: int id() const; virtual ~KMultiTabBarButton(); public Q_SLOTS: void setText(const QString &text); Q_SIGNALS: /** * this is emitted if the button is clicked * @param id the ID identifying the button */ void clicked(int id); protected Q_SLOTS: virtual void slotClicked(); protected: void hideEvent(class QHideEvent *) Q_DECL_OVERRIDE; void showEvent(class QShowEvent *) Q_DECL_OVERRIDE; void paintEvent(class QPaintEvent *) Q_DECL_OVERRIDE; /** Should not be created directly. Use KMultiTabBar::appendButton */ KMultiTabBarButton(const QIcon &icon, const QString &, int id, QWidget *parent); /** Should not be created directly. Use KMultiTabBar::appendButton */ KMultiTabBarButton(const QPixmap &pic, const QString &, int id, QWidget *parent); private: friend class KMultiTabBar; int m_id; KMultiTabBarButtonPrivate *const d; }; /** * Use KMultiTabBar::appendTab to append a tab, which creates a KMultiTabBarTab instance */ class KWIDGETSADDONS_EXPORT KMultiTabBarTab: public KMultiTabBarButton { Q_OBJECT public: virtual ~KMultiTabBarTab(); QSize sizeHint() const Q_DECL_OVERRIDE; QSize minimumSizeHint() const Q_DECL_OVERRIDE; public Q_SLOTS: /** * this is used internaly, but can be used by the user, if (s)he wants to * It the according call of KMultiTabBar is invoked though this modifications will be overwritten */ void setPosition(KMultiTabBar::KMultiTabBarPosition); /** * this is used internaly, but can be used by the user, if (s)he wants to * It the according call of KMultiTabBar is invoked though this modifications will be overwritten */ void setStyle(KMultiTabBar::KMultiTabBarStyle); /** * set the active state of the tab * @param state true==active false==not active */ void setState(bool state); void setIcon(const QString &); void setIcon(const QPixmap &); protected: void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE; private: KMultiTabBar::KMultiTabBarPosition m_position; KMultiTabBar::KMultiTabBarStyle m_style; void computeMargins(int *hMargin, int *vMargin) const; QSize computeSizeHint(bool withText) const; bool shouldDrawText() const; bool isVertical() const; QPixmap iconPixmap() const; void initStyleOption(QStyleOptionToolButton *opt) const; friend class KMultiTabBarInternal; /** * This class should never be created except with the appendTab call of KMultiTabBar */ KMultiTabBarTab(const QIcon &icon, const QString &, int id, QWidget *parent, KMultiTabBar::KMultiTabBarPosition pos, KMultiTabBar::KMultiTabBarStyle style); /** * This class should never be created except with the appendTab call of KMultiTabBar */ KMultiTabBarTab(const QPixmap &pic, const QString &, int id, QWidget *parent, KMultiTabBar::KMultiTabBarPosition pos, KMultiTabBar::KMultiTabBarStyle style); KMultiTabBarTabPrivate *const d; }; #endif diff --git a/src/knewpassworddialog.h b/src/knewpassworddialog.h index 09cdd7e..8668085 100644 --- a/src/knewpassworddialog.h +++ b/src/knewpassworddialog.h @@ -1,239 +1,239 @@ // vi: ts=8 sts=4 sw=4 /* This file is part of the KDE libraries Copyright (C) 1998 Pietro Iglio Copyright (C) 1999,2000 Geert Jansen Copyright (C) 2004,2005 Andrew Coles Copyright (C) 2006,2007 Olivier Goffart This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KNEWPASSWORDDIALOG_H #define KNEWPASSWORDDIALOG_H #include #include class QWidget; /** * @short A password input dialog. * * This dialog asks the user to enter a new password. * * The password has to be entered twice to check if the passwords * match. A hint about the strength of the entered password is also * shown. * * \section usage Usage Example * \subsection asynchronous Asynchronous * * \code * KNewPasswordDialog *dlg = new KNewPasswordDialog( parent ); * dlg->setPrompt( i18n( "Enter a password" ) ); * connect( dlg, SIGNAL( newPassword(QString) ) , this, SLOT( setPassword(QString) ) ); * connect( dlg, SIGNAL( rejected() ) , this, SLOT( slotCancel() ) ); * dlg->show(); * \endcode * * \subsection synchronous Synchronous * * \code * KNewPasswordDialog dlg( parent ); * dlg.setPrompt( i18n( "Enter a password" ) ); * if( dlg.exec() ) * setPassword( dlg.password() ); * \endcode * * \image html knewpassworddialog.png "KDE New Password Dialog" * * @author Geert Jansen * @author Olivier Goffart */ class KWIDGETSADDONS_EXPORT KNewPasswordDialog : public QDialog { Q_OBJECT public: /** * Constructs a password dialog. * * @param parent Passed to lower level constructor. */ - explicit KNewPasswordDialog(QWidget *parent = 0); + explicit KNewPasswordDialog(QWidget *parent = nullptr); /** * Destructs the password dialog. */ virtual ~KNewPasswordDialog(); /** * Sets the password prompt. */ void setPrompt(const QString &prompt); /** * Returns the password prompt. */ QString prompt() const; /** * Sets the pixmap that appears next to the prompt in the dialog. The default pixmap represent a simple key. * * the recommended size is KIconLoader::SizeHuge */ void setPixmap(const QPixmap &); /** * Returns the pixmap that appears next to the prompt in the dialog */ QPixmap pixmap() const; /** * Allow empty passwords? - Default: true * * same as setMinimumPasswordLength( allowed ? 0 : 1 ) */ void setAllowEmptyPasswords(bool allowed); /** * Allow empty passwords? * * @return true if minimumPasswordLength() == 0 */ bool allowEmptyPasswords() const; /** * Minimum acceptable password length. * * Default: 0 * * @param minLength The new minimum password length */ void setMinimumPasswordLength(int minLength); /** * Minimum acceptable password length. */ int minimumPasswordLength() const; /** * Maximum acceptable password length. * * @param maxLength The new maximum password length. */ void setMaximumPasswordLength(int maxLength); /** * Maximum acceptable password length. */ int maximumPasswordLength() const; /** * Password length that is expected to be reasonably safe. * * Used to compute the strength level * * Default: 8 - the standard UNIX password length * * @param reasonableLength The new reasonable password length. */ void setReasonablePasswordLength(int reasonableLength); /** * Password length that is expected to be reasonably safe. */ int reasonablePasswordLength() const; /** * Set the password strength level below which a warning is given * Value is in the range 0 to 99. Empty passwords score 0; * non-empty passwords score up to 100, depending on their length and whether they * contain numbers, mixed case letters and punctuation. * * Default: 1 - warn if the password has no discernable strength whatsoever * @param warningLevel The level below which a warning should be given. */ void setPasswordStrengthWarningLevel(int warningLevel); /** * Password strength level below which a warning is given */ int passwordStrengthWarningLevel() const; /** * When the verification password does not match, the background color * of the verification field is set to @p color. As soon as the passwords match, * the original color of the verification field is restored. * * Default: the background color from the current theme. * @since 5.17 */ void setBackgroundWarningColor(const QColor &color); /** * The color used as warning for the verification password field's background. */ QColor backgroundWarningColor() const; /** * Returns the password entered. * @note Only has meaningful data after accept has been called * if you want to access the password from a subclass use * checkAndGetPassword() */ QString password() const; /** * @internal */ void accept() Q_DECL_OVERRIDE; protected: /** * Virtual function that can be overridden to provide password * checking in derived classes. It should return @p true if the * password is valid, @p false otherwise. */ virtual bool checkPassword(const QString &); /** * Checks input password. * If the password is right, returns true * and fills pwd with the password. * Otherwise returns false and pwd will be null. * @since 4.2 */ bool checkAndGetPassword(QString *pwd); Q_SIGNALS: /** * The dialog has been accepted, and the new password is @p password */ void newPassword(const QString &password); private: class KNewPasswordDialogPrivate; KNewPasswordDialogPrivate *const d; Q_PRIVATE_SLOT(d, void _k_passwordStatusChanged()) }; #endif // KNEWPASSWORDDIALOG_H diff --git a/src/kpagedialog.h b/src/kpagedialog.h index c24d997..37aa38b 100644 --- a/src/kpagedialog.h +++ b/src/kpagedialog.h @@ -1,273 +1,273 @@ /* * This file is part of the KDE Libraries * Copyright (C) 1999-2001 Mirko Boehm (mirko@kde.org) and * Espen Sand (espen@kde.org) * Holger Freyther * 2005-2006 Olivier Goffart * 2006 Tobias Koenig * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef KPAGEDIALOG_H #define KPAGEDIALOG_H #include #include #include class KPageDialogPrivate; /** * @short A dialog base class which can handle multiple pages. * * This class provides a dialog base class which handles multiple * pages and allows the user to switch between these pages in * different ways. * * Currently, @p Auto, @p Plain, @p List, @p Tree and @p Tabbed face * types are available (@see KPageView). * * Example:\n * * \code * UrlDialog::UrlDialog( QWidget *parent ) * : KPageDialog( parent ) * { * setFaceType( List ); * * QLabel *label = new QLabel( "Test Page" ); * addPage( label, i18n( "My Test Page" ) ); * * label = new QLabel( "Second Test Page" ); * KPageWidgetItem *page = new KPageWidgetItem( label, i18n( "My Second Test Page" ) ); * page->setHeader( i18n( "My header string" ) ); * page->setIcon( QIcon::fromTheme( "file" ) ); * * addPage( page ); * } * \endcode * * @author Tobias Koenig (tokoe@kde.org) */ class KWIDGETSADDONS_EXPORT KPageDialog : public QDialog { Q_OBJECT Q_DECLARE_PRIVATE(KPageDialog) public: /** * @li @p Auto - A dialog with a face based on the structure of the * available pages. * If only a single page is added, the dialog behaves like * in @p Plain mode, with multiple pages without sub pages * it behaves like in @p List mode and like in @p Tree mode * otherwise. * @li @p Plain - A normal dialog. * @li @p List - A dialog with an icon list on the left side and a * representation of the contents on the right side. * @li @p Tree - A dialog with a tree on the left side and a * representation of the contents on the right side. * @li @p Tabbed - A dialog with a tab bar above the representation * of the contents. */ enum FaceType { Auto = KPageView::Auto, Plain = KPageView::Plain, List = KPageView::List, Tree = KPageView::Tree, Tabbed = KPageView::Tabbed }; public: /** * Creates a new page dialog. */ - explicit KPageDialog(QWidget *parent = 0, Qt::WindowFlags flags = 0); + explicit KPageDialog(QWidget *parent = nullptr, Qt::WindowFlags flags = nullptr); /** * Destroys the page dialog. */ ~KPageDialog(); /** * Sets the face type of the dialog. */ void setFaceType(FaceType faceType); /** * Adds a new top level page to the dialog. * * @param widget The widget of the page. * @param name The name which is displayed in the navigation view. * * @returns The associated @see KPageWidgetItem. */ KPageWidgetItem *addPage(QWidget *widget, const QString &name); /** * Adds a new top level page to the dialog. * * @param item The @see KPageWidgetItem which describes the page. */ void addPage(KPageWidgetItem *item); /** * Inserts a new page in the dialog. * * @param before The new page will be insert before this @see KPageWidgetItem * on the same level in hierarchy. * @param widget The widget of the page. * @param name The name which is displayed in the navigation view. * * @returns The associated @see KPageWidgetItem. */ KPageWidgetItem *insertPage(KPageWidgetItem *before, QWidget *widget, const QString &name); /** * Inserts a new page in the dialog. * * @param before The new page will be insert before this @see KPageWidgetItem * on the same level in hierarchy. * * @param item The @see KPageWidgetItem which describes the page. */ void insertPage(KPageWidgetItem *before, KPageWidgetItem *item); /** * Inserts a new sub page in the dialog. * * @param parent The new page will be insert as child of this @see KPageWidgetItem. * @param widget The widget of the page. * @param name The name which is displayed in the navigation view. * * @returns The associated @see KPageWidgetItem. */ KPageWidgetItem *addSubPage(KPageWidgetItem *parent, QWidget *widget, const QString &name); /** * Inserts a new sub page in the dialog. * * @param parent The new page will be insert as child of this @see KPageWidgetItem. * * @param item The @see KPageWidgetItem which describes the page. */ void addSubPage(KPageWidgetItem *parent, KPageWidgetItem *item); /** * Removes the page associated with the given @see KPageWidgetItem. */ void removePage(KPageWidgetItem *item); /** * Sets the page which is associated with the given @see KPageWidgetItem to * be the current page and emits the currentPageChanged() signal. */ void setCurrentPage(KPageWidgetItem *item); /** * Returns the @see KPageWidgetItem for the current page or 0 if there is no * current page. */ KPageWidgetItem *currentPage() const; /** * Sets the collection of standard buttons displayed by this dialog. */ void setStandardButtons(QDialogButtonBox::StandardButtons buttons); /** * Returns the QPushButton corresponding to the standard button which, or 0 if the standard * button doesn't exist in this dialog. */ QPushButton *button(QDialogButtonBox::StandardButton which) const; /** * Set an action button. */ void addActionButton(QAbstractButton *button); Q_SIGNALS: /** * This signal is emitted whenever the current page has changed. * * @param item The new current page or 0 if no current page is available. */ void currentPageChanged(KPageWidgetItem *current, KPageWidgetItem *before); /** * This signal is emitted whenever a page has been removed. * * @param page The page which has been removed **/ void pageRemoved(KPageWidgetItem *page); protected: /** * This constructor can be used by subclasses to provide a custom page widget. * * \param widget The KPageWidget object will be reparented to this object, so you can create * it without parent and you are not allowed to delete it. */ - KPageDialog(KPageWidget *widget, QWidget *parent, Qt::WindowFlags flags = 0); - KPageDialog(KPageDialogPrivate &dd, KPageWidget *widget, QWidget *parent, Qt::WindowFlags flags = 0); + KPageDialog(KPageWidget *widget, QWidget *parent, Qt::WindowFlags flags = nullptr); + KPageDialog(KPageDialogPrivate &dd, KPageWidget *widget, QWidget *parent, Qt::WindowFlags flags = nullptr); /** * Returns the page widget of the dialog or 0 if no page widget is set. */ KPageWidget *pageWidget(); /** * Returns the page widget of the dialog or 0 if no page widget is set. */ const KPageWidget *pageWidget() const; /** * Set the page widget of the dialog. * * @note the previous pageWidget will be deleted. * * @param widget The KPageWidget object will be reparented to this object, so you can create * it without parent and you are not allowed to delete it. */ void setPageWidget(KPageWidget *widget); /** * Returns the button box of the dialog or 0 if no button box is set. */ QDialogButtonBox *buttonBox(); /** * Returns the button box of the dialog or 0 if no button box is set. */ const QDialogButtonBox *buttonBox() const; /** * Set the button box of the dialog * * @note the previous buttonBox will be deleted. * * @param box The QDialogButtonBox object will be reparented to this object, so you can create * it without parent and you are not allowed to delete it. */ void setButtonBox(QDialogButtonBox *box); protected: KPageDialogPrivate *const d_ptr; }; #endif diff --git a/src/kpagedialog_p.h b/src/kpagedialog_p.h index 1e8286b..da8081d 100644 --- a/src/kpagedialog_p.h +++ b/src/kpagedialog_p.h @@ -1,72 +1,72 @@ /* This file is part of the KDE project Copyright (C) 2007 Matthias Kretz This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef PAGED_KPAGEDIALOG_P_H #define PAGED_KPAGEDIALOG_P_H #include "kpagedialog.h" #include #include class KPageDialogPrivate { Q_DECLARE_PUBLIC(KPageDialog) protected: KPageDialogPrivate(KPageDialog *parent) : q_ptr(parent), - mPageWidget(0), - mButtonBox(0) + mPageWidget(nullptr), + mButtonBox(nullptr) { } virtual ~KPageDialogPrivate() { } KPageDialog *const q_ptr; KPageWidget *mPageWidget; QDialogButtonBox *mButtonBox; void init() { Q_Q(KPageDialog); delete q->layout(); QVBoxLayout *layout = new QVBoxLayout; q->setLayout(layout); if (mPageWidget) { q->connect(mPageWidget, SIGNAL(currentPageChanged(KPageWidgetItem *, KPageWidgetItem *)), q, SIGNAL(currentPageChanged(KPageWidgetItem *, KPageWidgetItem *))); q->connect(mPageWidget, &KPageWidget::pageRemoved, q, &KPageDialog::pageRemoved); layout->addWidget(mPageWidget); } else { layout->addStretch(); } if (mButtonBox) { q->connect(mButtonBox, &QDialogButtonBox::accepted, q, &QDialog::accept); q->connect(mButtonBox, &QDialogButtonBox::rejected, q, &QDialog::reject); layout->addWidget(mButtonBox); } } }; #endif // PAGED_KPAGEDIALOG_P_H diff --git a/src/kpagemodel.cpp b/src/kpagemodel.cpp index d2831e9..99cee58 100644 --- a/src/kpagemodel.cpp +++ b/src/kpagemodel.cpp @@ -1,44 +1,44 @@ /* This file is part of the KDE Libraries Copyright (C) 2006 Tobias Koenig (tokoe@kde.org) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kpagemodel.h" #include "kpagemodel_p.h" KPageModelPrivate::~KPageModelPrivate() { } KPageModel::KPageModel(QObject *parent) - : QAbstractItemModel(parent), d_ptr(0) + : QAbstractItemModel(parent), d_ptr(nullptr) { } KPageModel::KPageModel(KPageModelPrivate &dd, QObject *parent) : QAbstractItemModel(parent), d_ptr(&dd) { d_ptr->q_ptr = this; } KPageModel::~KPageModel() { delete d_ptr; } diff --git a/src/kpagemodel.h b/src/kpagemodel.h index 347a3d9..688e3bb 100644 --- a/src/kpagemodel.h +++ b/src/kpagemodel.h @@ -1,98 +1,98 @@ /* This file is part of the KDE Libraries Copyright (C) 2006 Tobias Koenig (tokoe@kde.org) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KPAGEMODEL_H #define KPAGEMODEL_H #include #include class KPageModelPrivate; /** * @short A base class for a model used by KPageView. * * This class is an abstract base class which must be used to * implement custom models for KPageView. Additional to the standard * Qt::ItemDataRoles it provides the two roles * * @li HeaderRole * @li WidgetRole * * which are used to return a header string for a page and a QWidget * pointer to the page itself. * * Example:\n * * \code * KPageView *view = new KPageView( this ); * KPageModel *model = new MyPageModel( this ); * * view->setModel( model ); * \endcode * * @see KPageView * @author Tobias Koenig */ class KWIDGETSADDONS_EXPORT KPageModel : public QAbstractItemModel { Q_OBJECT Q_DECLARE_PRIVATE(KPageModel) public: /** * Additional roles that KPageView uses. */ enum Role { /** * A string to be rendered as page header. */ HeaderRole = Qt::UserRole + 1, /** * A pointer to the page widget. This is the widget that is shown when the item is * selected. * * You can make QVariant take a QWidget using * \code * QWidget *myWidget = new QWidget; * QVariant v = QVariant::fromValue(myWidget); * \endcode */ WidgetRole }; /** * Constructs a page model with the given parent. */ - explicit KPageModel(QObject *parent = 0); + explicit KPageModel(QObject *parent = nullptr); /** * Destroys the page model. */ virtual ~KPageModel(); protected: KPageModel(KPageModelPrivate &dd, QObject *parent); KPageModelPrivate *const d_ptr; }; #endif diff --git a/src/kpageview.cpp b/src/kpageview.cpp index e6ec0ab..b2ebbfe 100644 --- a/src/kpageview.cpp +++ b/src/kpageview.cpp @@ -1,500 +1,500 @@ /* This file is part of the KDE Libraries Copyright (C) 2006 Tobias Koenig (tokoe@kde.org) Copyright (C) 2007 Rafael Fernández López (ereslibre@kde.org) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kpageview.h" #include "kpageview_p.h" #include "kpagemodel.h" #include "loggingcategory.h" #include #include #include #include #include #include #include void KPageViewPrivate::_k_rebuildGui() { // clean up old view Q_Q(KPageView); QModelIndex currentLastIndex; if (view && view->selectionModel()) { QObject::disconnect(view->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), q, SLOT(_k_pageSelected(QItemSelection,QItemSelection))); currentLastIndex = view->selectionModel()->currentIndex(); } delete view; view = q->createView(); Q_ASSERT(view); view->setSelectionBehavior(QAbstractItemView::SelectItems); view->setSelectionMode(QAbstractItemView::SingleSelection); if (model) { view->setModel(model); } // setup new view if (view->selectionModel()) { QObject::connect(view->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), q, SLOT(_k_pageSelected(QItemSelection,QItemSelection))); if (currentLastIndex.isValid()) { view->selectionModel()->setCurrentIndex(currentLastIndex, QItemSelectionModel::Select); } else if (model) { view->selectionModel()->setCurrentIndex(model->index(0, 0), QItemSelectionModel::Select); } } if (faceType == KPageView::Tabbed) { stack->setVisible(false); layout->removeWidget(stack); } else { layout->addWidget(stack, 2, 1); stack->setVisible(true); } titleWidget->setVisible(q->showPageHeader()); Qt::Alignment alignment = q->viewPosition(); if (alignment & Qt::AlignTop) { layout->addWidget(view, 2, 1); } else if (alignment & Qt::AlignRight) { layout->addWidget(view, 1, 2, 2, 1); } else if (alignment & Qt::AlignBottom) { layout->addWidget(view, 4, 1); } else if (alignment & Qt::AlignLeft) { layout->addWidget(view, 1, 0, 2, 1); } } void KPageViewPrivate::updateSelection() { /** * Select the first item in the view if not done yet. */ if (!model) { return; } if (!view || !view->selectionModel()) { return; } const QModelIndex index = view->selectionModel()->currentIndex(); if (!index.isValid()) { view->selectionModel()->setCurrentIndex(model->index(0, 0), QItemSelectionModel::Select); } } void KPageViewPrivate::cleanupPages() { /** * Remove all orphan pages from the stacked widget. */ const QList widgets = collectPages(); for (int i = 0; i < stack->count(); ++i) { QWidget *page = stack->widget(i); bool found = false; for (int j = 0; j < widgets.count(); ++j) { if (widgets[ j ] == page) { found = true; } } if (!found) { stack->removeWidget(page); } } } QList KPageViewPrivate::collectPages(const QModelIndex &parentIndex) { /** * Traverse through the model recursive and collect all widgets in * a list. */ QList retval; int rows = model->rowCount(parentIndex); for (int j = 0; j < rows; ++j) { const QModelIndex index = model->index(j, 0, parentIndex); retval.append(qvariant_cast(model->data(index, KPageModel::WidgetRole))); if (model->rowCount(index) > 0) { retval += collectPages(index); } } return retval; } KPageView::FaceType KPageViewPrivate::detectAutoFace() const { if (!model) { return KPageView::Plain; } /** * Check whether the model has sub pages. */ bool hasSubPages = false; const int count = model->rowCount(); for (int i = 0; i < count; ++i) { if (model->rowCount(model->index(i, 0)) > 0) { hasSubPages = true; break; } } if (hasSubPages) { return KPageView::Tree; } if (model->rowCount() > 1) { return KPageView::List; } return KPageView::Plain; } void KPageViewPrivate::_k_modelChanged() { if (!model) { return; } /** * If the face type is Auto, we rebuild the GUI whenever the layout * of the model changes. */ if (faceType == KPageView::Auto) { _k_rebuildGui(); // If you discover some crashes use the line below instead... //QTimer::singleShot(0, q, SLOT(_k_rebuildGui())); } /** * Set the stack to the minimum size of the largest widget. */ QSize size = stack->size(); const QList widgets = collectPages(); for (int i = 0; i < widgets.count(); ++i) { const QWidget *widget = widgets[ i ]; if (widget) { size = size.expandedTo(widget->minimumSizeHint()); } } stack->setMinimumSize(size); updateSelection(); } void KPageViewPrivate::_k_pageSelected(const QItemSelection &index, const QItemSelection &previous) { if (!model) { return; } // Return if the current Index is not valid if (index.indexes().size() != 1) { return; } QModelIndex currentIndex = index.indexes().first(); QModelIndex previousIndex; // The previous index can be invalid if (previous.indexes().size() == 1) { previousIndex = previous.indexes().first(); } if (faceType != KPageView::Tabbed) { QWidget *widget = qvariant_cast(model->data(currentIndex, KPageModel::WidgetRole)); if (widget) { if (stack->indexOf(widget) == -1) { // not included yet stack->addWidget(widget); } stack->setCurrentWidget(widget); } else { stack->setCurrentWidget(defaultWidget); } updateTitleWidget(currentIndex); } Q_Q(KPageView); emit q->currentPageChanged(currentIndex, previousIndex); } void KPageViewPrivate::updateTitleWidget(const QModelIndex &index) { Q_Q(KPageView); QString header = model->data(index, KPageModel::HeaderRole).toString(); if (header.isNull()) { //TODO KDE5 remove that ugly logic, see also doxy-comments in KPageWidgetItem::setHeader() header = model->data(index, Qt::DisplayRole).toString(); } titleWidget->setText(header); titleWidget->setVisible(q->showPageHeader()); } void KPageViewPrivate::_k_dataChanged(const QModelIndex &, const QModelIndex &) { /** * When data has changed we update the header and icon for the currently selected * page. */ if (!view) { return; } QModelIndex index = view->selectionModel()->currentIndex(); if (!index.isValid()) { return; } updateTitleWidget(index); } KPageViewPrivate::KPageViewPrivate(KPageView *_parent) - : q_ptr(_parent), model(0), faceType(KPageView::Auto), - layout(0), stack(0), titleWidget(0), view(0) + : q_ptr(_parent), model(nullptr), faceType(KPageView::Auto), + layout(nullptr), stack(nullptr), titleWidget(nullptr), view(nullptr) { } void KPageViewPrivate::init() { Q_Q(KPageView); layout = new QGridLayout(q); stack = new KPageStackedWidget(q); titleWidget = new KTitleWidget(q); QPixmap emptyPixmap(22, 22); emptyPixmap.fill(Qt::transparent); titleWidget->setPixmap(emptyPixmap); layout->addWidget(titleWidget, 1, 1); layout->addWidget(stack, 2, 1); defaultWidget = new QWidget(q); stack->addWidget(defaultWidget); // stack should use most space layout->setColumnStretch(1, 1); layout->setRowStretch(2, 1); } /** * KPageView Implementation */ KPageView::KPageView(QWidget *parent) : QWidget(parent), d_ptr(new KPageViewPrivate(this)) { d_ptr->init(); } KPageView::KPageView(KPageViewPrivate &dd, QWidget *parent) : QWidget(parent), d_ptr(&dd) { d_ptr->init(); } KPageView::~KPageView() { delete d_ptr; } void KPageView::setModel(QAbstractItemModel *model) { Q_D(KPageView); // clean up old model if (d->model) { disconnect(d->model, SIGNAL(layoutChanged()), this, SLOT(_k_modelChanged())); disconnect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(_k_dataChanged(QModelIndex,QModelIndex))); } d->model = model; if (d->model) { connect(d->model, SIGNAL(layoutChanged()), this, SLOT(_k_modelChanged())); connect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(_k_dataChanged(QModelIndex,QModelIndex))); // set new model in navigation view if (d->view) { d->view->setModel(model); } } d->_k_rebuildGui(); } QAbstractItemModel *KPageView::model() const { return d_func()->model; } void KPageView::setFaceType(FaceType faceType) { Q_D(KPageView); d->faceType = faceType; d->_k_rebuildGui(); } KPageView::FaceType KPageView::faceType() const { return d_func()->faceType; } void KPageView::setCurrentPage(const QModelIndex &index) { Q_D(KPageView); if (!d->view || !d->view->selectionModel()) { return; } d->view->selectionModel()->setCurrentIndex(index, QItemSelectionModel::SelectCurrent); } QModelIndex KPageView::currentPage() const { Q_D(const KPageView); if (!d->view || !d->view->selectionModel()) { return QModelIndex(); } return d->view->selectionModel()->currentIndex(); } void KPageView::setItemDelegate(QAbstractItemDelegate *delegate) { Q_D(KPageView); if (d->view) { d->view->setItemDelegate(delegate); } } QAbstractItemDelegate *KPageView::itemDelegate() const { Q_D(const KPageView); if (d->view) { return d->view->itemDelegate(); } else { - return 0; + return nullptr; } } void KPageView::setDefaultWidget(QWidget *widget) { Q_D(KPageView); Q_ASSERT(widget); bool isCurrent = (d->stack->currentIndex() == d->stack->indexOf(d->defaultWidget)); // remove old default widget d->stack->removeWidget(d->defaultWidget); delete d->defaultWidget; // add new default widget d->defaultWidget = widget; d->stack->addWidget(d->defaultWidget); if (isCurrent) { d->stack->setCurrentWidget(d->defaultWidget); } } QAbstractItemView *KPageView::createView() { Q_D(KPageView); if (d->faceType == Auto) { const FaceType faceType = d->detectAutoFace(); if (faceType == Plain) { return new KDEPrivate::KPagePlainView(this); } else if (faceType == List) { return new KDEPrivate::KPageListView(this); } else if (faceType == Tree) { return new KDEPrivate::KPageTreeView(this); } else { // should never happen - return 0; + return nullptr; } } else if (d->faceType == Plain) { return new KDEPrivate::KPagePlainView(this); } else if (d->faceType == List) { return new KDEPrivate::KPageListView(this); } else if (d->faceType == Tree) { return new KDEPrivate::KPageTreeView(this); } else if (d->faceType == Tabbed) { return new KDEPrivate::KPageTabbedView(this); } else { - return 0; + return nullptr; } } bool KPageView::showPageHeader() const { Q_D(const KPageView); FaceType faceType = d->faceType; if (faceType == Auto) { faceType = d->detectAutoFace(); } if (faceType == Tabbed) { return false; } else { return !d->titleWidget->text().isEmpty(); } } Qt::Alignment KPageView::viewPosition() const { Q_D(const KPageView); FaceType faceType = d->faceType; if (faceType == Auto) { faceType = d->detectAutoFace(); } if (faceType == Plain || faceType == Tabbed) { return Qt::AlignTop; } else { return Qt::AlignLeft; } } #include "moc_kpageview.cpp" diff --git a/src/kpageview.h b/src/kpageview.h index c4188c8..c14a836 100644 --- a/src/kpageview.h +++ b/src/kpageview.h @@ -1,198 +1,198 @@ /* This file is part of the KDE Libraries Copyright (C) 2006 Tobias Koenig (tokoe@kde.org) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KPAGEVIEW_H #define KPAGEVIEW_H #include #include class KPageModel; class QAbstractItemDelegate; class QAbstractItemView; class QModelIndex; class KPageViewPrivate; class QAbstractItemModel; /** * @short A base class which can handle multiple pages. * * This class provides a widget base class which handles multiple * pages and allows the user to switch between these pages in * different ways. * * Currently, @p Auto, @p Plain, @p List, @p Tree and @p Tabbed face * types are available. @see KPageWidget * * Example:\n * * \code * KPageModel *model = new MyPageModel(); * * KPageView *view = new KPageView( this ); * view->setModel( model ); * * view->setFaceType( KPageView::List ); * \endcode * * @author Tobias Koenig (tokoe@kde.org) */ class KWIDGETSADDONS_EXPORT KPageView : public QWidget { Q_OBJECT Q_PROPERTY(FaceType faceType READ faceType WRITE setFaceType) Q_DECLARE_PRIVATE(KPageView) public: /** * This enum is used to decide which type of navigation view * shall be used in the page view. * * @li Auto - Depending on the number of pages in the model, * the Plain (one page), the List (several pages) * or the Tree face (nested pages) will be used. * This is the default face type. * @li Plain - No navigation view will be visible and only the * first page of the model will be shown. * * @li List - An icon list is used as navigation view. * * @li Tree - A tree list is used as navigation view. * * @li Tabbed - A tab widget is used as navigation view. */ enum FaceType { Auto, Plain, List, Tree, Tabbed }; Q_ENUM(FaceType) /** * Creates a page view with given parent. */ - explicit KPageView(QWidget *parent = 0); + explicit KPageView(QWidget *parent = nullptr); /** * Destroys the page view. */ virtual ~KPageView(); /** * Sets the @p model of the page view. * * The model has to provide data for the roles defined in KPageModel::Role. */ void setModel(QAbstractItemModel *model); /** * Returns the model of the page view. */ QAbstractItemModel *model() const; /** * Sets the face type of the page view. */ void setFaceType(FaceType faceType); /** * Returns the face type of the page view. */ FaceType faceType() const; /** * Sets the page with @param index to be the current page and emits * the @see currentPageChanged signal. */ void setCurrentPage(const QModelIndex &index); /** * Returns the index for the current page or an invalid index * if no current page exists. */ QModelIndex currentPage() const; /** * Sets the item @param delegate which can be used customize * the page view. */ void setItemDelegate(QAbstractItemDelegate *delegate); /** * Returns the item delegate of the page view. */ QAbstractItemDelegate *itemDelegate() const; /** * Sets the @p widget which will be shown when a page is selected * that has no own widget set. */ void setDefaultWidget(QWidget *widget); Q_SIGNALS: /** * This signal is emitted whenever the current page changes. * The previous page index is replaced by the current index. */ void currentPageChanged(const QModelIndex ¤t, const QModelIndex &previous); protected: /** * Returns the navigation view, depending on the current * face type. * * This method can be reimplemented to provide custom * navigation views. */ virtual QAbstractItemView *createView(); /** * Returns whether the page header should be visible. * * This method can be reimplemented for adapting custom * views. */ virtual bool showPageHeader() const; /** * Returns the position where the navigation view should be * located according to the page stack. * * This method can be reimplemented for adapting custom * views. */ virtual Qt::Alignment viewPosition() const; KPageView(KPageViewPrivate &dd, QWidget *parent); KPageViewPrivate *const d_ptr; private: Q_PRIVATE_SLOT(d_func(), void _k_rebuildGui()) Q_PRIVATE_SLOT(d_func(), void _k_modelChanged()) Q_PRIVATE_SLOT(d_func(), void _k_pageSelected(const QItemSelection &, const QItemSelection &)) Q_PRIVATE_SLOT(d_func(), void _k_dataChanged(const QModelIndex &, const QModelIndex &)) }; #endif diff --git a/src/kpageview_p.cpp b/src/kpageview_p.cpp index 4ce1a42..0852c41 100644 --- a/src/kpageview_p.cpp +++ b/src/kpageview_p.cpp @@ -1,635 +1,635 @@ /* This file is part of the KDE Libraries Copyright (C) 2006 Tobias Koenig (tokoe@kde.org) Copyright (C) 2007 Rafael Fernández López (ereslibre@kde.org) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kpageview_p.h" #include #include #include #include #include #include "kpagemodel.h" #include "loggingcategory.h" using namespace KDEPrivate; /** * KPagePlainView */ KPagePlainView::KPagePlainView(QWidget *parent) : QAbstractItemView(parent) { hide(); } QModelIndex KPagePlainView::indexAt(const QPoint &) const { return QModelIndex(); } void KPagePlainView::scrollTo(const QModelIndex &, ScrollHint) { } QRect KPagePlainView::visualRect(const QModelIndex &) const { return QRect(); } QModelIndex KPagePlainView::moveCursor(QAbstractItemView::CursorAction, Qt::KeyboardModifiers) { return QModelIndex(); } int KPagePlainView::horizontalOffset() const { return 0; } int KPagePlainView::verticalOffset() const { return 0; } bool KPagePlainView::isIndexHidden(const QModelIndex &) const { return false; } void KPagePlainView::setSelection(const QRect &, QFlags) { } QRegion KPagePlainView::visualRegionForSelection(const QItemSelection &) const { return QRegion(); } /** * KPageListView */ KPageListView::KPageListView(QWidget *parent) : QListView(parent) { setViewMode(QListView::ListMode); setMovement(QListView::Static); setVerticalScrollMode(QListView::ScrollPerPixel); QFont boldFont(font()); boldFont.setBold(true); setFont(boldFont); setItemDelegate(new KPageListViewDelegate(this)); } KPageListView::~KPageListView() { } void KPageListView::setModel(QAbstractItemModel *model) { /* KPageListViewProxy *proxy = new KPageListViewProxy( this ); proxy->setSourceModel( model ); proxy->rebuildMap(); connect( model, SIGNAL(layoutChanged()), proxy, SLOT(rebuildMap()) ); */ connect(model, &QAbstractItemModel::layoutChanged, this, &KPageListView::updateWidth); // QListView::setModel( proxy ); QListView::setModel(model); // Set our own selection model, which won't allow our current selection to be cleared setSelectionModel(new KDEPrivate::SelectionModel(model, this)); updateWidth(); } void KPageListView::updateWidth() { if (!model()) { return; } int rows = model()->rowCount(); int width = 0; for (int i = 0; i < rows; ++i) { width = qMax(width, sizeHintForIndex(model()->index(i, 0)).width()); } setFixedWidth(width + 25); } /** * KPageTreeView */ KPageTreeView::KPageTreeView(QWidget *parent) : QTreeView(parent) { header()->hide(); } void KPageTreeView::setModel(QAbstractItemModel *model) { connect(model, &QAbstractItemModel::layoutChanged, this, &KPageTreeView::updateWidth); QTreeView::setModel(model); // Set our own selection model, which won't allow our current selection to be cleared setSelectionModel(new KDEPrivate::SelectionModel(model, this)); updateWidth(); } void KPageTreeView::updateWidth() { if (!model()) { return; } int columns = model()->columnCount(); expandItems(); int width = 0; for (int i = 0; i < columns; ++i) { resizeColumnToContents(i); width = qMax(width, sizeHintForColumn(i)); } setFixedWidth(width + 25); } void KPageTreeView::expandItems(const QModelIndex &index) { setExpanded(index, true); const int count = model()->rowCount(index); for (int i = 0; i < count; ++i) { expandItems(model()->index(i, 0, index)); } } /** * KPageTabbedView */ KPageTabbedView::KPageTabbedView(QWidget *parent) : QAbstractItemView(parent) { // hide the viewport of the QAbstractScrollArea const QList list = findChildren(); for (int i = 0; i < list.count(); ++i) { list[ i ]->hide(); } setFrameShape(NoFrame); QVBoxLayout *layout = new QVBoxLayout(this); layout->setMargin(0); mTabWidget = new QTabWidget(this); connect(mTabWidget, &QTabWidget::currentChanged, this, &KPageTabbedView::currentPageChanged); layout->addWidget(mTabWidget); } KPageTabbedView::~KPageTabbedView() { if (model()) { for (int i = 0; i < mTabWidget->count(); ++i) { QWidget *page = qvariant_cast(model()->data(model()->index(i, 0), KPageModel::WidgetRole)); if (page) { page->setVisible(false); - page->setParent(0); // reparent our children before they are deleted + page->setParent(nullptr); // reparent our children before they are deleted } } } } void KPageTabbedView::setModel(QAbstractItemModel *model) { QAbstractItemView::setModel(model); connect(model, &QAbstractItemModel::layoutChanged, this, &KPageTabbedView::layoutChanged); layoutChanged(); } QModelIndex KPageTabbedView::indexAt(const QPoint &) const { if (model()) { return model()->index(0, 0); } else { return QModelIndex(); } } void KPageTabbedView::scrollTo(const QModelIndex &index, ScrollHint) { if (!index.isValid()) { return; } mTabWidget->setCurrentIndex(index.row()); } QRect KPageTabbedView::visualRect(const QModelIndex &) const { return QRect(); } QSize KPageTabbedView::minimumSizeHint() const { return mTabWidget->minimumSizeHint(); } QModelIndex KPageTabbedView::moveCursor(QAbstractItemView::CursorAction, Qt::KeyboardModifiers) { return QModelIndex(); } int KPageTabbedView::horizontalOffset() const { return 0; } int KPageTabbedView::verticalOffset() const { return 0; } bool KPageTabbedView::isIndexHidden(const QModelIndex &index) const { return (mTabWidget->currentIndex() != index.row()); } void KPageTabbedView::setSelection(const QRect &, QFlags) { } QRegion KPageTabbedView::visualRegionForSelection(const QItemSelection &) const { return QRegion(); } void KPageTabbedView::currentPageChanged(int index) { if (!model()) { return; } QModelIndex modelIndex = model()->index(index, 0); selectionModel()->setCurrentIndex(modelIndex, QItemSelectionModel::ClearAndSelect); } void KPageTabbedView::layoutChanged() { // save old position int pos = mTabWidget->currentIndex(); // clear tab bar int count = mTabWidget->count(); for (int i = 0; i < count; ++i) { mTabWidget->removeTab(0); } if (!model()) { return; } // add new tabs for (int i = 0; i < model()->rowCount(); ++i) { const QString title = model()->data(model()->index(i, 0)).toString(); const QIcon icon = model()->data(model()->index(i, 0), Qt::DecorationRole).value(); QWidget *page = qvariant_cast(model()->data(model()->index(i, 0), KPageModel::WidgetRole)); if (page) { QWidget *widget = new QWidget(this); QVBoxLayout *layout = new QVBoxLayout(widget); widget->setLayout(layout); layout->addWidget(page); page->setVisible(true); mTabWidget->addTab(widget, icon, title); } } mTabWidget->setCurrentIndex(pos); } void KPageTabbedView::dataChanged(const QModelIndex &index, const QModelIndex &, const QVector &roles) { if (!index.isValid()) { return; } if (index.row() < 0 || index.row() >= mTabWidget->count()) { return; } if (roles.isEmpty() || roles.contains(Qt::DisplayRole) || roles.contains(Qt::DecorationRole)) { const QString title = model()->data(index).toString(); const QIcon icon = model()->data(index, Qt::DecorationRole).value(); mTabWidget->setTabText(index.row(), title); mTabWidget->setTabIcon(index.row(), icon); } } /** * KPageListViewDelegate */ KPageListViewDelegate::KPageListViewDelegate(QObject *parent) : QAbstractItemDelegate(parent) { } static int layoutText(QTextLayout *layout, int maxWidth) { qreal height = 0; int textWidth = 0; layout->beginLayout(); while (true) { QTextLine line = layout->createLine(); if (!line.isValid()) { break; } line.setLineWidth(maxWidth); line.setPosition(QPointF(0, height)); height += line.height(); textWidth = qMax(textWidth, qRound(line.naturalTextWidth() + 0.5)); } layout->endLayout(); return textWidth; } void KPageListViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { if (!index.isValid()) { return; } QStyleOptionViewItem opt(option); opt.showDecorationSelected = true; QStyle *style = opt.widget ? opt.widget->style() : QApplication::style(); const QIcon::Mode iconMode = (option.state & QStyle::State_Selected) && (option.state & QStyle::State_Active) ? QIcon::Selected : QIcon::Normal; int iconSize = style->pixelMetric(QStyle::PM_IconViewIconSize); const QString text = index.model()->data(index, Qt::DisplayRole).toString(); const QIcon icon = index.model()->data(index, Qt::DecorationRole).value(); const QPixmap pixmap = icon.pixmap(iconSize, iconSize, iconMode); QFontMetrics fm = painter->fontMetrics(); int wp = pixmap.width() / pixmap.devicePixelRatio(); int hp = pixmap.height() / pixmap.devicePixelRatio(); QTextLayout iconTextLayout(text, option.font); QTextOption textOption(Qt::AlignHCenter); iconTextLayout.setTextOption(textOption); int maxWidth = qMax(3 * wp, 8 * fm.height()); layoutText(&iconTextLayout, maxWidth); QPen pen = painter->pen(); QPalette::ColorGroup cg = option.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled; if (cg == QPalette::Normal && !(option.state & QStyle::State_Active)) { cg = QPalette::Inactive; } style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget); if (option.state & QStyle::State_Selected) { painter->setPen(option.palette.color(cg, QPalette::HighlightedText)); } else { painter->setPen(option.palette.color(cg, QPalette::Text)); } painter->drawPixmap(option.rect.x() + (option.rect.width() / 2) - (wp / 2), option.rect.y() + 5, pixmap); if (!text.isEmpty()) { iconTextLayout.draw(painter, QPoint(option.rect.x() + (option.rect.width() / 2) - (maxWidth / 2), option.rect.y() + hp + 7)); } painter->setPen(pen); drawFocus(painter, option, option.rect); } QSize KPageListViewDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { if (!index.isValid()) { return QSize(0, 0); } QStyleOptionViewItem opt(option); opt.showDecorationSelected = true; QStyle *style = opt.widget ? opt.widget->style() : QApplication::style(); int iconSize = style->pixelMetric(QStyle::PM_IconViewIconSize); const QString text = index.model()->data(index, Qt::DisplayRole).toString(); const QIcon icon = index.model()->data(index, Qt::DecorationRole).value(); const QPixmap pixmap = icon.pixmap(iconSize, iconSize); QFontMetrics fm = option.fontMetrics; int gap = fm.height(); int wp = pixmap.width() / pixmap.devicePixelRatio(); int hp = pixmap.height() / pixmap.devicePixelRatio(); if (hp == 0) { /** * No pixmap loaded yet, we'll use the default icon size in this case. */ hp = iconSize; wp = iconSize; } QTextLayout iconTextLayout(text, option.font); int wt = layoutText(&iconTextLayout, qMax(3 * wp, 8 * fm.height())); int ht = iconTextLayout.boundingRect().height(); int width, height; if (text.isEmpty()) { height = hp; } else { height = hp + ht + 10; } width = qMax(wt, wp) + gap; return QSize(width, height); } void KPageListViewDelegate::drawFocus(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect) const { if (option.state & QStyle::State_HasFocus) { QStyleOptionFocusRect o; o.QStyleOption::operator=(option); o.rect = rect; o.state |= QStyle::State_KeyboardFocusChange; QPalette::ColorGroup cg = (option.state & QStyle::State_Enabled) ? QPalette::Normal : QPalette::Disabled; o.backgroundColor = option.palette.color(cg, (option.state & QStyle::State_Selected) ? QPalette::Highlight : QPalette::Background); QApplication::style()->drawPrimitive(QStyle::PE_FrameFocusRect, &o, painter); } } /** * KPageListViewProxy */ KPageListViewProxy::KPageListViewProxy(QObject *parent) : QAbstractProxyModel(parent) { } KPageListViewProxy::~KPageListViewProxy() { } int KPageListViewProxy::rowCount(const QModelIndex &) const { return mList.count(); } int KPageListViewProxy::columnCount(const QModelIndex &) const { return 1; } QModelIndex KPageListViewProxy::index(int row, int column, const QModelIndex &) const { if (column > 1 || row >= mList.count()) { return QModelIndex(); } else { return createIndex(row, column, mList[ row ].internalPointer()); } } QModelIndex KPageListViewProxy::parent(const QModelIndex &) const { return QModelIndex(); } QVariant KPageListViewProxy::data(const QModelIndex &index, int role) const { if (!index.isValid()) { return QVariant(); } if (index.row() >= mList.count()) { return QVariant(); } return sourceModel()->data(mList[ index.row() ], role); } QModelIndex KPageListViewProxy::mapFromSource(const QModelIndex &index) const { if (!index.isValid()) { return QModelIndex(); } for (int i = 0; i < mList.count(); ++i) { if (mList[ i ] == index) { return createIndex(i, 0, index.internalPointer()); } } return QModelIndex(); } QModelIndex KPageListViewProxy::mapToSource(const QModelIndex &index) const { if (!index.isValid()) { return QModelIndex(); } return mList[ index.row() ]; } void KPageListViewProxy::rebuildMap() { mList.clear(); const QAbstractItemModel *model = sourceModel(); if (!model) { return; } for (int i = 0; i < model->rowCount(); ++i) { addMapEntry(model->index(i, 0)); } for (int i = 0; i < mList.count(); ++i) { qCDebug(KWidgetsAddonsLog, "%d:0 -> %d:%d", i, mList[ i ].row(), mList[ i ].column()); } emit layoutChanged(); } void KPageListViewProxy::addMapEntry(const QModelIndex &index) { if (sourceModel()->rowCount(index) == 0) { mList.append(index); } else { const int count = sourceModel()->rowCount(index); for (int i = 0; i < count; ++i) { addMapEntry(sourceModel()->index(i, 0, index)); } } } SelectionModel::SelectionModel(QAbstractItemModel *model, QObject *parent) : QItemSelectionModel(model, parent) { } void SelectionModel::clear() { // Don't allow the current selection to be cleared } void SelectionModel::select(const QModelIndex &index, QItemSelectionModel::SelectionFlags command) { // Don't allow the current selection to be cleared if (!index.isValid() && (command & QItemSelectionModel::Clear)) { return; } QItemSelectionModel::select(index, command); } void SelectionModel::select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) { // Don't allow the current selection to be cleared if (!selection.count() && (command & QItemSelectionModel::Clear)) { return; } QItemSelectionModel::select(selection, command); } diff --git a/src/kpageview_p.h b/src/kpageview_p.h index 5d96cb4..049b2c7 100644 --- a/src/kpageview_p.h +++ b/src/kpageview_p.h @@ -1,241 +1,241 @@ /* This file is part of the KDE Libraries Copyright (C) 2006 Tobias Koenig (tokoe@kde.org) Copyright (C) 2007 Rafael Fernández López (ereslibre@kde.org) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KPAGEVIEW_P_H #define KPAGEVIEW_P_H #include "kpageview.h" #include #include #include #include #include #include #include #include class KPageStackedWidget : public QStackedWidget { public: - KPageStackedWidget(QWidget *parent = 0) + KPageStackedWidget(QWidget *parent = nullptr) : QStackedWidget(parent) { } void setMinimumSize(const QSize &size) { mMinimumSize = size; } QSize minimumSizeHint() const Q_DECL_OVERRIDE { return mMinimumSize.expandedTo(QStackedWidget::minimumSizeHint()); } private: QSize mMinimumSize; }; class KPageViewPrivate { Q_DECLARE_PUBLIC(KPageView) protected: KPageViewPrivate(KPageView *); KPageView *q_ptr; // data QAbstractItemModel *model; KPageView::FaceType faceType; // gui QGridLayout *layout; KPageStackedWidget *stack; KTitleWidget *titleWidget; QWidget *defaultWidget; QAbstractItemView *view; void updateTitleWidget(const QModelIndex &index); void updateSelection(); void cleanupPages(); QList collectPages(const QModelIndex &parent = QModelIndex()); KPageView::FaceType detectAutoFace() const; // private slots void _k_rebuildGui(); void _k_modelChanged(); void _k_dataChanged(const QModelIndex &, const QModelIndex &); void _k_pageSelected(const QItemSelection &, const QItemSelection &); private: void init(); }; namespace KDEPrivate { class KPageListViewDelegate; class KPageListViewProxy; class KPagePlainView : public QAbstractItemView { public: - KPagePlainView(QWidget *parent = 0); + KPagePlainView(QWidget *parent = nullptr); QModelIndex indexAt(const QPoint &point) const Q_DECL_OVERRIDE; void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible) Q_DECL_OVERRIDE; QRect visualRect(const QModelIndex &index) const Q_DECL_OVERRIDE; protected: QModelIndex moveCursor(QAbstractItemView::CursorAction, Qt::KeyboardModifiers) Q_DECL_OVERRIDE; int horizontalOffset() const Q_DECL_OVERRIDE; int verticalOffset() const Q_DECL_OVERRIDE; bool isIndexHidden(const QModelIndex &) const Q_DECL_OVERRIDE; void setSelection(const QRect &, QFlags) Q_DECL_OVERRIDE; QRegion visualRegionForSelection(const QItemSelection &) const Q_DECL_OVERRIDE; }; class KPageListView : public QListView { Q_OBJECT public: - KPageListView(QWidget *parent = 0); + KPageListView(QWidget *parent = nullptr); virtual ~KPageListView(); void setModel(QAbstractItemModel *model) Q_DECL_OVERRIDE; private Q_SLOTS: void updateWidth(); }; class KPageTreeView : public QTreeView { Q_OBJECT public: - KPageTreeView(QWidget *parent = 0); + KPageTreeView(QWidget *parent = nullptr); void setModel(QAbstractItemModel *model) Q_DECL_OVERRIDE; private Q_SLOTS: void updateWidth(); private: void expandItems(const QModelIndex &index = QModelIndex()); }; class KPageTabbedView : public QAbstractItemView { Q_OBJECT public: - KPageTabbedView(QWidget *parent = 0); + KPageTabbedView(QWidget *parent = nullptr); virtual ~KPageTabbedView(); void setModel(QAbstractItemModel *model) Q_DECL_OVERRIDE; QModelIndex indexAt(const QPoint &point) const Q_DECL_OVERRIDE; void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible) Q_DECL_OVERRIDE; QRect visualRect(const QModelIndex &index) const Q_DECL_OVERRIDE; QSize minimumSizeHint() const Q_DECL_OVERRIDE; protected: QModelIndex moveCursor(QAbstractItemView::CursorAction, Qt::KeyboardModifiers) Q_DECL_OVERRIDE; int horizontalOffset() const Q_DECL_OVERRIDE; int verticalOffset() const Q_DECL_OVERRIDE; bool isIndexHidden(const QModelIndex &) const Q_DECL_OVERRIDE; void setSelection(const QRect &, QFlags) Q_DECL_OVERRIDE; QRegion visualRegionForSelection(const QItemSelection &) const Q_DECL_OVERRIDE; private Q_SLOTS: void currentPageChanged(int); void layoutChanged(); void dataChanged(const QModelIndex &, const QModelIndex &, const QVector &roles) Q_DECL_OVERRIDE; private: QTabWidget *mTabWidget; }; class KPageListViewDelegate : public QAbstractItemDelegate { Q_OBJECT public: - KPageListViewDelegate(QObject *parent = 0); + KPageListViewDelegate(QObject *parent = nullptr); void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE; QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE; private: void drawFocus(QPainter *, const QStyleOptionViewItem &, const QRect &) const; }; /** * We need this proxy model to map the leaves of a tree-like model * to a one-level list model. */ class KPageListViewProxy : public QAbstractProxyModel { Q_OBJECT public: - KPageListViewProxy(QObject *parent = 0); + KPageListViewProxy(QObject *parent = nullptr); virtual ~KPageListViewProxy(); int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; QModelIndex parent(const QModelIndex &) const Q_DECL_OVERRIDE; QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE; QModelIndex mapFromSource(const QModelIndex &index) const Q_DECL_OVERRIDE; QModelIndex mapToSource(const QModelIndex &index) const Q_DECL_OVERRIDE; public Q_SLOTS: void rebuildMap(); private: void addMapEntry(const QModelIndex &); QList mList; }; class SelectionModel : public QItemSelectionModel { Q_OBJECT public: SelectionModel(QAbstractItemModel *model, QObject *parent); public Q_SLOTS: void clear() Q_DECL_OVERRIDE; void select(const QModelIndex &index, QItemSelectionModel::SelectionFlags command) Q_DECL_OVERRIDE; void select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) Q_DECL_OVERRIDE; }; } #endif diff --git a/src/kpagewidget.cpp b/src/kpagewidget.cpp index 044c1ef..91eb64e 100644 --- a/src/kpagewidget.cpp +++ b/src/kpagewidget.cpp @@ -1,144 +1,144 @@ /* This file is part of the KDE Libraries Copyright (C) 2006 Tobias Koenig (tokoe@kde.org) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kpagewidget.h" #include "kpagewidget_p.h" #include "kpagewidgetmodel.h" KPageWidgetPrivate::KPageWidgetPrivate(KPageWidget *q) : KPageViewPrivate(q) { } void KPageWidgetPrivate::_k_slotCurrentPageChanged(const QModelIndex ¤t, const QModelIndex &before) { - KPageWidgetItem *currentItem = 0; + KPageWidgetItem *currentItem = nullptr; if (current.isValid()) { currentItem = model()->item(current); } - KPageWidgetItem *beforeItem = 0; + KPageWidgetItem *beforeItem = nullptr; if (before.isValid()) { beforeItem = model()->item(before); } Q_Q(KPageWidget); emit q->currentPageChanged(currentItem, beforeItem); } KPageWidget::KPageWidget(KPageWidgetPrivate &dd, QWidget *parent) : KPageView(dd, parent) { Q_D(KPageWidget); connect(this, SIGNAL(currentPageChanged(QModelIndex,QModelIndex)), this, SLOT(_k_slotCurrentPageChanged(QModelIndex,QModelIndex))); if (!d->KPageViewPrivate::model) { setModel(new KPageWidgetModel(this)); } else { Q_ASSERT(qobject_cast(d->KPageViewPrivate::model)); } connect(d->model(), &KPageWidgetModel::toggled, this, &KPageWidget::pageToggled); } KPageWidget::KPageWidget(QWidget *parent) : KPageView(*new KPageWidgetPrivate(this), parent) { Q_D(KPageWidget); connect(this, SIGNAL(currentPageChanged(QModelIndex,QModelIndex)), this, SLOT(_k_slotCurrentPageChanged(QModelIndex,QModelIndex))); setModel(new KPageWidgetModel(this)); connect(d->model(), &KPageWidgetModel::toggled, this, &KPageWidget::pageToggled); } KPageWidget::~KPageWidget() { } KPageWidgetItem *KPageWidget::addPage(QWidget *widget, const QString &name) { // force layout margin to zero so that it aligns well with title widget if (widget->layout()) { widget->layout()->setMargin(0); } return d_func()->model()->addPage(widget, name); } void KPageWidget::addPage(KPageWidgetItem *item) { d_func()->model()->addPage(item); } KPageWidgetItem *KPageWidget::insertPage(KPageWidgetItem *before, QWidget *widget, const QString &name) { return d_func()->model()->insertPage(before, widget, name); } void KPageWidget::insertPage(KPageWidgetItem *before, KPageWidgetItem *item) { d_func()->model()->insertPage(before, item); } KPageWidgetItem *KPageWidget::addSubPage(KPageWidgetItem *parent, QWidget *widget, const QString &name) { return d_func()->model()->addSubPage(parent, widget, name); } void KPageWidget::addSubPage(KPageWidgetItem *parent, KPageWidgetItem *item) { d_func()->model()->addSubPage(parent, item); } void KPageWidget::removePage(KPageWidgetItem *item) { emit pageRemoved(item); // Q_EMIT signal before we remove it, because the item will be deleted in the model d_func()->model()->removePage(item); } void KPageWidget::setCurrentPage(KPageWidgetItem *item) { const QModelIndex index = d_func()->model()->index(item); if (!index.isValid()) { return; } KPageView::setCurrentPage(index); } KPageWidgetItem *KPageWidget::currentPage() const { const QModelIndex index = KPageView::currentPage(); if (!index.isValid()) { - return 0; + return nullptr; } return d_func()->model()->item(index); } #include "moc_kpagewidget.cpp" diff --git a/src/kpagewidget.h b/src/kpagewidget.h index 74c0efa..714a5c9 100644 --- a/src/kpagewidget.h +++ b/src/kpagewidget.h @@ -1,157 +1,157 @@ /* This file is part of the KDE Libraries Copyright (C) 2006 Tobias Koenig (tokoe@kde.org) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KPAGEWIDGET_H #define KPAGEWIDGET_H #include #include "kpageview.h" class KPageWidgetPrivate; /** * @short Page widget with many layouts (faces). * @see KPageView with hierarchical page model. * * @author Tobias Koenig (tokoe@kde.org) */ class KWIDGETSADDONS_EXPORT KPageWidget : public KPageView { Q_OBJECT Q_DECLARE_PRIVATE(KPageWidget) public: /** * Creates a new page widget. * * @param parent The parent widget. */ - explicit KPageWidget(QWidget *parent = 0); + explicit KPageWidget(QWidget *parent = nullptr); /** * Destroys the page widget. */ ~KPageWidget(); /** * Adds a new top level page to the widget. * * @param widget The widget of the page. * @param name The name which is displayed in the navigation view. * * @returns The associated @see KPageWidgetItem. */ KPageWidgetItem *addPage(QWidget *widget, const QString &name); /** * Adds a new top level page to the widget. * * @param item The @see KPageWidgetItem which describes the page. */ void addPage(KPageWidgetItem *item); /** * Inserts a new page in the widget. * * @param before The new page will be insert before this @see KPageWidgetItem * on the same level in hierarchy. * @param widget The widget of the page. * @param name The name which is displayed in the navigation view. * * @returns The associated @see KPageWidgetItem. */ KPageWidgetItem *insertPage(KPageWidgetItem *before, QWidget *widget, const QString &name); /** * Inserts a new page in the widget. * * @param before The new page will be insert before this @see KPageWidgetItem * on the same level in hierarchy. * * @param item The @see KPageWidgetItem which describes the page. */ void insertPage(KPageWidgetItem *before, KPageWidgetItem *item); /** * Inserts a new sub page in the widget. * * @param parent The new page will be insert as child of this @see KPageWidgetItem. * @param widget The widget of the page. * @param name The name which is displayed in the navigation view. * * @returns The associated @see KPageWidgetItem. */ KPageWidgetItem *addSubPage(KPageWidgetItem *parent, QWidget *widget, const QString &name); /** * Inserts a new sub page in the widget. * * @param parent The new page will be insert as child of this @see KPageWidgetItem. * * @param item The @see KPageWidgetItem which describes the page. */ void addSubPage(KPageWidgetItem *parent, KPageWidgetItem *item); /** * Removes the page associated with the given @see KPageWidgetItem. */ void removePage(KPageWidgetItem *item); /** * Sets the page which is associated with the given @see KPageWidgetItem to * be the current page and emits the currentPageChanged() signal. */ void setCurrentPage(KPageWidgetItem *item); /** * Returns the @see KPageWidgetItem for the current page or 0 if there is no * current page. */ KPageWidgetItem *currentPage() const; Q_SIGNALS: /** * This signal is emitted whenever the current page has changed. * * @param item The new current page or 0 if no current page is available. */ void currentPageChanged(KPageWidgetItem *current, KPageWidgetItem *before); /** * This signal is emitted whenever a checkable page changes its state. @param checked is true * when the @param page is checked, or false if the @param page is unchecked. */ void pageToggled(KPageWidgetItem *page, bool checked); /** * This signal is emitted when a page is removed. * @param page The page which is removed * */ void pageRemoved(KPageWidgetItem *page); protected: KPageWidget(KPageWidgetPrivate &dd, QWidget *parent); private: Q_PRIVATE_SLOT(d_func(), void _k_slotCurrentPageChanged(const QModelIndex &, const QModelIndex &)) }; #endif diff --git a/src/kpagewidgetmodel.cpp b/src/kpagewidgetmodel.cpp index 709e3d0..e1d4882 100644 --- a/src/kpagewidgetmodel.cpp +++ b/src/kpagewidgetmodel.cpp @@ -1,574 +1,574 @@ /* This file is part of the KDE Libraries Copyright (C) 2006 Tobias Koenig (tokoe@kde.org) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kpagewidgetmodel.h" #include "kpagewidgetmodel_p.h" #include "loggingcategory.h" #include #include #include class KPageWidgetItem::Private { public: Private() : checkable(false), checked(false), enabled(true) { } ~Private() { delete widget; - widget = 0; + widget = nullptr; } QString name; QString header; QIcon icon; QPointer widget; bool checkable : 1; bool checked : 1; bool enabled : 1; }; KPageWidgetItem::KPageWidgetItem(QWidget *widget) - : QObject(0), d(new Private) + : QObject(nullptr), d(new Private) { d->widget = widget; /** * Hide the widget, otherwise when the widget has this KPageView as * parent the widget is shown outside the QStackedWidget if the page * was not selected ( and reparented ) yet. */ if (d->widget) { d->widget->hide(); } } KPageWidgetItem::KPageWidgetItem(QWidget *widget, const QString &name) - : QObject(0), d(new Private) + : QObject(nullptr), d(new Private) { d->widget = widget; d->name = name; /** * Hide the widget, otherwise when the widget has this KPageView as * parent the widget is shown outside the QStackedWidget if the page * was not selected ( and reparented ) yet. */ if (d->widget) { d->widget->hide(); } } KPageWidgetItem::~KPageWidgetItem() { delete d; } void KPageWidgetItem::setEnabled(bool enabled) { d->enabled = enabled; if (d->widget) { d->widget->setEnabled(enabled); } emit changed(); } bool KPageWidgetItem::isEnabled() const { return d->enabled; } QWidget *KPageWidgetItem::widget() const { return d->widget; } void KPageWidgetItem::setName(const QString &name) { d->name = name; emit changed(); } QString KPageWidgetItem::name() const { return d->name; } void KPageWidgetItem::setHeader(const QString &header) { d->header = header; emit changed(); } QString KPageWidgetItem::header() const { return d->header; } void KPageWidgetItem::setIcon(const QIcon &icon) { d->icon = icon; emit changed(); } QIcon KPageWidgetItem::icon() const { return d->icon; } void KPageWidgetItem::setCheckable(bool checkable) { d->checkable = checkable; emit changed(); } bool KPageWidgetItem::isCheckable() const { return d->checkable; } void KPageWidgetItem::setChecked(bool checked) { d->checked = checked; emit toggled(checked); emit changed(); } bool KPageWidgetItem::isChecked() const { return d->checked; } PageItem::PageItem(KPageWidgetItem *pageWidgetItem, PageItem *parent) : mPageWidgetItem(pageWidgetItem), mParentItem(parent) { } PageItem::~PageItem() { delete mPageWidgetItem; - mPageWidgetItem = 0; + mPageWidgetItem = nullptr; qDeleteAll(mChildItems); } void PageItem::appendChild(PageItem *item) { mChildItems.append(item); } void PageItem::insertChild(int row, PageItem *item) { mChildItems.insert(row, item); } void PageItem::removeChild(int row) { mChildItems.removeAt(row); } PageItem *PageItem::child(int row) { return mChildItems.value(row); } int PageItem::childCount() const { return mChildItems.count(); } int PageItem::columnCount() const { return 1; } PageItem *PageItem::parent() { return mParentItem; } int PageItem::row() const { if (mParentItem) { return mParentItem->mChildItems.indexOf(const_cast(this)); } return 0; } KPageWidgetItem *PageItem::pageWidgetItem() const { return mPageWidgetItem; } PageItem *PageItem::findChild(const KPageWidgetItem *item) { if (mPageWidgetItem == item) { return this; } for (int i = 0; i < mChildItems.count(); ++i) { PageItem *pageItem = mChildItems[ i ]->findChild(item); if (pageItem) { return pageItem; } } - return 0; + return nullptr; } void PageItem::dump(int indent) { QString prefix; for (int i = 0; i < indent; ++i) { prefix.append(QStringLiteral(" ")); } const QString name = (mPageWidgetItem ? mPageWidgetItem->name() : QStringLiteral("root")); qCDebug(KWidgetsAddonsLog, "%s (%p)", qPrintable(QString(QStringLiteral("%1%2")).arg(prefix, name)), (void *)this); for (int i = 0; i < mChildItems.count(); ++i) { mChildItems[ i ]->dump(indent + 2); } } KPageWidgetModel::KPageWidgetModel(QObject *parent) : KPageModel(*new KPageWidgetModelPrivate, parent) { } KPageWidgetModel::~KPageWidgetModel() { } int KPageWidgetModel::columnCount(const QModelIndex &) const { return 1; } QVariant KPageWidgetModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) { return QVariant(); } PageItem *item = static_cast(index.internalPointer()); if (role == Qt::DisplayRole) { return QVariant(item->pageWidgetItem()->name()); } else if (role == Qt::DecorationRole) { return QVariant(item->pageWidgetItem()->icon()); } else if (role == HeaderRole) { return QVariant(item->pageWidgetItem()->header()); } else if (role == WidgetRole) { return QVariant::fromValue(item->pageWidgetItem()->widget()); } else if (role == Qt::CheckStateRole) { if (item->pageWidgetItem()->isCheckable()) { return (item->pageWidgetItem()->isChecked() ? Qt::Checked : Qt::Unchecked); } else { return QVariant(); } } else { return QVariant(); } } bool KPageWidgetModel::setData(const QModelIndex &index, const QVariant &value, int role) { if (!index.isValid()) { return false; } if (role != Qt::CheckStateRole) { return false; } PageItem *item = static_cast(index.internalPointer()); if (!item) { return false; } if (!item->pageWidgetItem()->isCheckable()) { return false; } if (value.toInt() == Qt::Checked) { item->pageWidgetItem()->setChecked(true); } else { item->pageWidgetItem()->setChecked(false); } return true; } Qt::ItemFlags KPageWidgetModel::flags(const QModelIndex &index) const { if (!index.isValid()) { - return 0; + return nullptr; } Qt::ItemFlags flags = Qt::ItemIsSelectable; PageItem *item = static_cast(index.internalPointer()); if (item->pageWidgetItem()->isCheckable()) { flags |= Qt::ItemIsUserCheckable; } if (item->pageWidgetItem()->isEnabled()) { flags |= Qt::ItemIsEnabled; } return flags; } QModelIndex KPageWidgetModel::index(int row, int column, const QModelIndex &parent) const { PageItem *parentItem; if (parent.isValid()) { parentItem = static_cast(parent.internalPointer()); } else { parentItem = d_func()->rootItem; } PageItem *childItem = parentItem->child(row); if (childItem) { return createIndex(row, column, childItem); } else { return QModelIndex(); } } QModelIndex KPageWidgetModel::parent(const QModelIndex &index) const { if (!index.isValid()) { return QModelIndex(); } PageItem *item = static_cast(index.internalPointer()); PageItem *parentItem = item->parent(); if (parentItem == d_func()->rootItem) { return QModelIndex(); } else { return createIndex(parentItem->row(), 0, parentItem); } } int KPageWidgetModel::rowCount(const QModelIndex &parent) const { PageItem *parentItem; if (!parent.isValid()) { parentItem = d_func()->rootItem; } else { parentItem = static_cast(parent.internalPointer()); } return parentItem->childCount(); } KPageWidgetItem *KPageWidgetModel::addPage(QWidget *widget, const QString &name) { KPageWidgetItem *item = new KPageWidgetItem(widget, name); addPage(item); return item; } void KPageWidgetModel::addPage(KPageWidgetItem *item) { emit layoutAboutToBeChanged(); Q_D(KPageWidgetModel); connect(item, SIGNAL(changed()), this, SLOT(_k_itemChanged())); connect(item, SIGNAL(toggled(bool)), this, SLOT(_k_itemToggled(bool))); // The row to be inserted int row = d->rootItem->childCount(); beginInsertRows(QModelIndex(), row, row); PageItem *pageItem = new PageItem(item, d->rootItem); d->rootItem->appendChild(pageItem); endInsertRows(); emit layoutChanged(); } KPageWidgetItem *KPageWidgetModel::insertPage(KPageWidgetItem *before, QWidget *widget, const QString &name) { KPageWidgetItem *item = new KPageWidgetItem(widget, name); insertPage(before, item); return item; } void KPageWidgetModel::insertPage(KPageWidgetItem *before, KPageWidgetItem *item) { PageItem *beforePageItem = d_func()->rootItem->findChild(before); if (!beforePageItem) { qCDebug(KWidgetsAddonsLog, "Invalid KPageWidgetItem passed!"); return; } emit layoutAboutToBeChanged(); connect(item, SIGNAL(changed()), this, SLOT(_k_itemChanged())); connect(item, SIGNAL(toggled(bool)), this, SLOT(_k_itemToggled(bool))); PageItem *parent = beforePageItem->parent(); // The row to be inserted int row = beforePageItem->row(); QModelIndex index; if (parent != d_func()->rootItem) { index = createIndex(parent->row(), 0, parent); } beginInsertRows(index, row, row); PageItem *newPageItem = new PageItem(item, parent); parent->insertChild(row, newPageItem); endInsertRows(); emit layoutChanged(); } KPageWidgetItem *KPageWidgetModel::addSubPage(KPageWidgetItem *parent, QWidget *widget, const QString &name) { KPageWidgetItem *item = new KPageWidgetItem(widget, name); addSubPage(parent, item); return item; } void KPageWidgetModel::addSubPage(KPageWidgetItem *parent, KPageWidgetItem *item) { PageItem *parentPageItem = d_func()->rootItem->findChild(parent); if (!parentPageItem) { qCDebug(KWidgetsAddonsLog, "Invalid KPageWidgetItem passed!"); return; } emit layoutAboutToBeChanged(); connect(item, SIGNAL(changed()), this, SLOT(_k_itemChanged())); connect(item, SIGNAL(toggled(bool)), this, SLOT(_k_itemToggled(bool))); // The row to be inserted int row = parentPageItem->childCount(); QModelIndex index; if (parentPageItem != d_func()->rootItem) { index = createIndex(parentPageItem->row(), 0, parentPageItem); } beginInsertRows(index, row, row); PageItem *newPageItem = new PageItem(item, parentPageItem); parentPageItem->appendChild(newPageItem); endInsertRows(); emit layoutChanged(); } void KPageWidgetModel::removePage(KPageWidgetItem *item) { if (!item) { return; } Q_D(KPageWidgetModel); PageItem *pageItem = d->rootItem->findChild(item); if (!pageItem) { qCDebug(KWidgetsAddonsLog, "Invalid KPageWidgetItem passed!"); return; } emit layoutAboutToBeChanged(); disconnect(item, SIGNAL(changed()), this, SLOT(_k_itemChanged())); disconnect(item, SIGNAL(toggled(bool)), this, SLOT(_k_itemToggled(bool))); PageItem *parentPageItem = pageItem->parent(); int row = parentPageItem->row(); QModelIndex index; if (parentPageItem != d->rootItem) { index = createIndex(row, 0, parentPageItem); } beginRemoveRows(index, pageItem->row(), pageItem->row()); parentPageItem->removeChild(pageItem->row()); delete pageItem; endRemoveRows(); emit layoutChanged(); } KPageWidgetItem *KPageWidgetModel::item(const QModelIndex &index) const { if (!index.isValid()) { - return 0; + return nullptr; } PageItem *item = static_cast(index.internalPointer()); if (!item) { - return 0; + return nullptr; } return item->pageWidgetItem(); } QModelIndex KPageWidgetModel::index(const KPageWidgetItem *item) const { if (!item) { return QModelIndex(); } const PageItem *pageItem = d_func()->rootItem->findChild(item); if (!pageItem) { return QModelIndex(); } return createIndex(pageItem->row(), 0, (void *)pageItem); } #include "moc_kpagewidgetmodel.cpp" diff --git a/src/kpagewidgetmodel.h b/src/kpagewidgetmodel.h index fd20970..9a1f946 100644 --- a/src/kpagewidgetmodel.h +++ b/src/kpagewidgetmodel.h @@ -1,302 +1,302 @@ /* This file is part of the KDE Libraries Copyright (C) 2006 Tobias Koenig (tokoe@kde.org) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KPAGEWIDGETMODEL_H #define KPAGEWIDGETMODEL_H #include "kpagemodel.h" class QWidget; /** * KPageWidgetItem is used by @ref KPageWidget and represents * a page. * * Example:\n * * \code * ColorPage *page = new ColorPage; * * KPageWidgetItem *item = new KPageWidgetItem( page, i18n( "Colors" ) ); * item->setHeader( i18n( "Colors of Main Window" ) ); * item->setIcon( QIcon::fromTheme( "colors" ) ); * * KPageWidget *pageWidget = new KPageWidget( this ); * pageWidget->addPage( item ); * \endcode * * @author Tobias Koenig (tokoe@kde.org) */ class KWIDGETSADDONS_EXPORT KPageWidgetItem : public QObject { Q_OBJECT Q_PROPERTY(QString name READ name WRITE setName) Q_PROPERTY(QString header READ header WRITE setHeader) Q_PROPERTY(QIcon icon READ icon WRITE setIcon) Q_PROPERTY(bool checkable READ isCheckable WRITE setCheckable) Q_PROPERTY(bool checked READ isChecked WRITE setChecked) /** * This property holds whether the item is enabled. * * It dis-/enables both the widget and the item in the list-/treeview. */ Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled) public: /** * Creates a new page widget item. * * @param widget The widget that is shown as page in the KPageWidget. */ KPageWidgetItem(QWidget *widget); /** * Creates a new page widget item. * * @param widget The widget that is shown as page in the KPageWidget. * @param name The localized string that is show in the navigation view * of the KPageWidget. */ KPageWidgetItem(QWidget *widget, const QString &name); /** * Destroys the page widget item. */ ~KPageWidgetItem(); /** * Returns the widget of the page widget item. */ QWidget *widget() const; /** * Sets the name of the item as shown in the navigation view of the page * widget. */ void setName(const QString &name); /** * Returns the name of the page widget item. */ QString name() const; /** * Sets the header of the page widget item. * * If setHeader(QString()) is used, what is the default if the header * does not got set explicit, then the defined name() will also be used * for the header. If setHeader("") is used, the header will be hidden * even if the @a KPageView::FaceType is something else then Tabbed. * * @param header Header of the page widget item. */ void setHeader(const QString &header); /** * Returns the header of the page widget item. */ QString header() const; /** * Sets the icon of the page widget item. * @param icon Icon of the page widget item. */ void setIcon(const QIcon &icon); /** * Returns the icon of the page widget item. */ QIcon icon() const; /** * Sets whether the page widget item is checkable in the view. * @param checkable True if the page widget is checkable, * otherwise false. */ void setCheckable(bool checkable); /** * Returns whether the page widget item is checkable. */ bool isCheckable() const; /** * Returns whether the page widget item is checked. */ bool isChecked() const; /** * Returns whether the page widget item is enabled. */ bool isEnabled() const; public Q_SLOTS: /** * Sets whether the page widget item is enabled. */ void setEnabled(bool); /** * Sets whether the page widget item is checked. */ void setChecked(bool checked); Q_SIGNALS: /** * This signal is emitted whenever the icon or header * is changed. */ void changed(); /** * This signal is emitted whenever the user checks or * unchecks the item of @see setChecked() is called. */ void toggled(bool checked); private: class Private; Private *const d; }; class KPageWidgetModelPrivate; /** * This page model is used by @see KPageWidget to provide * a hierarchical layout of pages. */ class KWIDGETSADDONS_EXPORT KPageWidgetModel : public KPageModel { Q_OBJECT Q_DECLARE_PRIVATE(KPageWidgetModel) public: /** * Creates a new page widget model. * * @param parent The parent object. */ - explicit KPageWidgetModel(QObject *parent = 0); + explicit KPageWidgetModel(QObject *parent = nullptr); /** * Destroys the page widget model. */ ~KPageWidgetModel(); /** * Adds a new top level page to the model. * * @param widget The widget of the page. * @param name The name which is displayed in the navigation view. * * @returns The associated @see KPageWidgetItem. */ KPageWidgetItem *addPage(QWidget *widget, const QString &name); /** * Adds a new top level page to the model. * * @param item The @see KPageWidgetItem which describes the page. */ void addPage(KPageWidgetItem *item); /** * Inserts a new page in the model. * * @param before The new page will be insert before this @see KPageWidgetItem * on the same level in hierarchy. * @param widget The widget of the page. * @param name The name which is displayed in the navigation view. * * @returns The associated @see KPageWidgetItem. */ KPageWidgetItem *insertPage(KPageWidgetItem *before, QWidget *widget, const QString &name); /** * Inserts a new page in the model. * * @param before The new page will be insert before this @see KPageWidgetItem * on the same level in hierarchy. * * @param item The @see KPageWidgetItem which describes the page. */ void insertPage(KPageWidgetItem *before, KPageWidgetItem *item); /** * Inserts a new sub page in the model. * * @param parent The new page will be insert as child of this @see KPageWidgetItem. * @param widget The widget of the page. * @param name The name which is displayed in the navigation view. * * @returns The associated @see KPageWidgetItem. */ KPageWidgetItem *addSubPage(KPageWidgetItem *parent, QWidget *widget, const QString &name); /** * Inserts a new sub page in the model. * * @param parent The new page will be insert as child of this @see KPageWidgetItem. * * @param item The @see KPageWidgetItem which describes the page. */ void addSubPage(KPageWidgetItem *parent, KPageWidgetItem *item); /** * Removes the page associated with the given @see KPageWidgetItem. */ void removePage(KPageWidgetItem *item); /** * These methods are reimplemented from QAbstractItemModel. */ int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) Q_DECL_OVERRIDE; Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE; QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; QModelIndex parent(const QModelIndex &index) const Q_DECL_OVERRIDE; int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; /** * Returns the @see KPageWidgetItem for a given index or 0 if the index is invalid. */ KPageWidgetItem *item(const QModelIndex &index) const; /** * Returns the index for a given @see KPageWidgetItem. The index is invalid if the * item can't be found in the model. */ QModelIndex index(const KPageWidgetItem *item) const; Q_SIGNALS: /** * This signal is emitted whenever a checkable page changes its state. @param checked is true * when the @param page is checked, or false if the @param page is unchecked. */ void toggled(KPageWidgetItem *page, bool checked); private: Q_PRIVATE_SLOT(d_func(), void _k_itemChanged()) Q_PRIVATE_SLOT(d_func(), void _k_itemToggled(bool)) }; #endif diff --git a/src/kpagewidgetmodel_p.h b/src/kpagewidgetmodel_p.h index 7fd179a..e739e33 100644 --- a/src/kpagewidgetmodel_p.h +++ b/src/kpagewidgetmodel_p.h @@ -1,100 +1,100 @@ /* This file is part of the KDE project Copyright (C) 2007 Matthias Kretz This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KPAGEWIDGETMODEL_P_H #define KPAGEWIDGETMODEL_P_H #include "kpagemodel_p.h" #include "kpagewidgetmodel.h" class PageItem { public: - explicit PageItem(KPageWidgetItem *pageItem, PageItem *parent = 0); + explicit PageItem(KPageWidgetItem *pageItem, PageItem *parent = nullptr); ~PageItem(); void appendChild(PageItem *child); void insertChild(int row, PageItem *child); void removeChild(int row); PageItem *child(int row); int childCount() const; int columnCount() const; int row() const; PageItem *parent(); KPageWidgetItem *pageWidgetItem() const; PageItem *findChild(const KPageWidgetItem *item); void dump(int indent = 0); private: KPageWidgetItem *mPageWidgetItem; QList mChildItems; PageItem *mParentItem; }; class KPageWidgetModelPrivate : public KPageModelPrivate { Q_DECLARE_PUBLIC(KPageWidgetModel) protected: KPageWidgetModelPrivate() - : rootItem(new PageItem(0, 0)) + : rootItem(new PageItem(nullptr, nullptr)) { } ~KPageWidgetModelPrivate() { delete rootItem; - rootItem = 0; + rootItem = nullptr; } PageItem *rootItem; void _k_itemChanged() { Q_Q(KPageWidgetModel); KPageWidgetItem *item = qobject_cast(q->sender()); if (!item) { return; } const QModelIndex index = q->index(item); if (!index.isValid()) { return; } emit q->dataChanged(index, index); } void _k_itemToggled(bool checked) { Q_Q(KPageWidgetModel); KPageWidgetItem *item = qobject_cast(q->sender()); if (!item) { return; } emit q->toggled(item, checked); } }; #endif // KPAGEWIDGETMODEL_P_H diff --git a/src/kpassworddialog.cpp b/src/kpassworddialog.cpp index 91538ab..6a37d43 100644 --- a/src/kpassworddialog.cpp +++ b/src/kpassworddialog.cpp @@ -1,444 +1,444 @@ /* This file is part of the KDE libraries Copyright (C) 2000 David Faure Copyright (C) 2007 Olivier Goffart This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kpassworddialog.h" #include #include #include #include #include #include #include #include #include #include #include "ui_kpassworddialog.h" /** @internal */ class KPasswordDialog::KPasswordDialogPrivate { public: KPasswordDialogPrivate(KPasswordDialog *q) : q(q), - userEditCombo(0), - pixmapLabel(0), + userEditCombo(nullptr), + pixmapLabel(nullptr), commentRow(0), isToggleEchoModeAvailable(true) {} void actuallyAccept(); void activated(const QString &userName); void updateFields(); void init(); void toggleEchoMode(); void showToggleEchoModeAction(const QString &text); KPasswordDialog *q; Ui_KPasswordDialog ui; QMap knownLogins; QComboBox *userEditCombo; QLabel *pixmapLabel; KPasswordDialogFlags m_flags; unsigned int commentRow; QAction *toggleEchoModeAction; bool isToggleEchoModeAvailable; }; KPasswordDialog::KPasswordDialog(QWidget *parent, const KPasswordDialogFlags &flags) : QDialog(parent), d(new KPasswordDialogPrivate(this)) { setWindowTitle(tr("Password")); setWindowIcon(QIcon::fromTheme(QStringLiteral("dialog-password"), windowIcon())); d->m_flags = flags; d->init(); } KPasswordDialog::~KPasswordDialog() { delete d; } void KPasswordDialog::KPasswordDialogPrivate::updateFields() { if (m_flags & KPasswordDialog::UsernameReadOnly) { ui.userEdit->setReadOnly(true); ui.credentialsGroup->setFocusProxy(ui.passEdit); } ui.domainEdit->setReadOnly((m_flags & KPasswordDialog::DomainReadOnly)); ui.credentialsGroup->setEnabled(!q->anonymousMode()); } void KPasswordDialog::KPasswordDialogPrivate::init() { ui.setupUi(q); ui.buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); ui.errorMessage->setHidden(true); // Row 4: Username field if (m_flags & KPasswordDialog::ShowUsernameLine) { ui.userEdit->setFocus(); ui.credentialsGroup->setFocusProxy(ui.userEdit); QObject::connect(ui.userEdit, SIGNAL(returnPressed()), ui.passEdit, SLOT(setFocus())); } else { ui.userNameLabel->hide(); ui.userEdit->hide(); ui.domainLabel->hide(); ui.domainEdit->hide(); ui.passEdit->setFocus(); ui.credentialsGroup->setFocusProxy(ui.passEdit); } if (!(m_flags & KPasswordDialog::ShowAnonymousLoginCheckBox)) { ui.anonymousRadioButton->hide(); ui.usePasswordButton->hide(); } if (!(m_flags & KPasswordDialog::ShowDomainLine)) { ui.domainLabel->hide(); ui.domainEdit->hide(); } if (!(m_flags & KPasswordDialog::ShowKeepPassword)) { ui.keepCheckBox->hide(); } updateFields(); QIcon visibilityIcon = QIcon::fromTheme(QStringLiteral("visibility"), QIcon(QStringLiteral(":/icons/visibility.svg"))); toggleEchoModeAction = ui.passEdit->addAction(visibilityIcon, QLineEdit::TrailingPosition); toggleEchoModeAction->setVisible(false); toggleEchoModeAction->setToolTip(tr("Change the visibility of the password")); connect(toggleEchoModeAction, SIGNAL(triggered(bool)), q, SLOT(toggleEchoMode())); connect(ui.passEdit, SIGNAL(textChanged(QString)), q, SLOT(showToggleEchoModeAction(QString))); QRect desktop = QApplication::desktop()->screenGeometry(q->topLevelWidget()); q->setMinimumWidth(qMin(1000, qMax(q->sizeHint().width(), desktop.width() / 4))); QStyleOption option; option.initFrom(q); const int iconSize = q->style()->pixelMetric(QStyle::PM_MessageBoxIconSize, &option, q); q->setPixmap(QIcon::fromTheme(QStringLiteral("dialog-password")).pixmap(iconSize)); } void KPasswordDialog::KPasswordDialogPrivate::toggleEchoMode() { if (ui.passEdit->echoMode() == QLineEdit::Password) { ui.passEdit->setEchoMode(QLineEdit::Normal); toggleEchoModeAction->setIcon(QIcon::fromTheme(QStringLiteral("hint"), QIcon(QStringLiteral(":/icons/hint.svg")))); } else if (ui.passEdit->echoMode() == QLineEdit::Normal) { ui.passEdit->setEchoMode(QLineEdit::Password); toggleEchoModeAction->setIcon(QIcon::fromTheme(QStringLiteral("visibility"), QIcon(QStringLiteral(":/icons/visibility.svg")))); } } void KPasswordDialog::KPasswordDialogPrivate::showToggleEchoModeAction(const QString &text) { toggleEchoModeAction->setVisible(isToggleEchoModeAvailable && !text.isEmpty()); } void KPasswordDialog::setPixmap(const QPixmap &pixmap) { if (!d->pixmapLabel) { d->pixmapLabel = new QLabel(this); d->pixmapLabel->setAlignment(Qt::AlignLeft | Qt::AlignTop); d->ui.hboxLayout->insertWidget(0, d->pixmapLabel); } d->pixmapLabel->setPixmap(pixmap); } QPixmap KPasswordDialog::pixmap() const { if (!d->pixmapLabel) { return QPixmap(); } return *d->pixmapLabel->pixmap(); } void KPasswordDialog::setUsername(const QString &user) { d->ui.userEdit->setText(user); if (user.isEmpty()) { return; } d->activated(user); if (d->ui.userEdit->isVisibleTo(this)) { d->ui.passEdit->setFocus(); } } QString KPasswordDialog::username() const { return d->ui.userEdit->text(); } QString KPasswordDialog::password() const { return d->ui.passEdit->text(); } void KPasswordDialog::setDomain(const QString &domain) { d->ui.domainEdit->setText(domain); } QString KPasswordDialog::domain() const { return d->ui.domainEdit->text(); } void KPasswordDialog::setAnonymousMode(bool anonymous) { if (anonymous && !(d->m_flags & KPasswordDialog::ShowAnonymousLoginCheckBox)) { // This is an error case, but we can at least let user see what's about // to happen if they proceed. d->ui.anonymousRadioButton->setVisible(true); d->ui.usePasswordButton->setVisible(true); d->ui.usePasswordButton->setEnabled(false); } d->ui.anonymousRadioButton->setChecked(anonymous); } bool KPasswordDialog::anonymousMode() const { return d->ui.anonymousRadioButton->isChecked(); } void KPasswordDialog::setKeepPassword(bool b) { d->ui.keepCheckBox->setChecked(b); } bool KPasswordDialog::keepPassword() const { return d->ui.keepCheckBox->isChecked(); } void KPasswordDialog::addCommentLine(const QString &label, const QString &comment) { int gridMarginLeft, gridMarginTop, gridMarginRight, gridMarginBottom; d->ui.formLayout->getContentsMargins(&gridMarginLeft, &gridMarginTop, &gridMarginRight, &gridMarginBottom); int spacing = d->ui.formLayout->horizontalSpacing(); if (spacing < 0) { // same inter-column spacing for all rows, see comment in qformlayout.cpp - spacing = style()->combinedLayoutSpacing(QSizePolicy::Label, QSizePolicy::LineEdit, Qt::Horizontal, 0, this); + spacing = style()->combinedLayoutSpacing(QSizePolicy::Label, QSizePolicy::LineEdit, Qt::Horizontal, nullptr, this); } QLabel *c = new QLabel(comment, this); c->setWordWrap(true); d->ui.formLayout->insertRow(d->commentRow, label, c); ++d->commentRow; // cycle through column 0 widgets and see the max width so we can set the minimum height of // column 2 wordwrapable labels int firstColumnWidth = 0; for (int i = 0; i < d->ui.formLayout->rowCount(); ++i) { QLayoutItem *li = d->ui.formLayout->itemAt(i, QFormLayout::LabelRole); if (li) { QWidget *w = li->widget(); if (w && !w->isHidden()) { firstColumnWidth = qMax(firstColumnWidth, w->sizeHint().width()); } } } for (int i = 0; i < d->ui.formLayout->rowCount(); ++i) { QLayoutItem *li = d->ui.formLayout->itemAt(i, QFormLayout::FieldRole); if (li) { QLabel *l = qobject_cast(li->widget()); if (l && l->wordWrap()) { const int marginHint = style()->pixelMetric(QStyle::PM_DefaultChildMargin); int w = sizeHint().width() - firstColumnWidth - (2 * marginHint) - gridMarginLeft - gridMarginRight - spacing; l->setMinimumSize(w, l->heightForWidth(w)); } } } } void KPasswordDialog::showErrorMessage(const QString &message, const ErrorType type) { d->ui.errorMessage->setText(message, KTitleWidget::ErrorMessage); QFont bold = font(); bold.setBold(true); switch (type) { case PasswordError: d->ui.passwordLabel->setFont(bold); d->ui.passEdit->clear(); d->ui.passEdit->setFocus(); break; case UsernameError: if (d->ui.userEdit->isVisibleTo(this)) { d->ui.userNameLabel->setFont(bold); d->ui.userEdit->setFocus(); } break; case DomainError: if (d->ui.domainEdit->isVisibleTo(this)) { d->ui.domainLabel->setFont(bold); d->ui.domainEdit->setFocus(); } break; case FatalError: d->ui.userNameLabel->setEnabled(false); d->ui.userEdit->setEnabled(false); d->ui.passwordLabel->setEnabled(false); d->ui.passEdit->setEnabled(false); d->ui.keepCheckBox->setEnabled(false); d->ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); break; default: break; } adjustSize(); } void KPasswordDialog::setPrompt(const QString &prompt) { d->ui.prompt->setText(prompt); d->ui.prompt->setWordWrap(true); const int marginHint = style()->pixelMetric(QStyle::PM_DefaultChildMargin); d->ui.prompt->setMinimumHeight(d->ui.prompt->heightForWidth(width() - (2 * marginHint))); } QString KPasswordDialog::prompt() const { return d->ui.prompt->text(); } void KPasswordDialog::setPassword(const QString &p) { d->isToggleEchoModeAvailable = p.isEmpty(); d->ui.passEdit->setText(p); } void KPasswordDialog::setUsernameReadOnly(bool readOnly) { d->ui.userEdit->setReadOnly(readOnly); if (readOnly && d->ui.userEdit->hasFocus()) { d->ui.passEdit->setFocus(); } } void KPasswordDialog::setKnownLogins(const QMap &knownLogins) { const int nr = knownLogins.count(); if (nr == 0) { return; } if (nr == 1) { d->ui.userEdit->setText(knownLogins.begin().key()); setPassword(knownLogins.begin().value()); return; } Q_ASSERT(!d->ui.userEdit->isReadOnly()); if (!d->userEditCombo) { int row = -1; QFormLayout::ItemRole userEditRole = QFormLayout::FieldRole; d->ui.formLayout->getWidgetPosition(d->ui.userEdit, &row, &userEditRole); d->ui.formLayout->removeWidget(d->ui.userEdit); delete d->ui.userEdit; d->userEditCombo = new QComboBox(d->ui.credentialsGroup); d->userEditCombo->setEditable(true); d->ui.userEdit = d->userEditCombo->lineEdit(); d->ui.userNameLabel->setBuddy(d->userEditCombo); d->ui.formLayout->setWidget(row > -1 ? row : 0, userEditRole, d->userEditCombo); setTabOrder(d->ui.userEdit, d->ui.anonymousRadioButton); setTabOrder(d->ui.anonymousRadioButton, d->ui.domainEdit); setTabOrder(d->ui.domainEdit, d->ui.passEdit); setTabOrder(d->ui.passEdit, d->ui.keepCheckBox); connect(d->ui.userEdit, SIGNAL(returnPressed()), d->ui.passEdit, SLOT(setFocus())); } d->knownLogins = knownLogins; d->userEditCombo->addItems(knownLogins.keys()); d->userEditCombo->setFocus(); connect(d->userEditCombo, SIGNAL(activated(QString)), this, SLOT(activated(QString))); } void KPasswordDialog::KPasswordDialogPrivate::activated(const QString &userName) { QMap::ConstIterator it = knownLogins.constFind(userName); if (it != knownLogins.constEnd()) { q->setPassword(it.value()); } } void KPasswordDialog::accept() { if (!d->ui.errorMessage->isHidden()) { d->ui.errorMessage->setText(QString()); } // reset the font in case we had an error previously if (!d->ui.passwordLabel->isHidden()) { d->ui.passwordLabel->setFont(font()); d->ui.userNameLabel->setFont(font()); } // we do this to allow the error message, if any, to go away // checkPassword() may block for a period of time QTimer::singleShot(0, this, SLOT(actuallyAccept())); } void KPasswordDialog::KPasswordDialogPrivate::actuallyAccept() { if (!q->checkPassword()) { return; } bool keep = ui.keepCheckBox->isVisibleTo(q) && ui.keepCheckBox->isChecked(); emit q->gotPassword(q->password(), keep); if (ui.userEdit->isVisibleTo(q)) { emit q->gotUsernameAndPassword(q->username(), q->password(), keep); } q->QDialog::accept(); } bool KPasswordDialog::checkPassword() { return true; } QDialogButtonBox *KPasswordDialog::buttonBox() const { return d->ui.buttonBox; } #include "moc_kpassworddialog.cpp" diff --git a/src/kpassworddialog.h b/src/kpassworddialog.h index cebe11a..3bae80d 100644 --- a/src/kpassworddialog.h +++ b/src/kpassworddialog.h @@ -1,322 +1,322 @@ /* This file is part of the KDE libraries Copyright (C) 2000 David Faure Copyright (C) 2000 Dawit Alemayehu Copyright (C) 2007 Olivier Goffart This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KPASSWORDDIALOG_H #define KPASSWORDDIALOG_H #include #include #include #include /** * A dialog for requesting a password and optionaly a login from the end user. * * \section usage Usage Example * * Requesting a simple password, assynchronous * * \code * KPasswordDialog *dlg = new KPasswordDialog( parent ); * dlg->setPrompt(i18n("Enter a password")); * connect( dlg, SIGNAL( gotPassword( const QString& , bool ) ) , this, SLOT( setPassword( const QString &) ) ); * connect( dlg, SIGNAL( rejected() ) , this, SLOT( slotCancel() ) ); * dlg->show(); * \endcode * * Requesting a login and a password, synchronous * * \code * KPasswordDialog dlg(parent, KPasswordDialog::ShowUsernameLine); * dlg.setPrompt(i18n("Enter a login and a password")); * if( !dlg.exec() ) * return; //the user canceled * use( dlg.username() , dlg.password() ); * \endcode * * \image html kpassworddialog.png "KDE Password Dialog" * * @short dialog for requesting login and password from the end user */ class KWIDGETSADDONS_EXPORT KPasswordDialog : public QDialog { Q_OBJECT public: enum KPasswordDialogFlag { NoFlags = 0x00, /** * If this flag is set, the "keep this password" checkbox will been shown, * otherwise, it will not be shown and keepPassword will have no effect */ ShowKeepPassword = 0x01, /** * If this flag is set, there will be an additional line to let the user enter his login. * otherwise, only the password line will be shown. */ ShowUsernameLine = 0x02, /** * If this flag is set, the login lineedit will be in read only mode. */ UsernameReadOnly = 0x04, /** * If this flag is set, the Anonymous Login checkbox will be displayed * @since 4.1 */ ShowAnonymousLoginCheckBox = 0x08, /** * If this flag is set, there will be an additional line to let the user enter the domain. * @since 4.1 */ ShowDomainLine = 0x10, /** * If this flag is set, the domain lineedit will be in read only mode. * @since 4.1 */ DomainReadOnly = 0x20 }; Q_DECLARE_FLAGS(KPasswordDialogFlags, KPasswordDialogFlag) enum ErrorType { UnknownError = 0, /** * A problem with the user name as entered **/ UsernameError, /** * Incorrect password */ PasswordError, /** * Error preventing further attempts, will result in disabling most of the interface */ FatalError, /** * A problem with the domain as entered * @since 4.1 **/ DomainError }; /** * create a password dialog * * @param parent the parent widget (default:NULL). * @param flags a set of KPasswordDialogFlag flags */ - explicit KPasswordDialog(QWidget *parent = 0L, - const KPasswordDialogFlags &flags = 0); + explicit KPasswordDialog(QWidget *parent = nullptr, + const KPasswordDialogFlags &flags = nullptr); /** * Destructor */ ~KPasswordDialog(); /** * Sets the prompt to show to the user. * @param prompt instructional text to be shown. */ void setPrompt(const QString &prompt); /** * Returns the prompt */ QString prompt() const; /** * set an image that appears next to the prompt. */ void setPixmap(const QPixmap &); /** * */ QPixmap pixmap() const; /** * Adds a comment line to the dialog. * * This function allows you to add one additional comment * line to this widget. Calling this function after a * comment has already been added will not have any effect. * * @param label label for comment (ex:"Command:") * @param comment the actual comment text. */ void addCommentLine(const QString &label, const QString &comment); /** * Shows an error message in the dialog box. Prevents having to show a dialog-on-a-dialog. * * @param message the error message to show */ void showErrorMessage(const QString &message, const ErrorType type = PasswordError); /** * Returns the password entered by the user. * @return the password */ QString password() const; /** * set the default username. */ void setUsername(const QString &); /** * Returns the username entered by the user. * @return the user name */ QString username() const; /** * set the default domain. * @since 4.1 */ void setDomain(const QString &); /** * Returns the domain entered by the user. * @return the domain name * @since 4.1 */ QString domain() const; /** * set anonymous mode (all other fields will be grayed out) * @since 4.1 */ void setAnonymousMode(bool anonymous); /** * @return anonymous mode has been selected. * @since 4.1 */ bool anonymousMode() const; /** * Determines whether supplied authorization should * persist even after the application has been closed. * * this is set with the check password checkbox is the ShowKeepCheckBox flag * is set in the constructor, if it is not set, this function return false * * @return true to keep the password */ bool keepPassword() const; /** * Check or uncheck the "keep password" checkbox. * This can be used to check it before showing the dialog, to tell * the user that the password is stored already (e.g. in the wallet). * enableKeep must have been set to true in the constructor. * * has only effect if ShowKeepCheckBox is set in the constructor */ void setKeepPassword(bool b); /** * Sets the username field read-only and sets the * focus to the password field. * * this can also be set by passing UsernameReadOnly as flag in the constructor * * @param readOnly true to set the user field to read-only */ void setUsernameReadOnly(bool readOnly); /** * Presets the password. * If the password is not empty, the ability to show the password will not be available. * @param password the password to set */ void setPassword(const QString &password); /** * Presets a number of login+password pairs that the user can choose from. * The passwords can be empty if you simply want to offer usernames to choose from. * * This require the flag ShowUnernameLine to be set in the constructoe, and not the flag UsernameReadOnly * @param knownLogins map of known logins: the keys are usernames, the values are passwords. */ void setKnownLogins(const QMap &knownLogins); /** * @internal */ void accept() Q_DECL_OVERRIDE; /** * Returns the button box used in the dialog. * This can be used to add new buttons. * * @return the button box * * @since 5.0 */ QDialogButtonBox *buttonBox() const; Q_SIGNALS: /** * emitted when the dialog has been accepted * @param password the entered password * @param keep true if the "remember password" checkbox was checked, false otherwise. false if ShowKeepPassword was not set in the constructor */ void gotPassword(const QString &password, bool keep); /** * emitted when the dialog has been accepted, and ShowUsernameLine was set on the constructor * @param username the entered username * @param password the entered password * @param keep true if the "remember password" checkbox was checked, false otherwise. false if ShowKeepPassword was not set in the constructor */ void gotUsernameAndPassword(const QString &username, const QString &password, bool keep); protected: /** * Virtual function that can be overridden to provide password * checking in derived classes. It should return @p true if the * password is valid, @p false otherwise. */ virtual bool checkPassword(); private: Q_PRIVATE_SLOT(d, void actuallyAccept()) Q_PRIVATE_SLOT(d, void activated(const QString &userName)) Q_PRIVATE_SLOT(d, void updateFields()) Q_PRIVATE_SLOT(d, void toggleEchoMode()) Q_PRIVATE_SLOT(d, void showToggleEchoModeAction(const QString &text)) private: class KPasswordDialogPrivate; friend class KPasswordDialogPrivate; KPasswordDialogPrivate *const d; Q_DISABLE_COPY(KPasswordDialog) }; Q_DECLARE_OPERATORS_FOR_FLAGS(KPasswordDialog::KPasswordDialogFlags) #endif diff --git a/src/kpixmapregionselectordialog.cpp b/src/kpixmapregionselectordialog.cpp index cb5b8ed..ad51ae3 100644 --- a/src/kpixmapregionselectordialog.cpp +++ b/src/kpixmapregionselectordialog.cpp @@ -1,172 +1,172 @@ /* This file is part of the KDE libraries Copyright (C) 2004 Antonio Larrosa #include #include #include #include #include class KPixmapRegionSelectorDialog::Private { public: Private(KPixmapRegionSelectorDialog *parent) - : pixmapSelectorWidget(0), q(parent) + : pixmapSelectorWidget(nullptr), q(parent) { } KPixmapRegionSelectorWidget *pixmapSelectorWidget; KPixmapRegionSelectorDialog *q; void init() { //When the image is rotated we need to enforce the maximum width&height into the //KPixmapRegionSelectorWidget; in order to avoid the dialog to get out of the screen q->connect(pixmapSelectorWidget, SIGNAL(pixmapRotated()), q, SLOT(_k_adjustPixmapSize())); } void _k_adjustPixmapSize() { if (pixmapSelectorWidget) { //Set maximum size for picture QDesktopWidget desktopWidget; QRect screen = desktopWidget.availableGeometry(); pixmapSelectorWidget->setMaximumWidgetSize( (int)(screen.width() * 4.0 / 5), (int)(screen.height() * 4.0 / 5)); } } }; KPixmapRegionSelectorDialog::KPixmapRegionSelectorDialog(QWidget *parent) : QDialog(parent), d(new Private(this)) { setWindowTitle(tr("Select Region of Image")); QVBoxLayout *boxLayout = new QVBoxLayout(this); QLabel *label = new QLabel(tr("Please click and drag on the image to select the region of interest:"), this); d->pixmapSelectorWidget = new KPixmapRegionSelectorWidget(this); QDialogButtonBox *buttonBox = new QDialogButtonBox(this); buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); boxLayout->addWidget(label); boxLayout->addWidget(d->pixmapSelectorWidget); boxLayout->addWidget(buttonBox); d->init(); } KPixmapRegionSelectorDialog::~KPixmapRegionSelectorDialog() { delete d; } KPixmapRegionSelectorWidget *KPixmapRegionSelectorDialog::pixmapRegionSelectorWidget() const { return d->pixmapSelectorWidget; } void KPixmapRegionSelectorDialog::adjustRegionSelectorWidgetSizeToFitScreen() { d->_k_adjustPixmapSize(); } QRect KPixmapRegionSelectorDialog::getSelectedRegion(const QPixmap &pixmap, QWidget *parent) { KPixmapRegionSelectorDialog dialog(parent); dialog.pixmapRegionSelectorWidget()->setPixmap(pixmap); dialog.adjustRegionSelectorWidgetSizeToFitScreen(); int result = dialog.exec(); QRect rect; if (result == QDialog::Accepted) { rect = dialog.pixmapRegionSelectorWidget()->unzoomedSelectedRegion(); } return rect; } QRect KPixmapRegionSelectorDialog::getSelectedRegion(const QPixmap &pixmap, int aspectRatioWidth, int aspectRatioHeight, QWidget *parent) { KPixmapRegionSelectorDialog dialog(parent); dialog.pixmapRegionSelectorWidget()->setPixmap(pixmap); dialog.pixmapRegionSelectorWidget()->setSelectionAspectRatio(aspectRatioWidth, aspectRatioHeight); dialog.adjustRegionSelectorWidgetSizeToFitScreen(); int result = dialog.exec(); QRect rect; if (result == QDialog::Accepted) { rect = dialog.pixmapRegionSelectorWidget()->unzoomedSelectedRegion(); } return rect; } QImage KPixmapRegionSelectorDialog::getSelectedImage(const QPixmap &pixmap, QWidget *parent) { KPixmapRegionSelectorDialog dialog(parent); dialog.pixmapRegionSelectorWidget()->setPixmap(pixmap); dialog.adjustRegionSelectorWidgetSizeToFitScreen(); int result = dialog.exec(); QImage image; if (result == QDialog::Accepted) { image = dialog.pixmapRegionSelectorWidget()->selectedImage(); } return image; } QImage KPixmapRegionSelectorDialog::getSelectedImage(const QPixmap &pixmap, int aspectRatioWidth, int aspectRatioHeight, QWidget *parent) { KPixmapRegionSelectorDialog dialog(parent); dialog.pixmapRegionSelectorWidget()->setPixmap(pixmap); dialog.pixmapRegionSelectorWidget()->setSelectionAspectRatio(aspectRatioWidth, aspectRatioHeight); dialog.adjustRegionSelectorWidgetSizeToFitScreen(); int result = dialog.exec(); QImage image; if (result == QDialog::Accepted) { image = dialog.pixmapRegionSelectorWidget()->selectedImage(); } return image; } #include "moc_kpixmapregionselectordialog.cpp" diff --git a/src/kpixmapregionselectordialog.h b/src/kpixmapregionselectordialog.h index e1d36d4..fde18c9 100644 --- a/src/kpixmapregionselectordialog.h +++ b/src/kpixmapregionselectordialog.h @@ -1,124 +1,124 @@ /* This file is part of the KDE libraries Copyright (C) 2004 Antonio Larrosa This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KPIXMAPREGIONSELECTORDIALOG_H #define KPIXMAPREGIONSELECTORDIALOG_H #include #include class KPixmapRegionSelectorWidget; class QImage; /** * A dialog that uses a KPixmapRegionSelectorWidget to allow the user * to select a region of an image. If you want to use special features * like forcing the selected area to have a fixed aspect ratio, you can use * @see pixmapRegionSelectorWidget() to get the pointer to the * KPixmapRegionSelectorWidget object and set the desired options there. * * There are some convenience methods that allow to easily show a dialog * for the user to select a region of an image, and just care about the selected * image. * * \image html kpixmapregionselectordialog.png "KDE Pixmap Region Selector Dialog" * * @author Antonio Larrosa */ class KWIDGETSADDONS_EXPORT KPixmapRegionSelectorDialog : public QDialog { Q_OBJECT public: /** * The constructor of an empty KPixmapRegionSelectorDialog, you have to call * later the setPixmap method of the KPixmapRegionSelectorWidget widget of * the new object. */ - explicit KPixmapRegionSelectorDialog(QWidget *parent = 0); + explicit KPixmapRegionSelectorDialog(QWidget *parent = nullptr); /** * The destructor of the dialog */ ~KPixmapRegionSelectorDialog(); /** * @returns the KPixmapRegionSelectorWidget widget so that additional * parameters can be set by using it. */ KPixmapRegionSelectorWidget *pixmapRegionSelectorWidget() const; /** * Creates a modal dialog, lets the user to select a region of the @p pixmap * and returns when the dialog is closed. * * @returns the selected rectangle, or an invalid rectangle if the user * pressed the Cancel button. */ - static QRect getSelectedRegion(const QPixmap &pixmap, QWidget *parent = 0L); + static QRect getSelectedRegion(const QPixmap &pixmap, QWidget *parent = nullptr); /** * Creates a modal dialog, lets the user to select a region of the @p pixmap * with the same aspect ratio than @p aspectRatioWidth x @p aspectRatioHeight * and returns when the dialog is closed. * * @returns the selected rectangle, or an invalid rectangle if the user * pressed the Cancel button. */ static QRect getSelectedRegion(const QPixmap &pixmap, int aspectRatioWidth, - int aspectRatioHeight, QWidget *parent = 0L); + int aspectRatioHeight, QWidget *parent = nullptr); /** * Creates a modal dialog, lets the user to select a region of the @p pixmap * and returns when the dialog is closed. * * @returns the selected image, or an invalid image if the user * pressed the Cancel button. */ - static QImage getSelectedImage(const QPixmap &pixmap, QWidget *parent = 0L); + static QImage getSelectedImage(const QPixmap &pixmap, QWidget *parent = nullptr); /** * Creates a modal dialog, lets the user to select a region of the @p pixmap * with the same aspect ratio than @p aspectRatioWidth x @p aspectRatioHeight * and returns when the dialog is closed. * * @returns the selected image, or an invalid image if the user * pressed the Cancel button. */ static QImage getSelectedImage(const QPixmap &pixmap, int aspectRatioWidth, - int aspectRatioHeight, QWidget *parent = 0L); + int aspectRatioHeight, QWidget *parent = nullptr); /** * @since 4.4.3 * Adjusts the size of the KPixmapRegionSelectorWidget to not overflow the screen size */ void adjustRegionSelectorWidgetSizeToFitScreen(); private: class Private; Private *const d; Q_PRIVATE_SLOT(d, void _k_adjustPixmapSize()) Q_DISABLE_COPY(KPixmapRegionSelectorDialog) }; #endif diff --git a/src/kpixmapregionselectorwidget.cpp b/src/kpixmapregionselectorwidget.cpp index 57e0da1..37e3670 100644 --- a/src/kpixmapregionselectorwidget.cpp +++ b/src/kpixmapregionselectorwidget.cpp @@ -1,511 +1,511 @@ /* This file is part of the KDE libraries Copyright (C) 2004 Antonio Larrosa #include #include #include #include #include #include #include #include #include #include class KPixmapRegionSelectorWidget::Private { public: Private(KPixmapRegionSelectorWidget *q): q(q) {} KPixmapRegionSelectorWidget *q; /** * Recalculates the pixmap that is shown based on the current selected area, * the original image, etc. */ void updatePixmap(); QRect calcSelectionRectangle(const QPoint &startPoint, const QPoint &endPoint); enum CursorState { None = 0, Resizing, Moving }; CursorState m_state; QPixmap m_unzoomedPixmap; QPixmap m_originalPixmap; QPixmap m_linedPixmap; QRect m_selectedRegion; QLabel *m_label; QPoint m_tempFirstClick; double m_forcedAspectRatio; int m_maxWidth, m_maxHeight; double m_zoomFactor; QRubberBand *m_rubberBand; }; KPixmapRegionSelectorWidget::KPixmapRegionSelectorWidget(QWidget *parent) : QWidget(parent), d(new Private(this)) { QHBoxLayout *hboxLayout = new QHBoxLayout(this); hboxLayout->addStretch(); QVBoxLayout *vboxLayout = new QVBoxLayout(); hboxLayout->addItem(vboxLayout); vboxLayout->addStretch(); d->m_label = new QLabel(this); d->m_label->setAttribute(Qt::WA_NoSystemBackground, true); //setBackgroundMode( Qt::NoBackground ); d->m_label->installEventFilter(this); vboxLayout->addWidget(d->m_label); vboxLayout->addStretch(); hboxLayout->addStretch(); d->m_forcedAspectRatio = 0; d->m_zoomFactor = 1.0; d->m_rubberBand = new QRubberBand(QRubberBand::Rectangle, d->m_label); d->m_rubberBand->hide(); } KPixmapRegionSelectorWidget::~KPixmapRegionSelectorWidget() { delete d; } QPixmap KPixmapRegionSelectorWidget::pixmap() const { return d->m_unzoomedPixmap; } void KPixmapRegionSelectorWidget::setPixmap(const QPixmap &pixmap) { Q_ASSERT(!pixmap.isNull()); //This class isn't designed to deal with null pixmaps. d->m_originalPixmap = pixmap; d->m_unzoomedPixmap = pixmap; d->m_label->setPixmap(pixmap); resetSelection(); } void KPixmapRegionSelectorWidget::resetSelection() { d->m_selectedRegion = d->m_originalPixmap.rect(); d->m_rubberBand->hide(); d->updatePixmap(); } QRect KPixmapRegionSelectorWidget::selectedRegion() const { return d->m_selectedRegion; } void KPixmapRegionSelectorWidget::setSelectedRegion(const QRect &rect) { if (!rect.isValid()) { resetSelection(); } else { d->m_selectedRegion = rect; d->updatePixmap(); } } void KPixmapRegionSelectorWidget::Private::updatePixmap() { Q_ASSERT(!m_originalPixmap.isNull()); if (m_originalPixmap.isNull()) { m_label->setPixmap(m_originalPixmap); return; } if (m_selectedRegion.width() > m_originalPixmap.width()) { m_selectedRegion.setWidth(m_originalPixmap.width()); } if (m_selectedRegion.height() > m_originalPixmap.height()) { m_selectedRegion.setHeight(m_originalPixmap.height()); } QPainter painter; if (m_linedPixmap.isNull()) { m_linedPixmap = m_originalPixmap; QPainter p(&m_linedPixmap); p.setCompositionMode(QPainter::CompositionMode_SourceAtop); p.fillRect(m_linedPixmap.rect(), QColor(0, 0, 0, 100)); } QPixmap pixmap = m_linedPixmap; painter.begin(&pixmap); painter.drawPixmap(m_selectedRegion.topLeft(), m_originalPixmap, m_selectedRegion); painter.end(); m_label->setPixmap(pixmap); - qApp->sendPostedEvents(0, QEvent::LayoutRequest); + qApp->sendPostedEvents(nullptr, QEvent::LayoutRequest); if (m_selectedRegion == m_originalPixmap.rect()) {//d->m_label->rect()) //### CHECK! m_rubberBand->hide(); } else { m_rubberBand->setGeometry(QRect(m_selectedRegion.topLeft(), m_selectedRegion.size())); /* m_rubberBand->setGeometry(QRect(m_label -> mapToGlobal(m_selectedRegion.topLeft()), m_selectedRegion.size())); */ if (m_state != None) { m_rubberBand->show(); } } } QMenu *KPixmapRegionSelectorWidget::createPopupMenu() { QMenu *popup = new QMenu(this); popup->setObjectName(QStringLiteral("PixmapRegionSelectorPopup")); popup->addSection(tr("Image Operations")); popup->addAction(QIcon::fromTheme(QStringLiteral("object-rotate-right")), tr("&Rotate Clockwise"), this, SLOT(rotateClockwise())); popup->addAction(QIcon::fromTheme(QStringLiteral("object-rotate-left")), tr("Rotate &Counterclockwise"), this, SLOT(rotateCounterclockwise())); /* I wonder if it would be appropriate to have here an "Open with..." option to edit the image (antlarr) */ return popup; } void KPixmapRegionSelectorWidget::rotate(RotateDirection direction) { int w = d->m_originalPixmap.width(); int h = d->m_originalPixmap.height(); QImage img = d->m_unzoomedPixmap.toImage(); if (direction == Rotate90) { img = img.transformed(QTransform().rotate(90.0)); } else if (direction == Rotate180) { img = img.transformed(QTransform().rotate(180.0)); } else { img = img.transformed(QTransform().rotate(270.0)); } d->m_unzoomedPixmap = QPixmap::fromImage(img); img = d->m_originalPixmap.toImage(); if (direction == Rotate90) { img = img.transformed(QTransform().rotate(90.0)); } else if (direction == Rotate180) { img = img.transformed(QTransform().rotate(180.0)); } else { img = img.transformed(QTransform().rotate(270.0)); } d->m_originalPixmap = QPixmap::fromImage(img); d->m_linedPixmap = QPixmap(); if (d->m_forcedAspectRatio > 0 && d->m_forcedAspectRatio != 1) { resetSelection(); } else { switch (direction) { case (Rotate90): { int x = h - d->m_selectedRegion.y() - d->m_selectedRegion.height(); int y = d->m_selectedRegion.x(); d->m_selectedRegion.setRect(x, y, d->m_selectedRegion.height(), d->m_selectedRegion.width()); d->updatePixmap(); // qApp->sendPostedEvents(0,QEvent::LayoutRequest); // updatePixmap(); } break; case (Rotate270): { int x = d->m_selectedRegion.y(); int y = w - d->m_selectedRegion.x() - d->m_selectedRegion.width(); d->m_selectedRegion.setRect(x, y, d->m_selectedRegion.height(), d->m_selectedRegion.width()); d->updatePixmap(); // qApp->sendPostedEvents(0,QEvent::LayoutRequest); // updatePixmap(); } break; default: resetSelection(); } } emit pixmapRotated(); } void KPixmapRegionSelectorWidget::rotateClockwise() { rotate(Rotate90); } void KPixmapRegionSelectorWidget::rotateCounterclockwise() { rotate(Rotate270); } bool KPixmapRegionSelectorWidget::eventFilter(QObject *obj, QEvent *ev) { if (ev->type() == QEvent::MouseButtonPress) { QMouseEvent *mev = (QMouseEvent *)(ev); //qCDebug(KWidgetsAddonsLog) << QString("click at %1,%2").arg( mev->x() ).arg( mev->y() ); if (mev->button() == Qt::RightButton) { QMenu *popup = createPopupMenu(); popup->exec(mev->globalPos()); delete popup; return true; } QCursor cursor; if (d->m_selectedRegion.contains(mev->pos()) && d->m_selectedRegion != d->m_originalPixmap.rect()) { d->m_state = Private::Moving; cursor.setShape(Qt::SizeAllCursor); d->m_rubberBand->show(); } else { d->m_state = Private::Resizing; cursor.setShape(Qt::CrossCursor); } QApplication::setOverrideCursor(cursor); d->m_tempFirstClick = mev->pos(); return true; } if (ev->type() == QEvent::MouseMove) { QMouseEvent *mev = (QMouseEvent *)(ev); //qCDebug(KWidgetsAddonsLog) << QString("move to %1,%2").arg( mev->x() ).arg( mev->y() ); if (d->m_state == Private::Resizing) { setSelectedRegion( d->calcSelectionRectangle(d->m_tempFirstClick, mev->pos())); } else if (d->m_state == Private::Moving) { int mevx = mev->x(); int mevy = mev->y(); bool mouseOutside = false; if (mevx < 0) { d->m_selectedRegion.translate(-d->m_selectedRegion.x(), 0); mouseOutside = true; } else if (mevx > d->m_originalPixmap.width()) { d->m_selectedRegion.translate(d->m_originalPixmap.width() - d->m_selectedRegion.width() - d->m_selectedRegion.x(), 0); mouseOutside = true; } if (mevy < 0) { d->m_selectedRegion.translate(0, -d->m_selectedRegion.y()); mouseOutside = true; } else if (mevy > d->m_originalPixmap.height()) { d->m_selectedRegion.translate(0, d->m_originalPixmap.height() - d->m_selectedRegion.height() - d->m_selectedRegion.y()); mouseOutside = true; } if (mouseOutside) { d->updatePixmap(); return true; }; d->m_selectedRegion.translate(mev->x() - d->m_tempFirstClick.x(), mev->y() - d->m_tempFirstClick.y()); // Check that the region has not fallen outside the image if (d->m_selectedRegion.x() < 0) { d->m_selectedRegion.translate(-d->m_selectedRegion.x(), 0); } else if (d->m_selectedRegion.right() > d->m_originalPixmap.width()) { d->m_selectedRegion.translate(-(d->m_selectedRegion.right() - d->m_originalPixmap.width()), 0); } if (d->m_selectedRegion.y() < 0) { d->m_selectedRegion.translate(0, -d->m_selectedRegion.y()); } else if (d->m_selectedRegion.bottom() > d->m_originalPixmap.height()) { d->m_selectedRegion.translate(0, -(d->m_selectedRegion.bottom() - d->m_originalPixmap.height())); } d->m_tempFirstClick = mev->pos(); d->updatePixmap(); } return true; } if (ev->type() == QEvent::MouseButtonRelease) { QMouseEvent *mev = (QMouseEvent *)(ev); if (d->m_state == Private::Resizing && mev->pos() == d->m_tempFirstClick) { resetSelection(); } d->m_state = Private::None; QApplication::restoreOverrideCursor(); d->m_rubberBand->hide(); return true; } QWidget::eventFilter(obj, ev); return false; } QRect KPixmapRegionSelectorWidget::Private::calcSelectionRectangle(const QPoint &startPoint, const QPoint &_endPoint) { QPoint endPoint = _endPoint; if (endPoint.x() < 0) { endPoint.setX(0); } else if (endPoint.x() > m_originalPixmap.width()) { endPoint.setX(m_originalPixmap.width()); } if (endPoint.y() < 0) { endPoint.setY(0); } else if (endPoint.y() > m_originalPixmap.height()) { endPoint.setY(m_originalPixmap.height()); } int w = abs(startPoint.x() - endPoint.x()); int h = abs(startPoint.y() - endPoint.y()); if (m_forcedAspectRatio > 0) { double aspectRatio = w / double(h); if (aspectRatio > m_forcedAspectRatio) { h = (int)(w / m_forcedAspectRatio); } else { w = (int)(h * m_forcedAspectRatio); } } int x, y; if (startPoint.x() < endPoint.x()) { x = startPoint.x(); } else { x = startPoint.x() - w; } if (startPoint.y() < endPoint.y()) { y = startPoint.y(); } else { y = startPoint.y() - h; } if (x < 0) { w += x; x = 0; h = (int)(w / m_forcedAspectRatio); if (startPoint.y() > endPoint.y()) { y = startPoint.y() - h; } } else if (x + w > m_originalPixmap.width()) { w = m_originalPixmap.width() - x; h = (int)(w / m_forcedAspectRatio); if (startPoint.y() > endPoint.y()) { y = startPoint.y() - h; } } if (y < 0) { h += y; y = 0; w = (int)(h * m_forcedAspectRatio); if (startPoint.x() > endPoint.x()) { x = startPoint.x() - w; } } else if (y + h > m_originalPixmap.height()) { h = m_originalPixmap.height() - y; w = (int)(h * m_forcedAspectRatio); if (startPoint.x() > endPoint.x()) { x = startPoint.x() - w; } } return QRect(x, y, w, h); } QRect KPixmapRegionSelectorWidget::unzoomedSelectedRegion() const { return QRect((int)(d->m_selectedRegion.x() / d->m_zoomFactor), (int)(d->m_selectedRegion.y() / d->m_zoomFactor), (int)(d->m_selectedRegion.width() / d->m_zoomFactor), (int)(d->m_selectedRegion.height() / d->m_zoomFactor)); } QImage KPixmapRegionSelectorWidget::selectedImage() const { QImage origImage = d->m_unzoomedPixmap.toImage(); return origImage.copy(unzoomedSelectedRegion()); } void KPixmapRegionSelectorWidget::setSelectionAspectRatio(int width, int height) { d->m_forcedAspectRatio = width / double(height); } void KPixmapRegionSelectorWidget::setFreeSelectionAspectRatio() { d->m_forcedAspectRatio = 0; } void KPixmapRegionSelectorWidget::setMaximumWidgetSize(int width, int height) { d->m_maxWidth = width; d->m_maxHeight = height; if (d->m_selectedRegion == d->m_originalPixmap.rect()) { d->m_selectedRegion = QRect(); } d->m_originalPixmap = d->m_unzoomedPixmap; // qCDebug(KWidgetsAddonsLog) << QString(" original Pixmap :") << d->m_originalPixmap.rect(); // qCDebug(KWidgetsAddonsLog) << QString(" unzoomed Pixmap : %1 x %2 ").arg(d->m_unzoomedPixmap.width()).arg(d->m_unzoomedPixmap.height()); if (!d->m_originalPixmap.isNull() && (d->m_originalPixmap.width() > d->m_maxWidth || d->m_originalPixmap.height() > d->m_maxHeight)) { /* We have to resize the pixmap to get it complete on the screen */ QImage image = d->m_originalPixmap.toImage(); d->m_originalPixmap = QPixmap::fromImage(image.scaled(width, height, Qt::KeepAspectRatio, Qt::SmoothTransformation)); double oldZoomFactor = d->m_zoomFactor; d->m_zoomFactor = d->m_originalPixmap.width() / (double)d->m_unzoomedPixmap.width(); if (d->m_selectedRegion.isValid()) { d->m_selectedRegion = QRect((int)(d->m_selectedRegion.x() * d->m_zoomFactor / oldZoomFactor), (int)(d->m_selectedRegion.y() * d->m_zoomFactor / oldZoomFactor), (int)(d->m_selectedRegion.width() * d->m_zoomFactor / oldZoomFactor), (int)(d->m_selectedRegion.height() * d->m_zoomFactor / oldZoomFactor)); } } if (!d->m_selectedRegion.isValid()) { d->m_selectedRegion = d->m_originalPixmap.rect(); } d->m_linedPixmap = QPixmap(); d->updatePixmap(); resize(d->m_label->width(), d->m_label->height()); } diff --git a/src/kpixmapregionselectorwidget.h b/src/kpixmapregionselectorwidget.h index 3dbebb0..92e5efd 100644 --- a/src/kpixmapregionselectorwidget.h +++ b/src/kpixmapregionselectorwidget.h @@ -1,165 +1,165 @@ /* This file is part of the KDE libraries Copyright (C) 2004 Antonio Larrosa #include #include class QMenu; /** * KPixmapRegionSelectorWidget is a widget that shows a picture and provides the * user with a friendly way to select a rectangular subregion of the pixmap. * * NOTE: There are two copies of this .h and the .cpp file, with subtle differences. * One copy is in kdelibs/kdeui, and the other copy is in kdepim/libkdepim * This is because kdepim has to remain backwards compatible. Any changes * to either file should be made to the other. * * \image html kpixmapregionselectorwidget.png "KDE Pixmap Region Selector" * * @author Antonio Larrosa */ class KWIDGETSADDONS_EXPORT KPixmapRegionSelectorWidget : public QWidget { Q_OBJECT Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap) public: /** * This enum provides a rotation direction. * @see KPixmapRegionSelectorWidget::rotate() */ enum RotateDirection { Rotate90, //!< Rotate 90 degrees to the right. Rotate180, //!< Rotate 180 degrees. Rotate270 //!< Rotate 90 degrees to the left. }; /** * Constructor for a KPixmapRegionSelectorWidget. */ - explicit KPixmapRegionSelectorWidget(QWidget *parent = 0); + explicit KPixmapRegionSelectorWidget(QWidget *parent = nullptr); /** * Destructor for a KPixmapRegionSelectorWidget */ ~KPixmapRegionSelectorWidget(); /** * Sets the pixmap which will be shown for the user to select a region from. * @param pixmap The pixmap. Must be non-null. * */ void setPixmap(const QPixmap &pixmap); /** * @return the original whole pixmap that we're using in this widget as the * pixmap the user is selecting a region from. */ QPixmap pixmap() const; /** * Sets the selected region to be @p rect (in zoomed pixmap coordinates) */ void setSelectedRegion(const QRect &rect); /** * Returns the selected region ( in zoomed pixmap coordinates ) */ QRect selectedRegion() const; /** * Returns the selected region ( in unzoomed, original pixmap coordinates ) */ QRect unzoomedSelectedRegion() const; /** * Resets the selection to use the whole image */ void resetSelection(); /** * @returns a QImage object with just the region the user selected from the * image */ QImage selectedImage() const; /** * Sets the aspect ration that the selected subimage should have. The way to * select it, is specifying an example valid @p width and @p height. * @see setFreeSelectionAspectRatio() */ void setSelectionAspectRatio(int width, int height); /** * Allows the user to do a selection which has any aspect ratio. This is * the default. * @see setSelectionAspectRatio() */ void setFreeSelectionAspectRatio(); /** * Sets the maximum size for the widget. If the image is larger than this * (either horizontally or vertically), it's scaled to adjust to the maximum * size (preserving the aspect ratio) */ void setMaximumWidgetSize(int width, int height); /** * Rotates the image as specified by the @p direction parameter, also tries * to rotate the selected region so that it doesn't change, as long as the * forced aspect ratio setting is respected, in other case, the selected region * is reset. */ void rotate(RotateDirection direction); public Q_SLOTS: /** * Rotates the current image 90º clockwise */ void rotateClockwise(); /** * Rotates the current image 90º counterclockwise */ void rotateCounterclockwise(); Q_SIGNALS: void pixmapRotated(); protected: /** * Creates a QMenu with the menu that appears when clicking with the right button on the label */ virtual QMenu *createPopupMenu(); bool eventFilter(QObject *obj, QEvent *ev) Q_DECL_OVERRIDE; private: class Private; friend class Private; Private *const d; Q_DISABLE_COPY(KPixmapRegionSelectorWidget) }; #endif diff --git a/src/kpixmapsequenceoverlaypainter.cpp b/src/kpixmapsequenceoverlaypainter.cpp index bdb37a1..e817298 100644 --- a/src/kpixmapsequenceoverlaypainter.cpp +++ b/src/kpixmapsequenceoverlaypainter.cpp @@ -1,275 +1,275 @@ /* Copyright 2009 Sebastian Trueg This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kpixmapsequenceoverlaypainter.h" #include "kpixmapsequence.h" #include #include #include #include #include #include #include #include class KPixmapSequenceOverlayPainter::Private { public: void init(KPixmapSequenceOverlayPainter *p); void _k_timeout(); void paintFrame(); KPixmapSequence &sequence(); QRect pixmapRect(); KPixmapSequence m_sequence; QPointer m_widget; Qt::Alignment m_alignment; QPoint m_offset; QRect m_rect; QTimer m_timer; int m_counter; bool m_started; KPixmapSequenceOverlayPainter *q; }; void KPixmapSequenceOverlayPainter::Private::init(KPixmapSequenceOverlayPainter *p) { q = p; - m_widget = 0; + m_widget = nullptr; m_alignment = Qt::AlignCenter; m_started = false; q->setInterval(200); connect(&m_timer, SIGNAL(timeout()), q, SLOT(_k_timeout())); } void KPixmapSequenceOverlayPainter::Private::_k_timeout() { if (sequence().isEmpty()) { return; } ++m_counter; m_counter %= sequence().frameCount(); if (m_widget) { m_widget->update(pixmapRect()); } } void KPixmapSequenceOverlayPainter::Private::paintFrame() { if (m_counter >= sequence().frameCount()) { return; } QPainter p(m_widget); p.drawPixmap(pixmapRect(), sequence().frameAt(m_counter), QRect(QPoint(0, 0), sequence().frameSize())); } KPixmapSequence &KPixmapSequenceOverlayPainter::Private::sequence() { return m_sequence; } QRect KPixmapSequenceOverlayPainter::Private::pixmapRect() { QRect rect(m_rect); if (!rect.isValid()) { rect = m_widget->rect(); } QPoint pos(rect.topLeft()); if (m_alignment & Qt::AlignHCenter) { pos.setX(rect.center().x() - (sequence().frameSize().width() / 2)); } else if (m_alignment & Qt::AlignRight) { pos.setX(rect.right() - sequence().frameSize().width()); } if (m_alignment & Qt::AlignVCenter) { pos.setY(rect.center().y() - (sequence().frameSize().height() / 2)); } else if (m_alignment & Qt::AlignBottom) { pos.setY(rect.bottom() - sequence().frameSize().height()); } pos += m_offset; return QRect(pos, sequence().frameSize()); } KPixmapSequenceOverlayPainter::KPixmapSequenceOverlayPainter(QObject *parent) : QObject(parent), d(new Private) { d->init(this); } KPixmapSequenceOverlayPainter::KPixmapSequenceOverlayPainter(const KPixmapSequence &seq, QObject *parent) : QObject(parent), d(new Private) { d->init(this); d->m_sequence = seq; } KPixmapSequenceOverlayPainter::~KPixmapSequenceOverlayPainter() { stop(); delete d; } KPixmapSequence KPixmapSequenceOverlayPainter::sequence() const { return d->sequence(); } int KPixmapSequenceOverlayPainter::interval() const { return d->m_timer.interval(); } QRect KPixmapSequenceOverlayPainter::rect() const { if (d->m_rect.isValid()) { return d->m_rect; } else if (d->m_widget) { return d->m_widget->rect(); } else { return QRect(); } } Qt::Alignment KPixmapSequenceOverlayPainter::alignment() const { return d->m_alignment; } QPoint KPixmapSequenceOverlayPainter::offset() const { return d->m_offset; } void KPixmapSequenceOverlayPainter::setSequence(const KPixmapSequence &seq) { bool restart = d->m_started; stop(); d->m_sequence = seq; if (restart) { start(); } } void KPixmapSequenceOverlayPainter::setInterval(int msecs) { d->m_timer.setInterval(msecs); } void KPixmapSequenceOverlayPainter::setWidget(QWidget *w) { stop(); d->m_widget = w; } void KPixmapSequenceOverlayPainter::setRect(const QRect &rect) { bool restart = d->m_started; stop(); d->m_rect = rect; if (restart) { start(); } } void KPixmapSequenceOverlayPainter::setAlignment(Qt::Alignment align) { bool restart = d->m_started; stop(); d->m_alignment = align; if (restart) { start(); } } void KPixmapSequenceOverlayPainter::setOffset(const QPoint &offset) { bool restart = d->m_started; stop(); d->m_offset = offset; if (restart) { start(); } } void KPixmapSequenceOverlayPainter::start() { if (d->m_widget) { stop(); d->m_counter = 0; d->m_started = true; d->m_widget->installEventFilter(this); if (d->m_widget->isVisible()) { d->m_timer.start(); d->m_widget->update(d->pixmapRect()); } } } void KPixmapSequenceOverlayPainter::stop() { d->m_timer.stop(); if (d->m_widget) { d->m_started = false; d->m_widget->removeEventFilter(this); d->m_widget->update(d->pixmapRect()); } } bool KPixmapSequenceOverlayPainter::eventFilter(QObject *obj, QEvent *event) { if (obj == d->m_widget) { switch (event->type()) { case QEvent::Paint: // make sure we paint after everyone else including other event filters obj->removeEventFilter(this); // don't recurse... QCoreApplication::sendEvent(obj, event); d->paintFrame(); obj->installEventFilter(this); // catch on... return true; break; case QEvent::Hide: d->m_timer.stop(); break; case QEvent::Show: if (d->m_started) { d->m_timer.start(); d->m_widget->update(d->pixmapRect()); } break; default: break; } } return false; } #include "moc_kpixmapsequenceoverlaypainter.cpp" diff --git a/src/kpixmapsequenceoverlaypainter.h b/src/kpixmapsequenceoverlaypainter.h index 4a9a139..7830af8 100644 --- a/src/kpixmapsequenceoverlaypainter.h +++ b/src/kpixmapsequenceoverlaypainter.h @@ -1,163 +1,163 @@ /* Copyright 2009 Sebastian Trueg This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _K_PIXMAPSEQUENCE_OVERLAY_PAINTER_H_ #define _K_PIXMAPSEQUENCE_OVERLAY_PAINTER_H_ #include #include #include class KPixmapSequence; class QWidget; class QEvent; class QRect; /** * \class KPixmapSequenceOverlayPainter kpixmapsequenceoverlaypainter.h KPixmapSequenceOverlayPainter * * \brief Paints a KPixmapSequence on top of any widget at any position. * * The KPixmapSequenceOverlayPainter paints an overlay on top of an arbitrary QWidget * using a KPixmapSequence. This is typically used for spinners indicating that a process * is not finished yet. * * \author Sebastian Trueg * * \since 4.4 */ class KWIDGETSADDONS_EXPORT KPixmapSequenceOverlayPainter : public QObject { Q_OBJECT public: /** * Constructor */ - KPixmapSequenceOverlayPainter(QObject *parent = 0); - KPixmapSequenceOverlayPainter(const KPixmapSequence &seq, QObject *parent = 0); + KPixmapSequenceOverlayPainter(QObject *parent = nullptr); + KPixmapSequenceOverlayPainter(const KPixmapSequence &seq, QObject *parent = nullptr); /** * Destructor */ ~KPixmapSequenceOverlayPainter(); /** * The sequence used to draw the overlay. * * \sa setSequence */ KPixmapSequence sequence() const; /** * The interval between frames. * * \sa setInterval */ int interval() const; /** * The optional rect to draw the pixmaps in. * \sa setRect */ QRect rect() const; /** * The alignment of the pixmaps in the rect. * \sa setAlignment */ Qt::Alignment alignment() const; /** * The optional offset within the rect. * \sa setOffset */ QPoint offset() const; public Q_SLOTS: /** * Set the sequence to be used. By default the KDE busy sequence is used. */ void setSequence(const KPixmapSequence &seq); /** * Set the interval between frames. The default is 200. */ void setInterval(int msecs); /** * Set the widget to draw the overlay on. */ void setWidget(QWidget *w); /** * Set the rect in which to place the sequence. Be aware that * this optional property does not scale the pixmaps (except if * it is smaller) but allows to change the placement. * * \param rect The rect in which to draw the pixmap using alignment * and offset. Be aware that setting a rect bigger than the widget * can lead to weird painting errors. * * Defaults to the widget's rect. */ void setRect(const QRect &rect); /** * Set the alignment of the sequence in rect. * * \param align alignment of the overlay. Qt::AlignJustify does not make sense here. * Defaults to Qt::Center. */ void setAlignment(Qt::Alignment align); /** * Set the offset relative to the placement determined by alignment * and rect. * * \param offset An optional offset which allows an absolute placement. * * Defaults to an empty point. */ void setOffset(const QPoint &offset); /** * Start drawing the sequence. * * The overlay will be drawn until a call to stop() */ void start(); /** * Stop drawing the overlay. */ void stop(); protected: bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE; private: class Private; Private *const d; Q_PRIVATE_SLOT(d, void _k_timeout()) }; #endif diff --git a/src/kpixmapsequencewidget.h b/src/kpixmapsequencewidget.h index 454b18f..da92d6b 100644 --- a/src/kpixmapsequencewidget.h +++ b/src/kpixmapsequencewidget.h @@ -1,96 +1,96 @@ /* Copyright 2009 Sebastian Trueg This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _K_PIXMAPSEQUENCE_WIDGET_H_ #define _K_PIXMAPSEQUENCE_WIDGET_H_ #include #include class KPixmapSequence; /** * \class KPixmapSequenceWidget kpixmapsequencewidget.h KPixmapSequenceWidget * * \brief A simple widget showing a fixed size pixmap sequence. * * The KPixmapSequenceWidget uses the KPixmapSequenceOverlayPainter to show a * sequence of pixmaps. It is intended as a simple wrapper around the * KPixmapSequenceOverlayPainter in case a widget is more appropriate than * an event filter. * * \author Sebastian Trueg * * \since 4.4 */ class KWIDGETSADDONS_EXPORT KPixmapSequenceWidget : public QWidget { Q_OBJECT Q_PROPERTY(int interval READ interval WRITE setInterval) public: /** * Constructor */ - KPixmapSequenceWidget(QWidget *parent = 0); - KPixmapSequenceWidget(const KPixmapSequence &seq, QWidget *parent = 0); + KPixmapSequenceWidget(QWidget *parent = nullptr); + KPixmapSequenceWidget(const KPixmapSequence &seq, QWidget *parent = nullptr); /** * Destructor */ ~KPixmapSequenceWidget(); /** * The sequence used to draw the overlay. * * \sa setSequence */ KPixmapSequence sequence() const; /** * The interval between frames. * * \sa setInterval, KPixmapSequenceOverlayPainter::interval */ int interval() const; /** * \reimpl */ QSize sizeHint() const Q_DECL_OVERRIDE; public Q_SLOTS: /** * Set the sequence to be used. By default the KDE busy sequence is used. */ void setSequence(const KPixmapSequence &seq); /** * Set the interval between frames. The default is 200. * \sa interval, KPixmapSequenceOverlayPainter::setInterval */ void setInterval(int msecs); private: class Private; Private *const d; }; #endif diff --git a/src/kpopupframe.cpp b/src/kpopupframe.cpp index 141beb1..915fbcb 100644 --- a/src/kpopupframe.cpp +++ b/src/kpopupframe.cpp @@ -1,193 +1,193 @@ /* -*- C++ -*- This file is part of the KDE libraries Copyright (C) 1997 Tim D. Gilman (tdgilman@best.org) (C) 1998-2001 Mirko Boehm (mirko@kde.org) (C) 2007 John Layt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kpopupframe.h" #include #include #include #include class KPopupFrame::KPopupFramePrivate { public: KPopupFramePrivate(KPopupFrame *q); ~KPopupFramePrivate(); KPopupFrame *q; /** * The result. It is returned from exec() when the popup window closes. */ int result; /** * The only subwidget that uses the whole dialog window. */ QWidget *main; // ### KDE 5: Remove this, add a hideEvent() reimplementation instead. class OutsideClickCatcher; OutsideClickCatcher *outsideClickCatcher; }; class KPopupFrame::KPopupFramePrivate::OutsideClickCatcher : public QObject { public: - OutsideClickCatcher(QObject *parent = 0) - : QObject(parent), m_popup(0) { } + OutsideClickCatcher(QObject *parent = nullptr) + : QObject(parent), m_popup(nullptr) { } ~OutsideClickCatcher() { } void setPopupFrame(KPopupFrame *popup) { m_popup = popup; popup->installEventFilter(this); } KPopupFrame *m_popup; bool eventFilter(QObject *object, QEvent *event) Q_DECL_OVERRIDE { Q_UNUSED(object); // To catch outside clicks, it is sufficient to check for // hide events on Qt::Popup type widgets if (event->type() == QEvent::Hide && m_popup) { // do not set d->result here, because the popup // hides itself after leaving the event loop. emit m_popup->leaveModality(); } return false; } }; KPopupFrame::KPopupFramePrivate::KPopupFramePrivate(KPopupFrame *q): q(q), result(0), // rejected - main(0), + main(nullptr), outsideClickCatcher(new OutsideClickCatcher) { outsideClickCatcher->setPopupFrame(q); } KPopupFrame::KPopupFramePrivate::~KPopupFramePrivate() { delete outsideClickCatcher; } KPopupFrame::KPopupFrame(QWidget *parent) : QFrame(parent, Qt::Popup), d(new KPopupFramePrivate(this)) { setFrameStyle(QFrame::Box | QFrame::Raised); setMidLineWidth(2); } KPopupFrame::~KPopupFrame() { delete d; } void KPopupFrame::keyPressEvent(QKeyEvent *e) { if (e->key() == Qt::Key_Escape) { d->result = 0; // rejected emit leaveModality(); //qApp->exit_loop(); } } void KPopupFrame::hideEvent(QHideEvent *e) { QFrame::hideEvent(e); } void KPopupFrame::close(int r) { d->result = r; emit leaveModality(); //qApp->exit_loop(); } void KPopupFrame::setMainWidget(QWidget *m) { d->main = m; if (d->main) { resize(d->main->width() + 2 * frameWidth(), d->main->height() + 2 * frameWidth()); } } void KPopupFrame::resizeEvent(QResizeEvent *e) { Q_UNUSED(e); if (d->main) { d->main->setGeometry(frameWidth(), frameWidth(), width() - 2 * frameWidth(), height() - 2 * frameWidth()); } } void KPopupFrame::popup(const QPoint &pos) { // Make sure the whole popup is visible. QRect desktopGeometry = QApplication::desktop()->screenGeometry(pos); int x = pos.x(); int y = pos.y(); int w = width(); int h = height(); if (x + w > desktopGeometry.x() + desktopGeometry.width()) { x = desktopGeometry.width() - w; } if (y + h > desktopGeometry.y() + desktopGeometry.height()) { y = desktopGeometry.height() - h; } if (x < desktopGeometry.x()) { x = 0; } if (y < desktopGeometry.y()) { y = 0; } // Pop the thingy up. move(x, y); show(); d->main->setFocus(); } int KPopupFrame::exec(const QPoint &pos) { popup(pos); repaint(); d->result = 0; // rejected QEventLoop eventLoop; connect(this, &KPopupFrame::leaveModality, &eventLoop, &QEventLoop::quit); eventLoop.exec(); hide(); return d->result; } int KPopupFrame::exec(int x, int y) { return exec(QPoint(x, y)); } diff --git a/src/kpopupframe.h b/src/kpopupframe.h index 5cb70ce..72c42e9 100644 --- a/src/kpopupframe.h +++ b/src/kpopupframe.h @@ -1,106 +1,106 @@ /* -*- C++ -*- This file is part of the KDE libraries Copyright (C) 1997 Tim D. Gilman (tdgilman@best.org) (C) 1998-2001 Mirko Boehm (mirko@kde.org) (C) 2007 John Layt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KPOPUPFRAME_H #define KPOPUPFRAME_H #include #include /** * Frame with popup menu behavior. * @author Tim Gilman, Mirko Boehm */ class KWIDGETSADDONS_EXPORT KPopupFrame : public QFrame { Q_OBJECT protected: /** * Catch key press events. */ void keyPressEvent(QKeyEvent *e) Q_DECL_OVERRIDE; /** * Catch hide events. */ void hideEvent(QHideEvent *e) Q_DECL_OVERRIDE; public Q_SLOTS: /** * Close the popup window. This is called from the main widget, usually. * @p r is the result returned from exec(). */ void close(int r); public: /** * The contructor. Creates a dialog without buttons. */ - KPopupFrame(QWidget *parent = 0); + KPopupFrame(QWidget *parent = nullptr); /** * The destructor */ ~KPopupFrame(); /** * Set the main widget. You cannot set the main widget from the constructor, * since it must be a child of the frame itselfes. * Be careful: the size is set to the main widgets size. It is up to you to * set the main widgets correct size before setting it as the main * widget. */ void setMainWidget(QWidget *m); /** * The resize event. Simply resizes the main widget to the whole * widgets client size. */ void resizeEvent(QResizeEvent *resize) Q_DECL_OVERRIDE; /** * Open the popup window at position pos. */ void popup(const QPoint &pos); /** * Execute the popup window. */ int exec(const QPoint &p); /** * Execute the popup window. */ int exec(int x, int y); Q_SIGNALS: void leaveModality(); private: class KPopupFramePrivate; friend class KPopupFramePrivate; KPopupFramePrivate *const d; Q_DISABLE_COPY(KPopupFrame) }; #endif // KPOPUPFRAME_H diff --git a/src/kratingwidget.h b/src/kratingwidget.h index 215519d..84c04d8 100644 --- a/src/kratingwidget.h +++ b/src/kratingwidget.h @@ -1,216 +1,216 @@ /* * This file is part of the KDE libraries * Copyright (C) 2006-2007 Sebastian Trueg * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KRATINGWIDGET_H #define KRATINGWIDGET_H #include #include /** * \class KRatingWidget kratingwidget.h KDE/KRatingWidget * * \brief Displays a rating value as a row of pixmaps. * * The KRatingWidget displays a range of stars or other arbitrary * pixmaps and allows the user to select a certain number by mouse. * * \sa KRatingPainter * * \author Sebastian Trueg */ class KWIDGETSADDONS_EXPORT KRatingWidget : public QFrame { Q_OBJECT Q_PROPERTY(int rating READ rating WRITE setRating) Q_PROPERTY(int maxRating READ maxRating WRITE setMaxRating) Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment) Q_PROPERTY(bool halfStepsEnabled READ halfStepsEnabled WRITE setHalfStepsEnabled) Q_PROPERTY(int spacing READ spacing WRITE setSpacing) Q_PROPERTY(QIcon icon READ icon WRITE setIcon) public: /** * Creates a new rating widget. */ - KRatingWidget(QWidget *parent = 0); + KRatingWidget(QWidget *parent = nullptr); /** * Destructor */ ~KRatingWidget(); /** * \return The current rating. */ unsigned int rating() const; /** * \return the maximum possible rating. */ int maxRating() const; /** * The alignment of the stars. * * \sa setAlignment */ Qt::Alignment alignment() const; /** * The layout direction. If RTL the stars * representing the rating value will be drawn from the * right. * * \sa setLayoutDirection */ Qt::LayoutDirection layoutDirection() const; /** * The spacing between the rating stars. * * \sa setSpacing */ int spacing() const; QSize sizeHint() const Q_DECL_OVERRIDE; /** * If half steps are enabled one star equals to 2 rating * points and uneven rating values result in half-stars being * drawn. * * \sa setHalfStepsEnabled */ bool halfStepsEnabled() const; /** * The icon used to draw a star. In case a custom pixmap has been set * this value is ignored. * * \sa setIcon, setCustomPixmap */ QIcon icon() const; Q_SIGNALS: /** * This signal is emitted when the rating is changed. */ void ratingChanged(unsigned int rating); void ratingChanged(int rating); public Q_SLOTS: /** * Set the current rating. Calling this method will trigger the * ratingChanged signal if @p rating is different from the previous rating. */ void setRating(int rating); /** * \deprecated use setRating( int rating ) */ #ifndef KWIDGETSADDONS_NO_DEPRECATED KWIDGETSADDONS_DEPRECATED void setRating(unsigned int rating); #endif /** * Set the maximum allowed rating value. The default is 10 which means * that a rating from 1 to 10 is selectable. If \a max is uneven steps * are automatically only allowed full. */ void setMaxRating(int max); /** * \deprecated use setMaxRating( int max ) */ #ifndef KWIDGETSADDONS_NO_DEPRECATED KWIDGETSADDONS_DEPRECATED void setMaxRating(unsigned int max); #endif /** * If half steps are enabled (the default) then * one rating step corresponds to half a star. */ void setHalfStepsEnabled(bool enabled); /** * \deprecated Use setHalfStepsEnabled */ #ifndef KWIDGETSADDONS_NO_DEPRECATED KWIDGETSADDONS_DEPRECATED void setOnlyPaintFullSteps(bool); #endif /** * Set the spacing between the pixmaps. The default is 0. */ void setSpacing(int); /** * The alignment of the stars in the drawing rect. * All alignment flags are supported. */ void setAlignment(Qt::Alignment align); /** * LTR or RTL */ void setLayoutDirection(Qt::LayoutDirection direction); /** * Set a custom icon. Defaults to "rating". */ void setIcon(const QIcon &icon); /** * Set a custom pixmap. */ void setCustomPixmap(const QPixmap &pixmap); /** * Set the pixap to be used to display a rating step. * By default the "rating" pixmap is loaded. * * \deprecated use setCustomPixmap */ #ifndef KWIDGETSADDONS_NO_DEPRECATED KWIDGETSADDONS_DEPRECATED void setPixmap(const QPixmap &); #endif /** * Set the recommended size of the pixmaps. This is * only used for the sizeHint. The actual size is always * dependent on the size of the widget itself. */ void setPixmapSize(int size); protected: void mousePressEvent(QMouseEvent *e) Q_DECL_OVERRIDE; void mouseMoveEvent(QMouseEvent *e) Q_DECL_OVERRIDE; void leaveEvent(QEvent *e) Q_DECL_OVERRIDE; void paintEvent(QPaintEvent *e) Q_DECL_OVERRIDE; void resizeEvent(QResizeEvent *e) Q_DECL_OVERRIDE; private: class Private; Private *const d; }; #endif diff --git a/src/kruler.h b/src/kruler.h index 8c0b6bb..3a2a0c3 100644 --- a/src/kruler.h +++ b/src/kruler.h @@ -1,384 +1,384 @@ /* -*- c++ -*- */ /* This file is part of the KDE libraries Copyright (C) 1998 Jörg Habenicht (j.habenicht@europemail.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KRULER_H #define KRULER_H #include #include /** * A ruler widget. * * The vertical ruler looks similar to this: * *\code * meters inches * * ------ <--- end mark ---> ------ * -- - * -- <---little mark---> -- * -- - * -- --- * --- <---medium mark - * -- -- * -- tiny mark----> - * -- ---- * -- - * ---- <-----big mark -- * -- - * |>-- <--ruler pointer--> |>-- * * \endcode * * There are tiny marks, little marks, medium marks, and big marks along the * ruler. * * To receive mouse clicks or mouse moves, the class has to be overloaded. * * \image html kruler.png "KDE Ruler Widget" * * @short A ruler widget. * @author Jörg Habenicht */ class KWIDGETSADDONS_EXPORT KRuler : public QAbstractSlider { Q_OBJECT Q_PROPERTY(bool showTinyMarks READ showTinyMarks WRITE setShowTinyMarks) Q_PROPERTY(bool showLittleMarks READ showLittleMarks WRITE setShowLittleMarks) Q_PROPERTY(bool showMediumMarks READ showMediumMarks WRITE setShowMediumMarks) Q_PROPERTY(bool showBigMarks READ showBigMarks WRITE setShowBigMarks) Q_PROPERTY(bool showPointer READ showPointer WRITE setShowPointer) Q_PROPERTY(bool showEndLabel READ showEndLabel WRITE setShowEndLabel) Q_PROPERTY(int tinyMarkDistance READ tinyMarkDistance WRITE setTinyMarkDistance) Q_PROPERTY(int littleMarkDistance READ littleMarkDistance WRITE setLittleMarkDistance) Q_PROPERTY(int mediumMarkDistance READ mediumMarkDistance WRITE setBigMarkDistance) Q_PROPERTY(int bigMarkDistance READ bigMarkDistance WRITE setBigMarkDistance) Q_PROPERTY(double pixelPerMark READ pixelPerMark WRITE setPixelPerMark) Q_PROPERTY(bool lengthFixed READ lengthFixed WRITE setLengthFixed) Q_PROPERTY(QString endLabel READ endLabel WRITE setEndLabel) Q_PROPERTY(int length READ length WRITE setLength) Q_PROPERTY(int offset READ offset) Q_PROPERTY(int endOffset READ endOffset) public: /** * The types of units used. **/ enum MetricStyle { Custom = 0, Pixel, Inch, Millimetres, Centimetres, Metres }; Q_ENUM(MetricStyle) /** * Constructs a horizontal ruler. */ - explicit KRuler(QWidget *parent = 0); + explicit KRuler(QWidget *parent = nullptr); /** * Constructs a ruler with orientation @p orient. * * @p parent and @p f are passed to QFrame. * The default look is a raised widget * but may be changed with the inherited QFrame methods. * * @param orient Orientation of the ruler. * @param parent Will be handed over to QFrame. * @param f Will be handed over to QFrame. * **/ - explicit KRuler(Qt::Orientation orient, QWidget *parent = 0, Qt::WindowFlags f = 0); + explicit KRuler(Qt::Orientation orient, QWidget *parent = nullptr, Qt::WindowFlags f = nullptr); /** * Constructs a ruler with orientation @p orient and initial width @p widgetWidth. * * The width sets the fixed width of the widget. This is useful if you * want to draw the ruler bigger or smaller than the default size. * Note: The size of the marks doesn't change. * @p parent and @p f are passed to QFrame. * * @param orient Orientation of the ruler. * @param widgetWidth Fixed width of the widget. * @param parent Will be handed over to QFrame. * @param f Will be handed over to QFrame. * */ - KRuler(Qt::Orientation orient, int widgetWidth, QWidget *parent = 0, - Qt::WindowFlags f = 0); + KRuler(Qt::Orientation orient, int widgetWidth, QWidget *parent = nullptr, + Qt::WindowFlags f = nullptr); /** * Destructor. */ ~KRuler(); /** * Sets the minimal value of the ruler pointer (default is 0). * * This method calls update() so that the widget is painted after leaving * to the main event loop. * **/ #ifndef KWIDGETSADDONS_NO_DEPRECATED KWIDGETSADDONS_DEPRECATED void setMinValue(int); #endif /** * Returns the minimal value of the ruler pointer. **/ #ifndef KWIDGETSADDONS_NO_DEPRECATED KWIDGETSADDONS_DEPRECATED int minValue() const; #endif /** * Sets the maximum value of the ruler pointer (default is 100). * * This method calls update() so that the widget is painted after leaving * to the main event loop. */ #ifndef KWIDGETSADDONS_NO_DEPRECATED KWIDGETSADDONS_DEPRECATED void setMaxValue(int); #endif /** * Returns the maximal value of the ruler pointer. */ #ifndef KWIDGETSADDONS_NO_DEPRECATED KWIDGETSADDONS_DEPRECATED int maxValue() const; #endif /** * Sets the distance between tiny marks. * * This is mostly used in the English system (inches) with distance of 1. */ void setTinyMarkDistance(int); /** * Returns the distance between tiny marks. **/ int tinyMarkDistance() const; /** * Sets the distance between little marks. * * The default value is 1 in the metric system and 2 in the English (inches) system. */ void setLittleMarkDistance(int); /** * Returns the distance between little marks. */ int littleMarkDistance() const; /** * Sets the distance between medium marks. * * For English (inches) styles it defaults to twice the little mark distance. * For metric styles it defaults to five times the little mark distance. **/ void setMediumMarkDistance(int); int mediumMarkDistance() const; /** * Sets distance between big marks. * * For English (inches) or metric styles it is twice the medium mark distance. **/ void setBigMarkDistance(int); /** * Returns the distance between big marks. **/ int bigMarkDistance() const; /** * Shows/hides tiny marks. **/ void setShowTinyMarks(bool); bool showTinyMarks() const; /** * Shows/hides little marks. **/ void setShowLittleMarks(bool); bool showLittleMarks() const; /** * Shows/hides medium marks. **/ void setShowMediumMarks(bool); bool showMediumMarks() const; /** * Shows/hides big marks. **/ void setShowBigMarks(bool); bool showBigMarks() const; /** * Shows/hides end marks. **/ void setShowEndMarks(bool); bool showEndMarks() const; /** * Shows/hides the pointer. */ void setShowPointer(bool); bool showPointer() const; #ifndef KWIDGETSADDONS_NO_DEPRECATED KWIDGETSADDONS_DEPRECATED void setFrameStyle(int); #endif /** * Show/hide number values of the end marks. * * Default is @p false. **/ void setShowEndLabel(bool); bool showEndLabel() const; /** * Sets the label this is drawn at the beginning of the visible part * of the ruler to @p label **/ void setEndLabel(const QString &); QString endLabel() const; /** * Sets up the necessary tasks for the provided styles. * * A convenience method. **/ void setRulerMetricStyle(KRuler::MetricStyle); /** * Sets the number of pixels between two base marks. * * Calling this method stretches or shrinks your ruler. * * For pixel display ( MetricStyle) the value is 10.0 marks * per pixel ;-) * For English (inches) it is 9.0, and for centimetres ~2.835 -> 3.0 . * If you want to magnify your part of display, you have to * adjust the mark distance @p here. * Notice: The double type is only supported to give the possibility * of having some double values. * It should be used with care. Using values below 10.0 * shows visible jumps of markpositions (e.g. 2.345). * Using whole numbers is highly recommended. * To use @p int values use setPixelPerMark((int)your_int_value); * default: 1 mark per 10 pixels */ void setPixelPerMark(double rate); /** * Returns the number of pixels between two base marks. **/ double pixelPerMark() const; /** * Sets the length of the ruler, i.e. the difference between * the begin mark and the end mark of the ruler. * * Same as (width() - offset()) * * when the length is not locked, it gets adjusted with the * length of the widget. */ void setLength(int); int length() const; /** * Locks the length of the ruler, i.e. the difference between * the two end marks doesn't change when the widget is resized. * * @param fix fixes the length, if true */ void setLengthFixed(bool fix); bool lengthFixed() const; /** * Sets the number of pixels by which the ruler may slide up or left. * The number of pixels moved is realive to the previous position. * The Method makes sense for updating a ruler, which is working with * a scrollbar. * * This doesn't affect the position of the ruler pointer. * Only the visible part of the ruler is moved. * * @param count Number of pixel moving up or left relative to the previous position **/ void slideUp(int count = 1); /** * Sets the number of pixels by which the ruler may slide down or right. * The number of pixels moved is realive to the previous position. * The Method makes sense for updating a ruler, which is working with * a scrollbar. * * This doesn't affect the position of the ruler pointer. * Only the visible part of the ruler is moved. * * @param count Number of pixel moving up or left relative to the previous position **/ void slideDown(int count = 1); /** * Sets the ruler slide offset. * * This is like slideup() or slidedown() with an absolute offset * from the start of the ruler. * * @param offset Number of pixel to move the ruler up or left from the beginning **/ void setOffset(int offset); /** * Returns the current ruler offset. **/ int offset() const; int endOffset() const; public Q_SLOTS: /** * Sets the pointer to a new position. * * The offset is NOT updated. * QWidget::repaint() is called afterwards. **/ void slotNewValue(int); /** * Sets the ruler marks to a new position. * * The pointer is NOT updated. * QWidget::repaint() is called afterwards. **/ void slotNewOffset(int); void slotEndOffset(int); protected: void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE; private: void initWidget(Qt::Orientation orientation); private: class KRulerPrivate; KRulerPrivate *const d; }; #endif diff --git a/src/kselectaction.cpp b/src/kselectaction.cpp index 5818e57..26cf7b2 100644 --- a/src/kselectaction.cpp +++ b/src/kselectaction.cpp @@ -1,780 +1,780 @@ /* This file is part of the KDE libraries Copyright (C) 1999 Reginald Stadlbauer (C) 1999 Simon Hausmann (C) 2000 Nicolas Hadacek (C) 2000 Kurt Granroth (C) 2000 Michael Koch (C) 2001 Holger Freyther (C) 2002 Ellis Whitehead (C) 2002 Joseph Wenninger (C) 2003 Andras Mantia (C) 2005-2006 Hamish Rodda (C) 2006 Albert Astals Cid (C) 2006 Clarence Dang (C) 2006 Michel Hermier (C) 2007 Nick Shaforostoff This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kselectaction.h" #include "kselectaction_p.h" #include "loggingcategory.h" #include #include #include #include #include #include #include // QAction::setText("Hi") and then KPopupAccelManager exec'ing, causes // QAction::text() to return "&Hi" :( Comboboxes don't have accels and // display ampersands literally. static QString DropAmpersands(const QString &text) { QString label = text; int p = label.indexOf(QLatin1Char('&')); while (p >= 0 && p < label.length() - 1) { if (label[p + 1].isLetterOrNumber() // Valid accelerator. || label[p + 1] == QLatin1Char('&')) { // Escaped accelerator marker. label = label.left(p) + label.mid(p + 1); } p = label.indexOf(QLatin1Char('&'), p + 1); } return label; } KSelectAction::KSelectAction(QObject *parent) : QWidgetAction(parent) , d_ptr(new KSelectActionPrivate()) { Q_D(KSelectAction); d->init(this); } KSelectAction::KSelectAction(const QString &text, QObject *parent) : QWidgetAction(parent) , d_ptr(new KSelectActionPrivate()) { Q_D(KSelectAction); d->init(this); setText(text); } KSelectAction::KSelectAction(const QIcon &icon, const QString &text, QObject *parent) : QWidgetAction(parent) , d_ptr(new KSelectActionPrivate()) { Q_D(KSelectAction); setIcon(icon); setText(text); d->init(this); } KSelectAction::KSelectAction(KSelectActionPrivate &dd, QObject *parent) : QWidgetAction(parent) , d_ptr(&dd) { Q_D(KSelectAction); d->init(this); } KSelectAction::~KSelectAction() { menu()->deleteLater(); delete d_ptr; } void KSelectActionPrivate::init(KSelectAction *q) { q_ptr = q; QObject::connect(q_ptr->selectableActionGroup(), &QActionGroup::triggered, q_ptr, &KSelectAction::actionTriggered); QObject::connect(q_ptr, &QAction::toggled, q_ptr, &KSelectAction::slotToggled); q_ptr->setMenu(new QMenu()); q_ptr->setEnabled(false); } QActionGroup *KSelectAction::selectableActionGroup() const { Q_D(const KSelectAction); return d->m_actionGroup; } QList KSelectAction::actions() const { return selectableActionGroup()->actions(); } QAction *KSelectAction::currentAction() const { return selectableActionGroup()->checkedAction(); } int KSelectAction::currentItem() const { return selectableActionGroup()->actions().indexOf(currentAction()); } QString KSelectAction::currentText() const { if (QAction *a = currentAction()) { return ::DropAmpersands(a->text()); } return QString(); } bool KSelectAction::setCurrentAction(QAction *action) { //qCDebug(KWidgetsAddonsLog) << "KSelectAction::setCurrentAction(" << action << ")"; if (action) { if (actions().contains(action)) { if (action->isVisible() && action->isEnabled() && action->isCheckable()) { action->setChecked(true); if (isCheckable()) { setChecked(true); } return true; } else { qCWarning(KWidgetsAddonsLog) << "Action does not have the correct properties to be current:" << action->text(); } } else { qCWarning(KWidgetsAddonsLog) << "Action does not belong to group:" << action->text(); } return false; } if (currentAction()) { currentAction()->setChecked(false); } return false; } bool KSelectAction::setCurrentItem(int index) { //qCDebug(KWidgetsAddonsLog) << "KSelectAction::setCurrentIndex(" << index << ")"; return setCurrentAction(action(index)); } QAction *KSelectAction::action(int index) const { if (index >= 0 && index < selectableActionGroup()->actions().count()) { return selectableActionGroup()->actions().at(index); } - return 0L; + return nullptr; } QAction *KSelectAction::action(const QString &text, Qt::CaseSensitivity cs) const { QString compare; if (cs == Qt::CaseSensitive) { compare = text; } else { compare = text.toLower(); } foreach (QAction *action, selectableActionGroup()->actions()) { const QString text = ::DropAmpersands(action->text()); if (cs == Qt::CaseSensitive) { if (text == compare) { return action; } } else if (cs == Qt::CaseInsensitive) { if (text.toLower() == compare) { return action; } } } - return 0L; + return nullptr; } bool KSelectAction::setCurrentAction(const QString &text, Qt::CaseSensitivity cs) { //qCDebug(KWidgetsAddonsLog) << "KSelectAction::setCurrentAction(" << text << ",cs=" << cs << ")"; return setCurrentAction(action(text, cs)); } void KSelectAction::setComboWidth(int width) { Q_D(KSelectAction); if (width < 0) { return; } d->m_comboWidth = width; foreach (QComboBox *box, d->m_comboBoxes) { box->setMaximumWidth(d->m_comboWidth); } emit changed(); } void KSelectAction::setMaxComboViewCount(int n) { Q_D(KSelectAction); d->m_maxComboViewCount = n; foreach (QComboBox *box, d->m_comboBoxes) if (d->m_maxComboViewCount != -1) { box->setMaxVisibleItems(d->m_maxComboViewCount); } else // hardcoded qt default { box->setMaxVisibleItems(10); } emit changed(); } void KSelectAction::addAction(QAction *action) { - insertAction(0, action); + insertAction(nullptr, action); } QAction *KSelectAction::addAction(const QString &text) { Q_D(KSelectAction); QAction *newAction = new QAction(parent()); newAction->setText(text); newAction->setCheckable(true); newAction->setProperty("isShortcutConfigurable", false); if (!d->m_menuAccelsEnabled) { newAction->setText(text); newAction->setShortcut(QKeySequence()); } addAction(newAction); return newAction; } QAction *KSelectAction::addAction(const QIcon &icon, const QString &text) { QAction *newAction = addAction(text); newAction->setIcon(icon); return newAction; } QAction *KSelectAction::removeAction(QAction *action) { Q_D(KSelectAction); //qCDebug(KWidgetsAddonsLog) << "KSelectAction::removeAction(" << action << ")"; //int index = selectableActionGroup()->actions().indexOf(action); //qCDebug(KWidgetsAddonsLog) << "\tindex=" << index; // Removes the action from the group and sets its parent to null. d->m_actionGroup->removeAction(action); // Disable when no action is in the group bool hasActions = selectableActionGroup()->actions().isEmpty(); setEnabled(!hasActions); foreach (QToolButton *button, d->m_buttons) { button->setEnabled(!hasActions); button->removeAction(action); } foreach (QComboBox *comboBox, d->m_comboBoxes) { comboBox->setEnabled(!hasActions); comboBox->removeAction(action); } menu()->removeAction(action); return action; } void KSelectAction::insertAction(QAction *before, QAction *action) { Q_D(KSelectAction); action->setActionGroup(selectableActionGroup()); // Re-Enable when an action is added setEnabled(true); // Keep in sync with createToolBarWidget() foreach (QToolButton *button, d->m_buttons) { button->setEnabled(true); button->insertAction(before, action); } foreach (QComboBox *comboBox, d->m_comboBoxes) { comboBox->setEnabled(true); comboBox->insertAction(before, action); } menu()->insertAction(before, action); } void KSelectAction::actionTriggered(QAction *action) { // cache values so we don't need access to members in the action // after we've done an emit() const QString text = ::DropAmpersands(action->text()); const int index = selectableActionGroup()->actions().indexOf(action); //qCDebug(KWidgetsAddonsLog) << "KSelectAction::actionTriggered(" << action << ") text=" << text // << " index=" << index << " emitting triggered()" << endl; if (isCheckable()) { // if this is subsidiary of other KSelectAction-derived class trigger(); // then imitate usual QAction behaviour so that other submenus (and their items) become unchecked } emit triggered(action); emit triggered(index); emit triggered(text); } QStringList KSelectAction::items() const { Q_D(const KSelectAction); QStringList ret; foreach (QAction *action, d->m_actionGroup->actions()) { ret << ::DropAmpersands(action->text()); } return ret; } void KSelectAction::changeItem(int index, const QString &text) { Q_D(KSelectAction); if (index < 0 || index >= actions().count()) { qCWarning(KWidgetsAddonsLog) << "KSelectAction::changeItem Index out of scope"; return; } actions()[index]->setText(d->makeMenuText(text)); } void KSelectAction::setItems(const QStringList &lst) { Q_D(KSelectAction); //qCDebug(KWidgetsAddonsLog) << "KSelectAction::setItems(" << lst << ")"; clear(); foreach (const QString &string, lst) { if (!string.isEmpty()) { addAction(string); } else { QAction *action = new QAction(this); action->setSeparator(true); addAction(action); } } // Disable if empty and not editable setEnabled(lst.count() > 0 || d->m_edit); } int KSelectAction::comboWidth() const { Q_D(const KSelectAction); return d->m_comboWidth; } void KSelectAction::clear() { Q_D(KSelectAction); //qCDebug(KWidgetsAddonsLog) << "KSelectAction::clear()"; // we need to delete the actions later since we may get a call to clear() // from a method called due to a triggered(...) signal const QList actions = d->m_actionGroup->actions(); for (int i = 0; i < actions.count(); ++i) { // deleteLater() only removes us from the actions() list (among // other things) on the next entry into the event loop. Until then, // e.g. action() and setCurrentItem() will be working on items // that are supposed to have been deleted. So detach the action to // prevent this from happening. removeAction(actions[i]); actions[i]->deleteLater(); } } void KSelectAction::removeAllActions() { Q_D(KSelectAction); while (d->m_actionGroup->actions().count()) { removeAction(d->m_actionGroup->actions().first()); } } void KSelectAction::setEditable(bool edit) { Q_D(KSelectAction); d->m_edit = edit; foreach (QComboBox *comboBox, d->m_comboBoxes) { comboBox->setEditable(edit); } emit changed(); } bool KSelectAction::isEditable() const { Q_D(const KSelectAction); return d->m_edit; } void KSelectAction::slotToggled(bool checked) { //if (checked && selectableActionGroup()->checkedAction()) if (!checked && currentAction()) { // other's submenu item has been selected currentAction()->setChecked(false); } } KSelectAction::ToolBarMode KSelectAction::toolBarMode() const { Q_D(const KSelectAction); return d->m_toolBarMode; } void KSelectAction::setToolBarMode(ToolBarMode mode) { Q_D(KSelectAction); d->m_toolBarMode = mode; } QToolButton::ToolButtonPopupMode KSelectAction::toolButtonPopupMode() const { Q_D(const KSelectAction); return d->m_toolButtonPopupMode; } void KSelectAction::setToolButtonPopupMode(QToolButton::ToolButtonPopupMode mode) { Q_D(KSelectAction); d->m_toolButtonPopupMode = mode; } void KSelectActionPrivate::_k_comboBoxDeleted(QObject *object) { foreach (QComboBox *comboBox, m_comboBoxes) if (object == comboBox) { m_comboBoxes.removeAll(static_cast(object)); break; } } void KSelectActionPrivate::_k_comboBoxCurrentIndexChanged(int index) { Q_Q(KSelectAction); //qCDebug(KWidgetsAddonsLog) << "KSelectActionPrivate::_k_comboBoxCurrentIndexChanged(" << index << ")"; QComboBox *triggeringCombo = qobject_cast (q->sender()); QAction *a = q->action(index); //qCDebug(KWidgetsAddonsLog) << "\ta=" << a; if (a) { //qCDebug(KWidgetsAddonsLog) << "\t\tsetting as current action"; a->trigger(); } else if (q->isEditable() && triggeringCombo && triggeringCombo->count() > 0 && index == triggeringCombo->count() - 1) { // User must have added a new item by typing and pressing enter. const QString newItemText = triggeringCombo->currentText(); //qCDebug(KWidgetsAddonsLog) << "\t\tuser typed new item '" << newItemText << "'"; // Only 1 combobox contains this and it's not a proper action. bool blocked = triggeringCombo->blockSignals(true); triggeringCombo->removeItem(index); triggeringCombo->blockSignals(blocked); QAction *newAction = q->addAction(newItemText); newAction->trigger(); } else { if (q->selectableActionGroup()->checkedAction()) { q->selectableActionGroup()->checkedAction()->setChecked(false); } } } // TODO: DropAmpersands() certainly makes sure this doesn't work. But I don't // think it did anyway esp. in the presence KCheckAccelerator - Clarence. void KSelectAction::setMenuAccelsEnabled(bool b) { Q_D(KSelectAction); d->m_menuAccelsEnabled = b; } bool KSelectAction::menuAccelsEnabled() const { Q_D(const KSelectAction); return d->m_menuAccelsEnabled; } QWidget *KSelectAction::createWidget(QWidget *parent) { Q_D(KSelectAction); QMenu *menu = qobject_cast(parent); if (menu) { // If used in a menu want to return 0 and use only the text, not a widget - return 0; + return nullptr; } ToolBarMode mode = toolBarMode(); QToolBar *toolBar = qobject_cast(parent); if (!toolBar && mode != ComboBoxMode) { // we can return a combobox just fine. - return 0; + return nullptr; } switch (mode) { case MenuMode: { QToolButton *button = new QToolButton(toolBar); button->setToolTip(toolTip()); button->setWhatsThis(whatsThis()); button->setStatusTip(statusTip()); button->setAutoRaise(true); button->setFocusPolicy(Qt::NoFocus); button->setIconSize(toolBar->iconSize()); button->setToolButtonStyle(toolBar->toolButtonStyle()); QObject::connect(toolBar, &QToolBar::iconSizeChanged, button, &QAbstractButton::setIconSize); QObject::connect(toolBar, &QToolBar::toolButtonStyleChanged, button, &QToolButton::setToolButtonStyle); button->setDefaultAction(this); QObject::connect(button, &QToolButton::triggered, toolBar, &QToolBar::actionTriggered); button->setPopupMode(toolButtonPopupMode()); button->addActions(selectableActionGroup()->actions()); d->m_buttons.append(button); return button; } case ComboBoxMode: { QComboBox *comboBox = new QComboBox(parent); comboBox->installEventFilter(this); if (d->m_maxComboViewCount != -1) { comboBox->setMaxVisibleItems(d->m_maxComboViewCount); } if (d->m_comboWidth > 0) { comboBox->setMaximumWidth(d->m_comboWidth); } comboBox->setEditable(isEditable()); comboBox->setToolTip(toolTip()); comboBox->setWhatsThis(whatsThis()); comboBox->setStatusTip(statusTip()); foreach (QAction *action, selectableActionGroup()->actions()) { comboBox->addAction(action); } if (selectableActionGroup()->actions().isEmpty()) { comboBox->setEnabled(false); } connect(comboBox, SIGNAL(destroyed(QObject*)), SLOT(_k_comboBoxDeleted(QObject*))); connect(comboBox, SIGNAL(currentIndexChanged(int)), SLOT(_k_comboBoxCurrentIndexChanged(int))); d->m_comboBoxes.append(comboBox); return comboBox; } } - return 0L; + return nullptr; } void KSelectAction::deleteWidget(QWidget *widget) { Q_D(KSelectAction); if (QToolButton *toolButton = qobject_cast(widget)) { d->m_buttons.removeAll(toolButton); } else if (QComboBox *comboBox = qobject_cast(widget)) { d->m_comboBoxes.removeAll(comboBox); } QWidgetAction::deleteWidget(widget); } bool KSelectAction::event(QEvent *event) { Q_D(KSelectAction); if (event->type() == QEvent::ActionChanged) { Q_FOREACH (QComboBox *comboBox, d->m_comboBoxes) { comboBox->setToolTip(toolTip()); comboBox->setWhatsThis(whatsThis()); comboBox->setStatusTip(statusTip()); } Q_FOREACH (QToolButton *toolButton, d->m_buttons) { toolButton->setToolTip(toolTip()); toolButton->setWhatsThis(whatsThis()); toolButton->setStatusTip(statusTip()); } } return QWidgetAction::event(event); } // KSelectAction::eventFilter() is called before action->setChecked() // invokes the signal to update QActionGroup so KSelectAction::currentItem() // returns an old value. There are 3 possibilities, where n actions will // report QAction::isChecked() where n is: // // 0: the checked action was unchecked // 1: the checked action did not change // 2: another action was checked but QActionGroup has not been invoked yet // to uncheck the one that was checked before // // TODO: we might want to cache this since QEvent::ActionChanged is fired // often. static int TrueCurrentItem(KSelectAction *sa) { QAction *curAction = sa->currentAction(); //qCDebug(KWidgetsAddonsLog) << "\tTrueCurrentItem(" << sa << ") curAction=" << curAction; foreach (QAction *action, sa->actions()) { if (action->isChecked()) { //qCDebug(KWidgetsAddonsLog) << "\t\taction " << action << " (text=" << action->text () << ") isChecked"; // 2 actions checked case? if (action != curAction) { //qCDebug(KWidgetsAddonsLog) << "\t\t\tmust be newly selected one"; return sa->actions().indexOf(action); } } } //qCDebug(KWidgetsAddonsLog) << "\t\tcurrent action still selected? " << (curAction && curAction->isChecked ()); // 1 or 0 actions checked case (in that order)? return (curAction && curAction->isChecked()) ? sa->actions().indexOf(curAction) : -1; } bool KSelectAction::eventFilter(QObject *watched, QEvent *event) { QComboBox *comboBox = qobject_cast (watched); if (!comboBox) { return false/*propagate event*/; } // If focus is lost, replace any edited text with the currently selected // item. if (event->type() == QEvent::FocusOut) { QFocusEvent *const e = static_cast (event); //qCDebug(KWidgetsAddonsLog) << "KSelectAction::eventFilter(FocusOut)" // << " comboBox: ptr=" << comboBox // << " reason=" << e->reason () // << endl; if (e->reason() != Qt::ActiveWindowFocusReason/*switch window*/ && e->reason() != Qt::PopupFocusReason/*menu*/ && e->reason() != Qt::OtherFocusReason/*inconsistently reproduceable actions...*/) { //qCDebug(KWidgetsAddonsLog) << "\tkilling text"; comboBox->setEditText(comboBox->itemText(comboBox->currentIndex())); } return false/*propagate event*/; } bool blocked = comboBox->blockSignals(true); if (event->type() == QEvent::ActionAdded) { QActionEvent *const e = static_cast (event); const int index = e->before() ? comboBox->findData(QVariant::fromValue(e->before())) : comboBox->count(); const int newItem = ::TrueCurrentItem(this); //qCDebug(KWidgetsAddonsLog) << "KSelectAction::eventFilter(ActionAdded)" // << " comboBox: ptr=" << comboBox // << " currentItem=" << comboBox->currentIndex () // << " add index=" << index // << " action new: e->before=" << e->before () // << " ptr=" << e->action () // << " icon=" << e->action ()->icon () // << " text=" << e->action ()->text () // << " currentItem=" << newItem // << endl; comboBox->insertItem(index, e->action()->icon(), ::DropAmpersands(e->action()->text()), QVariant::fromValue(e->action())); if (QStandardItemModel *model = qobject_cast(comboBox->model())) { QStandardItem *item = model->item(index); item->setEnabled(e->action()->isEnabled()); } // Inserting an item into a combobox can change the current item so // make sure the item corresponding to the checked action is selected. comboBox->setCurrentIndex(newItem); } else if (event->type() == QEvent::ActionChanged) { QActionEvent *const e = static_cast (event); const int index = comboBox->findData(QVariant::fromValue(e->action())); const int newItem = ::TrueCurrentItem(this); //qCDebug(KWidgetsAddonsLog) << "KSelectAction::eventFilter(ActionChanged)" // << " comboBox: ptr=" << comboBox // << " currentItem=" << comboBox->currentIndex () // << " changed action's index=" << index // << " action new: ptr=" << e->action () // << " icon=" << e->action ()->icon () // << " text=" << e->action ()->text () // << " currentItem=" << newItem // << endl; comboBox->setItemIcon(index, e->action()->icon()); comboBox->setItemText(index, ::DropAmpersands(e->action()->text())); if (QStandardItemModel *model = qobject_cast(comboBox->model())) { QStandardItem *item = model->item(index); item->setEnabled(e->action()->isEnabled()); } // The checked action may have become unchecked so // make sure the item corresponding to the checked action is selected. comboBox->setCurrentIndex(newItem); } else if (event->type() == QEvent::ActionRemoved) { QActionEvent *const e = static_cast (event); const int index = comboBox->findData(QVariant::fromValue(e->action())); const int newItem = ::TrueCurrentItem(this); //qCDebug(KWidgetsAddonsLog) << "KSelectAction::eventFilter(ActionRemoved)" // << " comboBox: ptr=" << comboBox // << " currentItem=" << comboBox->currentIndex () // << " delete action index=" << index // << " new: currentItem=" << newItem // << endl; comboBox->removeItem(index); // Removing an item from a combobox can change the current item so // make sure the item corresponding to the checked action is selected. comboBox->setCurrentIndex(newItem); } comboBox->blockSignals(blocked); return false/*propagate event*/; } // END #include "moc_kselectaction.cpp" diff --git a/src/kselectaction_p.h b/src/kselectaction_p.h index 747a4ee..2610bb0 100644 --- a/src/kselectaction_p.h +++ b/src/kselectaction_p.h @@ -1,108 +1,108 @@ /* This file is part of the KDE libraries Copyright (C) 1999 Reginald Stadlbauer (C) 1999 Simon Hausmann (C) 2000 Nicolas Hadacek (C) 2000 Kurt Granroth (C) 2000 Michael Koch (C) 2001 Holger Freyther (C) 2002 Ellis Whitehead (C) 2002 Joseph Wenninger (C) 2003 Andras Mantia (C) 2005-2006 Hamish Rodda (C) 2006 Albert Astals Cid (C) 2006 Clarence Dang (C) 2006 Michel Hermier (C) 2007 Nick Shaforostoff This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KSELECTACTION_P_H #define KSELECTACTION_P_H #include class KSelectActionPrivate { Q_DECLARE_PUBLIC(KSelectAction) public: KSelectActionPrivate() - : q_ptr(0) + : q_ptr(nullptr) { m_edit = false; m_menuAccelsEnabled = true; m_comboWidth = -1; m_maxComboViewCount = -1; m_toolBarMode = KSelectAction::ComboBoxMode; m_toolButtonPopupMode = QToolButton::InstantPopup; //InstantPopup by default because there is no default action - m_actionGroup = new QActionGroup(0L); + m_actionGroup = new QActionGroup(nullptr); } virtual ~KSelectActionPrivate() { // unhook the event filter, as the deletion of the actiongroup // will trigger it Q_FOREACH (QComboBox *box, m_comboBoxes) { box->removeEventFilter(q_ptr); } Q_FOREACH (QToolButton *button, m_buttons) { button->removeEventFilter(q_ptr); } delete m_actionGroup; } void _k_comboBoxDeleted(QObject *); void _k_comboBoxCurrentIndexChanged(int); void init(KSelectAction *); bool m_edit : 1; bool m_menuAccelsEnabled : 1; int m_comboWidth; int m_maxComboViewCount; KSelectAction::ToolBarMode m_toolBarMode; QToolButton::ToolButtonPopupMode m_toolButtonPopupMode; QActionGroup *m_actionGroup; QList m_buttons; QList m_comboBoxes; QString makeMenuText(const QString &_text) { if (m_menuAccelsEnabled) { return _text; } QString text = _text; int i = 0; while (i < text.length()) { if (text[ i ] == QLatin1Char('&')) { text.insert(i, QLatin1Char('&')); i += 2; } else { ++i; } } return text; } KSelectAction *q_ptr; }; #endif // KSELECTACTION_P_H diff --git a/src/kselector.h b/src/kselector.h index 981b5b7..0ee6394 100644 --- a/src/kselector.h +++ b/src/kselector.h @@ -1,206 +1,206 @@ /* This file is part of the KDE libraries Copyright (C) 1997 Martin Jones (mjones@kde.org) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ //----------------------------------------------------------------------------- // Selector widgets for KDE Color Selector, but probably useful for other // stuff also. #ifndef KSELECTOR_H #define KSELECTOR_H #include #include #include #include /** * KSelector is the base class for other widgets which * provides the ability to choose from a one-dimensional * range of values. An example is the KGradientSelector * which allows to choose from a range of colors. * * A custom drawing routine for the widget surface has * to be provided by the subclass. */ class KWIDGETSADDONS_EXPORT KSelector : public QAbstractSlider { Q_OBJECT Q_PROPERTY(int value READ value WRITE setValue) Q_PROPERTY(int minValue READ minimum WRITE setMinimum) Q_PROPERTY(int maxValue READ maximum WRITE setMaximum) Q_PROPERTY(bool indent READ indent WRITE setIndent) Q_PROPERTY(Qt::ArrowType arrowDirection READ arrowDirection WRITE setArrowDirection) public: /** * Constructs a horizontal one-dimensional selection widget. */ - explicit KSelector(QWidget *parent = 0); + explicit KSelector(QWidget *parent = nullptr); /** * Constructs a one-dimensional selection widget with * a given orientation. */ - explicit KSelector(Qt::Orientation o, QWidget *parent = 0); + explicit KSelector(Qt::Orientation o, QWidget *parent = nullptr); /* * Destructs the widget. */ ~KSelector(); /** * @return the rectangle on which subclasses should draw. */ QRect contentsRect() const; /** * Sets the indent option of the widget to i. * This determines whether a shaded frame is drawn. */ void setIndent(bool i); /** * @return whether the indent option is set. */ bool indent() const; /** * Sets the arrow direction. */ void setArrowDirection(Qt::ArrowType direction); /** * @return the current arrow direction */ Qt::ArrowType arrowDirection() const; protected: /** * Override this function to draw the contents of the control. * The default implementation does nothing. * * Draw only within contentsRect(). */ virtual void drawContents(QPainter *); /** * Override this function to draw the cursor which * indicates the current value. */ virtual void drawArrow(QPainter *painter, const QPoint &pos); void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE; void mousePressEvent(QMouseEvent *e) Q_DECL_OVERRIDE; void mouseMoveEvent(QMouseEvent *e) Q_DECL_OVERRIDE; void mouseReleaseEvent(QMouseEvent *e) Q_DECL_OVERRIDE; void wheelEvent(QWheelEvent *) Q_DECL_OVERRIDE; private: QPoint calcArrowPos(int val); void moveArrow(const QPoint &pos); private: class Private; friend class Private; Private *const d; Q_DISABLE_COPY(KSelector) }; /** * The KGradientSelector widget allows the user to choose * from a one-dimensional range of colors which is given as a * gradient between two colors provided by the programmer. * * \image html kgradientselector.png "KDE Gradient Selector Widget" * **/ class KWIDGETSADDONS_EXPORT KGradientSelector : public KSelector { Q_OBJECT Q_PROPERTY(QColor firstColor READ firstColor WRITE setFirstColor) Q_PROPERTY(QColor secondColor READ secondColor WRITE setSecondColor) Q_PROPERTY(QString firstText READ firstText WRITE setFirstText) Q_PROPERTY(QString secondText READ secondText WRITE setSecondText) public: /** * Constructs a horizontal color selector which * contains a gradient between white and black. */ - explicit KGradientSelector(QWidget *parent = 0); + explicit KGradientSelector(QWidget *parent = nullptr); /** * Constructs a colors selector with orientation o which * contains a gradient between white and black. */ - explicit KGradientSelector(Qt::Orientation o, QWidget *parent = 0); + explicit KGradientSelector(Qt::Orientation o, QWidget *parent = nullptr); /** * Destructs the widget. */ ~KGradientSelector(); /** * Sets the colors that make up the gradient. Any previously set colors * are removed. * @since 4.5 */ void setStops(const QGradientStops &stops); /** * Get the colors that make up the gradient. * @since 4.5 */ QGradientStops stops() const; /** * Sets the two colors which span the gradient. */ void setColors(const QColor &col1, const QColor &col2); void setText(const QString &t1, const QString &t2); /** * Set each color on its own. */ void setFirstColor(const QColor &col); void setSecondColor(const QColor &col); /** * Set each description on its own */ void setFirstText(const QString &t); void setSecondText(const QString &t); QColor firstColor() const; QColor secondColor() const; QString firstText() const; QString secondText() const; protected: void drawContents(QPainter *) Q_DECL_OVERRIDE; virtual QSize minimumSize() const; private: class KGradientSelectorPrivate; friend class KGradientSelectorPrivate; KGradientSelectorPrivate *const d; Q_DISABLE_COPY(KGradientSelector) }; #endif // KSELECTOR_H diff --git a/src/kseparator.h b/src/kseparator.h index 4121abe..5fc6c74 100644 --- a/src/kseparator.h +++ b/src/kseparator.h @@ -1,73 +1,73 @@ /* * Copyright (C) 1997 Michael Roth * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef KSEPARATOR_H #define KSEPARATOR_H #include #include /** * Standard horizontal or vertical separator. * * \image html kseparator-horizontal.png "KDE Separator with horizontal orientation" * \image html kseparator-vertical.png "KDE Separator with vertical orientation" * * @author Michael Roth */ class KWIDGETSADDONS_EXPORT KSeparator : public QFrame { Q_OBJECT Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation) public: /** * Constructor. * @param parent parent object. * @param f extra QWidget flags. **/ - explicit KSeparator(QWidget *parent = 0, Qt::WindowFlags f = 0); + explicit KSeparator(QWidget *parent = nullptr, Qt::WindowFlags f = nullptr); /** * Constructor. * @param orientation Set the orientation of the separator. * Possible values are Horizontal or Vertical. * @param parent parent object. * @param f extra QWidget flags. **/ - explicit KSeparator(Qt::Orientation orientation, QWidget *parent = 0, Qt::WindowFlags f = 0); + explicit KSeparator(Qt::Orientation orientation, QWidget *parent = nullptr, Qt::WindowFlags f = nullptr); /** * Returns the orientation of the separator. * @return int Possible values Horizontal or Vertical. **/ Qt::Orientation orientation() const; /** * Set the orientation of the separator to @p orientation * * @param orientation Possible values are Vertical and Horizontal. */ void setOrientation(Qt::Orientation orientation); private: class KSeparatorPrivate *d; }; #endif // KSEPARATOR_H diff --git a/src/ksplittercollapserbutton.cpp b/src/ksplittercollapserbutton.cpp index 0d41b4f..052fdf6 100644 --- a/src/ksplittercollapserbutton.cpp +++ b/src/ksplittercollapserbutton.cpp @@ -1,360 +1,360 @@ /* Copyright (c) 2014 Montel Laurent based on code: Copyright 2009 Aurélien Gâteau Copyright 2009 Kåre Sårs This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #include "ksplittercollapserbutton.h" // Qt #include #include #include #include #include #include #include #include enum Direction { LeftToRight = 0, RightToLeft, TopToBottom, BottomToTop }; const static int TIMELINE_DURATION = 500; const static qreal MINIMUM_OPACITY = 0.3; static const struct { Qt::ArrowType arrowVisible; Qt::ArrowType notArrowVisible; } s_arrowDirection[] = { {Qt::LeftArrow, Qt::RightArrow}, {Qt::RightArrow, Qt::LeftArrow}, {Qt::UpArrow, Qt::DownArrow}, {Qt::DownArrow, Qt::UpArrow} }; class KSplitterCollapserButton::Private { public: Private(KSplitterCollapserButton *qq); KSplitterCollapserButton *q; QSplitter *splitter; QWidget *childWidget; Direction direction; QTimeLine *opacityTimeLine; QList sizeAtCollapse; bool isVertical() const; bool isWidgetCollapsed() const; void updatePosition(); void updateArrow(); void widgetEventFilter(QEvent *event); void updateOpacity(); void startTimeLine(); }; KSplitterCollapserButton::Private::Private(KSplitterCollapserButton *qq) : q(qq), - splitter(0), - childWidget(0), - opacityTimeLine(0) + splitter(nullptr), + childWidget(nullptr), + opacityTimeLine(nullptr) { } bool KSplitterCollapserButton::Private::isVertical() const { return (splitter->orientation() == Qt::Vertical); } bool KSplitterCollapserButton::Private::isWidgetCollapsed() const { const QRect widgetRect = childWidget->geometry(); if ((widgetRect.height() == 0) || (widgetRect.width() == 0)) { return true; } else { return false; } } void KSplitterCollapserButton::Private::updatePosition() { int x = 0; int y = 0; const QRect widgetRect = childWidget->geometry(); const int handleWidth = splitter->handleWidth(); if (!isVertical()) { const int splitterWidth = splitter->width(); const int width = q->sizeHint().width(); // FIXME: Make this configurable y = 30; if (direction == LeftToRight) { if (!isWidgetCollapsed()) { x = widgetRect.right() + handleWidth; } else { x = 0; } } else { // RightToLeft if (!isWidgetCollapsed()) { x = widgetRect.left() - handleWidth - width; } else { x = splitterWidth - handleWidth - width; } } } else { x = 30; const int height = q->sizeHint().height(); const int splitterHeight = splitter->height(); if (direction == TopToBottom) { if (!isWidgetCollapsed()) { y = widgetRect.bottom() + handleWidth; } else { y = 0; } } else { // BottomToTop if (!isWidgetCollapsed()) { y = widgetRect.top() - handleWidth - height; } else { y = splitterHeight - handleWidth - height; } } } q->move(x, y); } void KSplitterCollapserButton::Private::updateArrow() { q->setArrowType(isWidgetCollapsed() ? s_arrowDirection[direction].notArrowVisible : s_arrowDirection[direction].arrowVisible); } void KSplitterCollapserButton::Private::widgetEventFilter(QEvent *event) { switch (event->type()) { case QEvent::Resize: case QEvent::Move: case QEvent::Show: case QEvent::Hide: updatePosition(); updateOpacity(); updateArrow(); break; default: break; } } void KSplitterCollapserButton::Private::updateOpacity() { const QPoint pos = q->parentWidget()->mapFromGlobal(QCursor::pos()); const QRect opaqueRect = q->geometry(); const bool opaqueCollapser = opaqueRect.contains(pos); if (opaqueCollapser) { opacityTimeLine->setDirection(QTimeLine::Forward); startTimeLine(); } else { opacityTimeLine->setDirection(QTimeLine::Backward); startTimeLine(); } } void KSplitterCollapserButton::Private::startTimeLine() { if (opacityTimeLine->state() == QTimeLine::Running) { opacityTimeLine->stop(); } opacityTimeLine->start(); } KSplitterCollapserButton::KSplitterCollapserButton(QWidget *childWidget, QSplitter *splitter) : QToolButton(), d(new Private(this)) { setObjectName(QStringLiteral("splittercollapser")); // We do not want our collapser to be added as a regular widget in the // splitter! setAttribute(Qt::WA_NoChildEventsForParent); d->opacityTimeLine = new QTimeLine(TIMELINE_DURATION, this); d->opacityTimeLine->setFrameRange(int(MINIMUM_OPACITY * 1000), 1000); connect(d->opacityTimeLine, SIGNAL(valueChanged(qreal)), SLOT(update())); d->childWidget = childWidget; d->childWidget->installEventFilter(this); d->splitter = splitter; setParent(d->splitter); switch (splitter->orientation()) { case Qt::Horizontal: if (splitter->indexOf(childWidget) < splitter->count() / 2) { d->direction = LeftToRight; } else { d->direction = RightToLeft; } break; case Qt::Vertical: if (splitter->indexOf(childWidget) < splitter->count() / 2) { d->direction = TopToBottom; } else { d->direction = BottomToTop; } break; } connect(this, &KSplitterCollapserButton::clicked, this, &KSplitterCollapserButton::slotClicked); } KSplitterCollapserButton::~KSplitterCollapserButton() { delete d; } bool KSplitterCollapserButton::isWidgetCollapsed() const { return d->isWidgetCollapsed(); } bool KSplitterCollapserButton::eventFilter(QObject *object, QEvent *event) { if (object == d->childWidget) { d->widgetEventFilter(event); } return QToolButton::eventFilter(object, event); } void KSplitterCollapserButton::enterEvent(QEvent *event) { Q_UNUSED(event) d->updateOpacity(); } void KSplitterCollapserButton::leaveEvent(QEvent *event) { Q_UNUSED(event) d->updateOpacity(); } void KSplitterCollapserButton::showEvent(QShowEvent *event) { Q_UNUSED(event) d->updateOpacity(); } QSize KSplitterCollapserButton::sizeHint() const { QStyleOption opt; opt.initFrom(this); const int extent = style()->pixelMetric(QStyle::PM_ScrollBarExtent, &opt); QSize sh(extent * 3 / 4, extent * 240 / 100); if (d->isVertical()) { sh.transpose(); } return sh.expandedTo(QApplication::globalStrut()); } void KSplitterCollapserButton::slotClicked() { QList sizes = d->splitter->sizes(); const int index = d->splitter->indexOf(d->childWidget); if (!d->isWidgetCollapsed()) { d->sizeAtCollapse = sizes; sizes[index] = 0; } else { if (!d->sizeAtCollapse.isEmpty()) { sizes = d->sizeAtCollapse; } else { if (d->isVertical()) { sizes[index] = d->childWidget->sizeHint().height(); } else { sizes[index] = d->childWidget->sizeHint().width(); } } } d->splitter->setSizes(sizes); d->opacityTimeLine->setDirection(QTimeLine::Backward); d->startTimeLine(); } void KSplitterCollapserButton::collapse() { if (!d->isWidgetCollapsed()) { slotClicked(); } // else do nothing } void KSplitterCollapserButton::restore() { if (d->isWidgetCollapsed()) { slotClicked(); } // else do nothing } void KSplitterCollapserButton::setCollapsed(bool collapse) { if (collapse == d->isWidgetCollapsed()) { slotClicked(); } // else do nothing } void KSplitterCollapserButton::paintEvent(QPaintEvent *) { QStylePainter painter(this); const qreal opacity = d->opacityTimeLine->currentFrame() / 1000.; painter.setOpacity(opacity); QStyleOptionToolButton opt; initStyleOption(&opt); if (d->isVertical()) { if (d->direction == TopToBottom) { opt.rect.setTop(-height()); } else { opt.rect.setHeight(height() * 2); } } else { if (d->direction == LeftToRight) { opt.rect.setLeft(-width()); } else { opt.rect.setWidth(width() * 2); } } painter.drawPrimitive(QStyle::PE_PanelButtonTool, opt); QStyleOptionToolButton opt2; initStyleOption(&opt2); painter.drawControl(QStyle::CE_ToolButtonLabel, opt2); } diff --git a/src/ksqueezedtextlabel.h b/src/ksqueezedtextlabel.h index eb8b63c..d6e3bc3 100644 --- a/src/ksqueezedtextlabel.h +++ b/src/ksqueezedtextlabel.h @@ -1,132 +1,132 @@ /* This file is part of the KDE libraries Copyright (C) 2000 Ronny Standtke This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KSQUEEZEDTEXTLABEL_H #define KSQUEEZEDTEXTLABEL_H #include #include class KSqueezedTextLabelPrivate; /** * @short A replacement for QLabel that squeezes its text * * A label class that squeezes its text into the label * * If the text is too long to fit into the label it is divided into * remaining left and right parts which are separated by three dots. * * Example: * http://www.kde.org/documentation/index.html could be squeezed to * http://www.kde...ion/index.html * * \image html ksqueezedtextlabel.png "KSqueezedTextLabel Widget" * * @author Ronny Standtke */ /* * QLabel */ class KWIDGETSADDONS_EXPORT KSqueezedTextLabel : public QLabel { Q_OBJECT Q_PROPERTY(Qt::TextElideMode textElideMode READ textElideMode WRITE setTextElideMode) public: /** * Default constructor. */ - explicit KSqueezedTextLabel(QWidget *parent = 0); - explicit KSqueezedTextLabel(const QString &text, QWidget *parent = 0); + explicit KSqueezedTextLabel(QWidget *parent = nullptr); + explicit KSqueezedTextLabel(const QString &text, QWidget *parent = nullptr); virtual ~KSqueezedTextLabel(); QSize minimumSizeHint() const Q_DECL_OVERRIDE; QSize sizeHint() const Q_DECL_OVERRIDE; /** * Overridden for internal reasons; the API remains unaffected. */ virtual void setAlignment(Qt::Alignment); /** * Returns the text elide mode. */ Qt::TextElideMode textElideMode() const; /** * Sets the text elide mode. * @param mode The text elide mode. */ void setTextElideMode(Qt::TextElideMode mode); /** * Get the full text set via setText. * * @since 4.4 */ QString fullText() const; public Q_SLOTS: /** * Sets the text. Note that this is not technically a reimplementation of QLabel::setText(), * which is not virtual (in Qt 4.3). Therefore, you may need to cast the object to * KSqueezedTextLabel in some situations: * \Example * \code * KSqueezedTextLabel* squeezed = new KSqueezedTextLabel("text", parent); * QLabel* label = squeezed; * label->setText("new text"); // this will not work * squeezed->setText("new text"); // works as expected * static_cast(label)->setText("new text"); // works as expected * \endcode * @param mode The new text. */ void setText(const QString &text); /** * Clears the text. Same remark as above. * */ void clear(); protected: /** * \reimp */ void mouseReleaseEvent(QMouseEvent *) Q_DECL_OVERRIDE; /** * Called when widget is resized */ void resizeEvent(QResizeEvent *) Q_DECL_OVERRIDE; /** * \reimp */ void contextMenuEvent(QContextMenuEvent *) Q_DECL_OVERRIDE; /** * does the dirty work */ void squeezeTextToLabel(); private: Q_PRIVATE_SLOT(d, void _k_copyFullText()) KSqueezedTextLabelPrivate *const d; }; #endif // KSQUEEZEDTEXTLABEL_H diff --git a/src/kstyleextensions.cpp b/src/kstyleextensions.cpp index d7f38a5..79ba73e 100644 --- a/src/kstyleextensions.cpp +++ b/src/kstyleextensions.cpp @@ -1,99 +1,99 @@ /* This file is part of the KDE libraries Copyright (C) 2014 Thomas Lübking This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kstyleextensions.h" #include namespace KStyleExtensions { /* Custom Style Element runtime extension: We reserve one StyleHint to let the effective style inform widgets whether it supports certain string based style elements. As this could lead to number conflicts (i.e. an app utilizing one of the hints itself for other purposes) there're various safety mechanisms to rule out such interference. 1) It's most unlikely that a widget in some 3rd party app will accidentally call a general QStyle/KStyle styleHint() or draw*() and (unconditionally) expect a valid return, however: a. The StyleHint is not directly above Qt's custom base, assuming most 3rd party apps would - in case - make use of such b. In order to be accepted, the StyleHint query must pass a widget with a perfectly matching name, containing the typical element prefix ("CE_", etc.) and being supported by the current style c. Instead using Qt's fragile qstyleoption_cast on the QStyleOption provided to the StyleHint query, try to dump out a string and hope for the best, we now manipulate the widgets objectName(). Plain Qt dependent widgets can do that themselves and if a widget uses KStyle's convenience access functions, it won't notice this at all 2) The key problem is that a common KDE widget will run into an apps custom style which will then falsely respond to the styleHint() call with an invalid value. To prevent this, supporting styles *must* set a Q_CLASSINFO "X-KDE-CustomElements". 3) If any of the above traps snaps, the returned id is 0 - the QStyle default, indicating that this element is not supported by the current style. Obviously, this contains the "diminished clean" action to (temporarily) manipulate the objectName() of a const QWidget* - but this happens completely inside KStyle or the widget, if it does not make use of KStyles static convenience functions. My biggest worry here would be, that in a multithreaded environment a thread (usually not being owner of the widget) does something crucially relying on the widgets name property... This however would also have to happen during the widget construction or stylechanges, when the functions in doubt will typically be called. So this is imho unlikely causing any trouble, ever. */ static const QStyle::StyleHint SH_KCustomStyleElement = (QStyle::StyleHint)0xff000001; static const int X_KdeBase = 0xff000000; /* The functions called by widgets that request custom element support, passed to the effective style. Collected in a static inline function due to similarity. */ static inline int customStyleElement(QStyle::StyleHint type, const QString &element, QWidget *widget) { if (!widget || widget->style()->metaObject()->indexOfClassInfo("X-KDE-CustomElements") < 0) return 0; const QString originalName = widget->objectName(); widget->setObjectName(element); - const int id = widget->style()->styleHint(type, 0, widget); + const int id = widget->style()->styleHint(type, nullptr, widget); widget->setObjectName(originalName); return id; } QStyle::StyleHint customStyleHint(const QString &element, const QWidget *widget) { return (QStyle::StyleHint) customStyleElement(SH_KCustomStyleElement, element, const_cast(widget)); } QStyle::ControlElement customControlElement(const QString &element, const QWidget *widget) { return (QStyle::ControlElement) customStyleElement(SH_KCustomStyleElement, element, const_cast(widget)); } QStyle::SubElement customSubElement(const QString &element, const QWidget *widget) { return (QStyle::SubElement) customStyleElement(SH_KCustomStyleElement, element, const_cast(widget)); } } \ No newline at end of file diff --git a/src/ktimecombobox.h b/src/ktimecombobox.h index 68a944d..f884fad 100644 --- a/src/ktimecombobox.h +++ b/src/ktimecombobox.h @@ -1,336 +1,336 @@ /* Copyright 2011 John Layt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KTIMECOMBOBOX_H #define KTIMECOMBOBOX_H #include #include #include class KTimeComboBoxPrivate; class KWIDGETSADDONS_EXPORT KTimeComboBox : public QComboBox { Q_OBJECT Q_PROPERTY(QTime time READ time WRITE setTime NOTIFY timeChanged USER true) Q_PROPERTY(QTime minimumTime READ minimumTime WRITE setMinimumTime RESET resetMinimumTime) Q_PROPERTY(QTime maximumTime READ maximumTime WRITE setMaximumTime RESET resetMaximumTime) Q_PROPERTY(int timeListInterval READ timeListInterval WRITE setTimeListInterval) Q_PROPERTY(Options options READ options WRITE setOptions) public: /** * Options provided by the widget * @see options * @see setOptions */ enum Option { EditTime = 0x0001, /**< Allow the user to manually edit the time in the combo line edit */ SelectTime = 0x0002, /**< Allow the user to select the time from a drop-down menu */ ForceTime = 0x0004, /**< Any set or entered time will be forced to one of the drop-down times */ WarnOnInvalid = 0x0008 /**< Show a warning box on focus out if the user enters an invalid time */ }; Q_DECLARE_FLAGS(Options, Option) Q_FLAG(Options) /** * Create a new KTimeComboBox widget */ - explicit KTimeComboBox(QWidget *parent = 0); + explicit KTimeComboBox(QWidget *parent = nullptr); /** * Destroy the widget */ virtual ~KTimeComboBox(); /** * Return the currently selected time * * @return the currently selected time */ QTime time() const; /** * Return if the current user input is valid * * If the user input is null then it is not valid * * @see isNull() * @return if the current user input is valid */ bool isValid() const; /** * Return if the current user input is null * * @see isValid() * @return if the current user input is null */ bool isNull() const; /** * Return the currently set widget options * * @return the currently set widget options */ Options options() const; /** * Return the currently set time format * * By default this is the Short Format * * @return the currently set time format */ QLocale::FormatType displayFormat() const; /** * Return the current minimum time * * @return the current minimum time */ QTime minimumTime() const; /** * Reset the minimum time to the default of 00:00:00.000 */ void resetMinimumTime(); /** * Return the current maximum time * * @return the current maximum time */ QTime maximumTime() const; /** * Reset the maximum time to the default of 23:59:59.999 */ void resetMaximumTime(); /** * Set the minimum and maximum time range. * * If either time is invalid, or min > max then the range will not be set. * * @param minTime the minimum time * @param maxTime the maximum time * @param minWarnMsg the minimum warning message * @param maxWarnMsg the maximum warning message */ void setTimeRange(const QTime &minTime, const QTime &maxTime, const QString &minWarnMsg = QString(), const QString &maxWarnMsg = QString()); /** * Reset the minimum and maximum time to the default values. */ void resetTimeRange(); /** * Return the interval between select time list entries if set by setTimeListInterval(). * * Returns -1 if not set. * * @see setTimeListInterval() * @return the select time list interval in minutes */ int timeListInterval() const; /** * Return the list of times able to be selected in the drop-down. * * @see setTimeList() * @see timeListInterval() * @see setTimeListInterval() * @return the select time list */ QList timeList() const; Q_SIGNALS: /** * Signal if the time has been manually entered or selected by the user. * * The returned time may be invalid. * * @param time the new time */ void timeEntered(const QTime &time); /** * Signal if the time has been changed either manually by the user * or programatically. * * The returned time may be invalid. * * @param time the new time */ void timeChanged(const QTime &time); /** * Signal if the time is being manually edited by the user. * * The returned time may be invalid. * * @param time the new time */ void timeEdited(const QTime &time); public Q_SLOTS: /** * Set the currently selected time * * You can set an invalid time or a time outside the valid range, validity * checking is only done via isValid(). * * @param time the new time */ void setTime(const QTime &time); /** * Set the new widget options * * @param options the new widget options */ void setOptions(Options options); /** * Sets the time format to display. * * By default is the Short Format. * * @param format the time format to use */ void setDisplayFormat(QLocale::FormatType formatOptions); /** * Set the minimum allowed time. * * If the time is invalid, or greater than current maximum, * then the minimum will not be set. * * @see minimumTime() * @see maximumTime() * @see setMaximumTime() * @see setTimeRange() * @param minTime the minimum time * @param minWarnMsg the minimum warning message */ void setMinimumTime(const QTime &minTime, const QString &minWarnMsg = QString()); /** * Set the maximum allowed time. * * If the time is invalid, or less than current minimum, * then the maximum will not be set. * * @see minimumTime() * @see maximumTime() * @see setMaximumTime() * @see setTimeRange() * @param maxTime the maximum time * @param maxWarnMsg the maximum warning message */ void setMaximumTime(const QTime &maxTime, const QString &maxWarnMsg = QString()); /** * Set the interval between times able to be selected from the drop-down. * * The combo drop-down will be populated with times every @param minutes * apart, starting from the minimumTime() and ending at maximumTime(). * * If the ForceInterval option is set then any time manually typed into the * combo line edit will be forced to the nearest interval. * * This interval must be an exact divisor of the valid time range hours. * For example with the default 24 hour range @p interval must divide 1440 * minutes exactly, meaning 1, 6 and 90 are valid but 7, 31 and 91 are not. * * Setting the time list interval will override any time list previously set * via setTimeList(). * * @see timeListInterval() * @param minutes the time list interval to display */ void setTimeListInterval(int minutes); /** * Set the list of times able to be selected from the drop-down. * * Setting the time list will override any time interval previously set via * setTimeListInterval(). * * Any invalid or duplicate times will be ignored, and the list will be * sorted. * * The minimum and maximum time will automatically be set to the earliest * and latest value in the list. * * @see timeList() * @param timeList the list of times able to be selected * @param minWarnMsg the minimum warning message * @param maxWarnMsg the maximum warning message */ void setTimeList(QList timeList, const QString &minWarnMsg = QString(), const QString &maxWarnMsg = QString()); protected: bool eventFilter(QObject *object, QEvent *event) Q_DECL_OVERRIDE; void showPopup() Q_DECL_OVERRIDE; void hidePopup() Q_DECL_OVERRIDE; void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE; void focusInEvent(QFocusEvent *event) Q_DECL_OVERRIDE; void focusOutEvent(QFocusEvent *event) Q_DECL_OVERRIDE; void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; /** * Assign the time for the widget. * * Virtual to allow sub-classes to apply extra validation rules. * * @param time the new time */ virtual void assignTime(const QTime &time); private: friend class KTimeComboBoxPrivate; KTimeComboBoxPrivate *const d; Q_PRIVATE_SLOT(d, void selectTime(int index)) Q_PRIVATE_SLOT(d, void editTime(const QString &)) Q_PRIVATE_SLOT(d, void enterTime(const QTime &)) Q_PRIVATE_SLOT(d, void parseTime()) }; Q_DECLARE_OPERATORS_FOR_FLAGS(KTimeComboBox::Options) #endif // KTIMECOMBOBOX_H diff --git a/src/ktitlewidget.h b/src/ktitlewidget.h index f084ecd..4cf64c1 100644 --- a/src/ktitlewidget.h +++ b/src/ktitlewidget.h @@ -1,212 +1,212 @@ /* This file is part of the KDE libraries Copyright (C) 2007-2009 Urs Wolfer This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KTITLEWIDGET_H #define KTITLEWIDGET_H #include #include /** * @short Standard title widget. * * This class provides a widget often used for dialog titles. * \image html ktitlewidget.png "KTitleWidget with title and icon" * * KTitleWidget uses the general application font at 1.4 times its size to * style the text. This is a visual change from 4.x. * * @section Usage * KTitleWidget is very simple to use. You can either use its default text * (and pixmap) properties or display your own widgets in the title widget. * * A title text with a right-aligned pixmap: * @code KTitleWidget *titleWidget = new KTitleWidget(this); titleWidget->setText(i18n("Title")); titleWidget->setPixmap(QIcon::fromTheme("screen").pixmap(22, 22)); * @endcode * * Use it with an own widget: * @code KTitleWidget *checkboxTitleWidget = new KTitleWidget(this); QWidget *checkBoxTitleMainWidget = new QWidget(this); QVBoxLayout *titleLayout = new QVBoxLayout(checkBoxTitleMainWidget); titleLayout->setMargin(6); QCheckBox *checkBox = new QCheckBox("Text Checkbox", checkBoxTitleMainWidget); titleLayout->addWidget(checkBox); checkboxTitleWidget->setWidget(checkBoxTitleMainWidget); * @endcode * * @see KPageView * @author Urs Wolfer \ */ class KWIDGETSADDONS_EXPORT KTitleWidget : public QWidget { Q_OBJECT Q_PROPERTY(QString text READ text WRITE setText) Q_PROPERTY(QString comment READ comment WRITE setComment) Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap) Q_PROPERTY(int autoHideTimeout READ autoHideTimeout WRITE setAutoHideTimeout) public: /** * Possible title pixmap alignments. * * @li ImageLeft: Display the pixmap left * @li ImageRight: Display the pixmap right (default) */ enum ImageAlignment { ImageLeft, /**< Display the pixmap on the left */ ImageRight /**< Display the pixmap on the right */ }; Q_ENUM(ImageAlignment) /** * Comment message types */ enum MessageType { PlainMessage, /**< Normal comment */ InfoMessage, /**< Information the user should be alerted to */ WarningMessage, /**< A warning the user should be alerted to */ ErrorMessage /**< An error message */ }; /** * Constructs a title widget with the given @param parent. */ - explicit KTitleWidget(QWidget *parent = 0); + explicit KTitleWidget(QWidget *parent = nullptr); virtual ~KTitleWidget(); /** * @param widget Widget displayed on the title widget. */ void setWidget(QWidget *widget); /** * @return the text displayed in the title * @see setText() */ QString text() const; /** * @return the text displayed in the comment below the title, if any * @see setComment() */ QString comment() const; /** * @return the pixmap displayed in the title * @see setPixmap() */ const QPixmap *pixmap() const; /** * Sets this label's buddy to buddy. * When the user presses the shortcut key indicated by the label in this * title widget, the keyboard focus is transferred to the label's buddy * widget. * @param buddy the widget to activate when the shortcut key is activated */ void setBuddy(QWidget *buddy); /** * Get the current timeout value in milliseconds * @return timeout value in msecs */ int autoHideTimeout() const; public Q_SLOTS: /** * @param text Text displayed on the label. It can either be plain text or rich text. If it * is plain text, the text is displayed as a bold title text. * @param alignment Alignment of the text. Default is left and vertical centered. * @see text() */ void setText(const QString &text, Qt::Alignment alignment = Qt::AlignLeft | Qt::AlignVCenter); /** * @param text Text displayed on the label. It can either be plain text or rich text. If it * is plain text, the text is displayed as a bold title text. * @param type The sort of message it is; will also set the icon accordingly @see MessageType * @see text() */ void setText(const QString &text, MessageType type); /** * @param comment Text displayed beneath the main title as a comment. * It can either be plain text or rich text. * @param type The sort of message it is. @see MessageType * @see comment() */ void setComment(const QString &comment, MessageType type = PlainMessage); /** * @param pixmap Pixmap displayed in the header. The pixmap is by default right, but * @param alignment can be used to display it also left. * @see pixmap() */ void setPixmap(const QPixmap &pixmap, ImageAlignment alignment = ImageRight); /** * @param icon name of the icon to display in the header. The pixmap is by default right, but * @param alignment can be used to display it also left. * @see pixmap() */ void setPixmap(const QString &icon, ImageAlignment alignment = ImageRight); /** * @param pixmap the icon to display in the header. The pixmap is by default right, but * @param alignment can be used to display it also left. * @see pixmap() */ void setPixmap(const QIcon &icon, ImageAlignment alignment = ImageRight); /** * @param pixmap the icon to display in the header. The pixmap is by default right, but * @param alignment can be used to display it also left. * @see pixmap() */ void setPixmap(MessageType type, ImageAlignment alignment = ImageRight); /** * Set the autohide timeout of the label * Set value to 0 to disable autohide, which is the default. * @param msecs timeout value in milliseconds */ void setAutoHideTimeout(int msecs); protected: void changeEvent(QEvent *e) Q_DECL_OVERRIDE; void showEvent(QShowEvent *event) Q_DECL_OVERRIDE; bool eventFilter(QObject *object, QEvent *event) Q_DECL_OVERRIDE; private: class Private; Private *const d; Q_PRIVATE_SLOT(d, void _k_timeoutFinished()) Q_DISABLE_COPY(KTitleWidget) }; #endif diff --git a/src/ktoggleaction.cpp b/src/ktoggleaction.cpp index 392a57a..fbd9559 100644 --- a/src/ktoggleaction.cpp +++ b/src/ktoggleaction.cpp @@ -1,109 +1,109 @@ /* This file is part of the KDE libraries Copyright (C) 1999 Reginald Stadlbauer (C) 1999 Simon Hausmann (C) 2000 Nicolas Hadacek (C) 2000 Kurt Granroth (C) 2000 Michael Koch (C) 2001 Holger Freyther (C) 2002 Ellis Whitehead (C) 2002 Joseph Wenninger (C) 2003 Andras Mantia (C) 2005-2006 Hamish Rodda This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "ktoggleaction.h" #include class KToggleAction::Private { public: Private(KToggleAction *_parent) - : parent(_parent), checkedGuiItem(0L) + : parent(_parent), checkedGuiItem(nullptr) { } ~Private() { delete checkedGuiItem; } void init() { parent->setCheckable(true); connect(parent, &QAction::toggled, parent, &KToggleAction::slotToggled); } KToggleAction *parent; KGuiItem *checkedGuiItem; }; KToggleAction::KToggleAction(QObject *parent) : QAction(parent), d(new Private(this)) { d->init(); } KToggleAction::KToggleAction(const QString &text, QObject *parent) : QAction(parent), d(new Private(this)) { setText(text); d->init(); } KToggleAction::KToggleAction(const QIcon &icon, const QString &text, QObject *parent) : QAction(parent), d(new Private(this)) { setIcon(icon); setText(text); d->init(); } KToggleAction::~KToggleAction() { delete d; } void KToggleAction::setCheckedState(const KGuiItem &checkedItem) { delete d->checkedGuiItem; d->checkedGuiItem = new KGuiItem(checkedItem); } void KToggleAction::slotToggled(bool) { if (d->checkedGuiItem) { QString string = d->checkedGuiItem->text(); d->checkedGuiItem->setText(text()); setText(string); string = d->checkedGuiItem->toolTip(); d->checkedGuiItem->setToolTip(toolTip()); setToolTip(string); if (d->checkedGuiItem->hasIcon()) { QIcon icon = d->checkedGuiItem->icon(); d->checkedGuiItem->setIcon(this->icon()); QAction::setIcon(icon); } } } diff --git a/src/ktogglefullscreenaction.cpp b/src/ktogglefullscreenaction.cpp index 4e8c746..06f6f2f 100644 --- a/src/ktogglefullscreenaction.cpp +++ b/src/ktogglefullscreenaction.cpp @@ -1,119 +1,119 @@ /* This file is part of the KDE libraries Copyright (C) 1999 Reginald Stadlbauer (C) 1999 Simon Hausmann (C) 2000 Nicolas Hadacek (C) 2000 Kurt Granroth (C) 2000 Michael Koch (C) 2001 Holger Freyther (C) 2002 Ellis Whitehead (C) 2002 Joseph Wenninger (C) 2003 Andras Mantia (C) 2005-2006 Hamish Rodda This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "ktogglefullscreenaction.h" #include class KToggleFullScreenAction::Private { public: Private(KToggleFullScreenAction *action) : q(action) - , window(0) + , window(nullptr) { } void updateTextsAndIcon() { if (q->isChecked()) { q->setText(KToggleFullScreenAction::tr("Exit F&ull Screen Mode", "@action:inmenu")); q->setIconText(KToggleFullScreenAction::tr("Exit Full Screen", "@action:intoolbar")); q->setToolTip(KToggleFullScreenAction::tr("Exit full screen mode", "@info:tooltip")); q->setIcon(QIcon::fromTheme(QStringLiteral("view-restore"))); } else { q->setText(KToggleFullScreenAction::tr("F&ull Screen Mode", "@action:inmenu")); q->setIconText(KToggleFullScreenAction::tr("Full Screen", "@action:intoolbar")); q->setToolTip(KToggleFullScreenAction::tr("Display the window in full screen", "@info:tooltip")); q->setIcon(QIcon::fromTheme(QStringLiteral("view-fullscreen"))); } } KToggleFullScreenAction *q; QWidget *window; }; KToggleFullScreenAction::KToggleFullScreenAction(QObject *parent) : KToggleAction(parent), d(new Private(this)) { d->updateTextsAndIcon(); } KToggleFullScreenAction::KToggleFullScreenAction(QWidget *window, QObject *parent) : KToggleAction(parent), d(new Private(this)) { d->updateTextsAndIcon(); setWindow(window); } KToggleFullScreenAction::~KToggleFullScreenAction() { delete d; } void KToggleFullScreenAction::setWindow(QWidget *window) { if (d->window) { d->window->removeEventFilter(this); } d->window = window; if (d->window) { d->window->installEventFilter(this); } } void KToggleFullScreenAction::slotToggled(bool checked) { KToggleAction::slotToggled(checked); d->updateTextsAndIcon(); } bool KToggleFullScreenAction::eventFilter(QObject *object, QEvent *event) { if (object == d->window) if (event->type() == QEvent::WindowStateChange) { if (d->window->isFullScreen() != isChecked()) { activate(QAction::Trigger); } } return false; } void KToggleFullScreenAction::setFullScreen(QWidget *window, bool set) { if (set) { window->setWindowState(window->windowState() | Qt::WindowFullScreen); } else { window->setWindowState(window->windowState() & ~Qt::WindowFullScreen); } } diff --git a/src/ktoolbarlabelaction.cpp b/src/ktoolbarlabelaction.cpp index 6f55e00..8e20e7b 100644 --- a/src/ktoolbarlabelaction.cpp +++ b/src/ktoolbarlabelaction.cpp @@ -1,131 +1,131 @@ /* This file is part of the KDE libraries Copyright (C) 2004 Felix Berger This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "ktoolbarlabelaction.h" #include #include #include #include class KToolBarLabelAction::Private { public: QPointer buddy; QPointer label; }; KToolBarLabelAction::KToolBarLabelAction(const QString &text, QObject *parent) : QWidgetAction(parent), d(new Private) { setText(text); - d->label = 0; + d->label = nullptr; } KToolBarLabelAction::KToolBarLabelAction(QAction *buddy, const QString &text, QObject *parent) : QWidgetAction(parent), d(new Private) { setBuddy(buddy); setText(text); - d->label = 0; + d->label = nullptr; } KToolBarLabelAction::~KToolBarLabelAction() { delete d; } void KToolBarLabelAction::setBuddy(QAction *buddy) { d->buddy = buddy; QList labels; Q_FOREACH (QWidget *widget, associatedWidgets()) if (QToolBar *toolBar = qobject_cast(widget)) if (QLabel *label = qobject_cast(toolBar->widgetForAction(this))) { labels.append(label); } Q_FOREACH (QWidget *widget, buddy->associatedWidgets()) if (QToolBar *toolBar = qobject_cast(widget)) { QWidget *newBuddy = toolBar->widgetForAction(buddy); Q_FOREACH (QLabel *label, labels) { label->setBuddy(newBuddy); } return; } } QAction *KToolBarLabelAction::buddy() const { return d->buddy; } bool KToolBarLabelAction::event(QEvent *event) { if (event->type() == QEvent::ActionChanged) { if (d->label && text() != d->label->text()) { emit textChanged(text()); d->label->setText(text()); } } return QWidgetAction::event(event); } bool KToolBarLabelAction::eventFilter(QObject *watched, QEvent *event) { if (d->label && d->buddy && event->type() == QEvent::PolishRequest && watched == d->label) { Q_FOREACH (QWidget *widget, d->buddy->associatedWidgets()) { if (QToolBar *toolBar = qobject_cast(widget)) { QWidget *newBuddy = toolBar->widgetForAction(d->buddy); d->label->setBuddy(newBuddy); } } } return QWidgetAction::eventFilter(watched, event); } QWidget *KToolBarLabelAction::createWidget(QWidget *_parent) { QToolBar *parent = qobject_cast(_parent); if (!parent) { return QWidgetAction::createWidget(_parent); } if (!d->label) { d->label = new QLabel(parent); /** * These lines were copied from Konqueror's KonqDraggableLabel class in * konq_misc.cc */ d->label->setBackgroundRole(QPalette::Button); d->label->setAlignment((QApplication::isRightToLeft() ? Qt::AlignRight : Qt::AlignLeft) | Qt::AlignVCenter); d->label->adjustSize(); d->label->setText(text()); d->label->installEventFilter(this); } return d->label; } diff --git a/src/ktoolbarspaceraction.cpp b/src/ktoolbarspaceraction.cpp index 69ee650..e91e314 100644 --- a/src/ktoolbarspaceraction.cpp +++ b/src/ktoolbarspaceraction.cpp @@ -1,40 +1,40 @@ /* This file is part of the KDE libraries Copyright (C) 2006 Hamish Rodda This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "ktoolbarspaceraction.h" KToolBarSpacerAction::KToolBarSpacerAction(QObject *parent) : QWidgetAction(parent) - , d(0) + , d(nullptr) { } KToolBarSpacerAction::~KToolBarSpacerAction() { } QWidget *KToolBarSpacerAction::createWidget(QWidget *parent) { if (!parent) { return QWidgetAction::createWidget(parent); } QWidget *spacer = new QWidget(parent); spacer->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); return spacer; } diff --git a/src/kurllabel.cpp b/src/kurllabel.cpp index 3dd5e0f..cff28e5 100644 --- a/src/kurllabel.cpp +++ b/src/kurllabel.cpp @@ -1,338 +1,338 @@ // Copyright (C) 2000 Peter Putzer // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA // 02110-1301 USA #include "kurllabel.h" #include #include #include #include class KUrlLabel::Private { public: Private(const QString &_url, KUrlLabel *_parent) : parent(_parent), url(_url), tipText(url), linkColor(_parent->palette().color(QPalette::Active, QPalette::Link)), highlightedLinkColor(_parent->palette().color(QPalette::Active, QPalette::BrightText)), - cursor(0), + cursor(nullptr), textUnderlined(true), realUnderlined(true), useTips(false), useCursor(false), glowEnabled(true), floatEnabled(false), timer(new QTimer(parent)) { connect(timer, SIGNAL(timeout()), parent, SLOT(updateColor())); } ~Private() { } void updateColor() { timer->stop(); if (!(glowEnabled || floatEnabled) || !parent->rect().contains(parent->mapFromGlobal(QCursor::pos()))) { setLinkColor(linkColor); } } void setLinkColor(const QColor &color) { QPalette palette = parent->palette(); palette.setColor(QPalette::WindowText, color); parent->setPalette(palette); parent->update(); } KUrlLabel *parent; QString url; QString tipText; QColor linkColor; QColor highlightedLinkColor; QCursor *cursor; bool textUnderlined : 1; bool realUnderlined : 1; bool useTips : 1; bool useCursor : 1; bool glowEnabled : 1; bool floatEnabled : 1; QPixmap alternatePixmap; QPixmap realPixmap; QTimer *timer; }; KUrlLabel::KUrlLabel(const QString &url, const QString &text, QWidget *parent) : QLabel(!text.isNull() ? text : url, parent), d(new Private(url, this)) { setFont(font()); setCursor(QCursor(Qt::PointingHandCursor)); d->setLinkColor(d->linkColor); } KUrlLabel::KUrlLabel(QWidget *parent) : QLabel(parent), d(new Private(QString(), this)) { setFont(font()); setCursor(QCursor(Qt::PointingHandCursor)); d->setLinkColor(d->linkColor); } KUrlLabel::~KUrlLabel() { delete d; } void KUrlLabel::mouseReleaseEvent(QMouseEvent *event) { QLabel::mouseReleaseEvent(event); d->setLinkColor(d->highlightedLinkColor); d->timer->start(300); switch (event->button()) { case Qt::LeftButton: emit leftClickedUrl(); emit leftClickedUrl(d->url); break; case Qt::MidButton: emit middleClickedUrl(); emit middleClickedUrl(d->url); break; case Qt::RightButton: emit rightClickedUrl(); emit rightClickedUrl(d->url); break; default: break; } } void KUrlLabel::setFont(const QFont &font) { QFont newFont = font; newFont.setUnderline(d->textUnderlined); QLabel::setFont(newFont); } void KUrlLabel::setUnderline(bool on) { d->textUnderlined = on; setFont(font()); } void KUrlLabel::setUrl(const QString &url) { if (d->tipText == d->url) { // update the tip as well d->tipText = url; setUseTips(d->useTips); } d->url = url; } QString KUrlLabel::url() const { return d->url; } void KUrlLabel::setUseCursor(bool on, QCursor *cursor) { d->useCursor = on; d->cursor = cursor; if (on) { if (cursor) { setCursor(*cursor); } else { setCursor(QCursor(Qt::PointingHandCursor)); } } else { unsetCursor(); } } bool KUrlLabel::useCursor() const { return d->useCursor; } void KUrlLabel::setUseTips(bool on) { d->useTips = on; if (on) { setToolTip(d->tipText); } else { setToolTip(QString()); } } void KUrlLabel::setTipText(const QString &tipText) { d->tipText = tipText; setUseTips(d->useTips); } bool KUrlLabel::useTips() const { return d->useTips; } QString KUrlLabel::tipText() const { return d->tipText; } void KUrlLabel::setHighlightedColor(const QColor &color) { d->linkColor = color; if (!d->timer->isActive()) { d->setLinkColor(color); } } void KUrlLabel::setHighlightedColor(const QString &color) { setHighlightedColor(QColor(color)); } void KUrlLabel::setSelectedColor(const QColor &color) { d->highlightedLinkColor = color; if (d->timer->isActive()) { d->setLinkColor(color); } } void KUrlLabel::setSelectedColor(const QString &color) { setSelectedColor(QColor(color)); } void KUrlLabel::setGlowEnabled(bool glowEnabled) { d->glowEnabled = glowEnabled; } void KUrlLabel::setFloatEnabled(bool floatEnabled) { d->floatEnabled = floatEnabled; } bool KUrlLabel::isGlowEnabled() const { return d->glowEnabled; } bool KUrlLabel::isFloatEnabled() const { return d->floatEnabled; } void KUrlLabel::setAlternatePixmap(const QPixmap &pixmap) { d->alternatePixmap = pixmap; } const QPixmap *KUrlLabel::alternatePixmap() const { return &d->alternatePixmap; } void KUrlLabel::enterEvent(QEvent *event) { QLabel::enterEvent(event); if (!d->alternatePixmap.isNull() && pixmap()) { d->realPixmap = *pixmap(); setPixmap(d->alternatePixmap); } if (d->glowEnabled || d->floatEnabled) { d->timer->stop(); d->setLinkColor(d->highlightedLinkColor); d->realUnderlined = d->textUnderlined; if (d->floatEnabled) { setUnderline(true); } } emit enteredUrl(); emit enteredUrl(d->url); } void KUrlLabel::leaveEvent(QEvent *event) { QLabel::leaveEvent(event); if (!d->alternatePixmap.isNull() && pixmap()) { setPixmap(d->realPixmap); } if ((d->glowEnabled || d->floatEnabled) && !d->timer->isActive()) { d->setLinkColor(d->linkColor); } setUnderline(d->realUnderlined); emit leftUrl(); emit leftUrl(d->url); } bool KUrlLabel::event(QEvent *event) { if (event->type() == QEvent::PaletteChange) { /** * Use parentWidget() unless you are a toplevel widget, then try qAapp */ QPalette palette = parentWidget() ? parentWidget()->palette() : qApp->palette(); palette.setBrush(QPalette::Base, palette.brush(QPalette::Normal, QPalette::Background)); palette.setColor(QPalette::Foreground, this->palette().color(QPalette::Active, QPalette::Foreground)); setPalette(palette); d->linkColor = palette.color(QPalette::Active, QPalette::Link); d->updateColor(); return true; } else { return QLabel::event(event); } } #include "moc_kurllabel.cpp" diff --git a/src/kurllabel.h b/src/kurllabel.h index 1eb0195..fa2ab25 100644 --- a/src/kurllabel.h +++ b/src/kurllabel.h @@ -1,358 +1,358 @@ /* This file is part of the KDE libraries Copyright (C) 1998 Kurt Granroth Copyright (C) 2000 Peter Putzer Copyright (C) 2005 Jarosław Staniek This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KURLLABEL_H #define KURLLABEL_H #include #include #include #include class QCursor; /** * @short A drop-in replacement for QLabel that displays hyperlinks. * * KUrlLabel is a drop-in replacement for QLabel that handles text * in a fashion similar to how an HTML widget handles hyperlinks. The * text can be underlined (or not) and set to different colors. It * can also "glow" (cycle colors) when the mouse passes over it. * * KUrlLabel also provides signals for several events, including * the mouse leaving and entering the text area and all forms of * mouse clicking. * * By default KUrlLabel accepts focus. When focused, standard * focus rectangle is displayed as in HTML widget. * Pressing Enter key accepts the focused label. * * A typical usage would be something like so: * * \code * KUrlLabel *address = new KUrlLabel(this); * address->setText("My homepage"); * address->setUrl("http://www.home.com/~me"); * connect(address, SIGNAL(leftClickedUrl(const QString&)), * SLOT(processMyUrl(const QString&))); * \endcode * * In this example, the text "My homepage" would be displayed * as blue, underlined text. When the mouse passed over it, * it would "glow" red. When the user clicks on the text, the * signal leftClickedUrl() would be emitted with "http://www.home.com/~me" * as its argument. * * \image html kurllabel.png "KDE URL Label" * * @author Kurt Granroth (Interface) * @author Peter Putzer (Rewrite) */ class KWIDGETSADDONS_EXPORT KUrlLabel : public QLabel { Q_OBJECT Q_PROPERTY(QString url READ url WRITE setUrl) Q_PROPERTY(QString tipText READ tipText WRITE setTipText) Q_PROPERTY(QPixmap alternatePixmap READ alternatePixmap WRITE setAlternatePixmap) Q_PROPERTY(bool glowEnabled READ isGlowEnabled WRITE setGlowEnabled) Q_PROPERTY(bool floatEnabled READ isFloatEnabled WRITE setFloatEnabled) Q_PROPERTY(bool useTips READ useTips WRITE setUseTips) Q_PROPERTY(bool useCursor READ useCursor WRITE setUseCursor) public: /** * Default constructor. * * Use setUrl() and setText() or QListView::setPixmap() * to set the resp. properties. */ - explicit KUrlLabel(QWidget *parent = 0L); + explicit KUrlLabel(QWidget *parent = nullptr); /** * Convenience constructor. * * @param url is the URL emitted when the label is clicked. * @param text is the displayed string. If it's equal to QString() * the @p url will be used instead. * @param parent Passed to lower level constructor * * @p parent and @p name are passed to QLabel, which in turn passes * them further down */ explicit KUrlLabel(const QString &url, const QString &text = QString(), - QWidget *parent = 0L); + QWidget *parent = nullptr); /** * Destructs the label. */ virtual ~KUrlLabel(); /** * Returns the URL. */ QString url() const; /** * Returns the current tooltip text. */ QString tipText() const; /** * @return true if a tooltip will be displayed. * * @see setTipText() */ bool useTips() const; /** * @return true if the cursor will change while over the URL. * * @see setUseCursor () */ bool useCursor() const; /** * When this is on, the text will switch to the selected * color whenever the mouse passes over it. */ bool isGlowEnabled() const; /** * This feature is very similar to the "glow" feature in that the color of the * label switches to the selected color when the cursor passes * over it. In addition, underlining is turned on for as * long as the mouse is overhead. Note that if "glow" and * underlining are both already turned on, this feature * will have no visible effect. */ bool isFloatEnabled() const; /** * @return the alternate pixmap (may be 0L if none was set). */ const QPixmap *alternatePixmap() const; public Q_SLOTS: /** * Turns on or off the underlining. * * When this is on, the * text will be underlined. By default, it is @p true. */ void setUnderline(bool on = true); /** * Sets the URL for this label to @p url. * * @see url */ void setUrl(const QString &url); /** * Overridden for internal reasons; the API remains unaffected. */ virtual void setFont(const QFont &font); /** * Turns on or off the tool tip feature. * * When this is on, the URL will be displayed as a * tooltip whenever the mouse passes passes over it. * By default, it is @p false. */ void setUseTips(bool on = true); /** * Specifies what text to display when tooltips are turned on. * * If this is not used, the tip will default to the URL. * * @see setUseTips() */ void setTipText(const QString &tip); /** * Sets the highlight color. * * This is the default foreground * color (non-selected). By default, it is @p blue. */ void setHighlightedColor(const QColor &highcolor); /** * This is an overloaded version for convenience. * * @see setHighlightedColor() */ void setHighlightedColor(const QString &highcolor); /** * Sets the selected color. * * This is the color the text will change * to when either a mouse passes over it and "glow" mode is on or * when it is selected (clicked). By default, it is @p red. */ void setSelectedColor(const QColor &color); /** * This is an overloaded version for convenience. * * @see setSelectedColor() */ void setSelectedColor(const QString &color); /** * Turns the custom cursor feature on or off. * * When this is on, the cursor will change to a custom cursor * (default is a "pointing hand") whenever the cursor passes * over the label. By default, it is on. * * @param on whether a custom cursor should be displayed. * @param cursor is the custom cursor. @p 0L indicates the default "hand cursor". */ - void setUseCursor(bool on, QCursor *cursor = 0L); + void setUseCursor(bool on, QCursor *cursor = nullptr); /** * Turns on or off the "glow" feature. * * When this is on, the text will switch to the * selected color whenever the mouse * passes over it. By default, it is @p true. */ void setGlowEnabled(bool glow = true); /** * Turns on or off the "float" feature. * * This feature is very similar to the "glow" feature in * that the color of the label switches to the selected * color when the cursor passes over it. In addition, * underlining is turned on for as long as the mouse is overhead. * Note that if "glow" and underlining are both already turned * on, this feature will have no visible effect. * By default, it is @p false. */ void setFloatEnabled(bool do_float = true); /** * Sets the "alt" pixmap. * * This pixmap will be displayed when the * cursor passes over the label. The effect is similar to the * trick done with 'onMouseOver' in javascript. * * @see alternatePixmap() */ void setAlternatePixmap(const QPixmap &pixmap); Q_SIGNALS: /** * Emitted when the mouse has passed over the label. * * @param url The URL for this label. */ void enteredUrl(const QString &url); /** * Emitted when the mouse has passed over the label. */ void enteredUrl(); /** * Emitted when the mouse is no longer over the label. * * @param url The URL for this label. */ void leftUrl(const QString &url); /** * Emitted when the mouse is no longer over the label. */ void leftUrl(); /** * Emitted when the user clicked the left mouse button on this label. * * @param url The URL for this label. */ void leftClickedUrl(const QString &url); /** * Emitted when the user clicked the left mouse button on this label. */ void leftClickedUrl(); /** * Emitted when the user clicked the right mouse button on this label. * * @param url The URL for this label. */ void rightClickedUrl(const QString &url); /** * Emitted when the user clicked the right mouse button on this label. */ void rightClickedUrl(); /** * Emitted when the user clicked the middle mouse button on this label. * * @param url The URL for this label. */ void middleClickedUrl(const QString &url); /** * Emitted when the user clicked the left mouse button on this label. */ void middleClickedUrl(); protected: /** * Overridden for internal reasons; the API remains unaffected. */ void mouseReleaseEvent(QMouseEvent *) Q_DECL_OVERRIDE; /** * Overridden for internal reasons; the API remains unaffected. */ void enterEvent(QEvent *) Q_DECL_OVERRIDE; /** * Overridden for internal reasons; the API remains unaffected. */ void leaveEvent(QEvent *) Q_DECL_OVERRIDE; /** * Catch parent palette changes */ bool event(QEvent *) Q_DECL_OVERRIDE; private: class Private; Private *const d; Q_PRIVATE_SLOT(d, void updateColor()) }; #endif diff --git a/src/kviewstatemaintainerbase.cpp b/src/kviewstatemaintainerbase.cpp index 240c45a..5e4dca6 100644 --- a/src/kviewstatemaintainerbase.cpp +++ b/src/kviewstatemaintainerbase.cpp @@ -1,115 +1,115 @@ /* Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net, author Stephen Kelly This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kviewstatemaintainerbase.h" #include #include #include class KViewStateMaintainerBasePrivate { KViewStateMaintainerBasePrivate(KViewStateMaintainerBase *qq) : q_ptr(qq) { } Q_DECLARE_PUBLIC(KViewStateMaintainerBase) KViewStateMaintainerBase *const q_ptr; void _k_modelAboutToBeReset(); void _k_modelReset(); QPointer m_view; QPointer m_selectionModel; }; void KViewStateMaintainerBasePrivate::_k_modelAboutToBeReset() { Q_Q(KViewStateMaintainerBase); q->saveState(); } void KViewStateMaintainerBasePrivate::_k_modelReset() { Q_Q(KViewStateMaintainerBase); q->restoreState(); } KViewStateMaintainerBase::KViewStateMaintainerBase(QObject *parent) : QObject(parent), d_ptr(new KViewStateMaintainerBasePrivate(this)) { } KViewStateMaintainerBase::~KViewStateMaintainerBase() { delete d_ptr; } QItemSelectionModel *KViewStateMaintainerBase::selectionModel() const { Q_D(const KViewStateMaintainerBase); if (d->m_selectionModel.isNull()) { - return 0; + return nullptr; } return d->m_selectionModel.data(); } void KViewStateMaintainerBase::setSelectionModel(QItemSelectionModel *selectionModel) { Q_D(KViewStateMaintainerBase); d->m_selectionModel = selectionModel; if (d->m_view && d->m_view.data()->model()) { disconnect(d->m_view.data()->model(), SIGNAL(modelAboutToBeReset()), this, SLOT(_k_modelAboutToBeReset())); disconnect(d->m_view.data()->model(), SIGNAL(modelReset()), this, SLOT(_k_modelReset())); } connect(d->m_selectionModel.data()->model(), SIGNAL(modelAboutToBeReset()), SLOT(_k_modelAboutToBeReset()), Qt::UniqueConnection); connect(d->m_selectionModel.data()->model(), SIGNAL(modelReset()), SLOT(_k_modelReset()), Qt::UniqueConnection); } QAbstractItemView *KViewStateMaintainerBase::view() const { Q_D(const KViewStateMaintainerBase); if (d->m_view.isNull()) { - return 0; + return nullptr; } return d->m_view.data(); } void KViewStateMaintainerBase::setView(QAbstractItemView *view) { Q_D(KViewStateMaintainerBase); d->m_view = view; if (d->m_selectionModel && d->m_selectionModel.data()->model()) { disconnect(d->m_selectionModel.data()->model(), SIGNAL(modelAboutToBeReset()), this, SLOT(_k_modelAboutToBeReset())); disconnect(d->m_selectionModel.data()->model(), SIGNAL(modelReset()), this, SLOT(_k_modelReset())); } if (d->m_view && d->m_view.data()->model()) { connect(d->m_view.data()->model(), SIGNAL(modelAboutToBeReset()), SLOT(_k_modelAboutToBeReset()), Qt::UniqueConnection); connect(d->m_view.data()->model(), SIGNAL(modelReset()), SLOT(_k_modelReset()), Qt::UniqueConnection); } } #include "moc_kviewstatemaintainerbase.cpp" diff --git a/src/kviewstatemaintainerbase.h b/src/kviewstatemaintainerbase.h index a531143..eaa8628 100644 --- a/src/kviewstatemaintainerbase.h +++ b/src/kviewstatemaintainerbase.h @@ -1,58 +1,58 @@ /* Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net, author Stephen Kelly This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KVIEWSTATEMAINTAINERBASE_H #define KVIEWSTATEMAINTAINERBASE_H #include "kwidgetsaddons_export.h" #include class QItemSelectionModel; class QAbstractItemView; class KViewStateMaintainerBasePrivate; class KWIDGETSADDONS_EXPORT KViewStateMaintainerBase : public QObject { Q_OBJECT public: - KViewStateMaintainerBase(QObject *parent = 0); + KViewStateMaintainerBase(QObject *parent = nullptr); ~KViewStateMaintainerBase(); void setSelectionModel(QItemSelectionModel *selectionModel); QItemSelectionModel *selectionModel() const; void setView(QAbstractItemView *view); QAbstractItemView *view() const; virtual void saveState() = 0; virtual void restoreState() = 0; private: Q_DECLARE_PRIVATE(KViewStateMaintainerBase) KViewStateMaintainerBasePrivate *const d_ptr; Q_PRIVATE_SLOT(d_func(), void _k_modelAboutToBeReset()) Q_PRIVATE_SLOT(d_func(), void _k_modelReset()) }; #endif diff --git a/src/kviewstateserializer.cpp b/src/kviewstateserializer.cpp index acc1f63..b5b60f4 100644 --- a/src/kviewstateserializer.cpp +++ b/src/kviewstateserializer.cpp @@ -1,370 +1,370 @@ /* Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net, author Stephen Kelly This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kviewstateserializer.h" #include #include #include #include class KViewStateSerializerPrivate { public: KViewStateSerializerPrivate(KViewStateSerializer *qq) : q_ptr(qq), - m_treeView(0), - m_view(0), - m_selectionModel(0), - m_scrollArea(0), + m_treeView(nullptr), + m_view(nullptr), + m_selectionModel(nullptr), + m_scrollArea(nullptr), m_horizontalScrollBarValue(-1), m_verticalScrollBarValue(-1) { } Q_DECLARE_PUBLIC(KViewStateSerializer) KViewStateSerializer *const q_ptr; QStringList getExpandedItems(const QModelIndex &index) const; void listenToPendingChanges(); void processPendingChanges(); inline void restoreScrollBarState() { if (m_horizontalScrollBarValue >= 0 && m_horizontalScrollBarValue <= m_scrollArea->horizontalScrollBar()->maximum()) { m_scrollArea->horizontalScrollBar()->setValue(m_horizontalScrollBarValue); m_horizontalScrollBarValue = -1; } if (m_verticalScrollBarValue >= 0 && m_verticalScrollBarValue <= m_scrollArea->verticalScrollBar()->maximum()) { m_scrollArea->verticalScrollBar()->setValue(m_verticalScrollBarValue); m_verticalScrollBarValue = -1; } } void restoreSelection(); void restoreCurrentItem(); void restoreExpanded(); inline bool hasPendingChanges() const { return !m_pendingCurrent.isEmpty() || !m_pendingExpansions.isEmpty() || !m_pendingSelections.isEmpty(); } const QAbstractItemModel *getModel() { if (m_selectionModel && m_selectionModel->model()) { return m_selectionModel->model(); } else if (m_view && m_view->model()) { return m_view->model(); } - return 0; + return nullptr; } void rowsInserted(const QModelIndex &/*index*/, int /*start*/, int /*end*/) { Q_Q(KViewStateSerializer); processPendingChanges(); if (!hasPendingChanges()) { q->disconnect(getModel(), SIGNAL(rowsInserted(QModelIndex,int,int)), q, SLOT(rowsInserted(QModelIndex,int,int))); q->deleteLater(); } } QTreeView *m_treeView; QAbstractItemView *m_view; QItemSelectionModel *m_selectionModel; QAbstractScrollArea *m_scrollArea; int m_horizontalScrollBarValue; int m_verticalScrollBarValue; QSet m_pendingSelections; QSet m_pendingExpansions; QString m_pendingCurrent; }; KViewStateSerializer::KViewStateSerializer(QObject *parent) - : QObject(0), d_ptr(new KViewStateSerializerPrivate(this)) + : QObject(nullptr), d_ptr(new KViewStateSerializerPrivate(this)) { Q_UNUSED(parent); qRegisterMetaType("QModelIndex"); } KViewStateSerializer::~KViewStateSerializer() { delete d_ptr; } void KViewStateSerializer::setView(QAbstractItemView *view) { Q_D(KViewStateSerializer); d->m_scrollArea = view; if (view) { d->m_selectionModel = view->selectionModel(); d->m_treeView = qobject_cast(view); } else { - d->m_selectionModel = 0; - d->m_treeView = 0; + d->m_selectionModel = nullptr; + d->m_treeView = nullptr; } d->m_view = view; } QAbstractItemView *KViewStateSerializer::view() const { Q_D(const KViewStateSerializer); return d->m_view; } QItemSelectionModel *KViewStateSerializer::selectionModel() const { Q_D(const KViewStateSerializer); return d->m_selectionModel; } void KViewStateSerializer::setSelectionModel(QItemSelectionModel *selectionModel) { Q_D(KViewStateSerializer); d->m_selectionModel = selectionModel; } void KViewStateSerializerPrivate::listenToPendingChanges() { Q_Q(KViewStateSerializer); // watch the model for stuff coming in delayed if (hasPendingChanges()) { const QAbstractItemModel *model = getModel(); if (model) { q->disconnect(model, SIGNAL(rowsInserted(QModelIndex,int,int)), q, SLOT(rowsInserted(QModelIndex,int,int))); q->connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)), SLOT(rowsInserted(QModelIndex,int,int))); return; } else { q->deleteLater(); } } else { q->deleteLater(); } } void KViewStateSerializerPrivate::processPendingChanges() { Q_Q(KViewStateSerializer); q->restoreCurrentItem(m_pendingCurrent); q->restoreSelection(m_pendingSelections.toList()); q->restoreExpanded(m_pendingExpansions.toList()); q->restoreScrollState(m_verticalScrollBarValue, m_horizontalScrollBarValue); } QStringList KViewStateSerializerPrivate::getExpandedItems(const QModelIndex &index) const { Q_Q(const KViewStateSerializer); QStringList expansion; for (int i = 0; i < m_treeView->model()->rowCount(index); ++i) { const QModelIndex child = m_treeView->model()->index(i, 0, index); // http://bugreports.qt.nokia.com/browse/QTBUG-18039 if (m_treeView->model()->hasChildren(child)) { if (m_treeView->isExpanded(child)) { expansion << q->indexToConfigString(child); } expansion << getExpandedItems(child); } } return expansion; } void KViewStateSerializerPrivate::restoreCurrentItem() { Q_Q(KViewStateSerializer); QModelIndex currentIndex = q->indexFromConfigString(m_selectionModel->model(), m_pendingCurrent); if (currentIndex.isValid()) { if (m_treeView) { m_treeView->setCurrentIndex(currentIndex); } else { m_selectionModel->setCurrentIndex(currentIndex, QItemSelectionModel::NoUpdate); } m_pendingCurrent.clear(); } } void KViewStateSerializer::restoreCurrentItem(const QString &indexString) { Q_D(KViewStateSerializer); if (!d->m_selectionModel || !d->m_selectionModel->model()) { return; } if (indexString.isEmpty()) { return; } d->m_pendingCurrent = indexString; d->restoreCurrentItem(); if (d->hasPendingChanges()) { d->listenToPendingChanges(); } } void KViewStateSerializerPrivate::restoreExpanded() { Q_Q(KViewStateSerializer); QSet::iterator it = m_pendingExpansions.begin(); for (; it != m_pendingExpansions.end();) { QModelIndex idx = q->indexFromConfigString(m_treeView->model(), *it); if (idx.isValid()) { m_treeView->expand(idx); it = m_pendingExpansions.erase(it); } else { ++it; } } } void KViewStateSerializer::restoreExpanded(const QStringList &indexStrings) { Q_D(KViewStateSerializer); if (!d->m_treeView || !d->m_treeView->model()) { return; } if (indexStrings.isEmpty()) { return; } d->m_pendingExpansions.unite(indexStrings.toSet()); d->restoreExpanded(); if (d->hasPendingChanges()) { d->listenToPendingChanges(); } } void KViewStateSerializer::restoreScrollState(int verticalScoll, int horizontalScroll) { Q_D(KViewStateSerializer); if (!d->m_scrollArea) { return; } d->m_verticalScrollBarValue = verticalScoll; d->m_horizontalScrollBarValue = horizontalScroll; QTimer::singleShot(0, this, SLOT(restoreScrollBarState())); } void KViewStateSerializerPrivate::restoreSelection() { Q_Q(KViewStateSerializer); QSet::iterator it = m_pendingSelections.begin(); for (; it != m_pendingSelections.end();) { QModelIndex idx = q->indexFromConfigString(m_selectionModel->model(), *it); if (idx.isValid()) { m_selectionModel->select(idx, QItemSelectionModel::Select); it = m_pendingSelections.erase(it); } else { ++it; } } } void KViewStateSerializer::restoreSelection(const QStringList &indexStrings) { Q_D(KViewStateSerializer); if (!d->m_selectionModel || !d->m_selectionModel->model()) { return; } if (indexStrings.isEmpty()) { return; } d->m_pendingSelections.unite(indexStrings.toSet()); d->restoreSelection(); if (d->hasPendingChanges()) { d->listenToPendingChanges(); } } QString KViewStateSerializer::currentIndexKey() const { Q_D(const KViewStateSerializer); if (!d->m_selectionModel) { return QString(); } return indexToConfigString(d->m_selectionModel->currentIndex()); } QStringList KViewStateSerializer::expansionKeys() const { Q_D(const KViewStateSerializer); if (!d->m_treeView || !d->m_treeView->model()) { return QStringList(); } return d->getExpandedItems(QModelIndex()); } QStringList KViewStateSerializer::selectionKeys() const { Q_D(const KViewStateSerializer); if (!d->m_selectionModel) { return QStringList(); } QModelIndexList selectedIndexes = d->m_selectionModel->selectedRows(); QStringList selection; Q_FOREACH (const QModelIndex &index, selectedIndexes) { selection << indexToConfigString(index); } return selection; } QPair KViewStateSerializer::scrollState() const { Q_D(const KViewStateSerializer); return qMakePair(d->m_scrollArea->verticalScrollBar()->value(), d->m_scrollArea->horizontalScrollBar()->value()); } void KViewStateSerializer::restoreState() { Q_D(KViewStateSerializer); // Delete myself if not finished after 60 seconds QTimer::singleShot(60000, this, SLOT(deleteLater())); d->processPendingChanges(); if (d->hasPendingChanges()) { d->listenToPendingChanges(); } } #include "moc_kviewstateserializer.cpp" diff --git a/src/kviewstateserializer.h b/src/kviewstateserializer.h index 12af61c..28f2932 100644 --- a/src/kviewstateserializer.h +++ b/src/kviewstateserializer.h @@ -1,263 +1,263 @@ /* Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net, author Stephen Kelly This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KVIEWSTATESERIALIZER_H #define KVIEWSTATESERIALIZER_H #include #include #include "kwidgetsaddons_export.h" class QAbstractItemView; class QItemSelectionModel; class QAbstractItemModel; class QAbstractScrollArea; class QModelIndex; class QStringList; class KViewStateSerializerPrivate; /** @brief Object for saving and restoring state in QTreeViews and QItemSelectionModels Implement the indexFromConfigString and indexToConfigString methods to handle the model in the view whose state is being saved. These implementations can be quite trivial: @code QModelIndex DynamicTreeStateSaver::indexFromConfigString(const QAbstractItemModel* model, const QString& key) const { QModelIndexList list = model->match(model->index(0, 0), DynamicTreeModel::DynamicTreeModelId, key.toInt(), 1, Qt::MatchRecursive); if (list.isEmpty()) return QModelIndex(); return list.first(); } QString DynamicTreeStateSaver::indexToConfigString(const QModelIndex& index) const { return index.data(DynamicTreeModel::DynamicTreeModelId).toString(); } @endcode It is possible to restore the state of a QTreeView (that is, the expanded state and selected state of all indexes as well as the horizontal and vertical scroll state) by using setTreeView. If there is no tree view state to restore (for example if using QML), the selection state of a QItemSelectionModel can be saved or restored instead. The state of any QAbstractScrollArea can also be saved and restored. A KViewStateSerializer should be created on the stack when saving and on the heap when restoring. The model may be populated dynamically between several event loops, so it may not be immediate for the indexes that should be selected to be in the model. The saver should *not* be persisted as a member. The saver will destroy itself when it has completed the restoration specified in the config group, or a small amount of time has elapsed. @code MyWidget::MyWidget(Qobject *parent) : QWidget(parent) { ... m_view = new QTreeView(splitter); m_view->setModel(model); connect( model, SIGNAL(modelAboutToBeReset()), SLOT(saveState()) ); connect( model, SIGNAL(modelReset()), SLOT(restoreState()) ); connect( qApp, SIGNAL(aboutToQuit()), SLOT(saveState()) ); restoreState(); } void StateSaverWidget::saveState() { ConcreteStateSaver saver; saver.setTreeView(m_view); KConfigGroup cfg( KSharedConfig::openConfig(), "ExampleViewState" ); saver.saveState( cfg ); cfg.sync(); } void StateSaverWidget::restoreState() { // Will delete itself. ConcreteTreeStateSaver *saver = new ConcreteStateSaver(); saver->setTreeView(m_view); KConfigGroup cfg( KSharedConfig::openConfig(), "ExampleViewState" ); saver->restoreState( cfg ); } @endcode After creating a saver, the state can be saved using a KConfigGroup. It is also possible to save and restore state directly by using the restoreSelection, restoreExpanded etc methods. Note that the implementation of these methods should return strings that the indexFromConfigString implementation can handle. @code class DynamicTreeStateSaver : public KViewStateSerializer { Q_OBJECT public: // ... void selectItems(const QList &items) { QStringList itemStrings; Q_FOREACH(qint64 item, items) itemStrings << QString::number(item); restoreSelection(itemStrings); } void expandItems(const QList &items) { QStringList itemStrings; Q_FOREACH(qint64 item, items) itemStrings << QString::number(item); restoreSelection(itemStrings); } }; @endcode Note that a single instance of this class should be used with only one widget. That is don't do this: @code saver->setTreeView(treeView1); saver->setSelectionModel(treeView2->selectionModel()); saver->setScrollArea(treeView3); @endcode To save the state of 3 different widgets, use three savers, even if they operate on the same root model. @code saver1->setTreeView(treeView1); saver2->setSelectionModel(treeView2->selectionModel()); saver3->setScrollArea(treeView3); @endcode @note The KViewStateSerializer does not take ownership of any widgets set on it. It is recommended to restore the state on application startup and after the model has been reset, and to save the state on application close and before the model has been reset. @see QAbstractItemModel::modelAboutToBeReset QAbstractItemModel::modelReset @author Stephen Kelly @since 4.5 */ class KWIDGETSADDONS_EXPORT KViewStateSerializer : public QObject { Q_OBJECT public: /** Constructor */ - explicit KViewStateSerializer(QObject *parent = 0); + explicit KViewStateSerializer(QObject *parent = nullptr); /** Destructor */ ~KViewStateSerializer(); /** * The view whose state is persisted. */ QAbstractItemView *view() const; /** * Sets the view whose state is persisted. */ void setView(QAbstractItemView *view); /** The QItemSelectionModel whose state is persisted. */ QItemSelectionModel *selectionModel() const; /** Sets the QItemSelectionModel whose state is persisted. */ void setSelectionModel(QItemSelectionModel *selectionModel); /** * Returns a QStringList describing the selection in the selectionModel. */ QStringList selectionKeys() const; /** * Returns a QStringList representing the expanded indexes in the QTreeView. */ QStringList expansionKeys() const; /** * Returns a QString describing the current index in the selection model. */ QString currentIndexKey() const; /** * Returns the vertical and horizontal scroll of the QAbstractScrollArea. */ QPair scrollState() const; /** * Select the indexes described by @p indexStrings */ void restoreSelection(const QStringList &indexStrings); /** * Make the index described by @p indexString the currentIndex in the selectionModel. */ void restoreCurrentItem(const QString &indexString); /** * Expand the indexes described by @p indexStrings in the QTreeView. */ void restoreExpanded(const QStringList &indexStrings); /** * Restores the scroll state of the QAbstractScrollArea to the @p verticalScoll * and @p horizontalScroll */ void restoreScrollState(int verticalScoll, int horizontalScroll); protected: /** Reimplement to return an index in the @p model described by the unique key @p key */ virtual QModelIndex indexFromConfigString(const QAbstractItemModel *model, const QString &key) const = 0; /** Reimplement to return a unique string for the @p index. */ virtual QString indexToConfigString(const QModelIndex &index) const = 0; void restoreState(); private: //@cond PRIVATE Q_DECLARE_PRIVATE(KViewStateSerializer) KViewStateSerializerPrivate *const d_ptr; Q_PRIVATE_SLOT(d_func(), void rowsInserted(const QModelIndex &, int, int)) Q_PRIVATE_SLOT(d_func(), void restoreScrollBarState()) //@endcond }; #endif diff --git a/src/kxyselector.h b/src/kxyselector.h index d4b52fe..806b937 100644 --- a/src/kxyselector.h +++ b/src/kxyselector.h @@ -1,149 +1,149 @@ /* This file is part of the KDE libraries Copyright (C) 1997 Martin Jones (mjones@kde.org) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KXYSELECTOR_H #define KXYSELECTOR_H #include #include #include /** * KXYSelector is the base class for other widgets which * provides the ability to choose from a two-dimensional * range of values. The currently chosen value is indicated * by a cross. An example is the KHSSelector which * allows to choose from a range of colors, and which is * used in KColorDialog. * * A custom drawing routine for the widget surface has * to be provided by the subclass. */ class KWIDGETSADDONS_EXPORT KXYSelector : public QWidget { Q_OBJECT Q_PROPERTY(int xValue READ xValue WRITE setXValue) Q_PROPERTY(int yValue READ yValue WRITE setYValue) public: /** * Constructs a two-dimensional selector widget which * has a value range of [0..100] in both directions. */ - explicit KXYSelector(QWidget *parent = 0); + explicit KXYSelector(QWidget *parent = nullptr); /** * Destructs the widget. */ ~KXYSelector(); /** * Sets the current values in horizontal and * vertical direction. * @param xPos the horizontal value * @param yPos the vertical value */ void setValues(int xPos, int yPos); /** * Sets the current horizontal value * @param xPos the horizontal value */ void setXValue(int xPos); /** * Sets the current vertical value * @param yPos the vertical value */ void setYValue(int yPos); /** * Sets the range of possible values. */ void setRange(int minX, int minY, int maxX, int maxY); /** * Sets the color used to draw the marker * @param col the color */ void setMarkerColor(const QColor &col); /** * @return the current value in horizontal direction. */ int xValue() const; /** * @return the current value in vertical direction. */ int yValue() const; /** * @return the rectangle on which subclasses should draw. */ QRect contentsRect() const; /** * Reimplemented to give the widget a minimum size */ QSize minimumSizeHint() const Q_DECL_OVERRIDE; Q_SIGNALS: /** * This signal is emitted whenever the user chooses a value, * e.g. by clicking with the mouse on the widget. */ void valueChanged(int x, int y); protected: /** * Override this function to draw the contents of the widget. * The default implementation does nothing. * * Draw within contentsRect() only. */ virtual void drawContents(QPainter *); /** * Override this function to draw the marker which * indicates the currently selected value pair. */ virtual void drawMarker(QPainter *p, int xp, int yp); void paintEvent(QPaintEvent *e) Q_DECL_OVERRIDE; void mousePressEvent(QMouseEvent *e) Q_DECL_OVERRIDE; void mouseMoveEvent(QMouseEvent *e) Q_DECL_OVERRIDE; void wheelEvent(QWheelEvent *) Q_DECL_OVERRIDE; /** * Converts a pixel position to its corresponding values. */ void valuesFromPosition(int x, int y, int &xVal, int &yVal) const; private: void setPosition(int xp, int yp); private: class Private; friend class Private; Private *const d; Q_DISABLE_COPY(KXYSelector) }; #endif /* KXYSELECTOR_H */ diff --git a/src/lineediturldropeventfilter.h b/src/lineediturldropeventfilter.h index 857f4f9..92be073 100644 --- a/src/lineediturldropeventfilter.h +++ b/src/lineediturldropeventfilter.h @@ -1,44 +1,44 @@ /* Copyright 2013 Albert Vaca This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef LINEEDITURLDROPEVENTFILTER_H #define LINEEDITURLDROPEVENTFILTER_H #include #include /** * This class provides an event filter that can be installed on a QLineEdit * or a subclass of it (KLineEdit) to make it handle url drop events so * when a url is dropped it replaces the existing content. */ class KWIDGETSADDONS_EXPORT LineEditUrlDropEventFilter : public QObject { Q_OBJECT public: - LineEditUrlDropEventFilter(QObject *parent = 0); + LineEditUrlDropEventFilter(QObject *parent = nullptr); virtual ~LineEditUrlDropEventFilter(); bool eventFilter(QObject *obj, QEvent *ev) Q_DECL_OVERRIDE; }; #endif diff --git a/tests/kactionselectortest.cpp b/tests/kactionselectortest.cpp index db9a52d..697b88b 100644 --- a/tests/kactionselectortest.cpp +++ b/tests/kactionselectortest.cpp @@ -1,36 +1,36 @@ /* Copyright (c) 2006 David Faure This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include int main(int argc, char *argv[]) { QApplication app(argc, argv); app.setAttribute(Qt::AA_UseHighDpiPixmaps, true); - KActionSelector actionSelector(0); + KActionSelector actionSelector(nullptr); actionSelector.availableListWidget()->addItems(QStringList() << QStringLiteral("A") << QStringLiteral("B") << QStringLiteral("C") << QStringLiteral("D") << QStringLiteral("E")); actionSelector.selectedListWidget()->addItems(QStringList() << QStringLiteral("1") << QStringLiteral("2")); actionSelector.show(); return app.exec(); } diff --git a/tests/kanimatedbuttontest.h b/tests/kanimatedbuttontest.h index 2c3d47d..cbcf37c 100644 --- a/tests/kanimatedbuttontest.h +++ b/tests/kanimatedbuttontest.h @@ -1,55 +1,55 @@ /* Copyright (c) 2008 Pino Toscano This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KANIMATEDBUTTONTEST_H #define KANIMATEDBUTTONTEST_H #include class QLineEdit; class QSpinBox; class KAnimatedButton; class AnimationGroup : public QGroupBox { Q_OBJECT public: - AnimationGroup(const QString &name, int size, QWidget *parent = 0); + AnimationGroup(const QString &name, int size, QWidget *parent = nullptr); private: KAnimatedButton *m_animButton; }; class MainWindow : public QWidget { Q_OBJECT public: - MainWindow(QWidget *parent = 0); + MainWindow(QWidget *parent = nullptr); private Q_SLOTS: void slotAddNew(); private: QLineEdit *m_path; QSpinBox *m_size; }; #endif diff --git a/tests/kcharselecttest.cpp b/tests/kcharselecttest.cpp index c204f3f..b68dd0e 100644 --- a/tests/kcharselecttest.cpp +++ b/tests/kcharselecttest.cpp @@ -1,19 +1,19 @@ #include #include "kcharselect.h" int main(int argc, char **argv) { QApplication::setApplicationName(QStringLiteral("kcharselecttest")); QApplication app(argc, argv); app.setAttribute(Qt::AA_UseHighDpiPixmaps, true); - KCharSelect selector(0, 0); + KCharSelect selector(nullptr, nullptr); selector.resize(selector.sizeHint()); selector.show(); selector.setWindowTitle(QStringLiteral("KCharSelect Test")); return app.exec(); } diff --git a/tests/kcolorcombotest.h b/tests/kcolorcombotest.h index 1e38ab5..f4d3864 100644 --- a/tests/kcolorcombotest.h +++ b/tests/kcolorcombotest.h @@ -1,26 +1,26 @@ #ifndef _KCOLORCOMBOTEST_H #define _KCOLORCOMBOTEST_H #include class QPushButton; class KColorCombo; class KColorComboTest : public QWidget { Q_OBJECT public: - KColorComboTest(QWidget *parent = 0); + KColorComboTest(QWidget *parent = nullptr); ~KColorComboTest(); private Q_SLOTS: void quitApp(); protected: KColorCombo *mStandard; KColorCombo *mCustom; QPushButton *mExit; }; #endif diff --git a/tests/kfontrequestertest.cpp b/tests/kfontrequestertest.cpp index e4f9efc..9d69a6c 100644 --- a/tests/kfontrequestertest.cpp +++ b/tests/kfontrequestertest.cpp @@ -1,54 +1,54 @@ /* This file is part of the KDE libraries Copyright (C) 2013 David Edmundson This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include class KFontRequesterTest : public QWidget { public: - KFontRequesterTest(QWidget *parent = 0) + KFontRequesterTest(QWidget *parent = nullptr) : QWidget(parent) { QVBoxLayout *mainLayout = new QVBoxLayout(this); KFontRequester *test1 = new KFontRequester(this); mainLayout->addWidget(test1); KFontRequester *test2 = new KFontRequester(this); test2->setSampleText(QStringLiteral("This is different sample text")); test2->setTitle(QStringLiteral("A different title")); test2->setFont(QFont(QStringLiteral("comic-sans"), 12, 1)); mainLayout->addWidget(test2); } }; int main(int argc, char **argv) { QApplication::setApplicationName(QStringLiteral("kfontrequestertest")); QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps, true); QApplication app(argc, argv); KFontRequesterTest *mainWidget = new KFontRequesterTest; mainWidget->show(); return app.exec(); } diff --git a/tests/kledtest.h b/tests/kledtest.h index f856d77..c4368f3 100644 --- a/tests/kledtest.h +++ b/tests/kledtest.h @@ -1,48 +1,48 @@ #ifndef kledtest_h #define kledtest_h #include #include #include #include class KLedTest : public QWidget { Q_OBJECT protected: QTimer timer; KLed *leds[/*KLed::NoOfShapes*/2 * /*KLed::NoOfLooks*/3 * /*KLed::NoOfStates*/2]; const int LedWidth; const int LedHeight; const int Grid; KLed::Shape shape; KLed::Look look; KLed::State state; int x, y, index; QTimer t_toggle, t_color, t_look; //KLed *l; // create lamp //KLed *l; // create lamp KLed *l; // create lamp //KLed *l; // create lamp //KLed *l; // create lamp int ledcolor; KLed::Look ledlook; public: - KLedTest(QWidget *parent = 0); + KLedTest(QWidget *parent = nullptr); ~KLedTest(); bool kled_round; public Q_SLOTS: void timeout(); void nextColor(); void nextLook(); }; #endif diff --git a/tests/kmessageboxtest.cpp b/tests/kmessageboxtest.cpp index 8ea2848..2e30731 100644 --- a/tests/kmessageboxtest.cpp +++ b/tests/kmessageboxtest.cpp @@ -1,372 +1,372 @@ #undef QT_NO_CAST_FROM_ASCII #include "kmessagebox.h" #include #include #include #include class ExampleWidget : public QLabel { public: - ExampleWidget(QWidget *parent = 0); + ExampleWidget(QWidget *parent = nullptr); }; ExampleWidget::ExampleWidget(QWidget *parent) : QLabel(parent) { // Make the top-level layout; a vertical box to contain all widgets // and sub-layouts. QSize sh; setText(QStringLiteral("

Hello.

")); sh = sizeHint(); qWarning("SizeHint = %d x %d", sh.width(), sh.height()); setText(QStringLiteral("Hello.")); sh = sizeHint(); qWarning("SizeHint = %d x %d", sh.width(), sh.height()); setText(QStringLiteral("

Hello
World

")); sh = sizeHint(); qWarning("SizeHint = %d x %d", sh.width(), sh.height()); // setText("Hello\nWorld"); sh = sizeHint(); qWarning("SizeHint = %d x %d", sh.width(), sh.height()); setMinimumSize(sizeHint()); } void showResult(int test, int i) { printf("Test %d. returned %d ", test, i); switch (i) { case KMessageBox::Ok : printf("(%s)\n", "Ok"); break; case KMessageBox::Cancel : printf("(%s)\n", "Cancel"); break; case KMessageBox::Yes : printf("(%s)\n", "Yes"); break; case KMessageBox::No : printf("(%s)\n", "No"); break; case KMessageBox::Continue : printf("(%s)\n", "Continue"); break; default: printf("(%s)\n", "ERROR!"); exit(1); } } bool testMessageBox(int test) { QStringList list; list.append(QStringLiteral("Hello")); list.append(QStringLiteral("World")); int i; switch (test) { case 1: { ExampleWidget *w = new ExampleWidget(); w->show(); i = KMessageBox::warningContinueCancel(w, QString::fromLatin1("You are about to .\n" "Are you sure?"), QStringLiteral("Print"), KGuiItem(QStringLiteral("&Print")), KStandardGuiItem::cancel(), QStringLiteral("dontask")); - i = KMessageBox::warningContinueCancel(0, + i = KMessageBox::warningContinueCancel(nullptr, QString::fromLatin1("You are about to .\n" "Are you sure?"), QStringLiteral("Print"), KGuiItem(QStringLiteral("&Print")), KStandardGuiItem::cancel(), QStringLiteral("dontask"), KMessageBox::AllowLink); - i = KMessageBox::questionYesNo(0, QStringLiteral("

Do you have a printer? thisisaverylongdkldhklghklghklashgkllasghkdlsghkldfghklsabla bla bbla bla. It also has this URL.

"), + i = KMessageBox::questionYesNo(nullptr, QStringLiteral("

Do you have a printer? thisisaverylongdkldhklghklghklashgkllasghkdlsghkldfghklsabla bla bbla bla. It also has this URL.

"), QStringLiteral("Bla"), KGuiItem(QStringLiteral("Yes")), KGuiItem(QStringLiteral("No")), QStringLiteral("bla"), KMessageBox::AllowLink); break; } case 2: - i = KMessageBox::questionYesNo(0, QStringLiteral("Do you have a printer?"), + i = KMessageBox::questionYesNo(nullptr, QStringLiteral("Do you have a printer?"), QStringLiteral("Printer setup")); break; case 3: - i = KMessageBox::questionYesNo(0, + i = KMessageBox::questionYesNo(nullptr, QStringLiteral("Does your printer support color or only black and white?"), QStringLiteral("Printer setup"), KGuiItem(QStringLiteral("&Color")), KGuiItem(QLatin1String("&Black & White"))); break; case 4: - i = KMessageBox::warningYesNo(0, + i = KMessageBox::warningYesNo(nullptr, QString::fromLatin1("KDVI could not locate the program 'dvipdfm' on your computer. That program is " "absolutely needed by the export function. You can, however, convert " "the DVI-file to PDF using the print function of KDVI, but that will often " "produce files which print ok, but are of inferior quality if viewed in the " "Acrobat Reader. It may be wise to upgrade to a more recent version of your " "TeX distribution which includes the 'dvipdfm' program.\n" "Hint to the perplexed system administrator: KDVI uses the shell's PATH variable " "when looking for programs.") ); break; case 5: - i = KMessageBox::warningYesNo(0, QString::fromLatin1("Your printer has been added.\n" + i = KMessageBox::warningYesNo(nullptr, QString::fromLatin1("Your printer has been added.\n" "Do you want to update your configuration?"), QStringLiteral("Printer Setup")); break; case 6: - i = KMessageBox::warningContinueCancel(0, + i = KMessageBox::warningContinueCancel(nullptr, QString::fromLatin1("You are about to print.\n" "Are you sure?"), QStringLiteral("Print"), KGuiItem(QStringLiteral("&Print"))); break; case 7: - i = KMessageBox::warningContinueCancel(0, + i = KMessageBox::warningContinueCancel(nullptr, QString::fromLatin1("You are about to .\n" "Are you sure?"), QStringLiteral("Print"), KGuiItem(QStringLiteral("&Print")), KStandardGuiItem::cancel(), QStringLiteral("dontask")); - i = KMessageBox::warningContinueCancel(0, + i = KMessageBox::warningContinueCancel(nullptr, QString::fromLatin1("You are about to .\n" "Are you sure?"), QStringLiteral("Print"), KGuiItem(QStringLiteral("&Print")), KStandardGuiItem::cancel(), QStringLiteral("dontask")); break; case 8: - i = KMessageBox::warningYesNoCancel(0, + i = KMessageBox::warningYesNoCancel(nullptr, QString::fromLatin1("Your document contains unsaved changes.\n" "Do you want to save your changes?\n")); break; case 9: - i = KMessageBox::warningYesNoCancel(0, + i = KMessageBox::warningYesNoCancel(nullptr, QString::fromLatin1("Your document contains unsaved changes.\n" "Do you want to save your changes?\n"), QStringLiteral("Close")); break; case 10: - i = KMessageBox::warningYesNoCancel(0, + i = KMessageBox::warningYesNoCancel(nullptr, QString::fromLatin1("Your document contains unsaved changes.\n" "Do you want to save or discard your changes?\n"), QStringLiteral("Close"), KGuiItem(QStringLiteral("&Save")), KGuiItem(QStringLiteral("&Discard"))); break; case 11: i = KMessageBox::Ok; - KMessageBox::error(0, QStringLiteral("Oops, Your harddisk is unreadable.")); + KMessageBox::error(nullptr, QStringLiteral("Oops, Your harddisk is unreadable.")); break; case 12: i = KMessageBox::Ok; - KMessageBox::detailedError(0, QStringLiteral("Oops, Your harddisk is unreadable."), QStringLiteral("We don't know more yet."), QStringLiteral("Uh ooh")); + KMessageBox::detailedError(nullptr, QStringLiteral("Oops, Your harddisk is unreadable."), QStringLiteral("We don't know more yet."), QStringLiteral("Uh ooh")); break; case 13: i = KMessageBox::Ok; - KMessageBox::sorry(0, QStringLiteral("Sorry, Your harddisk appears to be empty.")); + KMessageBox::sorry(nullptr, QStringLiteral("Sorry, Your harddisk appears to be empty.")); break; case 14: i = KMessageBox::Ok; - KMessageBox::detailedSorry(0, QStringLiteral("Sorry, Your harddisk appears to be empty."), QStringLiteral("We don't know more yet."), QStringLiteral("Oops")); + KMessageBox::detailedSorry(nullptr, QStringLiteral("Sorry, Your harddisk appears to be empty."), QStringLiteral("We don't know more yet."), QStringLiteral("Oops")); break; case 15: i = KMessageBox::Ok; - KMessageBox::information(0, QString::fromLatin1("You can enable the menubar again " + KMessageBox::information(nullptr, QString::fromLatin1("You can enable the menubar again " "with the right mouse button menu.")); break; case 16: i = KMessageBox::Ok; - KMessageBox::information(0, QString::fromLatin1("You can enable the menubar again " + KMessageBox::information(nullptr, QString::fromLatin1("You can enable the menubar again " "with the right mouse button menu."), QStringLiteral("Menubar Info")); break; case 17: i = KMessageBox::Ok; - KMessageBox::information(0, QStringLiteral("You can enable the menubar again\nwith the right mouse button menu."), QString(), QStringLiteral("Enable_Menubar")); + KMessageBox::information(nullptr, QStringLiteral("You can enable the menubar again\nwith the right mouse button menu."), QString(), QStringLiteral("Enable_Menubar")); break; case 18: i = KMessageBox::Ok; KMessageBox::enableAllMessages(); break; case 19: i = KMessageBox::Ok; - KMessageBox::information(0, QStringLiteral("Return of the annoying popup message."), QString(), QStringLiteral("Enable_Menubar")); + KMessageBox::information(nullptr, QStringLiteral("Return of the annoying popup message."), QString(), QStringLiteral("Enable_Menubar")); break; case 20: { QStringList strlist; strlist << QStringLiteral("/dev/hda") << QStringLiteral("/etc/inittab") << QStringLiteral("/usr/somefile") << QString::fromLatin1("/some/really/" "long/file/name/which/is/in/a/really/deep/directory/in/a/really/large/" "hard/disk/of/your/system") << QStringLiteral("/and/another/one"); - i = KMessageBox::questionYesNoList(0, QStringLiteral("Do you want to delete the following files?"), strlist); + i = KMessageBox::questionYesNoList(nullptr, QStringLiteral("Do you want to delete the following files?"), strlist); } break; case 21: { QStringList strlist; printf("Filling StringList...\n"); for (int j = 1; j <= 6000; j++) { strlist.append(QStringLiteral("/tmp/tmp.%1").arg(j)); } printf("Completed...\n"); - i = KMessageBox::questionYesNoList(0, QStringLiteral("Do you want to delete the following files?"), strlist); + i = KMessageBox::questionYesNoList(nullptr, QStringLiteral("Do you want to delete the following files?"), strlist); } break; case 22: i = KMessageBox::Ok; - KMessageBox::informationList(0, QStringLiteral("The following words have been found:"), list); + KMessageBox::informationList(nullptr, QStringLiteral("The following words have been found:"), list); break; case 23: i = KMessageBox::Ok; - KMessageBox::informationList(0, QStringLiteral("The following words have been found:"), list, QStringLiteral("Search Words")); + KMessageBox::informationList(nullptr, QStringLiteral("The following words have been found:"), list, QStringLiteral("Search Words")); break; case 24: i = KMessageBox::Ok; - KMessageBox::informationList(0, QStringLiteral("The follwoing words have been found:"), list, QString(), QStringLiteral("Search_Words")); + KMessageBox::informationList(nullptr, QStringLiteral("The follwoing words have been found:"), list, QString(), QStringLiteral("Search_Words")); break; case 25: { i = KMessageBox::Ok; QString msg; for (int j = 0; j < 200; ++j) { msg.append("LongMessageWithoutAnyBreaksShouldAppearSqueezed."); } - KMessageBox::sorry(0, msg); + KMessageBox::sorry(nullptr, msg); break; } default: return false; // done } // Switch showResult(test, i); return true; } int main(int argc, char *argv[]) { QApplication app(argc, argv); app.setAttribute(Qt::AA_UseHighDpiPixmaps, true); app.setApplicationName(QStringLiteral("kmessageboxtest")); // Syntax: kmessageboxtest if (argc > 1) { testMessageBox(QByteArray(argv[1]).toInt()); return 0; } // No argument specified, run all tests int test = 1; while (++test) { if (!testMessageBox(test)) { break; } } return 0; } #if 0 //this is my sequence for testing messagebox layout: KMessageBox::questionYesNoCancel( 0, "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", "long", KStandardGuiItem::saveAs(), KGuiItem("dsdddddd"), KStandardGuiItem::cancel() ); KMessageBox::questionYesNoCancel( 0, "ddddddddddddddddddddd ddddddddddddddddddddd dddddddddd dddddddddd ddddddddddddddddddd dddddddddddd ddddddddd", "long wrap", KStandardGuiItem::saveAs(), KGuiItem("dsdddddd"), KStandardGuiItem::cancel() ); KMessageBox::questionYesNoCancel( 0, "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd", "height", KStandardGuiItem::saveAs(), KGuiItem("dsdddddd"), KStandardGuiItem::cancel() ); QStringList strlist; strlist << "fgfghghghgfhgf" << "fgfghghghgfhgf" << "fgfgh\nghghgfhgf" << "f\ngfg\nhg\nhghgfhgf" << "fgfghghghgfhgf" << "fgfghghghgfhgf" << "fgfghghghgfhgf" << "fgfghghghgfhgf" << "fgfghghghgfhgf" << "fgfghghghgfhgf" << "fgfghghghgfhgf" << "fgfghghghgfhgf" << "fgfghghghgfhgf" << "fgfghghghgfhgf" << "fgfghghghgfhgf" << "fgfghghghgfhgf" << "fgfghghghgfhgf" << "fgfghghghgfhgf" << "fgfghghghgfhgf" << "fgfghghghgfhgf"; KMessageBox::errorList(0, "short\n", strlist, "short"); KMessageBox::errorList(0, "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", strlist, "short"); KMessageBox::errorList(0, "ddddddddddddddddddddd ddddddddddddddddddddd dddddddddd dddddddddd ddddddddddddddddddd dddddddddddd ddddddddd", strlist, "short"); KMessageBox::errorList(0, "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd", strlist, "short"); KMessageBox::detailedError(0, "sss", "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" ); KMessageBox::detailedError(0, "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" ); KMessageBox::detailedError(0, "ddddddddddddddddddddd ddddddddddddddddddddd dddddddddd dddddddddd ddddddddddddddddddd dddddddddddd ddddddddd", "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" ); KMessageBox::detailedError(0, "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd", "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" "dddddd\ndddddd\nddddddddd ddddd\ndddd\ndddddddddddd \ndddddddddd dddddddddd dd\nddddddddddd\ndd\ndddd dddd\ndddddddd ddd\ndd\ndddd" ); #endif diff --git a/tests/kmimetypechoosertest.cpp b/tests/kmimetypechoosertest.cpp index d7a6a7e..6d006ef 100644 --- a/tests/kmimetypechoosertest.cpp +++ b/tests/kmimetypechoosertest.cpp @@ -1,41 +1,41 @@ /* This file is part of the KDE project Copyright (C) 2006 David Faure This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include int main(int argc, char **argv) { QApplication app(argc, argv); app.setAttribute(Qt::AA_UseHighDpiPixmaps, true); QString text = QStringLiteral("Select the MimeTypes you want for this file type."); QStringList list; list << QStringLiteral("inode/directory") << QStringLiteral("text/plain"); KMimeTypeChooserDialog dlg(QStringLiteral("Select Mime Types"), text, list, QStringLiteral("text"), QStringList(), KMimeTypeChooser::Comments | KMimeTypeChooser::Patterns | KMimeTypeChooser::EditButton, - (QWidget *)0); + (QWidget *)nullptr); if (dlg.exec() == QDialog::Accepted) { qDebug() << dlg.chooser()->patterns(); qDebug() << dlg.chooser()->mimeTypes().join(QLatin1Char(';')); } return 0; // app.exec(); } diff --git a/tests/kpagedialogtest.cpp b/tests/kpagedialogtest.cpp index 8ba8a54..89993ab 100644 --- a/tests/kpagedialogtest.cpp +++ b/tests/kpagedialogtest.cpp @@ -1,70 +1,70 @@ /* This file is part of the KDE Libraries Copyright (C) 2006 Tobias Koenig (tokoe@kde.org) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include "kpagedialogtest.h" KPageDialogTest::KPageDialogTest(QWidget *parent) : KPageDialog(parent) { setFaceType(Tabbed); QWidget *page = new QWidget(this); QBoxLayout *layout = new QVBoxLayout(page); QLabel *label = new QLabel(QStringLiteral("first page")); layout->addWidget(label); label = new QLabel(QStringLiteral("This is a very long text that is contained in a single string within a single label")); layout->addWidget(label); addPage(page, QStringLiteral("First")); page = new QWidget(this); layout = new QHBoxLayout(page); label = new QLabel(QStringLiteral("second page")); label->setMinimumSize(300, 200); layout->addWidget(label); addPage(page, QStringLiteral("Second")); } KPageDialogTest::~KPageDialogTest() { } int main(int argc, char **argv) { QApplication::setApplicationName(QStringLiteral("KPageDialogTest")); QApplication app(argc, argv); app.setAttribute(Qt::AA_UseHighDpiPixmaps, true); - KPageDialogTest testDialog(0); + KPageDialogTest testDialog(nullptr); testDialog.exec(); return 0; } diff --git a/tests/kpagedialogtest.h b/tests/kpagedialogtest.h index e77c3bd..523aba7 100644 --- a/tests/kpagedialogtest.h +++ b/tests/kpagedialogtest.h @@ -1,36 +1,36 @@ /* This file is part of the KDE Libraries Copyright (C) 2006 Tobias Koenig (tokoe@kde.org) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KPAGEDIALOGTEST_H #define KPAGEDIALOGTEST_H #include "kpagedialog.h" class KPageDialogTest : public KPageDialog { Q_OBJECT public: - KPageDialogTest(QWidget *parent = 0); + KPageDialogTest(QWidget *parent = nullptr); ~KPageDialogTest(); }; #endif diff --git a/tests/kpagewidgettest.cpp b/tests/kpagewidgettest.cpp index efbc54d..3b24e15 100644 --- a/tests/kpagewidgettest.cpp +++ b/tests/kpagewidgettest.cpp @@ -1,212 +1,212 @@ /* This file is part of the KDE Libraries Copyright (C) 2006 Tobias Koenig (tokoe@kde.org) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include "kpagewidgetmodel.h" #include "kpagewidgettest.h" KPageWidgetTest::KPageWidgetTest(QWidget *parent) : QWidget(parent) { QGridLayout *layout = new QGridLayout(this); mWidget = new KPageWidget(this); layout->addWidget(mWidget, 0, 0, 7, 1); connect(mWidget, SIGNAL(currentPageChanged(KPageWidgetItem*,KPageWidgetItem*)), this, SLOT(currentPageChanged(KPageWidgetItem*,KPageWidgetItem*))); connect(mWidget, &KPageWidget::pageToggled, this, &KPageWidgetTest::pageToggled); int rowCount = 0; QPushButton *button = new QPushButton(QStringLiteral("Auto"), this); layout->addWidget(button, rowCount, 1); connect(button, &QAbstractButton::clicked, this, &KPageWidgetTest::setAutoFace); rowCount++; button = new QPushButton(QStringLiteral("Plain"), this); layout->addWidget(button, rowCount, 1); connect(button, &QAbstractButton::clicked, this, &KPageWidgetTest::setPlainFace); rowCount++; button = new QPushButton(QStringLiteral("List"), this); layout->addWidget(button, rowCount, 1); connect(button, &QAbstractButton::clicked, this, &KPageWidgetTest::setListFace); rowCount++; button = new QPushButton(QStringLiteral("Tree"), this); layout->addWidget(button, rowCount, 1); connect(button, &QAbstractButton::clicked, this, &KPageWidgetTest::setTreeFace); rowCount++; button = new QPushButton(QStringLiteral("Tabbed"), this); layout->addWidget(button, rowCount, 1); connect(button, &QAbstractButton::clicked, this, &KPageWidgetTest::setTabbedFace); rowCount++; button = new QPushButton(QStringLiteral("Add Page"), this); layout->addWidget(button, rowCount, 1); connect(button, &QAbstractButton::clicked, this, &KPageWidgetTest::addPage); rowCount++; button = new QPushButton(QStringLiteral("Add Sub Page"), this); layout->addWidget(button, rowCount, 1); connect(button, &QAbstractButton::clicked, this, &KPageWidgetTest::addSubPage); rowCount++; button = new QPushButton(QStringLiteral("Insert Page"), this); layout->addWidget(button, rowCount, 1); connect(button, &QAbstractButton::clicked, this, &KPageWidgetTest::insertPage); rowCount++; button = new QPushButton(QStringLiteral("Delete Page"), this); layout->addWidget(button, rowCount, 1); connect(button, &QAbstractButton::clicked, this, &KPageWidgetTest::deletePage); rowCount++; KPageWidgetItem *item = mWidget->addPage(new QPushButton(QStringLiteral("folder")), QStringLiteral("folder")); item->setIcon(QIcon::fromTheme(QStringLiteral("folder"))); item = mWidget->addSubPage(item, new QPushButton(QStringLiteral("subfolder")), QStringLiteral("subfolder")); item->setIcon(QIcon::fromTheme(QStringLiteral("folder"))); item = mWidget->addPage(new QLabel(QStringLiteral("second folder")), QStringLiteral("second folder")); item->setIcon(QIcon::fromTheme(QStringLiteral("folder"))); } KPageWidgetTest::~KPageWidgetTest() { } void KPageWidgetTest::setAutoFace() { mWidget->setFaceType(KPageWidget::Auto); } void KPageWidgetTest::setPlainFace() { mWidget->setFaceType(KPageWidget::Plain); } void KPageWidgetTest::setListFace() { mWidget->setFaceType(KPageWidget::List); } void KPageWidgetTest::setTreeFace() { mWidget->setFaceType(KPageWidget::Tree); } void KPageWidgetTest::setTabbedFace() { mWidget->setFaceType(KPageWidget::Tabbed); } void KPageWidgetTest::addPage() { static int counter = 0; const QString title = QString(QStringLiteral("dynamic folder %1")).arg(QString::number(counter)); KPageWidgetItem *item = mWidget->addPage(new QPushButton(title), title); item->setIcon(QIcon::fromTheme(QStringLiteral("folder"))); item->setHeader(QString(QStringLiteral("Header Test No. %1")).arg(QString::number(counter))); item->setCheckable(true); counter++; } void KPageWidgetTest::addSubPage() { static int counter = 0; KPageWidgetItem *item = mWidget->currentPage(); if (!item) { return; } const QString title = QString(QStringLiteral("subfolder %1")).arg(QString::number(counter)); item = mWidget->addSubPage(item, new QLabel(title), title); item->setIcon(QIcon::fromTheme(QStringLiteral("folder"))); counter++; } void KPageWidgetTest::insertPage() { static int counter = 0; KPageWidgetItem *item = mWidget->currentPage(); if (!item) { return; } const QString title = QString(QStringLiteral("before folder %1")).arg(QString::number(counter)); item = mWidget->insertPage(item, new QLabel(title), title); item->setIcon(QIcon::fromTheme(QStringLiteral("folder"))); counter++; } void KPageWidgetTest::deletePage() { KPageWidgetItem *item = mWidget->currentPage(); if (item) { mWidget->removePage(item); } } void KPageWidgetTest::currentPageChanged(KPageWidgetItem *current, KPageWidgetItem *before) { if (current) { qDebug("Current item: %s", qPrintable(current->name())); } else { qDebug("No current item"); } if (before) { qDebug("Item before: %s", qPrintable(before->name())); } else { qDebug("No item before"); } } void KPageWidgetTest::pageToggled(KPageWidgetItem *item, bool checked) { qDebug("Item %s changed check state to: %s", qPrintable(item->name()), checked ? "checked" : "unchecked"); } int main(int argc, char **argv) { QApplication::setApplicationName(QStringLiteral("KPageWidgetTest")); QApplication app(argc, argv); app.setAttribute(Qt::AA_UseHighDpiPixmaps, true); - KPageWidgetTest testWidget(0); + KPageWidgetTest testWidget(nullptr); testWidget.show(); return app.exec(); } diff --git a/tests/kpagewidgettest.h b/tests/kpagewidgettest.h index bceb104..cf6e6f2 100644 --- a/tests/kpagewidgettest.h +++ b/tests/kpagewidgettest.h @@ -1,56 +1,56 @@ /* This file is part of the KDE Libraries Copyright (C) 2006 Tobias Koenig (tokoe@kde.org) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KPAGEWIDGETTEST_H #define KPAGEWIDGETTEST_H #include #include "kpagewidget.h" class KPageWidgetTest : public QWidget { Q_OBJECT public: - KPageWidgetTest(QWidget *parent = 0); + KPageWidgetTest(QWidget *parent = nullptr); ~KPageWidgetTest(); private Q_SLOTS: void setAutoFace(); void setPlainFace(); void setListFace(); void setTreeFace(); void setTabbedFace(); void addPage(); void addSubPage(); void insertPage(); void deletePage(); void currentPageChanged(KPageWidgetItem *, KPageWidgetItem *); void pageToggled(KPageWidgetItem *, bool); private: KPageWidget *mWidget; }; #endif diff --git a/tests/kpassworddialogtest.cpp b/tests/kpassworddialogtest.cpp index df5f8b8..fb75da8 100644 --- a/tests/kpassworddialogtest.cpp +++ b/tests/kpassworddialogtest.cpp @@ -1,89 +1,89 @@ /* This file is part of the KDE libraries Copyright (C) 2007 Olivier Goffart This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include // We can't depend on i18n in this test, but still -- show good practice (other than the line below) :-) #define i18n QString::fromLatin1 int main(int argc, char *argv[]) { QApplication::setColorSpec(QApplication::CustomColor); QApplication::setApplicationName(QStringLiteral("KNewPasswordDialogTest")); QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps, true); QApplication a(argc, argv); //step 1 simple password { - KPasswordDialog dlg(0, KPasswordDialog::ShowKeepPassword); + KPasswordDialog dlg(nullptr, KPasswordDialog::ShowKeepPassword); dlg.setPrompt(i18n("This is a long prompt line. It is important it to be long so we can test the dialog does not get broken because of multiline labels. Please enter a password:")); dlg.addCommentLine(i18n("This is a rather large left comment line"), i18n("Right part of the comment line has to be long too so be test the layouting works really ok. Please visit http://www.kde.org")); if (dlg.exec()) { std::cout << "Entered password: " << qPrintable(dlg.password()) << std::endl; } else { std::cout << "No password" << std::endl; return -1; } } //step 2 readonly username { - KPasswordDialog dlg(0, KPasswordDialog::ShowUsernameLine | KPasswordDialog::UsernameReadOnly); + KPasswordDialog dlg(nullptr, KPasswordDialog::ShowUsernameLine | KPasswordDialog::UsernameReadOnly); dlg.setPrompt(i18n("Enter a password for the test")); dlg.setUsername(QStringLiteral("konqui")); dlg.addCommentLine(i18n("Site"), i18n("http://www.kde.org")); if (dlg.exec()) { std::cout << "Entered password: " << qPrintable(dlg.password()) << std::endl; } else { std::cout << "No password" << std::endl; return -1; } } //step 3 with some username preset { - KPasswordDialog dlg(0, KPasswordDialog::ShowUsernameLine); + KPasswordDialog dlg(nullptr, KPasswordDialog::ShowUsernameLine); dlg.setPrompt(i18n("Enter a password for the test")); QMap logins; logins.insert(QStringLiteral("konqui"), QStringLiteral("foo")); logins.insert(QStringLiteral("watson"), QStringLiteral("bar")); logins.insert(QStringLiteral("ogoffart"), QString()); dlg.setKnownLogins(logins); if (dlg.exec()) { std::cout << "Entered password: " << qPrintable(dlg.password()) << " for username " << qPrintable(dlg.username()) << std::endl; } else { std::cout << "No password" << std::endl; return -1; } } return 0; } diff --git a/tests/kselectactiontest.h b/tests/kselectactiontest.h index 70456d3..1a2d53d 100644 --- a/tests/kselectactiontest.h +++ b/tests/kselectactiontest.h @@ -1,49 +1,49 @@ /* Copyright 2006 Hamish Rodda This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KSELECTACTION_TEST_H #define KSELECTACTION_TEST_H #include class KSelectAction; class SelectActionTest : public QMainWindow { Q_OBJECT public: - SelectActionTest(QWidget *parent = 0); + SelectActionTest(QWidget *parent = nullptr); public Q_SLOTS: void triggered(QAction *action); void triggered(int index); void triggered(const QString &text); void slotActionTriggered(bool state); void addAction(); void removeAction(); private: KSelectAction *m_comboSelect; KSelectAction *m_buttonSelect; }; #endif diff --git a/tests/ksplittercollapserbuttongui_test.h b/tests/ksplittercollapserbuttongui_test.h index 851bccc..6f9c7a5 100644 --- a/tests/ksplittercollapserbuttongui_test.h +++ b/tests/ksplittercollapserbuttongui_test.h @@ -1,35 +1,35 @@ /* Copyright (c) 2014 Montel Laurent This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #ifndef KSPLITTERCOLLAPSERBUTTONGUI_TEST_H #define KSPLITTERCOLLAPSERBUTTONGUI_TEST_H #include class KSplitterCollapserButtonGui_test : public QWidget { Q_OBJECT public: - explicit KSplitterCollapserButtonGui_test(int indexOfWidgetAssociateToSplitterCollapser, Qt::Orientation orientation, QWidget *parent = 0); + explicit KSplitterCollapserButtonGui_test(int indexOfWidgetAssociateToSplitterCollapser, Qt::Orientation orientation, QWidget *parent = nullptr); ~KSplitterCollapserButtonGui_test(); }; #endif // KSPLITTERCOLLAPSERBUTTONGUI_TEST_H diff --git a/tests/ktitlewidgettest.cpp b/tests/ktitlewidgettest.cpp index e095b10..b313e63 100644 --- a/tests/ktitlewidgettest.cpp +++ b/tests/ktitlewidgettest.cpp @@ -1,77 +1,77 @@ /* This file is part of the KDE libraries Copyright (C) 2007 Urs Wolfer This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include class KTitleWidgetTestWidget : public QWidget { public: - KTitleWidgetTestWidget(QWidget *parent = 0) + KTitleWidgetTestWidget(QWidget *parent = nullptr) : QWidget(parent) { QVBoxLayout *mainLayout = new QVBoxLayout(this); KTitleWidget *titleWidget = new KTitleWidget(this); titleWidget->setText(QStringLiteral("Title")); titleWidget->setPixmap(QIcon::fromTheme(QStringLiteral("screen")).pixmap(22, 22), KTitleWidget::ImageLeft); mainLayout->addWidget(titleWidget); KTitleWidget *errorTitle = new KTitleWidget(this); errorTitle->setText(QStringLiteral("Title")); errorTitle->setComment(QStringLiteral("Error Comment"), KTitleWidget::ErrorMessage); mainLayout->addWidget(errorTitle); KTitleWidget *checkboxTitleWidget = new KTitleWidget(this); QWidget *checkBoxTitleMainWidget = new QWidget(this); QVBoxLayout *titleLayout = new QVBoxLayout(checkBoxTitleMainWidget); titleLayout->setMargin(6); QCheckBox *checkBox = new QCheckBox(QStringLiteral("Text Checkbox"), checkBoxTitleMainWidget); titleLayout->addWidget(checkBox); checkboxTitleWidget->setWidget(checkBoxTitleMainWidget); mainLayout->addWidget(checkboxTitleWidget); QLabel *otherLabel = new QLabel(QStringLiteral("Some text..."), this); mainLayout->addWidget(otherLabel); mainLayout->addStretch(); } }; int main(int argc, char **argv) { QApplication::setApplicationName(QStringLiteral("ktitlewidgettest")); QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps, true); QApplication app(argc, argv); KTitleWidgetTestWidget *mainWidget = new KTitleWidgetTestWidget; mainWidget->show(); return app.exec(); }