diff options
author | Petr Mrázek <peterix@gmail.com> | 2014-06-30 02:02:57 +0200 |
---|---|---|
committer | Petr Mrázek <peterix@gmail.com> | 2014-06-30 02:02:57 +0200 |
commit | 421a46e3d3036ea0dea4889125ee58309d0ed21e (patch) | |
tree | b3665ec5c94c991c7dba5436580ffd4047395aa8 /gui/pages | |
parent | 5179aed3a066dfc9885a75d36a0e64c48aa448f7 (diff) | |
download | MultiMC-421a46e3d3036ea0dea4889125ee58309d0ed21e.tar MultiMC-421a46e3d3036ea0dea4889125ee58309d0ed21e.tar.gz MultiMC-421a46e3d3036ea0dea4889125ee58309d0ed21e.tar.lz MultiMC-421a46e3d3036ea0dea4889125ee58309d0ed21e.tar.xz MultiMC-421a46e3d3036ea0dea4889125ee58309d0ed21e.zip |
Redo the console window. Log is now a page. Console window has relevant pages.
Dirty fix for screenshot thumbnail generation. Needs more QTimer.
Diffstat (limited to 'gui/pages')
-rw-r--r-- | gui/pages/InstanceSettingsPage.cpp | 10 | ||||
-rw-r--r-- | gui/pages/InstanceSettingsPage.h | 8 | ||||
-rw-r--r-- | gui/pages/LegacyJarModPage.cpp | 5 | ||||
-rw-r--r-- | gui/pages/LegacyJarModPage.h | 1 | ||||
-rw-r--r-- | gui/pages/LegacyUpgradePage.cpp | 6 | ||||
-rw-r--r-- | gui/pages/LegacyUpgradePage.h | 1 | ||||
-rw-r--r-- | gui/pages/LogPage.cpp | 137 | ||||
-rw-r--r-- | gui/pages/LogPage.h | 72 | ||||
-rw-r--r-- | gui/pages/LogPage.ui | 76 | ||||
-rw-r--r-- | gui/pages/ModFolderPage.cpp | 10 | ||||
-rw-r--r-- | gui/pages/ModFolderPage.h | 6 | ||||
-rw-r--r-- | gui/pages/ResourcePackPage.h | 5 | ||||
-rw-r--r-- | gui/pages/ScreenshotsPage.cpp | 86 | ||||
-rw-r--r-- | gui/pages/TexturePackPage.h | 5 | ||||
-rw-r--r-- | gui/pages/VersionPage.cpp | 5 | ||||
-rw-r--r-- | gui/pages/VersionPage.h | 1 |
16 files changed, 385 insertions, 49 deletions
diff --git a/gui/pages/InstanceSettingsPage.cpp b/gui/pages/InstanceSettingsPage.cpp index b4a6405f..6e2ce238 100644 --- a/gui/pages/InstanceSettingsPage.cpp +++ b/gui/pages/InstanceSettingsPage.cpp @@ -23,13 +23,19 @@ QString InstanceSettingsPage::id() return "settings"; } -InstanceSettingsPage::InstanceSettingsPage(SettingsObject *s, QWidget *parent) - : QWidget(parent), ui(new Ui::InstanceSettingsPage), m_settings(s) +InstanceSettingsPage::InstanceSettingsPage(BaseInstance *inst, QWidget *parent) + : QWidget(parent), ui(new Ui::InstanceSettingsPage), m_instance(inst) { + m_settings = &(inst->settings()); ui->setupUi(this); loadSettings(); } +bool InstanceSettingsPage::shouldDisplay() +{ + return !m_instance->isRunning(); +} + InstanceSettingsPage::~InstanceSettingsPage() { delete ui; diff --git a/gui/pages/InstanceSettingsPage.h b/gui/pages/InstanceSettingsPage.h index db37d8d8..2447168f 100644 --- a/gui/pages/InstanceSettingsPage.h +++ b/gui/pages/InstanceSettingsPage.h @@ -32,15 +32,14 @@ class InstanceSettingsPage : public QWidget, public BasePage Q_OBJECT public: - explicit InstanceSettingsPage(SettingsObject *s, QWidget *parent = 0); + explicit InstanceSettingsPage(BaseInstance *inst, QWidget *parent = 0); virtual ~InstanceSettingsPage(); virtual QString displayName() override; virtual QIcon icon() override; virtual QString id() override; virtual bool apply(); - virtual QString helpPage() override { return "Instance-settings"; }; -private: - void updateCheckboxStuff(); + virtual QString helpPage() override { return "Instance-settings"; } + virtual bool shouldDisplay(); private slots: void on_javaDetectBtn_clicked(); @@ -54,6 +53,7 @@ private slots: void loadSettings(); private: Ui::InstanceSettingsPage *ui; + BaseInstance *m_instance; SettingsObject *m_settings; std::shared_ptr<JavaChecker> checker; }; diff --git a/gui/pages/LegacyJarModPage.cpp b/gui/pages/LegacyJarModPage.cpp index f0f3d753..b1c0d49a 100644 --- a/gui/pages/LegacyJarModPage.cpp +++ b/gui/pages/LegacyJarModPage.cpp @@ -54,6 +54,11 @@ QString LegacyJarModPage::displayName() return tr("Jar Mods"); } +bool LegacyJarModPage::shouldDisplay() +{ + return !m_inst->isRunning(); +} + QIcon LegacyJarModPage::icon() { return QIcon::fromTheme("plugin-red"); diff --git a/gui/pages/LegacyJarModPage.h b/gui/pages/LegacyJarModPage.h index 0b28777b..016f4a8f 100644 --- a/gui/pages/LegacyJarModPage.h +++ b/gui/pages/LegacyJarModPage.h @@ -38,6 +38,7 @@ public: virtual QIcon icon(); virtual QString id(); virtual QString helpPage() override { return "Legacy-jar-mods"; }; + virtual bool shouldDisplay(); private slots: diff --git a/gui/pages/LegacyUpgradePage.cpp b/gui/pages/LegacyUpgradePage.cpp index 02729c79..bb54210c 100644 --- a/gui/pages/LegacyUpgradePage.cpp +++ b/gui/pages/LegacyUpgradePage.cpp @@ -1,4 +1,5 @@ #include "LegacyUpgradePage.h" +#include <logic/LegacyInstance.h> #include "ui_LegacyUpgradePage.h" QString LegacyUpgradePage::displayName() @@ -31,3 +32,8 @@ void LegacyUpgradePage::on_upgradeButton_clicked() { // now what? } + +bool LegacyUpgradePage::shouldDisplay() +{ + return !m_inst->isRunning(); +}
\ No newline at end of file diff --git a/gui/pages/LegacyUpgradePage.h b/gui/pages/LegacyUpgradePage.h index 4f287e95..eb816a7a 100644 --- a/gui/pages/LegacyUpgradePage.h +++ b/gui/pages/LegacyUpgradePage.h @@ -37,6 +37,7 @@ public: virtual QIcon icon() override; virtual QString id() override; virtual QString helpPage() override { return "Legacy-upgrade"; }; + virtual bool shouldDisplay(); private slots: void on_upgradeButton_clicked(); diff --git a/gui/pages/LogPage.cpp b/gui/pages/LogPage.cpp new file mode 100644 index 00000000..dd088862 --- /dev/null +++ b/gui/pages/LogPage.cpp @@ -0,0 +1,137 @@ +#include "LogPage.h" +#include <gui/dialogs/CustomMessageBox.h> +#include <gui/dialogs/ProgressDialog.h> +#include <logic/MinecraftProcess.h> +#include <QtGui/QIcon> +#include "ui_LogPage.h" +#include "logic/net/PasteUpload.h" +#include <QScrollBar> + +QString LogPage::displayName() +{ + return tr("Minecraft Log"); +} + +QIcon LogPage::icon() +{ + return QIcon::fromTheme("refresh"); +} + +QString LogPage::id() +{ + return "console"; +} + +LogPage::LogPage(MinecraftProcess *proc, QWidget *parent) + : QWidget(parent), ui(new Ui::LogPage), m_process(proc) +{ + ui->setupUi(this); + connect(m_process, SIGNAL(log(QString, MessageLevel::Enum)), this, + SLOT(write(QString, MessageLevel::Enum))); +} + +LogPage::~LogPage() +{ + delete ui; +} + +bool LogPage::apply() +{ + return true; +} + +bool LogPage::shouldDisplay() +{ + return m_process->instance()->isRunning(); +} + +void LogPage::on_btnPaste_clicked() +{ + auto text = ui->text->toPlainText(); + ProgressDialog dialog(this); + PasteUpload *paste = new PasteUpload(this, text); + dialog.exec(paste); + if (!paste->successful()) + { + CustomMessageBox::selectable(this, "Upload failed", paste->failReason(), + QMessageBox::Critical)->exec(); + } +} + +void LogPage::writeColor(QString text, const char *color, const char * background) +{ + // append a paragraph + QString newtext; + newtext += "<span style=\""; + { + if (color) + newtext += QString("color:") + color + ";"; + if (background) + newtext += QString("background-color:") + background + ";"; + newtext += "font-family: monospace;"; + } + newtext += "\">"; + newtext += text.toHtmlEscaped(); + newtext += "</span>"; + ui->text->appendHtml(newtext); +} + +void LogPage::write(QString data, MessageLevel::Enum mode) +{ + QScrollBar *bar = ui->text->verticalScrollBar(); + int max_bar = bar->maximum(); + int val_bar = bar->value(); + if(isVisible()) + { + if (m_scroll_active) + { + m_scroll_active = (max_bar - val_bar) <= 1; + } + else + { + m_scroll_active = val_bar == max_bar; + } + } + if (data.endsWith('\n')) + data = data.left(data.length() - 1); + QStringList paragraphs = data.split('\n'); + QStringList filtered; + for (QString ¶graph : paragraphs) + { + // Quick hack for + if(paragraph.contains("Detected an attempt by a mod null to perform game activity during mod construction")) + continue; + filtered.append(paragraph.trimmed()); + } + QListIterator<QString> iter(filtered); + if (mode == MessageLevel::MultiMC) + while (iter.hasNext()) + writeColor(iter.next(), "blue", 0); + else if (mode == MessageLevel::Error) + while (iter.hasNext()) + writeColor(iter.next(), "red", 0); + else if (mode == MessageLevel::Warning) + while (iter.hasNext()) + writeColor(iter.next(), "orange", 0); + else if (mode == MessageLevel::Fatal) + while (iter.hasNext()) + writeColor(iter.next(), "red", "black"); + else if (mode == MessageLevel::Debug) + while (iter.hasNext()) + writeColor(iter.next(), "green", 0); + else if (mode == MessageLevel::PrePost) + while (iter.hasNext()) + writeColor(iter.next(), "grey", 0); + // TODO: implement other MessageLevels + else + while (iter.hasNext()) + writeColor(iter.next(), 0, 0); + if(isVisible()) + { + if (m_scroll_active) + { + bar->setValue(bar->maximum()); + } + m_last_scroll_value = bar->value(); + } +} diff --git a/gui/pages/LogPage.h b/gui/pages/LogPage.h new file mode 100644 index 00000000..7cdea2c1 --- /dev/null +++ b/gui/pages/LogPage.h @@ -0,0 +1,72 @@ +/* Copyright 2014 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#pragma once +#include <QWidget> + +#include <logic/BaseInstance.h> +#include <logic/net/NetJob.h> +#include <logic/MinecraftProcess.h> +#include "BasePage.h" + +class EnabledItemFilter; +class MinecraftProcess; +namespace Ui +{ +class LogPage; +} + +class LogPage : public QWidget, public BasePage +{ + Q_OBJECT + +public: + explicit LogPage(MinecraftProcess *proc, QWidget *parent = 0); + virtual ~LogPage(); + virtual QString displayName() override; + virtual QIcon icon() override; + virtual QString id() override; + virtual bool apply(); + virtual QString helpPage() override { return "Minecraft-Log"; }; + virtual bool shouldDisplay(); + +private: + /** + * @brief write a colored paragraph + * @param data the string + * @param color the css color name + * this will only insert a single paragraph. + * \n are ignored. a real \n is always appended. + */ + void writeColor(QString text, const char *color, const char *background); + +private slots: + /** + * @brief write a string + * @param data the string + * @param mode the WriteMode + * lines have to be put through this as a whole! + */ + void write(QString data, MessageLevel::Enum level = MessageLevel::MultiMC); + void on_btnPaste_clicked(); + +private: + Ui::LogPage *ui; + MinecraftProcess *m_process; + int m_last_scroll_value = 0; + bool m_scroll_active = true; + int m_saved_offset = 0; +}; diff --git a/gui/pages/LogPage.ui b/gui/pages/LogPage.ui new file mode 100644 index 00000000..00b611b5 --- /dev/null +++ b/gui/pages/LogPage.ui @@ -0,0 +1,76 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>LogPage</class> + <widget class="QWidget" name="LogPage"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>831</width> + <height>596</height> + </rect> + </property> + <property name="windowTitle"> + <string>Log</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QPlainTextEdit" name="text"> + <property name="undoRedoEnabled"> + <bool>false</bool> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + <property name="plainText"> + <string notr="true"/> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> + </property> + <property name="centerOnScroll"> + <bool>false</bool> + </property> + </widget> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QPushButton" name="btnPaste"> + <property name="text"> + <string>Upload Log</string> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/gui/pages/ModFolderPage.cpp b/gui/pages/ModFolderPage.cpp index 6d5c6226..2035e57a 100644 --- a/gui/pages/ModFolderPage.cpp +++ b/gui/pages/ModFolderPage.cpp @@ -48,11 +48,12 @@ QString ModFolderPage::id() return m_id; } -ModFolderPage::ModFolderPage(std::shared_ptr<ModList> mods, QString id, QString iconName, +ModFolderPage::ModFolderPage(BaseInstance * inst, std::shared_ptr<ModList> mods, QString id, QString iconName, QString displayName, QString helpPage, QWidget *parent) : QWidget(parent), ui(new Ui::ModFolderPage) { ui->setupUi(this); + m_inst = inst; m_mods = mods; m_id = id; m_displayName = displayName; @@ -72,6 +73,13 @@ ModFolderPage::~ModFolderPage() delete ui; } +bool ModFolderPage::shouldDisplay() +{ + if(m_inst) + return !m_inst->isRunning(); + return true; +} + bool ModFolderPage::modListFilter(QKeyEvent *keyEvent) { switch (keyEvent->key()) diff --git a/gui/pages/ModFolderPage.h b/gui/pages/ModFolderPage.h index b4e05928..c193f4c1 100644 --- a/gui/pages/ModFolderPage.h +++ b/gui/pages/ModFolderPage.h @@ -32,17 +32,19 @@ class ModFolderPage : public QWidget, public BasePage Q_OBJECT public: - explicit ModFolderPage(std::shared_ptr<ModList> mods, QString id, QString iconName, + explicit ModFolderPage(BaseInstance * inst, std::shared_ptr<ModList> mods, QString id, QString iconName, QString displayName, QString helpPage = "" , QWidget *parent = 0); virtual ~ModFolderPage(); virtual QString displayName() override; virtual QIcon icon() override; virtual QString id() override; virtual QString helpPage() override { return m_helpName; }; + virtual bool shouldDisplay(); protected: bool eventFilter(QObject *obj, QEvent *ev); bool modListFilter(QKeyEvent *ev); - +protected: + BaseInstance * m_inst; private: Ui::ModFolderPage *ui; std::shared_ptr<ModList> m_mods; diff --git a/gui/pages/ResourcePackPage.h b/gui/pages/ResourcePackPage.h index 9332a6fa..06367905 100644 --- a/gui/pages/ResourcePackPage.h +++ b/gui/pages/ResourcePackPage.h @@ -5,10 +5,9 @@ class ResourcePackPage : public ModFolderPage { public: explicit ResourcePackPage(BaseInstance *instance, QWidget *parent = 0) - : ModFolderPage(instance->resourcePackList(), "resourcepacks", "resourcepacks", + : ModFolderPage(instance, instance->resourcePackList(), "resourcepacks", "resourcepacks", tr("Resource packs"), "Resource-packs", parent) { - m_inst = instance; } virtual ~ResourcePackPage() {}; @@ -17,6 +16,4 @@ public: return !m_inst->traits().contains("no-texturepacks") && !m_inst->traits().contains("texturepacks"); } -private: - BaseInstance *m_inst; }; diff --git a/gui/pages/ScreenshotsPage.cpp b/gui/pages/ScreenshotsPage.cpp index 3dc144ca..051bc12d 100644 --- a/gui/pages/ScreenshotsPage.cpp +++ b/gui/pages/ScreenshotsPage.cpp @@ -18,43 +18,63 @@ #include "logic/screenshots/ImgurAlbumCreation.h" #include "logic/tasks/SequentialTask.h" -class ThumbnailProvider : public QFileIconProvider -{ -public: - virtual ~ThumbnailProvider() {}; - virtual QIcon icon(const QFileInfo &info) const - { - QImage image(info.absoluteFilePath()); - if (image.isNull()) - { - return QFileIconProvider::icon(info); - } - QImage thumbnail = image.scaledToWidth(256, Qt::SmoothTransformation); - return QIcon(QPixmap::fromImage(thumbnail)); - } -}; - class FilterModel : public QIdentityProxyModel { +public: virtual QVariant data(const QModelIndex &proxyIndex, int role = Qt::DisplayRole) const { auto model = sourceModel(); - if(!model) + if (!model) return QVariant(); - QVariant result = sourceModel()->data(mapToSource(proxyIndex), role); - if(role == Qt::DisplayRole || role == Qt::EditRole) + if (role == Qt::DisplayRole || role == Qt::EditRole) + { + QVariant result = sourceModel()->data(mapToSource(proxyIndex), role); + return result.toString().remove(QRegExp("\\.png$")); + } + if (role == Qt::DecorationRole) { - return result.toString().remove(QRegExp("\.png$")); + QVariant result = sourceModel()->data(mapToSource(proxyIndex), QFileSystemModel::FilePathRole); + QString filePath = result.toString(); + if(thumbnailCache.contains(filePath)) + { + return thumbnailCache[filePath]; + } + bool failed = false; + QFileInfo info(filePath); + failed |= info.isDir(); + failed |= (info.suffix().compare("png", Qt::CaseInsensitive) != 0); + // WARNING: really an IF! this is purely for using break instead of goto... + while(!failed) + { + QImage image(info.absoluteFilePath()); + if (image.isNull()) + { + // TODO: schedule a retry. + failed = true; + break; + } + QImage thumbnail = image.scaledToWidth(512).scaledToWidth(256, Qt::SmoothTransformation); + QIcon icon(QPixmap::fromImage(thumbnail)); + // the casts are a hack for the stupid method being const. + ((QMap<QString, QIcon> &)thumbnailCache).insert(filePath, icon); + return icon; + } + // we failed anyway... + return sourceModel()->data(mapToSource(proxyIndex), QFileSystemModel::FileIconRole); + } + else + { + QVariant result = sourceModel()->data(mapToSource(proxyIndex), role); + return result; } - return result; } virtual bool setData(const QModelIndex &index, const QVariant &value, - int role = Qt::EditRole) + int role = Qt::EditRole) { auto model = sourceModel(); - if(!model) + if (!model) return false; - if(role != Qt::EditRole) + if (role != Qt::EditRole) return false; // FIXME: this is a workaround for a bug in QFileSystemModel, where it doesn't // sort after renames @@ -64,22 +84,25 @@ class FilterModel : public QIdentityProxyModel } return model->setData(mapToSource(index), value.toString() + ".png", role); } +private: + QMap<QString, QIcon> thumbnailCache; }; class CenteredEditingDelegate : public QStyledItemDelegate { public: - explicit CenteredEditingDelegate(QObject *parent = 0) - : QStyledItemDelegate(parent) + explicit CenteredEditingDelegate(QObject *parent = 0) : QStyledItemDelegate(parent) + { + } + virtual ~CenteredEditingDelegate() { } - virtual ~CenteredEditingDelegate() {} virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { auto widget = QStyledItemDelegate::createEditor(parent, option, index); - auto foo = dynamic_cast<QLineEdit *> (widget); - if(foo) + auto foo = dynamic_cast<QLineEdit *>(widget); + if (foo) { foo->setAlignment(Qt::AlignHCenter); foo->setFrame(true); @@ -111,7 +134,6 @@ ScreenshotsPage::ScreenshotsPage(BaseInstance *instance, QWidget *parent) m_filterModel.reset(new FilterModel()); m_filterModel->setSourceModel(m_model.get()); m_model->setFilter(QDir::Files | QDir::Writable | QDir::Readable); - m_model->setIconProvider(new ThumbnailProvider); m_model->setReadOnly(false); m_folder = PathCombine(instance->minecraftRoot(), "screenshots"); m_valid = ensureFolderPathExists(m_folder); @@ -218,11 +240,11 @@ void ScreenshotsPage::on_deleteBtn_clicked() QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No); std::unique_ptr<QMessageBox> box(mbox); - if(box->exec() != QMessageBox::Yes) + if (box->exec() != QMessageBox::Yes) return; auto selected = ui->listView->selectionModel()->selectedIndexes(); - for(auto item : selected) + for (auto item : selected) { m_model->remove(item); } diff --git a/gui/pages/TexturePackPage.h b/gui/pages/TexturePackPage.h index b1a2f544..69a47204 100644 --- a/gui/pages/TexturePackPage.h +++ b/gui/pages/TexturePackPage.h @@ -5,16 +5,13 @@ class TexturePackPage : public ModFolderPage { public: explicit TexturePackPage(BaseInstance *instance, QWidget *parent = 0) - : ModFolderPage(instance->texturePackList(), "texturepacks", "resourcepacks", + : ModFolderPage(instance, instance->texturePackList(), "texturepacks", "resourcepacks", tr("Texture packs"), "Texture-packs", parent) { - m_inst = instance; } virtual ~TexturePackPage() {}; virtual bool shouldDisplay() override { return m_inst->traits().contains("texturepacks"); } -private: - BaseInstance *m_inst; }; diff --git a/gui/pages/VersionPage.cpp b/gui/pages/VersionPage.cpp index 3fd98d27..34599111 100644 --- a/gui/pages/VersionPage.cpp +++ b/gui/pages/VersionPage.cpp @@ -66,6 +66,11 @@ QString VersionPage::id() return "version"; } +bool VersionPage::shouldDisplay() +{ + return !m_inst->isRunning(); +} + VersionPage::VersionPage(OneSixInstance *inst, QWidget *parent) : QWidget(parent), ui(new Ui::VersionPage), m_inst(inst) { diff --git a/gui/pages/VersionPage.h b/gui/pages/VersionPage.h index a8bc1515..dfbb6741 100644 --- a/gui/pages/VersionPage.h +++ b/gui/pages/VersionPage.h @@ -37,6 +37,7 @@ public: virtual QIcon icon() override; virtual QString id() override; virtual QString helpPage() override { return "Instance-version"; }; + virtual bool shouldDisplay(); private slots: |