#include "wxMain.h"
wxIMPLEMENT_APP(MyApp);
bool MyApp::OnInit()
{
MyFrame* frame = new MyFrame("No Title - Notepad");
frame->Show(true);
return true;
}
MyFrame::MyFrame(const wxString& title)
: wxFrame(NULL, wxID_ANY, title)
{
m_menuFile = new wxMenu;
m_menuFile->Append(wxID_NEW, "&New\tCtrl-N", "New a Notepad");
m_menuFile->Append(ID_NEW_WINDOW, "&New Windows\tCtrl+Shift+N", "Open a new window.");
m_menuFile->Append(wxID_OPEN, "&Open\tCtrl-O", "Open a file");
m_menuFile->Append(wxID_SAVE, "&Save\tCtrl-S", "Save the file");
m_menuFile->Append(ID_SAVE_AS, "&Save As\tCtrl+Shift-S", "Save the file");
m_menuFile->AppendSeparator();
m_menuFile->Append(ID_QUIT, "E&xit\tAlt-X", "Exit Program");
m_menuEdit = new wxMenu;
m_menuEdit->Append(wxID_UNDO, "&Undo\tCtrl+Z", "Undo the last action");
m_menuEdit->Append(wxID_REDO, "&Redo\tCtrl+Y", "Redo the last undone action");
m_menuFile->AppendSeparator();
m_menuEdit->Append(wxID_CUT, "Cu&t\tCtrl+X", "Cut the selected text to the clipboard");
m_menuEdit->Append(wxID_COPY, "&Copy\tCtrl+C", "Copy the selected text to the clipboard");
m_menuEdit->Append(ID_SELECT_ALL, "&Select All\tCtrl+A", "Select all text");
m_menuFile->AppendSeparator();
m_menuEdit->AppendCheckItem(ID_DATETIME, "&DateTime\tF5", "DateTime");
m_menuFormat = new wxMenu;
m_menuFormat->AppendCheckItem(ID_WordWarp, "Word &Wrap\tCtrl+W", "Toggle word wrapping.");
m_menuFormat->Append(ID_FontSetting, "&Font", "Font Set Menu");
m_menuView = new wxMenu;
m_menuView->AppendCheckItem(ID_StatusBar, "Show &StatusBar", "Toggle Status Bar.");
m_menuBar = new wxMenuBar;
m_menuBar->Append(m_menuFile, "&File");
m_menuBar->Append(m_menuEdit, "&Edit");
m_menuBar->Append(m_menuFormat, "F&omat");
m_menuBar->Append(m_menuView, "&View");
SetMenuBar(m_menuBar);
m_textControl = new wxTextCtrl(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
// sizer를 생성하여 텍스트 컨트롤의 크기를 조정합니다.
wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
sizer->Add(m_textControl, 1, wxEXPAND | wxALL, 0); // wxEXPAND는 컨트롤이 sizer의 가능한 모든 공간을 차지하도록 합니다. 1은 비율을 의미하며, 이 경우 다른 컨트롤이 없으므로 전체 크기를 차지합니다.
// 프레임에 sizer를 설정합니다.
this->SetSizer(sizer);
this->Layout(); // sizer를 강제로 다시 계산하여 적용합니다.
// 폰트 설정
wxFont font(16, wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD);
m_textControl->SetFont(font);
//m_statusBar = new wxStatusBar(this);
m_statusBar = CreateStatusBar();
SetStatusText("Ready");
// ID_StatusBar 메뉴 항목을 자동으로 체크되어 있도록 설정
m_menuView->Check(ID_StatusBar, true);
// 이벤트 핸들러 연결
Bind(wxEVT_MENU, &MyFrame::OnNew, this, wxID_NEW);
// MyFrame 생성자 또는 초기화 함수 내
Bind(wxEVT_MENU, &MyFrame::OnNewWindow, this, ID_NEW_WINDOW);
Bind(wxEVT_MENU, &MyFrame::OnOpen, this, wxID_OPEN);
Bind(wxEVT_MENU, &MyFrame::OnSave, this, wxID_SAVE);
Bind(wxEVT_MENU, &MyFrame::OnSaveAs, this, ID_SAVE_AS);
Bind(wxEVT_MENU, &MyFrame::OnQuit, this, ID_QUIT);
// 메뉴 Edit에 관련된 이벤트 핸들러
Bind(wxEVT_MENU, &MyFrame::OnUndo, this, wxID_UNDO);
Bind(wxEVT_MENU, &MyFrame::OnRedo, this, wxID_REDO);
Bind(wxEVT_MENU, &MyFrame::OnCut, this, wxID_CUT);
Bind(wxEVT_MENU, &MyFrame::OnCopy, this, wxID_COPY);
Bind(wxEVT_MENU, &MyFrame::OnSelectAll, this, ID_DATETIME);
Bind(wxEVT_MENU, &MyFrame::OnInsertDateTime, this, ID_DATETIME);
// 메뉴 Format에 관련된 이벤트 핸들러
Bind(wxEVT_MENU, &MyFrame::OnToggleWordWrap, this, ID_WordWarp);
Bind(wxEVT_MENU, &MyFrame::OnFontSetting, this, ID_FontSetting);
// 메뉴 View에 관련된 이벤트 핸들러
Bind(wxEVT_MENU, &MyFrame::OnToggleStatusBar, this, ID_StatusBar);
// 메뉴바 갱신 이벤트 핸들러
Bind(wxEVT_UPDATE_UI, &MyFrame::OnUpdateUndo, this, wxID_UNDO);
Bind(wxEVT_UPDATE_UI, &MyFrame::OnUpdateRedo, this, wxID_REDO);
Bind(wxEVT_UPDATE_UI, &MyFrame::OnUpdateCut, this, wxID_CUT);
Bind(wxEVT_UPDATE_UI, &MyFrame::OnUpdateCopy, this, wxID_COPY);
// 이벤트 처리기 등록
Bind(MY_CUSTOM_EVENT, &MyFrame::OnMyCustomEvent, this);
}
void MyFrame::OnQuit(wxCommandEvent& event)
{
Close(true);
}
void MyFrame::OnNew(wxCommandEvent& event) {
// 텍스트 컨트롤의 내용을 비웁니다.
m_textControl->Clear();
// 타이틀에 메시지를 새로 작성합니다.
wxString titleNames = "No Title";
titleNames += " - Notepad";
SetTitle(titleNames);
// 상태 표시줄에 메시지를 표시합니다.
SetStatusText("New document created.");
}
// MyFrame 클래스 내
void MyFrame::OnNewWindow(wxCommandEvent& event)
{
// 새로운 창을 생성하고 표시
MyFrame* newFrame = new MyFrame("No Title - Notepad");
newFrame->Show(true);
}
void MyFrame::OnOpen(wxCommandEvent& event)
{
wxFileDialog openFileDialog(this, _("Open TXT file"), "", "",
"TXT files (*.txt)|*.txt", wxFD_OPEN | wxFD_FILE_MUST_EXIST);
wxString openFileName = m_currentFileName;
wxString openFilePath = m_currentFilePath;
switch (openFileDialog.ShowModal()) {
case wxID_OK: {
openFileName = openFileDialog.GetFilename();
// 세이브 및 적용이 완료했을 경우.
openFilePath = openFileDialog.GetPath();
break;
}
case wxID_CANCEL: {
return; // 사용자가 취소했을 때
}
}
std::ifstream file(openFilePath.ToStdString());
// 파일을 열고 텍스트 컨트롤에 내용을 로드합니다.
if (m_textControl->LoadFile(openFilePath)) {
std::stringstream buffer;
buffer << file.rdbuf(); // 파일의 내용을 buffer에 읽어 들입니다.
file.close(); // 파일을 닫습니다.
// textControl의 내용을 갱신합니다.
m_textControl->SetValue(buffer.str());
//textControl->SetLabelText(buffer.str());
m_currentFileName = openFileName;
m_currentFilePath = openFilePath;
wxString titleNames = m_currentFileName;
titleNames += " - Notepad";
// 타이틀을 열린 파일의 이름으로 설정합니다.
SetTitle(titleNames);
}
else {
wxMessageBox("Cannot open File!", "Error", wxOK | wxICON_ERROR);
}
}
void MyFrame::OnSaveAs(wxCommandEvent& event)
{
wxFileDialog saveFileDialog(this, _("Save TXT file"), "", "",
"TXT files (*.txt)|*.txt", wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
wxString saveAsFileName;
wxString saveAsFilePath;
switch (saveFileDialog.ShowModal()) {
case wxID_OK: {
saveAsFileName = saveFileDialog.GetFilename();
saveAsFilePath = saveFileDialog.GetPath();
break;
}
case wxID_CANCEL: {
return;
}
}
// 사용자가 선택한 파일 경로를 저장합니다.
if (!m_textControl->SaveFile(saveAsFilePath))
{
wxMessageBox("Could not save the file!", "Error", wxOK | wxICON_ERROR);
return;
}
// 파일이 성공적으로 저장되었다면, 현재 파일 경로를 업데이트하고 타이틀을 설정합니다.
m_currentFileName = saveAsFileName;
m_currentFilePath = saveAsFilePath;
wxString titleNames = m_currentFileName;
SetTitle(titleNames + " - Notepad"); // 타이틀 업데이트
// 상태 표시줄에 메시지를 표시합니다.
SetStatusText("File saved successfully.");
}
void MyFrame::OnSave(wxCommandEvent& event)
{
wxFileDialog saveFileDialog(this, _("Save TXT file"), "", "",
"TXT files (*.txt)|*.txt", wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
wxString saveFileName = m_currentFileName;
wxString saveFilePath = m_currentFilePath;
// 경로가 비어있는 경우엔.
if (m_currentFilePath.IsEmpty()) {
switch (saveFileDialog.ShowModal()) {
case wxID_CANCEL: {
return;
}
case wxID_OK: {
saveFileName = saveFileDialog.GetFilename();
// 세이브 및 적용이 완료했을 경우.
saveFilePath = saveFileDialog.GetPath();
break;
}
}
}
// 현재 텍스트 컨트롤의 내용을 파일에 저장합니다.
if (!m_textControl->SaveFile(saveFilePath)) {
// 현재 텍스트의 내용을 파일에 저장하지 못한다면.
wxMessageBox("Could Not save the File!", "Error", wxOK);
return;
}
m_currentFileName = saveFileName;
m_currentFilePath = saveFilePath;
wxString titleNames = m_currentFileName;
titleNames += " - Notepad";
// 타이틀을 열린 파일의 이름으로 설정합니다.
SetTitle(titleNames);
}
void MyFrame::OnUndo(wxCommandEvent& event) {
if (m_textControl->CanUndo()) {
m_textControl->Undo();
}
}
void MyFrame::OnRedo(wxCommandEvent& event)
{
if (m_textControl->CanRedo())
{
m_textControl->Redo();
}
}
void MyFrame::OnCut(wxCommandEvent& event) {
if (m_textControl->CanCut()) {
m_textControl->Cut();
}
}
void MyFrame::OnCopy(wxCommandEvent& event) {
if (m_textControl->CanCopy()) {
m_textControl->Copy();
}
}
void MyFrame::OnSelectAll(wxCommandEvent& event) {
m_textControl->SelectAll();
}
void MyFrame::OnInsertDateTime(wxCommandEvent& event) {
wxDateTime now = wxDateTime::Now();
wxString dateTimeStr = now.Format();
m_textControl->WriteText(dateTimeStr);
}
void MyFrame::OnToggleWordWrap(wxCommandEvent& event)
{
bool isChecked = m_menuFormat->IsChecked(ID_WordWarp);
m_textControl->SetWindowStyleFlag(isChecked ? (m_textControl->GetWindowStyleFlag() | wxTE_WORDWRAP) : (m_textControl->GetWindowStyleFlag() & ~wxTE_WORDWRAP));
m_textControl->Refresh(); // 화면 갱신
}
void MyFrame::OnFontSetting(wxCommandEvent& event)
{
/*dialog = new wxOptionDialog(this, wxID_ANY, "Settings");
dialog->ShowModal();*/
wxFontData fontData;
fontData.SetInitialFont(m_textControl->GetFont());
fontData.SetColour(m_textControl->GetForegroundColour());
wxFontDialog fontDialog(this, fontData);
if (fontDialog.ShowModal() == wxID_OK)
{
wxFontData retData = fontDialog.GetFontData();
wxFont font = retData.GetChosenFont();
wxColour colour = retData.GetColour();
m_textControl->SetFont(font);
m_textControl->SetForegroundColour(colour);
}
}
void MyFrame::OnToggleStatusBar(wxCommandEvent& event)
{
bool isChecked = m_menuView->IsChecked(ID_StatusBar);
// StatusBar의 보임/숨김 상태를 설정합니다.
if (m_statusBar) { // m_statusBar가 유효한지 확인합니다.
m_statusBar->Show(isChecked);
}
// 프레임의 레이아웃을 갱신하여 m_textControl이 남은 공간을 가득 채우도록 합니다.
this->Layout();
// 프레임의 크기를 조정하여 내부 컨트롤들이 적절하게 배치되도록 합니다.
// 이 부분은 필요에 따라 추가하거나 생략할 수 있습니다.
this->SendSizeEvent();
}
// 메뉴바 갱신 이벤트 핸들러
void MyFrame::OnUpdateUndo(wxUpdateUIEvent& event)
{
event.Enable(m_textControl->CanUndo());
}
void MyFrame::OnUpdateRedo(wxUpdateUIEvent& event)
{
event.Enable(m_textControl->CanRedo());
}
void MyFrame::OnUpdateCut(wxUpdateUIEvent& event)
{
event.Enable(m_textControl->CanCut());
}
void MyFrame::OnUpdateCopy(wxUpdateUIEvent& event)
{
event.Enable(m_textControl->CanCopy());
}
// 이벤트 처리 함수 구현
void MyFrame::OnMyCustomEvent(MyCustomEvent& event)
{
const wxFont info = event.GetwxFont();
int fontSize = info.GetPointSize();
// 이벤트와 함께 전달된 정보 처리
m_textControl->SetFont(info);
//textControl->SetFont(font);
//m_dialog->Destroy(); // dialog를 안전하게 삭제
//delete m_dialog;
}