Entropy Piano Tuner  1.1.3 (documentation not yet complete)
An open-source experimental software for piano tuning by entropy minimization
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
simplefiledialog.cpp
Go to the documentation of this file.
1 /*****************************************************************************
2  * Copyright 2015 Haye Hinrichsen, Christoph Wick
3  *
4  * This file is part of Entropy Piano Tuner.
5  *
6  * Entropy Piano Tuner is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by the
8  * Free Software Foundation, either version 3 of the License, or (at your
9  * option) any later version.
10  *
11  * Entropy Piano Tuner is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along with
17  * Entropy Piano Tuner. If not, see http://www.gnu.org/licenses/.
18  *****************************************************************************/
19 
20 #include "simplefiledialog.h"
21 #include <QHBoxLayout>
22 #include <QVBoxLayout>
23 #include <QListWidget>
24 #include <QDialogButtonBox>
25 #include <QLineEdit>
26 #include <QLabel>
27 #include <QGuiApplication>
28 #include <QPushButton>
29 #include <QHeaderView>
30 #include <QToolButton>
31 #include <QMessageBox>
32 #include <QScroller>
33 
34 #include "qtconfig.h"
36 #include "core/system/log.h"
37 
39  QDialog(0, Qt::Window),
40  mMode(mode),
41  mDir(dir)
42 {
43  setModal(true);
44 
45  QVBoxLayout *layout = new QVBoxLayout;
46  setLayout(layout);
47 
48  QDialogButtonBox *buttons = new QDialogButtonBox;
49  QString title;
50  if (mode == Mode::Open) {
51  buttons->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Open);
52  title = buttons->button(QDialogButtonBox::Open)->text();
53  } else {
54  buttons->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Save);
55  title = buttons->button(QDialogButtonBox::Save)->text();
56  }
57  title.remove('&');
58 
59  layout->addWidget(new QLabel(QString("<h1>%1</h1>").arg(title)));
60 
61  mFilesList = new QTreeWidget;
62  layout->addWidget(mFilesList);
63  mFilesList->setColumnCount(2);
64  mFilesList->header()->setSectionResizeMode(0, QHeaderView::Stretch);
65  mFilesList->header()->setSectionResizeMode(1, QHeaderView::Fixed);
66  mFilesList->header()->setVisible(false);
67 
68  QStringList files = dir.entryList(QDir::Files | QDir::Writable);
69  int itemSize = mFilesList->fontMetrics().height();
70  for (QString file : files) {
71  if (file.endsWith(".ept") == false) {
72  continue;
73  }
74  file = file.left(file.size() - 4);
75  QTreeWidgetItem *item = new QTreeWidgetItem(mFilesList, QStringList() << file);
76  item->setSizeHint(0, QSize(0, itemSize * 2));
77  QToolButton *tb = new QToolButton;
78  tb->setAutoRaise(true);
79  tb->setIcon(QIcon(":/media/icons/edit-delete.png"));
80  tb->setIconSize(QSize(itemSize, itemSize) * 1.7);
81  QObject::connect(tb, SIGNAL(clicked(bool)), this, SLOT(onDeleteFile()));
82  mFilesList->setItemWidget(item, 1, tb);
83  }
84  mFilesList->setIconSize(QSize(64, 64));
85  mFilesList->setCurrentItem(mFilesList->topLevelItem(0));
86 
87  mFilesList->header()->setStretchLastSection(false);
88  mFilesList->header()->resizeSection(1, itemSize * 2);
89  mFilesList->header()->resizeSection(0, QHeaderView::Stretch);
90 
91  QHBoxLayout *nameLayout = new QHBoxLayout(this);
92  nameLayout->addWidget(new QLabel(tr("Name:")));
93 
94  QLineEdit *nameEdit = new QLineEdit;
95  mNameEdit = nameEdit;
96  nameLayout->addWidget(nameEdit);
97 
98  if (mode == Mode::Save) {
99  layout->addLayout(nameLayout);
100  }
101 
102  layout->addWidget(buttons);
103 
104 
105  QObject::connect(buttons, SIGNAL(accepted()), this, SLOT(accept()));
106  QObject::connect(buttons, SIGNAL(rejected()), this, SLOT(reject()));
107  QObject::connect(mFilesList, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT(accept()));
108  QObject::connect(mFilesList, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(onCurrentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)));
109  QObject::connect(this, SIGNAL(fileSelectionChanged(QString)), nameEdit, SLOT(setText(QString)));
110 
111  SHOW_DIALOG(this);
112 
113  if (mode == Mode::Save) {
114  mNameEdit->setText(QString());
115  } else {
116  if (mFilesList->currentItem()) {
117  mNameEdit->setText(mFilesList->currentItem()->text(0));
118  }
119  }
120 
121  QScroller::grabGesture(mFilesList);
122 }
123 
124 QString SimpleFileDialog::getOpenFile(QDir dir) {
125  SimpleFileDialog dialog(Mode::Open, dir);
126  if (dialog.exec() == QDialog::Rejected) {
127  return QString();
128  }
129 
130  return dir.absoluteFilePath(dialog.getFileName());
131 }
132 
133 QString SimpleFileDialog::getSaveFile(QDir dir) {
134  SimpleFileDialog dialog(Mode::Save, dir);
135  if (dialog.exec() == QDialog::Rejected) {
136  return QString();
137  }
138 
139  return dir.absoluteFilePath(dialog.getFileName());
140 }
141 
143  const QFileInfo fi(mDir.absoluteFilePath(getFileName()));
144  if (mMode == Mode::Save) {
145  // check if the file already exists
146  if (fi.exists()) {
147  if (QMessageBox::warning(this,
148  tr("File existing"),
149  tr("A file with the given name already exists at %1. Do you want to overwrite it?").arg(fi.absoluteFilePath()),
150  QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) {
151  return;
152  }
153  }
154  }
155 
156  if (fi.baseName().isEmpty()) {
157  QMessageBox::information(this, tr("Invalid filename"), tr("Please provide a valid filename."));
158  } else {
159  QDialog::accept();
160  }
161 }
162 
164  EptAssert(sender(), "This is a slot and has to be sent by a QPushButton.");
165 
166  QTreeWidgetItem *fileItem = nullptr;
167  for (int i = 0; i < mFilesList->topLevelItemCount(); ++i) {
168  QTreeWidgetItem *item = mFilesList->topLevelItem(i);
169  if (sender() == mFilesList->itemWidget(item, 1)) {
170  fileItem = item;
171  break;
172  }
173  }
174 
175  EptAssert(fileItem, "Item not found that contains the sender in column 1.");
176 
177  // ask for confirmation
178  if (QMessageBox::question(this, tr("Remove file"),
179  tr("Are you sure that you really want to delete the file \"%1\"?").arg(fileItem->text(0)),
180  QMessageBox::Yes | QMessageBox::Cancel) == QMessageBox::Cancel) {
181  // cancel
182  return;
183  }
184 
185  QFile file(mDir.absoluteFilePath(fileItem->text(0) + ".ept"));
186 
187  EptAssert(file.exists(), "File has to exists.");
188 
189  if (!file.remove()) {
190  LogW("File '%s' could not be removed.", file.fileName().toStdString().c_str());
191  return;
192  }
193 
194  mFilesList->removeItemWidget(fileItem, 1);
195  delete fileItem;
196 }
197 
198 void SimpleFileDialog::onCurrentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) {
199  Q_UNUSED(previous);
200 
201  if (!current) {
202  emit fileSelectionChanged(QString());
203  } else {
204  emit fileSelectionChanged(current->text(0));
205  }
206 }
#define LogW(...)
Definition: log.h:56
QTreeWidget * mFilesList
QLineEdit * mNameEdit
#define SHOW_DIALOG(d)
Definition: qtconfig.h:41
void fileSelectionChanged(QString)
static QString getSaveFile(QDir dir)
SimpleFileDialog(Mode mode, QDir dir)
static QString getOpenFile(QDir dir)
void onCurrentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
QString getFileName() const
#define EptAssert(a, b)
Definition: eptexception.h:47