added: rename, import and export

This commit is contained in:
Mathias Panzenböck
2014-02-25 04:16:43 +01:00
parent 008450a949
commit fdedbf8662
5 changed files with 216 additions and 37 deletions

View File

@ -7,8 +7,8 @@
//a nice simple way of throwing up an error message if something goes wrong. //a nice simple way of throwing up an error message if something goes wrong.
inline void errorBox(const QString &type, const QString &message, QWidget *parent = 0) { inline void errorBox(const QString &title, const QString &message, QWidget *parent = 0) {
QMessageBox::warning(parent, QString("%1 - %2").arg(QJOYPAD_DEVDIR, type), QMessageBox::warning(parent, QString("%1 - %2").arg(title, QJOYPAD_NAME),
message, QMessageBox::Ok, Qt::NoButton); message, QMessageBox::Ok, Qt::NoButton);
} }

View File

@ -1,11 +1,14 @@
#include "layout.h"
#include "config.h"
#include <errno.h> #include <errno.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include <QFileDialog>
#include "layout.h"
#include "config.h"
//initialize things and set up an icon :) //initialize things and set up an icon :)
LayoutManager::LayoutManager( bool useTrayIcon, const QString &devdir, const QString &settingsDir ) LayoutManager::LayoutManager( bool useTrayIcon, const QString &devdir, const QString &settingsDir )
: devdir(devdir), settingsDir(settingsDir), : devdir(devdir), settingsDir(settingsDir),
@ -168,13 +171,13 @@ bool LayoutManager::load(const QString& name) {
//if the file isn't available, //if the file isn't available,
if (!file.exists()) { if (!file.exists()) {
errorBox("Load error","Failed to find a layout named " + name); errorBox(tr("Load error"), tr("Failed to find a layout named %1.").arg(name), le);
return false; return false;
} }
//if the file isn't readable, //if the file isn't readable,
if (!file.open(QIODevice::ReadOnly)) { if (!file.open(QIODevice::ReadOnly)) {
errorBox("Load error","Error reading from file " + file.fileName()); errorBox(tr("Load error"), tr("Error reading from file: %1").arg(file.fileName()), le);
return false; return false;
} }
@ -205,7 +208,9 @@ bool LayoutManager::load(const QString& name) {
num = word.toInt(&okay); num = word.toInt(&okay);
//make sure the number of the joystick is valid //make sure the number of the joystick is valid
if (!okay || num < 1) { if (!okay || num < 1) {
errorBox( tr("Load error"), tr("Error reading joystick definition. Unexpected token \"%1\". Expected a positive number.").arg(word)); errorBox(tr("Load error"),
tr("Error reading joystick definition. Unexpected token \"%1\". Expected a positive number.").arg(word),
le);
if (name != currentLayout) reload(); if (name != currentLayout) reload();
else clear(); else clear();
return false; return false;
@ -213,7 +218,9 @@ bool LayoutManager::load(const QString& name) {
stream.skipWhiteSpace(); stream.skipWhiteSpace();
stream >> ch; stream >> ch;
if (ch != QChar('{')) { if (ch != QChar('{')) {
errorBox( tr("Load error"), tr("Error reading joystick definition. Unexpected character \"%1\". Expected '{'.").arg(ch)); errorBox(tr("Load error"),
tr("Error reading joystick definition. Unexpected character \"%1\". Expected '{'.").arg(ch),
le);
if (name != currentLayout) reload(); if (name != currentLayout) reload();
else clear(); else clear();
return false; return false;
@ -225,7 +232,7 @@ bool LayoutManager::load(const QString& name) {
} }
//try to read the joypad, report error on fail. //try to read the joypad, report error on fail.
if (!joypads[index]->readConfig(stream)) { if (!joypads[index]->readConfig(stream)) {
errorBox( tr("Load error"), tr("Error reading definition for joystick %1.").arg(index)); errorBox(tr("Load error"), tr("Error reading definition for joystick %1.").arg(index), le);
//if this was attempting to change to a new layout and it failed, //if this was attempting to change to a new layout and it failed,
//revert back to the old layout. //revert back to the old layout.
if (name != currentLayout) reload(); if (name != currentLayout) reload();
@ -240,7 +247,9 @@ bool LayoutManager::load(const QString& name) {
stream.readLine(); stream.readLine();
} }
else { else {
errorBox(tr("Load error"), tr("Error reading joystick definition. Unexpected token \"%1\". Expected \"Joystick\".").arg(word)); errorBox(tr("Load error"),
tr("Error reading joystick definition. Unexpected token \"%1\". Expected \"Joystick\".").arg(word),
le);
if (name != currentLayout) reload(); if (name != currentLayout) reload();
else clear(); else clear();
return false; return false;
@ -288,12 +297,18 @@ void LayoutManager::clear() {
void LayoutManager::save() { void LayoutManager::save() {
if (currentLayout.isNull()) { if (currentLayout.isNull()) {
saveAs(); saveAs();
return;
} }
else {
save(getFileName(currentLayout));
}
}
//get a filename void LayoutManager::save(const QString &filename) {
QString filename = getFileName( currentLayout );
QFile file(filename); QFile file(filename);
save(file);
}
void LayoutManager::save(QFile &file) {
//if it's good, start writing the file //if it's good, start writing the file
if (file.open(QIODevice::WriteOnly)) { if (file.open(QIODevice::WriteOnly)) {
QTextStream stream( &file ); QTextStream stream( &file );
@ -305,25 +320,32 @@ void LayoutManager::save() {
} }
//if it's not, error. //if it's not, error.
else { else {
errorBox(tr("Save error"), tr("Could not open file %1, layout not saved.").arg(filename)); errorBox(tr("Save error"), tr("Could not open file %1, layout not saved.").arg(file.fileName()), le);
} }
} }
void LayoutManager::saveAs() { void LayoutManager::saveAs() {
bool ok; bool ok = false;
//request a new name! //request a new name!
QString name = QInputDialog::getText(le, QString name = QInputDialog::getText(le,
tr("%1 - Name new layout").arg(QJOYPAD_NAME), tr("Name new layout - %1").arg(QJOYPAD_NAME),
tr("Enter a name for the new layout:"), tr("Enter a name for the new layout:"),
QLineEdit::Normal, QString::null, &ok ); QLineEdit::Normal, QString::null, &ok);
if (!ok) { if (!ok) {
return; return;
} }
QFile file(settingsDir + name + ".lyt"); else if (name.isEmpty()) {
errorBox(tr("Save error"), tr("Layout name cannot be empty."), le);
return;
}
else if (name.contains('/')) {
errorBox(tr("Save error"), tr("Layout name may not contain a '/' (slash)."), le);
return;
}
QFile file(getFileName(name));
//don't overwrite an existing layout. //don't overwrite an existing layout.
if (file.exists()) { if (file.exists()) {
errorBox(tr("Save error"), tr("That name's already taken!")); errorBox(tr("Save error"), tr("That name's already taken!"), le);
return; return;
} }
@ -331,7 +353,7 @@ void LayoutManager::saveAs() {
setLayoutName(name); setLayoutName(name);
//since we have a new name for this layout now, we can save it normally :) //since we have a new name for this layout now, we can save it normally :)
save(); save(file);
//add the new name to our lists //add the new name to our lists
fillPopup(); fillPopup();
@ -340,6 +362,67 @@ void LayoutManager::saveAs() {
} }
} }
void LayoutManager::importLayout() {
QFileDialog dialog(le);
dialog.setWindowTitle(tr("Import layout - %1").arg(QJOYPAD_NAME));
dialog.setFileMode(QFileDialog::ExistingFile);
dialog.setAcceptMode(QFileDialog::AcceptOpen);
QStringList filters;
filters.append(tr("QJoyPad layout files (*.lyt)"));
filters.append(tr("Any files (*)"));
dialog.setNameFilters(filters);
dialog.setDefaultSuffix("lyt");
if (dialog.exec() && !dialog.selectedFiles().isEmpty()) {
QString sourceFile = dialog.selectedFiles()[0];
QFileInfo info(sourceFile);
QString layoutName = info.baseName();
if (layoutName.endsWith(".lyt",Qt::CaseInsensitive)) {
layoutName.truncate(layoutName.size() - 4);
}
QString filename = getFileName(layoutName);
if (info == QFileInfo(filename)) {
errorBox(tr("Import error"), tr("Cannot import file from QJoyPad settings directory."));
return;
}
if (QFile::exists(filename)) {
if (QMessageBox::warning(le,
QString("%1 - %2").arg(tr("Layout exists"), QJOYPAD_NAME),
tr("Layout %1 exists. Do you want to overwrite it?"),
tr("Over&write"), tr("&Cancel"), QString::null, 0, 1) == 1) {
return;
}
QFile::remove(filename);
}
QFile::copy(sourceFile, filename);
fillPopup();
if (le) {
le->updateLayoutList();
}
load(layoutName);
}
}
void LayoutManager::exportLayout() {
QFileDialog dialog(le);
dialog.setWindowTitle(tr("Export layout - %1").arg(QJOYPAD_NAME));
dialog.setFileMode(QFileDialog::AnyFile);
dialog.setAcceptMode(QFileDialog::AcceptSave);
QStringList filters;
filters.append(tr("QJoyPad layout files (*.lyt)"));
filters.append(tr("Any files (*)"));
dialog.setNameFilters(filters);
dialog.setDefaultSuffix("lyt");
if (dialog.exec() && !dialog.selectedFiles().isEmpty()) {
save(dialog.selectedFiles()[0]);
}
}
void LayoutManager::saveDefault() { void LayoutManager::saveDefault() {
QFile file( settingsDir + "layout"); QFile file( settingsDir + "layout");
if (file.open(QIODevice::WriteOnly)) { if (file.open(QIODevice::WriteOnly)) {
@ -350,12 +433,13 @@ void LayoutManager::saveDefault() {
void LayoutManager::remove() { void LayoutManager::remove() {
if (currentLayout.isNull()) return; if (currentLayout.isNull()) return;
if (QMessageBox::warning(le, tr("%1 - Delete layout?").arg(QJOYPAD_NAME), if (QMessageBox::warning(le, tr("Delete layout? - %1").arg(QJOYPAD_NAME),
tr("Remove layout %1 permanently from your hard drive?").arg(currentLayout), tr("Delete"), tr("Cancel"), 0, 0, 1 ) == 1) tr("Remove layout %1 permanently from your hard drive?").arg(currentLayout), tr("&Delete"), tr("&Cancel"), QString::null, 0, 1 ) == 1) {
return; return;
}
QString filename = getFileName( currentLayout ); QString filename = getFileName( currentLayout );
if (!QFile(filename).remove()) { if (!QFile(filename).remove()) {
errorBox(tr("Remove error"), tr("Could not remove file %1").arg(filename)); errorBox(tr("Remove error"), tr("Could not remove file %1").arg(filename), le);
} }
fillPopup(); fillPopup();
@ -365,6 +449,45 @@ void LayoutManager::remove() {
clear(); clear();
} }
void LayoutManager::rename() {
if (currentLayout.isNull()) return;
bool ok = false;
QString name = QInputDialog::getText(le,
tr("Rename layout - %1").arg(QJOYPAD_NAME),
tr("Enter a new name for the layout:"),
QLineEdit::Normal, currentLayout, &ok);
if (!ok) {
return;
}
else if (name.isEmpty()) {
errorBox(tr("Rename error"), tr("Layout name cannot be empty."), le);
return;
}
else if (name.contains('/')) {
errorBox(tr("Rename error"), tr("Layout name may not contain a '/' (slash)."), le);
return;
}
QString filename = getFileName(name);
if (QFile::exists(filename)) {
errorBox(tr("Rename error"), tr("Layout with name %1 already exists.").arg(name), le);
return;
}
if (!QFile::rename(getFileName(currentLayout), filename)) {
errorBox(tr("Rename error"), tr("Error renaming layout."), le);
return;
}
fillPopup();
if (le) {
le->updateLayoutList();
}
load(name);
}
QStringList LayoutManager::getLayoutNames() const { QStringList LayoutManager::getLayoutNames() const {
//goes through the list of .lyt files and removes the file extensions ;) //goes through the list of .lyt files and removes the file extensions ;)
QStringList result = QDir(settingsDir).entryList(QStringList("*.lyt")); QStringList result = QDir(settingsDir).entryList(QStringList("*.lyt"));
@ -397,7 +520,8 @@ void LayoutManager::iconClick() {
//don't show the dialog if there aren't any joystick devices plugged in //don't show the dialog if there aren't any joystick devices plugged in
if (available.isEmpty()) { if (available.isEmpty()) {
errorBox(tr("No joystick devices available"), errorBox(tr("No joystick devices available"),
tr("No joystick devices are currently available to configure.\nPlease plug in a gaming device and select\n\"Update Joystick Devices\" from the popup menu.")); tr("No joystick devices are currently available to configure.\nPlease plug in a gaming device and select\n\"Update Joystick Devices\" from the popup menu."),
le);
return; return;
} }
if (le) { if (le) {

View File

@ -54,13 +54,19 @@ class LayoutManager : public QObject {
//save the current layout with its current name //save the current layout with its current name
void save(); void save();
void save(const QString& filename);
void save(QFile& file);
//save the current layout with a new name //save the current layout with a new name
void saveAs(); void saveAs();
void exportLayout();
void importLayout();
//save the currently loaded layout so it can be recalled later //save the currently loaded layout so it can be recalled later
void saveDefault(); void saveDefault();
//get rid of a layout //get rid of a layout
void remove(); void remove();
//rename current layout
void rename();
//when the tray icon is clicked //when the tray icon is clicked
void iconClick(); void iconClick();

View File

@ -2,35 +2,80 @@
#include "config.h" #include "config.h"
//build the dialog //build the dialog
LayoutEdit::LayoutEdit( LayoutManager* l ): QWidget(NULL) { LayoutEdit::LayoutEdit( LayoutManager* l )
lm = l; : QWidget(0),
lm(l),
mainLayout(0),
padStack(0),
joyButtons(0),
cmbLayouts(0),
btnAdd(0),
btnRem(0),
btnUpd(0),
btnRev(0),
btnExport(0),
btnImport(0),
btnRename(0) {
setAttribute(Qt::WA_DeleteOnClose); setAttribute(Qt::WA_DeleteOnClose);
setWindowTitle( QJOYPAD_NAME ); setWindowTitle( QJOYPAD_NAME );
setWindowIcon(QPixmap(QJOYPAD_ICON64)); setWindowIcon(QPixmap(QJOYPAD_ICON64));
mainLayout = new QVBoxLayout( this); mainLayout = new QVBoxLayout(this);
mainLayout->setSpacing(5); mainLayout->setSpacing(5);
mainLayout->setMargin(5); mainLayout->setMargin(5);
QFrame* frame = new QFrame(this); QFrame* frame = new QFrame(this);
frame->setFrameStyle(QFrame::Box | QFrame::Sunken ); frame->setFrameStyle(QFrame::Box | QFrame::Sunken);
QGridLayout* g = new QGridLayout(frame); QGridLayout* g = new QGridLayout(frame);
g->setMargin(5); g->setMargin(5);
g->setSpacing(5); g->setSpacing(5);
cmbLayouts = new QComboBox(frame); cmbLayouts = new QComboBox(frame);
connect(cmbLayouts, SIGNAL(activated(int)), this, SLOT(load(int))); connect(cmbLayouts, SIGNAL(activated(int)), this, SLOT(load(int)));
g->addWidget(cmbLayouts,0,0,1,4);
QHBoxLayout *layoutLayout = new QHBoxLayout(this);
//most of these buttons can link directly into slots in the LayoutManager //most of these buttons can link directly into slots in the LayoutManager
btnAdd = new QPushButton(QIcon::fromTheme("list-add"), tr("&Add"), frame); btnAdd = new QPushButton(frame);
btnAdd->setIcon(QIcon::fromTheme("list-add"));
btnAdd->setToolTip(tr("Add Layout"));
if (btnAdd->icon().isNull()) {
btnAdd->setText("+");
}
btnAdd->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
connect(btnAdd, SIGNAL(clicked()), lm, SLOT(saveAs())); connect(btnAdd, SIGNAL(clicked()), lm, SLOT(saveAs()));
g->addWidget(btnAdd,1,0);
btnRem = new QPushButton(QIcon::fromTheme("list-remove"), tr("&Remove"), frame); btnRem = new QPushButton(frame);
btnRem->setIcon(QIcon::fromTheme("list-remove"));
if (btnRem->icon().isNull()) {
btnRem->setText("-");
}
btnRem->setToolTip(tr("Remove Layout"));
btnRem->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
connect(btnRem, SIGNAL(clicked()), lm, SLOT(remove())); connect(btnRem, SIGNAL(clicked()), lm, SLOT(remove()));
g->addWidget(btnRem,1,1);
btnRename = new QPushButton(tr("&Rename"), frame);
btnRename->setToolTip(tr("Rename Layout"));
btnRename->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
connect(btnRename, SIGNAL(clicked()), lm, SLOT(rename()));
layoutLayout->addWidget(cmbLayouts);
layoutLayout->addWidget(btnAdd);
layoutLayout->addWidget(btnRem);
layoutLayout->addWidget(btnRename);
mainLayout->addLayout(layoutLayout);
btnImport = new QPushButton(QIcon::fromTheme("document-open"), tr("&Import"), frame);
connect(btnImport, SIGNAL(clicked()), lm, SLOT(importLayout()));
g->addWidget(btnImport,1,0);
btnExport = new QPushButton(QIcon::fromTheme("document-save-as"), tr("E&xport"), frame);
connect(btnExport, SIGNAL(clicked()), lm, SLOT(exportLayout()));
g->addWidget(btnExport,1,1);
btnUpd = new QPushButton(QIcon::fromTheme("document-save"), tr("&Save"), frame); btnUpd = new QPushButton(QIcon::fromTheme("document-save"), tr("&Save"), frame);
connect(btnUpd, SIGNAL(clicked()), lm, SLOT(save())); connect(btnUpd, SIGNAL(clicked()), lm, SLOT(save()));
g->addWidget(btnUpd,1,2); g->addWidget(btnUpd,1,2);
btnRev = new QPushButton(QIcon::fromTheme("document-revert"), tr("Re&vert"), frame); btnRev = new QPushButton(QIcon::fromTheme("document-revert"), tr("Re&vert"), frame);
connect(btnRev, SIGNAL(clicked()), lm, SLOT(reload())); connect(btnRev, SIGNAL(clicked()), lm, SLOT(reload()));
g->addWidget(btnRev,1,3); g->addWidget(btnRev,1,3);
@ -70,7 +115,7 @@ LayoutEdit::LayoutEdit( LayoutManager* l ): QWidget(NULL) {
updateLayoutList(); updateLayoutList();
//add the buttons at the bottom. //add the buttons at the bottom.
QHBoxLayout* h = new QHBoxLayout(0); QHBoxLayout* h = new QHBoxLayout(this);
h->setMargin(0); h->setMargin(0);
h->setSpacing(5); h->setSpacing(5);
QPushButton* close = new QPushButton(QIcon::fromTheme("window-close"), tr("&Close Dialog"), this ); QPushButton* close = new QPushButton(QIcon::fromTheme("window-close"), tr("&Close Dialog"), this );
@ -94,6 +139,10 @@ void LayoutEdit::setLayout(const QString &layout) {
} }
} }
bool hasLayout = !layout.isNull();
btnRem->setEnabled(hasLayout);
btnRename->setEnabled(hasLayout);
//update all the JoyPadWidgets. //update all the JoyPadWidgets.
for (int i = 0, n = lm->available.count(); i < n; i++) { for (int i = 0, n = lm->available.count(); i < n; i++) {
((JoyPadWidget*)padStack->widget(i))->update(); ((JoyPadWidget*)padStack->widget(i))->update();

View File

@ -36,7 +36,7 @@ class LayoutEdit : public QWidget {
QStackedWidget *padStack; QStackedWidget *padStack;
FlashRadioArray *joyButtons; FlashRadioArray *joyButtons;
QComboBox* cmbLayouts; QComboBox* cmbLayouts;
QPushButton *btnAdd, *btnRem, *btnUpd, *btnRev; QPushButton *btnAdd, *btnRem, *btnUpd, *btnRev, *btnExport, *btnImport, *btnRename;
}; };
#endif #endif