mirror of https://github.com/bsnes-emu/bsnes.git
393 lines
10 KiB
C++
Executable File
393 lines
10 KiB
C++
Executable File
#ifndef NALL_QT_FILEDIALOG_HPP
|
|
#define NALL_QT_FILEDIALOG_HPP
|
|
|
|
#include <nall/platform.hpp>
|
|
#include <nall/string.hpp>
|
|
#include <nall/qt/window.moc.hpp>
|
|
|
|
namespace nall {
|
|
|
|
class FileDialog;
|
|
|
|
class NewFolderDialog : public Window {
|
|
Q_OBJECT
|
|
|
|
public:
|
|
void show();
|
|
NewFolderDialog(FileDialog*);
|
|
|
|
protected slots:
|
|
void createFolderAction();
|
|
|
|
protected:
|
|
FileDialog *parent;
|
|
QVBoxLayout *layout;
|
|
QLineEdit *folderNameEdit;
|
|
QHBoxLayout *controlLayout;
|
|
QPushButton *okButton;
|
|
QPushButton *cancelButton;
|
|
};
|
|
|
|
class FileView : public QListView {
|
|
Q_OBJECT
|
|
|
|
protected:
|
|
void keyPressEvent(QKeyEvent*);
|
|
|
|
signals:
|
|
void changed(const QModelIndex&);
|
|
void browseUp();
|
|
|
|
protected slots:
|
|
void currentChanged(const QModelIndex&, const QModelIndex&);
|
|
};
|
|
|
|
class FileDialog : public Window {
|
|
Q_OBJECT
|
|
|
|
public:
|
|
void showLoad();
|
|
void showSave();
|
|
void showFolder();
|
|
|
|
void setPath(string path);
|
|
void setNameFilters(const string &filters);
|
|
FileDialog();
|
|
|
|
signals:
|
|
void changed(const string&);
|
|
void activated(const string&);
|
|
void accepted(const string&);
|
|
void rejected();
|
|
|
|
protected slots:
|
|
void fileViewChange(const QModelIndex&);
|
|
void fileViewActivate(const QModelIndex&);
|
|
void pathBoxChanged();
|
|
void filterBoxChanged();
|
|
void createNewFolder();
|
|
void browseUp();
|
|
void acceptAction();
|
|
void rejectAction();
|
|
|
|
protected:
|
|
NewFolderDialog *newFolderDialog;
|
|
QVBoxLayout *layout;
|
|
QHBoxLayout *navigationLayout;
|
|
QComboBox *pathBox;
|
|
QPushButton *newFolderButton;
|
|
QPushButton *upFolderButton;
|
|
QHBoxLayout *browseLayout;
|
|
QFileSystemModel *fileSystemModel;
|
|
FileView *fileView;
|
|
QGroupBox *previewFrame;
|
|
QLineEdit *fileNameEdit;
|
|
QHBoxLayout *controlLayout;
|
|
QComboBox *filterBox;
|
|
QPushButton *optionsButton;
|
|
QPushButton *acceptButton;
|
|
QPushButton *rejectButton;
|
|
bool lock;
|
|
void createFolderAction(const string &name);
|
|
void closeEvent(QCloseEvent*);
|
|
|
|
friend class NewFolderDialog;
|
|
};
|
|
|
|
inline void NewFolderDialog::show() {
|
|
folderNameEdit->setText("");
|
|
Window::show();
|
|
folderNameEdit->setFocus();
|
|
}
|
|
|
|
inline void NewFolderDialog::createFolderAction() {
|
|
string name = folderNameEdit->text().toUtf8().constData();
|
|
if(name == "") {
|
|
folderNameEdit->setFocus();
|
|
} else {
|
|
parent->createFolderAction(name);
|
|
close();
|
|
}
|
|
}
|
|
|
|
inline NewFolderDialog::NewFolderDialog(FileDialog *fileDialog) : parent(fileDialog) {
|
|
setMinimumWidth(240);
|
|
setWindowTitle("Create New Folder");
|
|
|
|
layout = new QVBoxLayout;
|
|
layout->setAlignment(Qt::AlignTop);
|
|
layout->setMargin(5);
|
|
layout->setSpacing(5);
|
|
setLayout(layout);
|
|
|
|
folderNameEdit = new QLineEdit;
|
|
layout->addWidget(folderNameEdit);
|
|
|
|
controlLayout = new QHBoxLayout;
|
|
controlLayout->setAlignment(Qt::AlignRight);
|
|
layout->addLayout(controlLayout);
|
|
|
|
okButton = new QPushButton("Ok");
|
|
controlLayout->addWidget(okButton);
|
|
|
|
cancelButton = new QPushButton("Cancel");
|
|
controlLayout->addWidget(cancelButton);
|
|
|
|
connect(folderNameEdit, SIGNAL(returnPressed()), this, SLOT(createFolderAction()));
|
|
connect(okButton, SIGNAL(released()), this, SLOT(createFolderAction()));
|
|
connect(cancelButton, SIGNAL(released()), this, SLOT(close()));
|
|
}
|
|
|
|
inline void FileView::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) {
|
|
QAbstractItemView::currentChanged(current, previous);
|
|
emit changed(current);
|
|
}
|
|
|
|
inline void FileView::keyPressEvent(QKeyEvent *event) {
|
|
//enhance consistency: force OS X to act like Windows and Linux; enter = activate item
|
|
if(event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) {
|
|
emit activated(currentIndex());
|
|
return;
|
|
}
|
|
|
|
//simulate popular file manager behavior; backspace = go up one directory
|
|
if(event->key() == Qt::Key_Backspace) {
|
|
emit browseUp();
|
|
return;
|
|
}
|
|
|
|
//fallback: unrecognized keypresses get handled by the widget itself
|
|
QListView::keyPressEvent(event);
|
|
}
|
|
|
|
inline void FileDialog::showLoad() {
|
|
acceptButton->setText("Load");
|
|
fileNameEdit->hide();
|
|
filterBox->show();
|
|
show();
|
|
}
|
|
|
|
inline void FileDialog::showSave() {
|
|
acceptButton->setText("Save");
|
|
fileNameEdit->show();
|
|
filterBox->show();
|
|
show();
|
|
}
|
|
|
|
inline void FileDialog::showFolder() {
|
|
acceptButton->setText("Choose");
|
|
fileNameEdit->hide();
|
|
filterBox->hide();
|
|
setNameFilters("Folders ()");
|
|
show();
|
|
}
|
|
|
|
inline void FileDialog::fileViewChange(const QModelIndex &index) {
|
|
string path = fileSystemModel->filePath(index).toUtf8().constData();
|
|
if(path == fileSystemModel->rootPath().toUtf8().constData()) path = "";
|
|
fileNameEdit->setText(notdir(path));
|
|
emit changed(path);
|
|
}
|
|
|
|
inline void FileDialog::fileViewActivate(const QModelIndex &index) {
|
|
string path = fileSystemModel->filePath(index).toUtf8().constData();
|
|
if(fileSystemModel->isDir(index)) {
|
|
emit activated(path);
|
|
setPath(path);
|
|
} else {
|
|
emit activated(path);
|
|
close();
|
|
}
|
|
}
|
|
|
|
inline void FileDialog::pathBoxChanged() {
|
|
if(lock) return;
|
|
setPath(pathBox->currentText().toUtf8().constData());
|
|
}
|
|
|
|
inline void FileDialog::filterBoxChanged() {
|
|
if(lock) return;
|
|
string filters = filterBox->currentText().toUtf8().constData();
|
|
if(filters.length() == 0) {
|
|
fileSystemModel->setNameFilters(QStringList() << "*");
|
|
} else {
|
|
filters = substr(filters, strpos(filters, "(")());
|
|
ltrim(filters, "(");
|
|
rtrim(filters, ")");
|
|
lstring part;
|
|
part.split(" ", filters);
|
|
QStringList list;
|
|
for(unsigned i = 0; i < part.size(); i++) list << part[i];
|
|
fileSystemModel->setNameFilters(list);
|
|
}
|
|
}
|
|
|
|
inline void FileDialog::createNewFolder() {
|
|
newFolderDialog->show();
|
|
}
|
|
|
|
inline void FileDialog::browseUp() {
|
|
if(pathBox->count() > 1) pathBox->setCurrentIndex(1);
|
|
}
|
|
|
|
inline void FileDialog::setPath(string path) {
|
|
lock = true;
|
|
newFolderDialog->close();
|
|
|
|
if(QDir(path).exists()) {
|
|
newFolderButton->setEnabled(true);
|
|
} else {
|
|
newFolderButton->setEnabled(false);
|
|
path = "";
|
|
}
|
|
|
|
fileSystemModel->setRootPath(path);
|
|
fileView->setRootIndex(fileSystemModel->index(path));
|
|
fileView->setCurrentIndex(fileView->rootIndex());
|
|
fileView->setFocus();
|
|
|
|
pathBox->clear();
|
|
if(path.length() > 0) {
|
|
QDir directory(path);
|
|
while(true) {
|
|
pathBox->addItem(directory.absolutePath());
|
|
if(directory.isRoot()) break;
|
|
directory.cdUp();
|
|
}
|
|
}
|
|
pathBox->addItem("<root>");
|
|
fileNameEdit->setText("");
|
|
|
|
lock = false;
|
|
}
|
|
|
|
inline void FileDialog::setNameFilters(const string &filters) {
|
|
lock = true;
|
|
|
|
lstring list;
|
|
list.split("\n", filters);
|
|
|
|
filterBox->clear();
|
|
for(unsigned i = 0; i < list.size(); i++) {
|
|
filterBox->addItem(list[i]);
|
|
}
|
|
|
|
lock = false;
|
|
filterBoxChanged();
|
|
}
|
|
|
|
inline void FileDialog::acceptAction() {
|
|
string path = fileSystemModel->rootPath().toUtf8().constData();
|
|
path << "/" << notdir(fileNameEdit->text().toUtf8().constData());
|
|
rtrim(path, "/");
|
|
if(QDir(path).exists()) {
|
|
emit accepted(path);
|
|
setPath(path);
|
|
} else {
|
|
emit accepted(path);
|
|
close();
|
|
}
|
|
}
|
|
|
|
inline void FileDialog::rejectAction() {
|
|
emit rejected();
|
|
close();
|
|
}
|
|
|
|
inline void FileDialog::createFolderAction(const string &name) {
|
|
string path = fileSystemModel->rootPath().toUtf8().constData();
|
|
path << "/" << notdir(name);
|
|
mkdir(path, 0755);
|
|
}
|
|
|
|
inline void FileDialog::closeEvent(QCloseEvent *event) {
|
|
newFolderDialog->close();
|
|
Window::closeEvent(event);
|
|
}
|
|
|
|
inline FileDialog::FileDialog() {
|
|
newFolderDialog = new NewFolderDialog(this);
|
|
resize(640, 360);
|
|
|
|
layout = new QVBoxLayout;
|
|
layout->setMargin(5);
|
|
layout->setSpacing(5);
|
|
setLayout(layout);
|
|
|
|
navigationLayout = new QHBoxLayout;
|
|
layout->addLayout(navigationLayout);
|
|
|
|
pathBox = new QComboBox;
|
|
pathBox->setEditable(true);
|
|
pathBox->setMinimumContentsLength(16);
|
|
pathBox->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLength);
|
|
pathBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
|
navigationLayout->addWidget(pathBox);
|
|
|
|
newFolderButton = new QPushButton;
|
|
newFolderButton->setIconSize(QSize(16, 16));
|
|
newFolderButton->setIcon(QIcon(":/16x16/folder-new.png"));
|
|
navigationLayout->addWidget(newFolderButton);
|
|
|
|
upFolderButton = new QPushButton;
|
|
upFolderButton->setIconSize(QSize(16, 16));
|
|
upFolderButton->setIcon(QIcon(":/16x16/go-up.png"));
|
|
navigationLayout->addWidget(upFolderButton);
|
|
|
|
browseLayout = new QHBoxLayout;
|
|
layout->addLayout(browseLayout);
|
|
|
|
fileSystemModel = new QFileSystemModel;
|
|
fileSystemModel->setFilter(QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot);
|
|
fileSystemModel->setNameFilterDisables(false);
|
|
|
|
fileView = new FileView;
|
|
fileView->setMinimumWidth(320);
|
|
fileView->setModel(fileSystemModel);
|
|
fileView->setIconSize(QSize(16, 16));
|
|
browseLayout->addWidget(fileView);
|
|
|
|
previewFrame = new QGroupBox;
|
|
previewFrame->hide();
|
|
browseLayout->addWidget(previewFrame);
|
|
|
|
fileNameEdit = new QLineEdit;
|
|
layout->addWidget(fileNameEdit);
|
|
|
|
controlLayout = new QHBoxLayout;
|
|
controlLayout->setAlignment(Qt::AlignRight);
|
|
layout->addLayout(controlLayout);
|
|
|
|
filterBox = new QComboBox;
|
|
filterBox->setMinimumContentsLength(16);
|
|
filterBox->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLength);
|
|
filterBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
|
controlLayout->addWidget(filterBox);
|
|
|
|
optionsButton = new QPushButton("Options");
|
|
optionsButton->hide();
|
|
controlLayout->addWidget(optionsButton);
|
|
|
|
acceptButton = new QPushButton("Ok");
|
|
controlLayout->addWidget(acceptButton);
|
|
|
|
rejectButton = new QPushButton("Cancel");
|
|
controlLayout->addWidget(rejectButton);
|
|
|
|
lock = false;
|
|
connect(pathBox, SIGNAL(currentIndexChanged(int)), this, SLOT(pathBoxChanged()));
|
|
connect(newFolderButton, SIGNAL(released()), this, SLOT(createNewFolder()));
|
|
connect(upFolderButton, SIGNAL(released()), this, SLOT(browseUp()));
|
|
connect(fileView, SIGNAL(changed(const QModelIndex&)), this, SLOT(fileViewChange(const QModelIndex&)));
|
|
connect(fileView, SIGNAL(activated(const QModelIndex&)), this, SLOT(fileViewActivate(const QModelIndex&)));
|
|
connect(fileView, SIGNAL(browseUp()), this, SLOT(browseUp()));
|
|
connect(fileNameEdit, SIGNAL(returnPressed()), this, SLOT(acceptAction()));
|
|
connect(filterBox, SIGNAL(currentIndexChanged(int)), this, SLOT(filterBoxChanged()));
|
|
connect(acceptButton, SIGNAL(released()), this, SLOT(acceptAction()));
|
|
connect(rejectButton, SIGNAL(released()), this, SLOT(rejectAction()));
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|