From 5c33bf473e6b6e9165d1bb2788bd88216c438b80 Mon Sep 17 00:00:00 2001 From: SeeLook <945374+SeeLook@users.noreply.github.com> Date: Sun, 1 Nov 2015 20:40:41 +0100 Subject: [PATCH] New TfileDialog for Mobile and calling it selector, creator and starter. --- TODO | 2 - src/exam/tstartexamdlg.cpp | 2 +- src/libs/core/level/tlevelselector.cpp | 34 +-- src/libs/core/widgets/tfiledialog.cpp | 369 +++++++++++++++++++------ src/libs/core/widgets/tfiledialog.h | 84 ++++-- src/plugins/level/tlevelcreatordlg.cpp | 29 +- 6 files changed, 378 insertions(+), 142 deletions(-) diff --git a/TODO b/TODO index 13cf1455d..e0e4bebc9 100644 --- a/TODO +++ b/TODO @@ -17,8 +17,6 @@ waring - merge with stable ANDROID: - crash when audio out was disables and enabled again in settings (audio in probably also) -- keep extra dialogues maximized (file, color dialog) - or create special ones for mobile - add 'smallest font size' to Tmtr ??? - add labels with smallest font under level cretor options instead of status tips - solve issue with restart for settings reset diff --git a/src/exam/tstartexamdlg.cpp b/src/exam/tstartexamdlg.cpp index 88127ca0b..d33efa8c0 100644 --- a/src/exam/tstartexamdlg.cpp +++ b/src/exam/tstartexamdlg.cpp @@ -318,7 +318,7 @@ void TstartExamDlg::continuePrevExam() { void TstartExamDlg::examFromFileDialog() { #if defined (Q_OS_ANDROID) - QString fileName = TfileDialog::getOpenFileName(this, TexTrans::loadExamFileTxt(), m_examParams->examsDir, TexTrans::examFilterTxt()); + QString fileName = TfileDialog::getOpenFileName(this, m_examParams->examsDir, QStringLiteral("noo")); #else QString fileName = QFileDialog::getOpenFileName(this, TexTrans::loadExamFileTxt(), m_examParams->examsDir, TexTrans::examFilterTxt()); #endif diff --git a/src/libs/core/level/tlevelselector.cpp b/src/libs/core/level/tlevelselector.cpp index 9ceb647bd..557dd358d 100644 --- a/src/libs/core/level/tlevelselector.cpp +++ b/src/libs/core/level/tlevelselector.cpp @@ -37,7 +37,7 @@ /*static*/ QString TlevelSelector::checkLevel(Tlevel& l) { - QString warringText = ""; + QString warringText; if (Tcore::gl()->instrument == e_noInstrument && l.instrument != e_noInstrument) warringText = tr("Level is not suitable for current instrument type"); else if (l.canBeGuitar() || (l.instrument != e_noInstrument && l.canBeSound())) { @@ -102,8 +102,8 @@ TlevelSelector::TlevelSelector(QWidget *parent) : mainLay->addWidget(m_levelPreview); setLayout(mainLay); - m_fakeLevel.name = ""; - m_fakeLevel.desc = ""; + m_fakeLevel.name.clear(); + m_fakeLevel.desc.clear(); findLevels(); connect(m_levelsListWdg, SIGNAL(currentRowChanged(int)), this, SLOT(levelSelected(int))); @@ -125,7 +125,7 @@ TlevelSelector::~TlevelSelector() { void TlevelSelector::levelSelected(int id) { if (id >= 0 && id < m_levelsListWdg->count()) { m_levelPreview->setLevel(m_levels[id].level); - if (m_levels[id].file == "") + if (m_levels[id].file.isEmpty()) m_removeButt->setDisabled(true); else m_removeButt->setDisabled(false); @@ -153,7 +153,7 @@ void TlevelSelector::findLevels() { QFile file(recentLevels[i]); if (file.exists()) { Tlevel level = getLevelFromFile(file); - if (level.name != "") { + if (!level.name.isEmpty()) { addLevel(level, file.fileName()); m_levels.last().suitable = isSuitable(level); } else @@ -166,7 +166,7 @@ void TlevelSelector::findLevels() { void TlevelSelector::addLevel(const Tlevel& lev, QString levelFile, bool check) { - if (check && levelFile != "") { + if (check && !levelFile.isEmpty()) { int pos = -1; for (int i = 0; i < m_levels.size(); i++) if (m_levels[i].file == levelFile) // file and level exist @@ -194,7 +194,7 @@ void TlevelSelector::addLevel(const Tlevel& lev, QString levelFile, bool check) bool TlevelSelector::isSuitable(Tlevel &l) { QString warringText = checkLevel(l); - if (warringText != "") { + if (!warringText.isEmpty()) { m_levels.last().item->setStatusTip("<span style=\"color: red;\">" + warringText + "</span>"); m_levels.last().item->setForeground(QBrush(Qt::red)); return false; @@ -234,13 +234,13 @@ void TlevelSelector::selectLevel() { void TlevelSelector::loadFromFile(QString levelFile) { if (levelFile.isEmpty()) #if defined (Q_OS_ANDROID) - levelFile = TfileDialog::getOpenFileName(this, tr("Load exam's level"), Tcore::gl()->E->levelsDir, levelFilterTxt() + " (*.nel)"); + levelFile = TfileDialog::getOpenFileName(this, Tcore::gl()->E->levelsDir, QStringLiteral("nel")); #else levelFile = QFileDialog::getOpenFileName(this, tr("Load exam's level"), Tcore::gl()->E->levelsDir, levelFilterTxt() + " (*.nel)"); #endif QFile file(levelFile); Tlevel level = getLevelFromFile(file); - if (level.name != "") { + if (!level.name.isEmpty()) { Tcore::gl()->E->levelsDir = QFileInfo(levelFile).absoluteDir().absolutePath(); addLevel(level, levelFile, true); if (isSuitable(level)) @@ -261,7 +261,7 @@ Tlevel& TlevelSelector::getSelectedLevel() { void TlevelSelector::updateRecentLevels() { QStringList recentLevels; for (int i = m_levels.size() - 1; i > 1; i--) { - if (m_levels[i].file != "") + if (!m_levels[i].file.isEmpty()) recentLevels << m_levels[i].file; } Tcore::gl()->config->setValue("recentLevels", recentLevels); @@ -280,7 +280,7 @@ void TlevelSelector::loadFromFilePrivate() { Tlevel TlevelSelector::getLevelFromFile(QFile &file) { Tlevel level; - level.name = ""; + level.name.clear();; if (file.open(QIODevice::ReadOnly)) { QDataStream in(&file); in.setVersion(QDataStream::Qt_5_2); @@ -310,13 +310,13 @@ Tlevel TlevelSelector::getLevelFromFile(QFile &file) { wasLevelFile = false; file.close(); if (!wasLevelFile) { - QMessageBox::critical(this, "", tr("File: %1 \n is not Nootka level file!").arg(file.fileName())); - level.name = ""; + QMessageBox::critical(this, QString(), tr("File: %1 \n is not Nootka level file!").arg(file.fileName())); + level.name.clear(); return level; } else if (!wasLevelValid) - QMessageBox::warning(0, "", tr("Level file\n %1 \n was corrupted and repaired!\n Check please, if its parameters are as expected.").arg(file.fileName())); + QMessageBox::warning(0, QString(), tr("Level file\n %1 \n was corrupted and repaired!\n Check please, if its parameters are as expected.").arg(file.fileName())); } else { - if (file.fileName() != "") // skip empty file names (ignored by user) + if (!file.fileName().isEmpty()) // skip empty file names (ignored by user) Tlevel::fileIOerrorMsg(file, this); } return level; @@ -360,10 +360,10 @@ TremoveLevel::TremoveLevel(const QString& levelName, const QString& fileName, QW QDialog(parent, Qt::CustomizeWindowHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint), m_levelFile(fileName) { - setWindowTitle(removeTxt().replace("<b>", "").replace("</b>", "")); + setWindowTitle(removeTxt().replace("<b>", QString()).replace("</b>", QString())); QLabel *removeLab = new QLabel(removeTxt(levelName), this); m_deleteChB = new QCheckBox(tr("Also delete level file:"), this); - QLabel *fNameLab = new QLabel("<b>" + fileName + "</b>", this); + QLabel *fNameLab = new QLabel(QLatin1String("<b>") + fileName + QLatin1String("</b>"), this); QDialogButtonBox *stdButtons = new QDialogButtonBox(this); QPushButton *removeButton = stdButtons->addButton(tr("Remove"), QDialogButtonBox::AcceptRole); diff --git a/src/libs/core/widgets/tfiledialog.cpp b/src/libs/core/widgets/tfiledialog.cpp index 02aa17d6f..e47505a65 100644 --- a/src/libs/core/widgets/tfiledialog.cpp +++ b/src/libs/core/widgets/tfiledialog.cpp @@ -1,112 +1,311 @@ -/*************************************************************************** - * Copyright (C) 2015 by Tomasz Bojczuk * - * tomaszbojczuk@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 3 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 General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ + #include "tfiledialog.h" +#include "tmtr.h" +#include <tpath.h> #include <QtWidgets/QtWidgets> +class TiconProvider : public QFileIconProvider +{ + +public: + + TiconProvider(QFileIconProvider *realProv) : + QFileIconProvider(), + m_realProvider(realProv) + { + } + + virtual QIcon icon(const QFileInfo& info) const { + if (info.isDir()) + return qApp->style()->standardIcon(QStyle::SP_DirIcon); + else if (info.suffix().contains(QLatin1String("nel"))) + return QIcon(Tpath::img("nootka-level")); + else if (info.suffix().contains(QLatin1String("noo"))) + return QIcon(Tpath::img("nootka-exam")); + else + return m_realProvider->icon(info); + } + + virtual QIcon icon(IconType type) const { + switch (type) { + case Folder: + return qApp->style()->standardIcon(QStyle::SP_DirIcon); + default: + return qApp->style()->standardIcon(QStyle::SP_FileIcon); + } + } + +private: + QFileIconProvider *m_realProvider; +}; + + +class TnewDirMessage : public QDialog +{ + +public: + explicit TnewDirMessage(QWidget* parent = 0) : + QDialog(parent) + { + auto label = new QLabel(QApplication::translate("QFileDialog", "Create New Folder"), this); + m_edit = new QLineEdit(this); + m_edit->setPlaceholderText(QApplication::translate("QFileDialog", "Directory:")); + auto box = new QDialogButtonBox(this); + auto okButt = box->addButton(QDialogButtonBox::Ok); + okButt->setIcon(style()->standardIcon(QStyle::QStyle::SP_FileDialogNewFolder)); + auto cancelButt = box->addButton(QDialogButtonBox::Cancel); + cancelButt->setIcon(style()->standardIcon(QStyle::SP_DialogCancelButton)); + + auto lay = new QVBoxLayout; + lay->addWidget(label); + lay->addWidget(m_edit); + lay->addWidget(box); + setLayout(lay); + + connect(box, &QDialogButtonBox::accepted, this, &QDialog::accept); + connect(box, &QDialogButtonBox::rejected, this, &QDialog::reject); + } + + QString getName() { return m_edit->text(); } + + static QString dirName(QWidget* parent = 0) { + TnewDirMessage newDir(parent); + if (newDir.exec() == Accepted && !newDir.getName().isEmpty()) + return newDir.getName(); + else + return QString(); + } + +private: + QLineEdit *m_edit; +}; + + + /* static */ -QString TfileDialog::getSaveFileName(QWidget* parent, const QString& caption, const QString& directory, const QString& filter) { - TfileDialog saveDialog(parent, caption, directory, filter); - saveDialog.setAcceptMode(AcceptSave); - if (saveDialog.exec() == QDialog::Accepted) - return saveDialog.selectedFiles().first(); +QString TfileDialog::getOpenFileName(QWidget* parent, const QString& directory, const QString& filter) { + TfileDialog openDialog(parent, directory, filter, TfileDialog::e_acceptOpen); + if (openDialog.exec() == QFileDialog::Accepted) + return openDialog.selectedFile(); else return QString(); } -QString TfileDialog::getOpenFileName(QWidget* parent, const QString& caption, const QString& directory, const QString& filter) { - TfileDialog openDialog(parent, caption, directory, filter); - openDialog.setAcceptMode(AcceptOpen); - if (openDialog.exec() == QDialog::Accepted) - return openDialog.selectedFiles().first(); +QString TfileDialog::getSaveFileName(QWidget* parent, const QString& directory, const QString& filter) { + TfileDialog saveDialog(parent, directory, filter, TfileDialog::e_acceptSave); + if (saveDialog.exec() == QFileDialog::Accepted) + return saveDialog.selectedFile(); else return QString(); } - -TfileDialog::TfileDialog(QWidget* parent, const QString& caption, const QString& directory, const QString& filter) : - QFileDialog(parent, caption, directory, filter) +//################################################################################################# +//################################################################################################# +//################### class TfileDialog ############################################ +//################################################################################################# +//################################################################################################# +TfileDialog::TfileDialog(QWidget *parent, const QString& directory, const QString& filter, EacceptMode mode) : + QDialog(parent), + m_acceptMode(mode) { -// setFileMode(QFileDialog::AnyFile); -// setOption(QFileDialog::DontUseNativeDialog); -// setOption(QFileDialog::HideNameFilterDetails); -// setOption(QFileDialog::DontUseCustomDirectoryIcons); - -#if defined (Q_OS_ANDROID) showMaximized(); - layout()->setContentsMargins(0, 0, 0, 0); -#endif - - foreach(QAbstractScrollArea *a, findChildren<QAbstractScrollArea*>()) { -// qDebug() << "scrolls" << a->objectName(); - a->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - a->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - QScroller::grabGesture(a->viewport(), QScroller::LeftMouseButtonGesture); + + m_menu = new QListWidget(this); + m_menu->setIconSize(QSize(60, 60)); + m_menu->setMaximumWidth(80); + m_menu->setViewMode(QListView::IconMode); + m_menu->setMovement(QListView::Static); + m_menu->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_menu->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + int bSize = qBound<int>(Tmtr::fingerPixels() * 1.1, Tmtr::longScreenSide() / 12, Tmtr::fingerPixels() * 1.6); + m_menu->setIconSize(QSize(bSize, bSize)); + m_menu->setMaximumWidth(bSize + 10); + QFont f = font(); + f.setPixelSize(qMin<int>(bSize / 5, fontMetrics().height())); + m_menu->setFont(f); +// m_menu->setObjectName("fileMenu"); // revert colors +// m_menu->setStyleSheet(m_menu->styleSheet() + " QListWidget#fileMenu { background: palette(text); color: palette(base); }"); + QScroller::grabGesture(m_menu->viewport(), QScroller::LeftMouseButtonGesture); + + if (mode == e_acceptSave) + m_acceptItem = addMenuItem(style()->standardIcon(QStyle::SP_DialogSaveButton), QApplication::translate("QShortcut", "Save")); + else + m_acceptItem = addMenuItem(style()->standardIcon(QStyle::SP_DialogOpenButton), QApplication::translate("QShortcut", "Open")); + + m_dirUpItem = addMenuItem(style()->standardIcon(QStyle::SP_ArrowUp)); + m_newDirItem = addMenuItem(style()->standardIcon(QStyle::QStyle::SP_FileDialogNewFolder)); + m_cancelItem = addMenuItem(style()->standardIcon(QStyle::QStyle::SP_DialogCloseButton), QApplication::translate("QShortcut", "Close")); + + m_locationLab = new QLabel(this); + m_locationLab->setAlignment(Qt::AlignRight); + m_locationLab->setFixedWidth(Tmtr::longScreenSide() / 3); + + m_editName = new QLineEdit(this); + m_editName->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);; + if (mode == e_acceptOpen) + m_editName->setReadOnly(true); + + m_extensionCombo = new QComboBox(this); + m_list = new QListView(this); + int is = style()->pixelMetric(QStyle::PM_SmallIconSize) * 1.1; + m_list->setIconSize(QSize(is, is)); + m_list->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); + m_list->setSelectionBehavior(QAbstractItemView::SelectItems); + m_list->setSelectionMode(QAbstractItemView::SingleSelection); + m_list->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_list->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + QScroller::grabGesture(m_list->viewport(), QScroller::LeftMouseButtonGesture); + + m_lay = new QBoxLayout(QBoxLayout::LeftToRight); + m_lay->addWidget(m_menu); + auto innLay = new QVBoxLayout; + auto fileLay = new QHBoxLayout; + fileLay->addWidget(m_locationLab); + fileLay->addWidget(m_editName); + fileLay->addWidget(m_extensionCombo); + innLay->addLayout(fileLay); + innLay->addWidget(m_list); + m_lay->addLayout(innLay); + setLayout(m_lay); + m_lay->setContentsMargins(0, m_lay->contentsMargins().top(), m_lay->contentsMargins().right(), 0); + + m_fileModel = new QFileSystemModel(this); + + QFileInfo fi(directory); + if (fi.isDir()) + m_fileModel->setRootPath(directory); + else { + m_fileModel->setRootPath(fi.absolutePath()); + m_editName->setText(fi.fileName()); + } + updateLocationLabel(); + + QStringList filters = filter.split(QLatin1String("|")); + if (filters.size()) { + for(int i = 0; i < filters.size(); ++i) { + filters[i].prepend(QLatin1String(".")); + m_extensionCombo->addItem(filters[i]); + filters[i].prepend(QLatin1String("*")); + } + m_extensionCombo->setCurrentIndex(0); + m_fileModel->setNameFilters(filters); + m_fileModel->setNameFilterDisables(false); } - foreach(QWidget *w, findChildren<QWidget*>()) { -// qDebug() << "widgets" << w->objectName(); - if (w->objectName() == QLatin1String("sidebar")) - w->hide(); -// else if (w->objectName() == QLatin1String("lookInLabel")) -// w->hide(); -// else if (w->objectName() == QLatin1String("lookInCombo")) -// w->hide(); - else if (w->objectName() == QLatin1String("listModeButton")) - w->hide(); - else if (w->objectName() == QLatin1String("detailModeButton")) - w->hide(); - else if (w->objectName() == QLatin1String("fileTypeCombo")) - w->hide(); - else if (w->objectName() == QLatin1String("fileTypeLabel")) - w->hide(); - else if (w->objectName() == QLatin1String("fileTypeLabel")) - w->hide(); + m_list->setModel(m_fileModel); + m_list->setRootIndex(m_fileModel->index(m_fileModel->rootPath())); + + m_fileModel->setIconProvider(new TiconProvider(m_fileModel->iconProvider())); + + connect(m_menu, &QListWidget::itemClicked, this, &TfileDialog::menuClickedSlot); + connect(m_list, &QListView::clicked, this, &TfileDialog::itemClickedSlot); +} + + +TfileDialog::~TfileDialog() +{ + delete m_fileModel; +} + + +//################################################################################################# +//################### PROTECTED ############################################ +//################################################################################################# + +void TfileDialog::itemClickedSlot(const QModelIndex& index) { + if (m_fileModel->isDir(index)) { + m_list->setRootIndex(index); + m_fileModel->setRootPath(m_fileModel->filePath(index)); + updateLocationLabel(); + if (acceptMode() == e_acceptOpen) { + m_editName->setText(QString()); + m_selectedFile.clear(); // reset previously selected file + } + } else { + m_selectedFile = m_fileModel->fileInfo(index).absoluteFilePath(); + m_editName->setText(QFileInfo(m_selectedFile).fileName()); } +} - foreach(QPushButton *b, findChildren<QPushButton*>()) { -// qDebug() << "buttons" << b->objectName(); - QSize iSize(style()->pixelMetric(QStyle::PM_SmallIconSize), style()->pixelMetric(QStyle::PM_SmallIconSize)); - if (b->objectName() == QLatin1String("backButton")) - b->setIconSize(iSize); - else if (b->objectName() == QLatin1String("forwardButton")) - b->setIconSize(iSize); - else if (b->objectName() == QLatin1String("toParentButton")) - b->setIconSize(iSize); - else if (b->objectName() == QLatin1String("newFolderButton")) - b->setIconSize(iSize); + +void TfileDialog::performAction() { + if (acceptMode() == e_acceptSave) { + if (m_editName->text().isEmpty()) { + QMessageBox::warning(this, QString(), QApplication::translate("QFileSystemModel", "Invalid filename")); + return; + } else { + m_selectedFile = m_fileModel->rootPath() + QLatin1String("/") + m_editName->text(); + QFileInfo fi(m_selectedFile); + bool addExt = false; // Add current file extension + if (!fi.suffix().isEmpty()) { + if (m_extensionCombo->currentIndex() > -1 && m_extensionCombo->currentText() != m_selectedFile.right(4)) + addExt = true; + } else + addExt = true; + if (addExt) { + m_selectedFile.append(m_extensionCombo->currentText()); + fi.setFile(m_selectedFile); + } + if (fi.exists()) { + if (QMessageBox::question(this, QString(), + QApplication::translate("QFileDialog", "%1 already exists.\nDo you want to replace it?").arg(m_selectedFile)) != QMessageBox::Ok) { + m_selectedFile.clear(); + return; + } + } + } } + QDialog::accept(); +} + + +void TfileDialog::menuClickedSlot(QListWidgetItem* item) { + if (item == m_cancelItem) + reject(); + else if (item == m_acceptItem) + performAction(); + else if (item == m_dirUpItem) + dirUpSlot(); + else if (item == m_newDirItem) + newDirSlot(); +} + - foreach(QListView *l, findChildren<QListView*>()) { -// qDebug() << "lists" << l->objectName(); -// if (l->objectName() == QLatin1String("listView")) { - l->setFlow(QListView::TopToBottom); - l->setDragDropMode(QAbstractItemView::NoDragDrop); - l->setDragEnabled(false); -// l->setIconSize(QSize(48, 48)); -// auto model = qobject_cast<QFileSystemModel*>(l->model()); -// qDebug() << l->model()->columnCount() << model->iconProvider(); -// model->setIconProvider(saveDialog.iconProvider()); -// model->removeColumns(1, 10); -// } +void TfileDialog::dirUpSlot() { + QDir dir(m_fileModel->rootDirectory()); + if (dir.cdUp()) { + m_fileModel->setRootPath(dir.absolutePath()); + m_list->setRootIndex(m_fileModel->index(dir.absolutePath())); + updateLocationLabel(); } +} + +void TfileDialog::newDirSlot() { + QString newDir = TnewDirMessage::dirName(this); + if (!newDir.isEmpty()) + m_fileModel->mkdir(m_list->rootIndex(), newDir); } + + +QListWidgetItem* TfileDialog::addMenuItem(const QIcon& icon, const QString& text) { + QListWidgetItem *menuButton = new QListWidgetItem(m_menu); + menuButton->setIcon(icon); + if (!text.isEmpty()) + menuButton->setText(text); + menuButton->setTextAlignment(Qt::AlignHCenter); + menuButton->setFlags(Qt::ItemIsEnabled | Qt::ItemNeverHasChildren); + return menuButton; +} + + +void TfileDialog::updateLocationLabel() { + m_locationLab->setText(fontMetrics().elidedText(m_fileModel->rootPath() + QLatin1String("/"), + Qt::ElideMiddle, m_locationLab->width(), Qt::TextShowMnemonic)); +} + + diff --git a/src/libs/core/widgets/tfiledialog.h b/src/libs/core/widgets/tfiledialog.h index 308c779ab..2a99efb95 100644 --- a/src/libs/core/widgets/tfiledialog.h +++ b/src/libs/core/widgets/tfiledialog.h @@ -1,37 +1,73 @@ -/*************************************************************************** - * Copyright (C) 2015 by Tomasz Bojczuk * - * tomaszbojczuk@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 3 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 General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - #ifndef TFILEDIALOG_H #define TFILEDIALOG_H -#include <QtWidgets/qfiledialog.h> +#include <QtWidgets/qdialog.h> +#include <QtWidgets/qfilesystemmodel.h> +#include <QtWidgets/qboxlayout.h> + + +class QListWidget; +class QListWidgetItem; +class QListView; +class QLineEdit; +class QLabel; +class QComboBox; /** - * + * Implementation of file dialog for mobile devices. + * It is far from ideal but much better than native QFileDialog. + * It has two static methods @p getOpenFileName and @p getSaveFileName + * with three parameters (in contrary to native there is no caption). + * Third @param filter may support multiple filters but only single one has been tested so far. + * NOTICE: In contrary to @class QFileDialog @param filter takes: + * only extension name WITHOUT any dots, parenthesis, asterisks or so. + * Multiple extensions can should be separated by | + * noo|nel or bz|gz|bz2 */ -class TfileDialog : public QFileDialog +class TfileDialog : public QDialog { + Q_OBJECT + public: - TfileDialog(QWidget* parent, const QString& caption, const QString& directory, const QString& filter); + enum EacceptMode { e_acceptSave, e_acceptOpen }; /** File dialog type: for opening or saving */ + Q_ENUM(EacceptMode) + + explicit TfileDialog(QWidget* parent, const QString& directory, const QString& filter, EacceptMode mode); + ~TfileDialog(); + + static QString getSaveFileName(QWidget* parent = 0, const QString& directory = QString(), const QString& filter = QString()); + static QString getOpenFileName(QWidget* parent = 0, const QString& directory = QString(), const QString& filter = QString()); + + QString selectedFile() const { return m_selectedFile; } + + void setDirection(QBoxLayout::Direction dir) { m_lay->setDirection(dir); } /** Left to right by default */ + EacceptMode acceptMode() { return m_acceptMode; } + + +protected: + void itemClickedSlot(const QModelIndex& index); + void menuClickedSlot(QListWidgetItem* item); + void dirUpSlot(); + void newDirSlot(); + void performAction(); /** Open or save */ + + QListWidgetItem* addMenuItem(const QIcon& icon, const QString& text = QString()); + void updateLocationLabel(); + +private: + QFileSystemModel *m_fileModel; + QString m_selectedFile; + EacceptMode m_acceptMode; + + QBoxLayout *m_lay; + QListView *m_list; + QListWidget *m_menu; + QListWidgetItem *m_acceptItem, *m_cancelItem, *m_dirUpItem, *m_newDirItem; + QLineEdit *m_editName; + QLabel *m_locationLab; + QComboBox *m_extensionCombo; - static QString getSaveFileName(QWidget* parent, const QString& caption, const QString& directory, const QString& filter); - static QString getOpenFileName(QWidget* parent, const QString& caption, const QString& directory, const QString& filter); }; #endif // TFILEDIALOG_H diff --git a/src/plugins/level/tlevelcreatordlg.cpp b/src/plugins/level/tlevelcreatordlg.cpp index 64cd1952a..f0e58b080 100644 --- a/src/plugins/level/tlevelcreatordlg.cpp +++ b/src/plugins/level/tlevelcreatordlg.cpp @@ -137,8 +137,8 @@ void TlevelCreatorDlg::levelWasSelected(Tlevel level) { void TlevelCreatorDlg::levelNotSaved() { if (!isNotSaved) { - navList->item(0)->setIcon(QIcon(Tcore::gl()->path+"picts/notSaved.png")); - setWindowTitle(levelCreatorTxt() + " (" + tr("level not saved!") + ")"); + navList->item(0)->setIcon(QIcon(Tcore::gl()->path + "picts/notSaved.png")); + setWindowTitle(levelCreatorTxt() + QLatin1String(" (") + tr("level not saved!") + QLatin1String(")")); isNotSaved = true; } } @@ -148,7 +148,7 @@ void TlevelCreatorDlg::saveLevel() { if ( QMessageBox::question(this, tr("level not saved!"), tr("Level was changed and not saved!"), QMessageBox::Save, QMessageBox::Cancel) == QMessageBox::Save ) { saveToFile(); - } else + } else levelSaved(); } @@ -180,19 +180,22 @@ void TlevelCreatorDlg::saveToFile() { newLevel.name = nameList[0]; newLevel.desc = nameList[1]; // Saving to file - QString fName = QDir::toNativeSeparators(Tcore::gl()->E->examsDir + QStringLiteral("/") + newLevel.name); - if (QFileInfo(fName + QStringLiteral(".nel")).exists()) - fName += QStringLiteral("-") + QDateTime::currentDateTime().toString("(dd-MMM-hhmmss)"); - + QLatin1String dotNel(".nel"); + QString fName = QDir::toNativeSeparators(Tcore::gl()->E->levelsDir + QLatin1String("/") + newLevel.name); + if (QFileInfo(fName + dotNel).exists()) + fName += QLatin1String("-") + QDateTime::currentDateTime().toString(QLatin1String("(dd-MMM-hhmmss)")); + qDebug() << "Sugested name" << fName; #if defined (Q_OS_ANDROID) - QString fileName = TfileDialog::getSaveFileName(this, tr("Save exam level"), fName, TlevelSelector::levelFilterTxt() + QStringLiteral(" (*.nel)")); + QString fileName = TfileDialog::getSaveFileName(this, fName, QStringLiteral("nel")); #else - QString fileName = QFileDialog::getSaveFileName(this, tr("Save exam level"), fName, TlevelSelector::levelFilterTxt() + QStringLiteral(" (*.nel)")); + QString fileName = QFileDialog::getSaveFileName(this, tr("Save exam level"), fName, TlevelSelector::levelFilterTxt() + QLatin1String(" (*.nel)")); #endif - if (fileName.isEmpty()) + if (fileName.isEmpty()) { + qDebug() << "empty file name"; return; - if (fileName.right(4) != QLatin1String(".nel")) - fileName += QStringLiteral(".nel"); + } + if (fileName.right(4) != dotNel) + fileName += dotNel; Tcore::gl()->E->levelsDir = QFileInfo(fileName).absoluteDir().absolutePath(); if (!Tlevel::saveToFile(newLevel, fileName)) { QMessageBox::critical(this, QStringLiteral(" "), tr("Cannot open file for writing")); @@ -226,7 +229,7 @@ QString TlevelCreatorDlg::validateLevel(Tlevel &l) { if (!l.canBeScore() && ! l.canBeName() && !l.canBeGuitar() && !l.canBeSound()) { res = tr("There aren't any questions or answers selected.<br>Level makes no sense."); return res; - } + } // checking range // determine the highest note of fret range on available strings if (l.canBeGuitar() || (l.instrument != e_noInstrument && l.answerIsSound())) { -- GitLab