diff --git a/CMakeLists.txt b/CMakeLists.txt
index 927d6a3..427c9d6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -41,6 +41,11 @@ add_executable(wxMASSManager WIN32
GUI/MainFrame.cpp
GUI/EvtMainFrame.h
GUI/EvtMainFrame.cpp
+ GUI/NameChangeDialog.fbp
+ GUI/NameChangeDialog.h
+ GUI/NameChangeDialog.cpp
+ GUI/EvtNameChangeDialog.h
+ GUI/EvtNameChangeDialog.cpp
MassManager/MassManager.h
MassManager/MassManager.cpp
resource.rc)
diff --git a/GUI/EvtNameChangeDialog.cpp b/GUI/EvtNameChangeDialog.cpp
new file mode 100644
index 0000000..53a124c
--- /dev/null
+++ b/GUI/EvtNameChangeDialog.cpp
@@ -0,0 +1,89 @@
+// wxMASSManager
+// Copyright (C) 2020 Guillaume Jacquemin
+//
+// 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 .
+
+#include
+
+#include "EvtNameChangeDialog.h"
+
+EvtNameChangeDialog::EvtNameChangeDialog(wxWindow* parent): NameChangeDialog(parent) {
+ wxTextValidator validator(wxFILTER_INCLUDE_CHAR_LIST, nullptr);
+
+ validator.SuppressBellOnError(false);
+ validator.SetCharIncludes("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789- ");
+
+ _nameInput->SetValidator(validator);
+}
+
+auto EvtNameChangeDialog::getName() -> std::string {
+ std::string name = _nameInput->GetValue().ToStdString();
+ return name;
+}
+
+void EvtNameChangeDialog::setName(const std::string& name) {
+ _nameInput->SetValue(wxString::FromUTF8(name.c_str()));
+}
+
+void EvtNameChangeDialog::textEditEvent(wxCommandEvent&) {
+ const wxString value = _nameInput->GetValue();
+
+ if(value.length() >= 6 && value.length() <= 32) {
+ _lengthBitmap->SetBitmap(wxArtProvider::GetBitmap(wxART_TICK_MARK, wxART_BUTTON));
+ }
+ else {
+ _lengthBitmap->SetBitmap(wxArtProvider::GetBitmap(wxART_CROSS_MARK, wxART_BUTTON));
+ }
+
+ _nameLength->SetLabel(wxString::Format("%u", value.length()));
+
+ if(_nameInput->Validate() == true) {
+ _charsBitmap->SetBitmap(wxArtProvider::GetBitmap(wxART_TICK_MARK, wxART_BUTTON));
+ }
+ else {
+ _charsBitmap->SetBitmap(wxArtProvider::GetBitmap(wxART_CROSS_MARK, wxART_BUTTON));
+ }
+
+ if(!(value.StartsWith(" ") || value.EndsWith(" "))) {
+ _whitespaceAtBeginOrEndBitmap->SetBitmap(wxArtProvider::GetBitmap(wxART_TICK_MARK, wxART_BUTTON));
+ }
+ else {
+ _whitespaceAtBeginOrEndBitmap->SetBitmap(wxArtProvider::GetBitmap(wxART_CROSS_MARK, wxART_BUTTON));
+ }
+
+ if(validateName() == true) {
+ _okButton->Enable();
+ }
+ else {
+ _okButton->Disable();
+ }
+}
+
+void EvtNameChangeDialog::okButtonEvent(wxCommandEvent&) {
+ if(validateName() == false) {
+ wxMessageBox("The new name couldn't be validated.", "Error", wxOK|wxCENTRE|wxICON_ERROR, this);
+ return;
+ }
+
+ EndModal(wxID_OK);
+}
+
+void EvtNameChangeDialog::cancelButtonEvent(wxCommandEvent&) {
+ EndModal(wxID_CANCEL);
+}
+
+auto EvtNameChangeDialog::validateName() -> bool {
+ const wxString value = _nameInput->GetValue();
+ return ((value.length() >= 6 && value.length() <= 32) && _nameInput->Validate() && !(value.StartsWith(" ") || value.EndsWith(" ")));
+}
diff --git a/GUI/EvtNameChangeDialog.h b/GUI/EvtNameChangeDialog.h
new file mode 100644
index 0000000..af58a57
--- /dev/null
+++ b/GUI/EvtNameChangeDialog.h
@@ -0,0 +1,38 @@
+#ifndef __EvtNameChangeDialog__
+#define __EvtNameChangeDialog__
+
+// wxMASSManager
+// Copyright (C) 2020 Guillaume Jacquemin
+//
+// 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 .
+
+#include "NameChangeDialog.h"
+
+class EvtNameChangeDialog: public NameChangeDialog {
+ public:
+ EvtNameChangeDialog(wxWindow* parent);
+
+ auto getName() -> std::string;
+ void setName(const std::string& name);
+
+ protected:
+ void textEditEvent(wxCommandEvent&);
+ void okButtonEvent(wxCommandEvent&);
+ void cancelButtonEvent(wxCommandEvent&);
+
+ private:
+ auto validateName() -> bool;
+};
+
+#endif // __EvtNameChangeDialog__
diff --git a/GUI/NameChangeDialog.cpp b/GUI/NameChangeDialog.cpp
new file mode 100644
index 0000000..6e236e9
--- /dev/null
+++ b/GUI/NameChangeDialog.cpp
@@ -0,0 +1,112 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Oct 26 2018)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO *NOT* EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "NameChangeDialog.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+NameChangeDialog::NameChangeDialog( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bSizerMain;
+ bSizerMain = new wxBoxSizer( wxVERTICAL );
+
+ _nameLabel = new wxStaticText( this, wxID_ANY, wxT("Please enter a new name:"), wxDefaultPosition, wxDefaultSize, 0 );
+ _nameLabel->Wrap( -1 );
+ bSizerMain->Add( _nameLabel, 0, wxALL, 5 );
+
+ _nameInput = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ #ifdef __WXGTK__
+ if ( !_nameInput->HasFlag( wxTE_MULTILINE ) )
+ {
+ _nameInput->SetMaxLength( 32 );
+ }
+ #else
+ _nameInput->SetMaxLength( 32 );
+ #endif
+ bSizerMain->Add( _nameInput, 0, wxALL|wxEXPAND, 5 );
+
+ _conditionsLabel = new wxStaticText( this, wxID_ANY, wxT("The name must satisfy the following conditions:"), wxDefaultPosition, wxDefaultSize, 0 );
+ _conditionsLabel->Wrap( -1 );
+ bSizerMain->Add( _conditionsLabel, 0, wxALL, 5 );
+
+ wxFlexGridSizer* fgSizerConditions;
+ fgSizerConditions = new wxFlexGridSizer( 0, 2, 0, 0 );
+ fgSizerConditions->SetFlexibleDirection( wxBOTH );
+ fgSizerConditions->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ _lengthBitmap = new wxStaticBitmap( this, wxID_ANY, wxArtProvider::GetBitmap( wxART_CROSS_MARK, wxART_BUTTON ), wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizerConditions->Add( _lengthBitmap, 0, wxALL, 5 );
+
+ wxBoxSizer* bSizer3;
+ bSizer3 = new wxBoxSizer( wxHORIZONTAL );
+
+ _lengthLabel = new wxStaticText( this, wxID_ANY, wxT("Between 6 and 32 characters inclusive. Current: "), wxDefaultPosition, wxDefaultSize, 0 );
+ _lengthLabel->Wrap( -1 );
+ bSizer3->Add( _lengthLabel, 0, wxTOP|wxBOTTOM|wxLEFT, 5 );
+
+ _nameLength = new wxStaticText( this, wxID_ANY, wxT("0"), wxDefaultPosition, wxDefaultSize, 0 );
+ _nameLength->Wrap( -1 );
+ bSizer3->Add( _nameLength, 0, wxTOP|wxBOTTOM, 5 );
+
+
+ fgSizerConditions->Add( bSizer3, 1, wxEXPAND, 5 );
+
+ _charsBitmap = new wxStaticBitmap( this, wxID_ANY, wxArtProvider::GetBitmap( wxART_CROSS_MARK, wxART_BUTTON ), wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizerConditions->Add( _charsBitmap, 0, wxALL, 5 );
+
+ _charsLabel = new wxStaticText( this, wxID_ANY, wxT("Uses only the allowed characters: A-Z, a-z, 0-9, -, and spaces."), wxDefaultPosition, wxDefaultSize, 0 );
+ _charsLabel->Wrap( -1 );
+ fgSizerConditions->Add( _charsLabel, 0, wxALL, 5 );
+
+ _whitespaceAtBeginOrEndBitmap = new wxStaticBitmap( this, wxID_ANY, wxArtProvider::GetBitmap( wxART_CROSS_MARK, wxART_BUTTON ), wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizerConditions->Add( _whitespaceAtBeginOrEndBitmap, 0, wxALL, 5 );
+
+ _whitespaceAtBeginOrEndLabel = new wxStaticText( this, wxID_ANY, wxT("Has no whitespace at the beginning or end."), wxDefaultPosition, wxDefaultSize, 0 );
+ _whitespaceAtBeginOrEndLabel->Wrap( -1 );
+ fgSizerConditions->Add( _whitespaceAtBeginOrEndLabel, 0, wxALL, 5 );
+
+
+ bSizerMain->Add( fgSizerConditions, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizerButtons;
+ bSizerButtons = new wxBoxSizer( wxHORIZONTAL );
+
+
+ bSizerButtons->Add( 0, 0, 1, wxEXPAND, 5 );
+
+ _okButton = new wxButton( this, wxID_ANY, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerButtons->Add( _okButton, 0, wxRIGHT|wxLEFT, 5 );
+
+ _cancelButton = new wxButton( this, wxID_ANY, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerButtons->Add( _cancelButton, 0, wxRIGHT|wxLEFT, 5 );
+
+
+ bSizerMain->Add( bSizerButtons, 0, wxEXPAND, 5 );
+
+
+ this->SetSizer( bSizerMain );
+ this->Layout();
+ bSizerMain->Fit( this );
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ _nameInput->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( NameChangeDialog::textEditEvent ), NULL, this );
+ _okButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( NameChangeDialog::okButtonEvent ), NULL, this );
+ _cancelButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( NameChangeDialog::cancelButtonEvent ), NULL, this );
+}
+
+NameChangeDialog::~NameChangeDialog()
+{
+ // Disconnect Events
+ _nameInput->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( NameChangeDialog::textEditEvent ), NULL, this );
+ _okButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( NameChangeDialog::okButtonEvent ), NULL, this );
+ _cancelButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( NameChangeDialog::cancelButtonEvent ), NULL, this );
+
+}
diff --git a/GUI/NameChangeDialog.fbp b/GUI/NameChangeDialog.fbp
new file mode 100644
index 0000000..2b14d26
--- /dev/null
+++ b/GUI/NameChangeDialog.fbp
@@ -0,0 +1,865 @@
+
+
+
+
+
diff --git a/GUI/NameChangeDialog.h b/GUI/NameChangeDialog.h
new file mode 100644
index 0000000..0794e89
--- /dev/null
+++ b/GUI/NameChangeDialog.h
@@ -0,0 +1,64 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Oct 26 2018)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO *NOT* EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#pragma once
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class NameChangeDialog
+///////////////////////////////////////////////////////////////////////////////
+class NameChangeDialog : public wxDialog
+{
+ private:
+
+ protected:
+ wxStaticText* _nameLabel;
+ wxTextCtrl* _nameInput;
+ wxStaticText* _conditionsLabel;
+ wxStaticBitmap* _lengthBitmap;
+ wxStaticText* _lengthLabel;
+ wxStaticText* _nameLength;
+ wxStaticBitmap* _charsBitmap;
+ wxStaticText* _charsLabel;
+ wxStaticBitmap* _whitespaceAtBeginOrEndBitmap;
+ wxStaticText* _whitespaceAtBeginOrEndLabel;
+ wxButton* _okButton;
+ wxButton* _cancelButton;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void textEditEvent( wxCommandEvent& event ) { event.Skip(); }
+ virtual void okButtonEvent( wxCommandEvent& event ) { event.Skip(); }
+ virtual void cancelButtonEvent( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ NameChangeDialog( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Name change"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE );
+ ~NameChangeDialog();
+
+};
+