基本版本
This commit is contained in:
17
.clang-format
Normal file
17
.clang-format
Normal file
@@ -0,0 +1,17 @@
|
||||
BasedOnStyle: LLVM
|
||||
IndentWidth: 4
|
||||
PointerAlignment: Left
|
||||
AccessModifierOffset: -4
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterFunction: true
|
||||
AfterClass: true
|
||||
Cpp11BracedListStyle: true
|
||||
ReflowComments: true
|
||||
SpacesBeforeTrailingComments: 3
|
||||
TabWidth: 4
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
ColumnLimit: 130
|
||||
AllowShortBlocksOnASingleLine: Never
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
AllowShortEnumsOnASingleLine: false
|
||||
45
.gitignore
vendored
Normal file
45
.gitignore
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
# Prerequisites
|
||||
*.d
|
||||
.idea
|
||||
cmake-build-*
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
!lebo_motor.lib
|
||||
!lebo_motor.dll
|
||||
!liblebo_motor.so
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
build
|
||||
*.user
|
||||
compile_commands.json
|
||||
.vs
|
||||
out
|
||||
.cache
|
||||
CMakeLists.txt.*
|
||||
173
.vscode/settings.json
vendored
Normal file
173
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,173 @@
|
||||
{
|
||||
"files.autoSave": "onFocusChange",
|
||||
"editor.fontSize": 14,
|
||||
"cmake.configureOnOpen": true,
|
||||
"editor.fontFamily": "'Maple Mono NL NF CN Light', 'Maple Mono NL NF CN Light', 'Maple Mono NL NF CN Light'",
|
||||
"cmake.debugConfig": {
|
||||
"type": "lldb",
|
||||
"console": "externalTerminal",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"args": []
|
||||
},
|
||||
"cmake.configureSettings": {
|
||||
"CMAKE_PREFIX_PATH": "C:/local",
|
||||
},
|
||||
"cmake.configureArgs": [
|
||||
"-Wno-dev"
|
||||
],
|
||||
"cmake.options.statusBarVisibility": "visible",
|
||||
"cmake.generator": "Ninja",
|
||||
"C_Cpp.default.compileCommands": "${workspaceRoot}/build/compile_commands.json",
|
||||
"C_Cpp.default.cppStandard": "c++17",
|
||||
"C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools",
|
||||
"editor.inlayHints.enabled": "off",
|
||||
"editor.unicodeHighlight.allowedLocales": {
|
||||
"ja": true,
|
||||
"zh-hant": true,
|
||||
"zh-hans": true
|
||||
},
|
||||
"files.associations": {
|
||||
"string": "cpp",
|
||||
"any": "cpp",
|
||||
"array": "cpp",
|
||||
"atomic": "cpp",
|
||||
"bit": "cpp",
|
||||
"bitset": "cpp",
|
||||
"cctype": "cpp",
|
||||
"charconv": "cpp",
|
||||
"chrono": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"codecvt": "cpp",
|
||||
"compare": "cpp",
|
||||
"concepts": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"deque": "cpp",
|
||||
"forward_list": "cpp",
|
||||
"list": "cpp",
|
||||
"map": "cpp",
|
||||
"set": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"vector": "cpp",
|
||||
"exception": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"functional": "cpp",
|
||||
"iterator": "cpp",
|
||||
"memory": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"numeric": "cpp",
|
||||
"optional": "cpp",
|
||||
"random": "cpp",
|
||||
"ratio": "cpp",
|
||||
"source_location": "cpp",
|
||||
"string_view": "cpp",
|
||||
"system_error": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"format": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"iostream": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"mutex": "cpp",
|
||||
"new": "cpp",
|
||||
"numbers": "cpp",
|
||||
"ostream": "cpp",
|
||||
"queue": "cpp",
|
||||
"ranges": "cpp",
|
||||
"semaphore": "cpp",
|
||||
"shared_mutex": "cpp",
|
||||
"span": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"stop_token": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"text_encoding": "cpp",
|
||||
"thread": "cpp",
|
||||
"cfenv": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"variant": "cpp",
|
||||
"ios": "cpp",
|
||||
"locale": "cpp",
|
||||
"xfacet": "cpp",
|
||||
"xhash": "cpp",
|
||||
"xiosbase": "cpp",
|
||||
"xlocale": "cpp",
|
||||
"xlocbuf": "cpp",
|
||||
"xlocinfo": "cpp",
|
||||
"xlocmes": "cpp",
|
||||
"xlocmon": "cpp",
|
||||
"xlocnum": "cpp",
|
||||
"xloctime": "cpp",
|
||||
"xmemory": "cpp",
|
||||
"xstring": "cpp",
|
||||
"xtr1common": "cpp",
|
||||
"xutility": "cpp",
|
||||
"coroutine": "cpp",
|
||||
"csignal": "cpp",
|
||||
"future": "cpp",
|
||||
"stdfloat": "cpp",
|
||||
"regex": "cpp",
|
||||
"stack": "cpp",
|
||||
"valarray": "cpp",
|
||||
"filesystem": "cpp",
|
||||
"qmainwindow": "cpp",
|
||||
"qlabel": "cpp",
|
||||
"*.in": "cpp",
|
||||
"fstream": "cpp",
|
||||
"xmemory0": "cpp",
|
||||
"xstddef": "cpp",
|
||||
"xtree": "cpp",
|
||||
"qxmlstreamwriter": "cpp",
|
||||
"qgraphicsdropshadoweffect": "cpp",
|
||||
"qpushbutton": "cpp",
|
||||
"qpainter": "cpp",
|
||||
"qdialog": "cpp",
|
||||
"quuid": "cpp",
|
||||
"complex": "cpp",
|
||||
"expected": "cpp",
|
||||
"qmessagebox": "cpp"
|
||||
},
|
||||
"editor.tokenColorCustomizations": {
|
||||
"textMateRules": [
|
||||
{
|
||||
"scope": "googletest.failed",
|
||||
"settings": {
|
||||
"foreground": "#f00"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "googletest.passed",
|
||||
"settings": {
|
||||
"foreground": "#0f0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "googletest.run",
|
||||
"settings": {
|
||||
"foreground": "#0f0"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
27
CMakeLists.txt
Normal file
27
CMakeLists.txt
Normal file
@@ -0,0 +1,27 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
project(cmakeCreate LANGUAGES CXX)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
if (MSVC)
|
||||
add_compile_options(/utf-8)
|
||||
endif()
|
||||
|
||||
set(CMAKE_DEBUG_POSTFIX "d")
|
||||
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib/${CMAKE_BUILD_TYPE})
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin/${CMAKE_BUILD_TYPE}/)
|
||||
|
||||
find_package(wxWidgets CONFIG REQUIRED)
|
||||
|
||||
set(SOURCES
|
||||
src/mainframe.h
|
||||
src/mainframe.cpp
|
||||
res/ico.rc
|
||||
res/manifest.rc
|
||||
)
|
||||
|
||||
include_directories(src)
|
||||
add_executable(cmakeCreate main.cpp ${SOURCES})
|
||||
target_link_libraries(cmakeCreate PRIVATE wx::core wx::base wx::stc)
|
||||
set_target_properties(cmakeCreate PROPERTIES WIN32_EXECUTABLE TRUE)
|
||||
26
main.cpp
Normal file
26
main.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#include "mainframe.h"
|
||||
|
||||
class CWxNewProject : public wxApp
|
||||
{
|
||||
public:
|
||||
virtual bool OnInit()
|
||||
{
|
||||
wxString title = wxString::Format(wxT("创建cmake工程 v1.0.0"));
|
||||
auto* f = new MainFrame(title);
|
||||
f->Show(true);
|
||||
f->SetIcon(wxICON(IDI_ICON1));
|
||||
|
||||
#ifdef __WXMSW__
|
||||
SetProcessDPIAware();
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
virtual int OnExit()
|
||||
{
|
||||
return wxApp::OnExit();
|
||||
}
|
||||
};
|
||||
|
||||
IMPLEMENT_APP(CWxNewProject);
|
||||
DECLARE_APP(CWxNewProject);
|
||||
BIN
res/ico.ico
Normal file
BIN
res/ico.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 66 KiB |
1
res/ico.rc
Normal file
1
res/ico.rc
Normal file
@@ -0,0 +1 @@
|
||||
IDI_ICON1 ICON DISCARDABLE "ico.ico"
|
||||
1
res/manifest.rc
Normal file
1
res/manifest.rc
Normal file
@@ -0,0 +1 @@
|
||||
1 24 "manifest.xml"
|
||||
42
res/manifest.xml
Normal file
42
res/manifest.xml
Normal file
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<assemblyIdentity
|
||||
version="1.0.0.0"
|
||||
processorArchitecture="*"
|
||||
name="cmakeCreate"
|
||||
type="win32"/>
|
||||
|
||||
<description>Your Application Description</description>
|
||||
|
||||
<!-- 启用 Windows 通用控件 -->
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity
|
||||
type="win32"
|
||||
name="Microsoft.Windows.Common-Controls"
|
||||
version="6.0.0.0"
|
||||
processorArchitecture="*"
|
||||
publicKeyToken="6595b64144ccf1df"
|
||||
language="*"/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
|
||||
<!-- 启用 DPI 感知 -->
|
||||
<asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
|
||||
<asmv3:windowsSettings>
|
||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
|
||||
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
|
||||
</asmv3:windowsSettings>
|
||||
</asmv3:application>
|
||||
|
||||
<!-- 请求管理员权限(可选) -->
|
||||
<!--
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<security>
|
||||
<requestedPrivileges>
|
||||
<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
-->
|
||||
</assembly>
|
||||
573
src/mainframe.cpp
Normal file
573
src/mainframe.cpp
Normal file
@@ -0,0 +1,573 @@
|
||||
#include "mainframe.h"
|
||||
#include <wx/dir.h>
|
||||
#include <wx/dirdlg.h>
|
||||
#include <wx/file.h>
|
||||
#include <wx/fileconf.h>
|
||||
#include <wx/filename.h>
|
||||
#include <wx/filesys.h>
|
||||
#include <wx/msgdlg.h>
|
||||
#include <wx/stdpaths.h>
|
||||
#include <wx/utils.h>
|
||||
|
||||
MainFrame::MainFrame(const wxString& title) : wxFrame(nullptr, wxID_ANY, title)
|
||||
{
|
||||
SetSize(wxSize(1100, 600));
|
||||
InitControl();
|
||||
InitCMakeSyntaxHighlighting();
|
||||
configDir_ = GetConfigDir();
|
||||
ShowConfig();
|
||||
ShowExist();
|
||||
LoadConfig();
|
||||
}
|
||||
|
||||
void MainFrame::InitControl()
|
||||
{
|
||||
addID_ = wxNewId();
|
||||
delID_ = wxNewId();
|
||||
|
||||
wxPanel* mainPanel = new wxPanel(this, wxID_ANY);
|
||||
listBox_ = new wxListBox(mainPanel, wxID_ANY, wxDefaultPosition, wxSize(200, -1));
|
||||
listBox_->Bind(wxEVT_COMMAND_LISTBOX_SELECTED, &MainFrame::OnListBoxSelected, this);
|
||||
listBox_->Bind(wxEVT_CONTEXT_MENU, &MainFrame::OnRightClick, this);
|
||||
|
||||
textCtrl_ = new wxStyledTextCtrl(mainPanel, wxID_ANY);
|
||||
btnNewer_ = new wxButton(mainPanel, wxID_ANY, wxT("新建工程"));
|
||||
btnExit_ = new wxButton(mainPanel, wxID_ANY, wxT("退出"));
|
||||
btnRefresh_ = new wxButton(mainPanel, wxID_ANY, wxT("刷新列表"));
|
||||
btnRefresh_->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &MainFrame::ShowConfig, this);
|
||||
btnSelectPath_ = new wxButton(mainPanel, wxID_ANY, wxT("选择路径"));
|
||||
|
||||
//
|
||||
btnSave_ = new wxButton(mainPanel, wxID_ANY, wxT("保存"), wxDefaultPosition, wxSize(150, -1));
|
||||
|
||||
textPath_ = new wxTextCtrl(mainPanel, wxID_ANY);
|
||||
auto* labelProjectName = new wxStaticText(mainPanel, wxID_ANY, wxT("项目名称:"));
|
||||
projectName_ = new wxTextCtrl(mainPanel, wxID_ANY);
|
||||
|
||||
//
|
||||
btnExit_->SetMinSize(wxSize(150, -1));
|
||||
btnNewer_->SetMinSize(wxSize(150, -1));
|
||||
|
||||
//
|
||||
btnOpenPrjDir_ = new wxButton(mainPanel, wxID_ANY, wxT("打开项目目录"));
|
||||
auto* staticSelectPath = new wxStaticText(mainPanel, wxID_ANY, wxT("工程目录:"));
|
||||
wxBoxSizer* selectSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
selectSizer->Add(staticSelectPath, 0, wxALL | wxCENTER, 2);
|
||||
selectSizer->Add(textPath_, 1, wxALL | wxEXPAND, 2);
|
||||
selectSizer->Add(btnSelectPath_, 0, wxALL | wxCENTER, 2);
|
||||
selectSizer->Add(btnOpenPrjDir_, 0, wxALL | wxCENTER, 2);
|
||||
|
||||
//
|
||||
curFileTitle_ = new wxStaticText(mainPanel, wxID_ANY, wxT("无当前文件"));
|
||||
auto* centerSizer = new wxBoxSizer(wxVERTICAL);
|
||||
centerSizer->Add(curFileTitle_, 0, wxALL | wxLEFT, 2);
|
||||
centerSizer->Add(textCtrl_, 1, wxALL | wxEXPAND, 2);
|
||||
centerSizer->Add(selectSizer, 0, wxALL | wxEXPAND, 2);
|
||||
|
||||
//
|
||||
btnOpenResDir_ = new wxButton(mainPanel, wxID_ANY, wxT("打开模板目录"));
|
||||
auto* controlSizer = new wxBoxSizer(wxVERTICAL);
|
||||
controlSizer->Add(btnRefresh_, 0, wxALL | wxEXPAND, 2);
|
||||
controlSizer->Add(btnSave_, 0, wxALL | wxEXPAND, 2);
|
||||
controlSizer->Add(btnOpenResDir_, 0, wxALL | wxEXPAND, 2);
|
||||
controlSizer->AddStretchSpacer(1);
|
||||
controlSizer->Add(labelProjectName, 0, wxALL | wxLEFT, 2);
|
||||
controlSizer->Add(projectName_, 0, wxALL | wxEXPAND, 2);
|
||||
controlSizer->Add(btnNewer_, 0, wxALL | wxCENTER, 2);
|
||||
controlSizer->Add(btnExit_, 0, wxALL | wxCENTER, 2);
|
||||
|
||||
//
|
||||
auto* topSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
topSizer->Add(listBox_, 0, wxALL | wxEXPAND, 2);
|
||||
topSizer->Add(centerSizer, 3, wxALL | wxEXPAND, 2);
|
||||
topSizer->Add(controlSizer, 0, wxALL | wxEXPAND, 2);
|
||||
|
||||
SetMinSize(wxSize(800, 500));
|
||||
mainPanel->SetSizer(topSizer);
|
||||
|
||||
btnExit_->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &MainFrame::OnExitClick, this);
|
||||
btnNewer_->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &MainFrame::OnNewerClick, this);
|
||||
btnSelectPath_->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &MainFrame::OnSelectPathClick, this);
|
||||
btnSave_->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &MainFrame::SaveCurrent, this);
|
||||
btnOpenResDir_->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &MainFrame::OpenResDir, this);
|
||||
btnOpenPrjDir_->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &MainFrame::OpenPrjDir, this);
|
||||
Bind(wxEVT_MENU, &MainFrame::DelMenu, this, delID_);
|
||||
Bind(wxEVT_MENU, &MainFrame::AddMenu, this, addID_);
|
||||
}
|
||||
|
||||
void MainFrame::OnNewerClick(wxCommandEvent& event)
|
||||
{
|
||||
wxString targetPath = textPath_->GetValue().Trim();
|
||||
if (targetPath.IsEmpty()) {
|
||||
wxMessageBox(wxT("目标路径不能为空"), wxT("错误"), wxOK | wxICON_ERROR, this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!wxDirExists(targetPath)) {
|
||||
wxMessageBox(wxString::Format(wxT("目标路径不存在:\n%s"), targetPath), wxT("错误"), wxOK | wxICON_ERROR, this);
|
||||
return;
|
||||
}
|
||||
|
||||
wxString projectName = projectName_->GetValue().Trim();
|
||||
if (projectName.IsEmpty()) {
|
||||
wxMessageBox(wxT("项目名称不能为空"), wxT("错误"), wxOK | wxICON_ERROR, this);
|
||||
return;
|
||||
}
|
||||
|
||||
wxString destDir = wxFileName::DirName(targetPath).GetFullPath();
|
||||
destDir += wxFileName::GetPathSeparator() + projectName;
|
||||
destDir = Normalize(destDir);
|
||||
|
||||
if (wxDirExists(destDir)) {
|
||||
wxMessageBox(wxString::Format(wxT("目标目录已存在:\n%s"), destDir), wxT("错误"), wxOK | wxICON_ERROR, this);
|
||||
return;
|
||||
}
|
||||
|
||||
wxString sourceDir = configDir_ + wxFileName::GetPathSeparator() + curFileTitle_->GetLabelText();
|
||||
sourceDir = Normalize(sourceDir);
|
||||
if (!wxDirExists(sourceDir)) {
|
||||
wxMessageBox(wxString::Format(wxT("源目录不存在:\n%s"), sourceDir), wxT("错误"), wxOK | wxICON_ERROR, this);
|
||||
return;
|
||||
}
|
||||
if (!wxFileName::Mkdir(destDir, 0755, wxPATH_MKDIR_FULL)) {
|
||||
wxMessageBox(wxString::Format(wxT("无法创建目录:\n%s"), destDir), wxT("错误"), wxOK | wxICON_ERROR, this);
|
||||
return;
|
||||
}
|
||||
|
||||
wxDir dir(sourceDir);
|
||||
wxString filename;
|
||||
bool success = true;
|
||||
wxString errorFile;
|
||||
|
||||
if (dir.GetFirst(&filename, wxEmptyString, wxDIR_FILES | wxDIR_DIRS)) {
|
||||
do {
|
||||
wxString sourceItem = sourceDir + wxFileName::GetPathSeparator() + filename;
|
||||
wxString destItem = destDir + wxFileName::GetPathSeparator() + filename;
|
||||
sourceItem = Normalize(sourceItem);
|
||||
destItem = Normalize(destItem);
|
||||
|
||||
if (wxDirExists(sourceItem)) {
|
||||
if (!wxFileName::Mkdir(destItem, 0755, wxPATH_MKDIR_FULL)) {
|
||||
success = false;
|
||||
errorFile = filename;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!CopyDirectory(sourceItem, destItem, projectName)) {
|
||||
success = false;
|
||||
errorFile = filename;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (!wxCopyFile(sourceItem, destItem)) {
|
||||
success = false;
|
||||
errorFile = filename;
|
||||
break;
|
||||
}
|
||||
if (filename == wxT("CMakeLists.txt")) {
|
||||
ProcessCMakeListsFile(destItem, projectName);
|
||||
}
|
||||
}
|
||||
} while (success && dir.GetNext(&filename));
|
||||
}
|
||||
if (success) {
|
||||
wxMessageBox(wxString::Format(wxT("成功创建项目:\n%s\n并复制所有文件"), destDir), wxT("完成"), wxOK | wxICON_INFORMATION,
|
||||
this);
|
||||
} else {
|
||||
wxMessageBox(wxString::Format(wxT("复制文件失败:\n%s"), errorFile), wxT("错误"), wxOK | wxICON_ERROR, this);
|
||||
wxFileName::Rmdir(destDir, wxPATH_RMDIR_RECURSIVE);
|
||||
}
|
||||
SaveConfig();
|
||||
}
|
||||
|
||||
void MainFrame::OnExitClick(wxCommandEvent& event)
|
||||
{
|
||||
Close(true);
|
||||
}
|
||||
|
||||
void MainFrame::OnSelectPathClick(wxCommandEvent& event)
|
||||
{
|
||||
wxDirDialog dirDialog(this, wxT("选择工程创建所在目录"), textPath_->GetValue(), wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST);
|
||||
if (dirDialog.ShowModal() == wxID_OK) {
|
||||
wxString selectedPath = dirDialog.GetPath();
|
||||
textPath_->SetValue(selectedPath);
|
||||
}
|
||||
}
|
||||
|
||||
wxString MainFrame::GetConfigDir()
|
||||
{
|
||||
wxString exePath = wxStandardPaths::Get().GetExecutablePath();
|
||||
wxFileName exeFile(exePath);
|
||||
wxString parentDir = exeFile.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
|
||||
wxString configDir = parentDir + wxFileName::GetPathSeparator() + wxT("res");
|
||||
wxFileName configDirFile(configDir);
|
||||
configDirFile.Normalize(wxPATH_NORM_ALL);
|
||||
if (!configDirFile.DirExists()) {
|
||||
if (!wxFileName::Mkdir(configDirFile.GetFullPath(), 0755, wxPATH_MKDIR_FULL)) {
|
||||
wxLogError(wxT("无法创建配置目录: %s"), configDirFile.GetFullPath());
|
||||
return wxEmptyString;
|
||||
}
|
||||
wxLogMessage(wxT("已创建配置目录: %s"), configDirFile.GetFullPath());
|
||||
}
|
||||
return configDirFile.GetFullPath();
|
||||
}
|
||||
|
||||
void MainFrame::ShowConfig()
|
||||
{
|
||||
listBox_->Clear();
|
||||
if (configDir_.empty()) {
|
||||
wxMessageBox(wxT("配置目录路径为空"));
|
||||
return;
|
||||
}
|
||||
if (!wxDirExists(configDir_)) {
|
||||
if (!wxFileName::Mkdir(configDir_, 0755, wxPATH_MKDIR_FULL)) {
|
||||
wxMessageBox(wxString::Format(wxT("无法创建配置目录: %s"), configDir_));
|
||||
return;
|
||||
}
|
||||
wxMessageBox(wxString::Format(wxT("已创建配置目录: %s"), configDir_));
|
||||
}
|
||||
|
||||
wxDir dir(configDir_);
|
||||
if (!dir.IsOpened()) {
|
||||
wxMessageBox(wxString::Format(wxT("无法打开配置目录: %s"), configDir_));
|
||||
return;
|
||||
}
|
||||
|
||||
wxString dirName;
|
||||
bool cont = dir.GetFirst(&dirName, wxEmptyString, wxDIR_DIRS);
|
||||
while (cont) {
|
||||
wxString fullPath = configDir_ + wxFileName::GetPathSeparator() + dirName;
|
||||
if (wxDirExists(fullPath)) {
|
||||
listBox_->Append(dirName);
|
||||
int lastIndex = listBox_->GetCount() - 1;
|
||||
listBox_->SetClientData(lastIndex, new wxString(fullPath));
|
||||
}
|
||||
cont = dir.GetNext(&dirName);
|
||||
}
|
||||
}
|
||||
|
||||
void MainFrame::ShowConfig(wxCommandEvent& event)
|
||||
{
|
||||
ShowConfig();
|
||||
}
|
||||
|
||||
void MainFrame::OnListBoxSelected(wxCommandEvent& event)
|
||||
{
|
||||
wxString cmakeContent;
|
||||
int selection = listBox_->GetSelection();
|
||||
if (selection == wxNOT_FOUND) {
|
||||
return;
|
||||
}
|
||||
|
||||
wxString selectedText = listBox_->GetString(selection);
|
||||
wxString fullPath = configDir_ + wxFileName::GetPathSeparator() + selectedText;
|
||||
|
||||
if (!wxDirExists(fullPath)) {
|
||||
wxMessageBox(wxString::Format(wxT("目录不存在: %s"), fullPath), wxT("错误"), wxOK | wxICON_ERROR, this);
|
||||
return;
|
||||
}
|
||||
|
||||
curFileTitle_->SetLabel(selectedText);
|
||||
currentFilePath_ = fullPath + wxFileName::GetPathSeparator() + wxT("CMakeLists.txt");
|
||||
if (!wxFileExists(currentFilePath_)) {
|
||||
textCtrl_->SetValue(cmakeContent);
|
||||
return;
|
||||
}
|
||||
|
||||
wxFile cmakeFile(currentFilePath_);
|
||||
if (!cmakeFile.IsOpened()) {
|
||||
wxMessageBox(wxT("无法打开CMakeLists.txt文件"), wxT("错误"), wxOK | wxICON_ERROR, this);
|
||||
return;
|
||||
}
|
||||
|
||||
cmakeFile.ReadAll(&cmakeContent);
|
||||
cmakeFile.Close();
|
||||
textCtrl_->SetValue(cmakeContent);
|
||||
}
|
||||
|
||||
void MainFrame::InitCMakeSyntaxHighlighting()
|
||||
{
|
||||
textCtrl_->SetLexer(wxSTC_LEX_CMAKE);
|
||||
|
||||
// 基础样式配置
|
||||
textCtrl_->StyleSetForeground(wxSTC_CMAKE_DEFAULT, *wxBLACK);
|
||||
textCtrl_->StyleSetForeground(wxSTC_CMAKE_COMMENT, wxColour(0, 128, 0)); // 绿色注释
|
||||
|
||||
// 字符串类型
|
||||
textCtrl_->StyleSetForeground(wxSTC_CMAKE_STRINGDQ, wxColour(163, 21, 21)); // 红色双引号字符串
|
||||
textCtrl_->StyleSetForeground(wxSTC_CMAKE_STRINGLQ, wxColour(163, 21, 21)); // 红色左单引号
|
||||
textCtrl_->StyleSetForeground(wxSTC_CMAKE_STRINGRQ, wxColour(163, 21, 21)); // 红色右单引号
|
||||
|
||||
// 命令和参数
|
||||
textCtrl_->StyleSetForeground(wxSTC_CMAKE_COMMANDS, wxColour(0, 0, 255)); // 蓝色命令
|
||||
textCtrl_->StyleSetBold(wxSTC_CMAKE_COMMANDS, true);
|
||||
textCtrl_->StyleSetForeground(wxSTC_CMAKE_PARAMETERS, wxColour(255, 105, 0)); // 橙色参数
|
||||
|
||||
// 变量和数字
|
||||
textCtrl_->StyleSetForeground(wxSTC_CMAKE_VARIABLE, wxColour(128, 0, 128)); // 紫色变量
|
||||
textCtrl_->StyleSetForeground(wxSTC_CMAKE_STRINGVAR, wxColour(128, 0, 128)); // 紫色字符串变量
|
||||
textCtrl_->StyleSetForeground(wxSTC_CMAKE_NUMBER, wxColour(0, 100, 0)); // 深绿色数字
|
||||
|
||||
// 控制结构
|
||||
textCtrl_->StyleSetForeground(wxSTC_CMAKE_WHILEDEF, wxColour(0, 0, 139)); // 深蓝色while
|
||||
textCtrl_->StyleSetForeground(wxSTC_CMAKE_FOREACHDEF, wxColour(0, 0, 139)); // 深蓝色foreach
|
||||
textCtrl_->StyleSetForeground(wxSTC_CMAKE_IFDEFINEDEF, wxColour(0, 0, 139)); // 深蓝色if
|
||||
textCtrl_->StyleSetForeground(wxSTC_CMAKE_MACRODEF, wxColour(139, 0, 139)); // 深紫色宏
|
||||
|
||||
const char* cmakeCommands = "add_executable add_library target_link_libraries "
|
||||
"find_package if else endif foreach endfunction project cmake_minimum_required"
|
||||
"while endwhile macro endmacro function set add_compile_options";
|
||||
|
||||
textCtrl_->SetKeyWords(0, cmakeCommands);
|
||||
textCtrl_->StyleSetBackground(wxSTC_CMAKE_DEFAULT, wxColour(255, 255, 255));
|
||||
}
|
||||
|
||||
void MainFrame::SaveCurrent(wxCommandEvent& event)
|
||||
{
|
||||
if (currentFilePath_.empty()) {
|
||||
wxMessageBox(wxT("当前无配置选择"), wxT("提示"), wxOK | wxICON_ERROR, this);
|
||||
return;
|
||||
}
|
||||
wxFile cmakeFile(currentFilePath_, wxFile::write);
|
||||
if (!cmakeFile.IsOpened()) {
|
||||
wxMessageBox(wxT("无法打开CMakeLists.txt文件"), wxT("错误"), wxOK | wxICON_ERROR, this);
|
||||
return;
|
||||
}
|
||||
wxString content = textCtrl_->GetValue();
|
||||
if (!cmakeFile.Write(content)) {
|
||||
wxMessageBox(wxString::Format(wxT("写入文件失败: %s"), currentFilePath_), wxT("错误"), wxOK | wxICON_ERROR, this);
|
||||
cmakeFile.Close();
|
||||
return;
|
||||
}
|
||||
cmakeFile.Close();
|
||||
wxMessageBox(wxT("已保存"));
|
||||
}
|
||||
|
||||
void MainFrame::OnRightClick(wxCommandEvent& event)
|
||||
{
|
||||
wxMenu menu;
|
||||
bool hasSelection = (listBox_->GetSelection() != wxNOT_FOUND);
|
||||
menu.Append(addID_, wxT("添加"));
|
||||
menu.AppendSeparator();
|
||||
menu.Append(delID_, wxT("删除"))->Enable(hasSelection);
|
||||
listBox_->PopupMenu(&menu);
|
||||
}
|
||||
|
||||
void MainFrame::AddMenu(wxCommandEvent& event)
|
||||
{
|
||||
wxTextEntryDialog dialog(this, wxT("请输入新条目名称:"), wxT("添加新条目"), wxEmptyString, wxOK | wxCANCEL | wxCENTRE);
|
||||
if (dialog.ShowModal() != wxID_OK) {
|
||||
return;
|
||||
}
|
||||
wxString newItem = dialog.GetValue().Trim();
|
||||
if (newItem.IsEmpty()) {
|
||||
wxMessageBox(wxT("条目名称不能为空"), wxT("错误"), wxOK | wxICON_ERROR, this);
|
||||
return;
|
||||
}
|
||||
wxString newDir = configDir_ + wxFileName::GetPathSeparator() + newItem;
|
||||
|
||||
if (!wxFileName::Mkdir(newDir, 0755, wxPATH_MKDIR_FULL)) {
|
||||
wxMessageBox(wxT("无法创建目录: ") + newDir, wxT("错误"), wxOK | wxICON_ERROR, this);
|
||||
return;
|
||||
}
|
||||
|
||||
listBox_->Append(newItem);
|
||||
listBox_->SetSelection(listBox_->GetCount() - 1);
|
||||
curFileTitle_->SetLabel(newItem);
|
||||
currentFilePath_ = newDir + wxFileName::GetPathSeparator() + wxT("CMakeLists.txt");
|
||||
textCtrl_->SetValue(wxEmptyString);
|
||||
}
|
||||
|
||||
void MainFrame::DelMenu(wxCommandEvent& event)
|
||||
{
|
||||
int selection = listBox_->GetSelection();
|
||||
if (selection == wxNOT_FOUND) {
|
||||
return;
|
||||
}
|
||||
wxString selectedItem = listBox_->GetString(selection);
|
||||
wxString targetDir = Normalize(configDir_ + wxFileName::GetPathSeparator() + selectedItem);
|
||||
wxString msg = wxString::Format(wxT("确定要删除目录:\n%s\n及其所有内容吗?"), targetDir);
|
||||
|
||||
wxMessageDialog dlg(this, msg, wxT("确认删除"), wxYES_NO | wxNO_DEFAULT | wxICON_WARNING);
|
||||
|
||||
if (dlg.ShowModal() != wxID_YES) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (wxDirExists(targetDir)) {
|
||||
wxFileName::Rmdir(targetDir, wxPATH_RMDIR_RECURSIVE);
|
||||
listBox_->Delete(selection);
|
||||
ShowExist();
|
||||
} else {
|
||||
wxMessageBox(wxString::Format(wxT("目录 %s 不存在"), targetDir), wxT("错误"), wxOK | wxICON_ERROR, this);
|
||||
}
|
||||
}
|
||||
|
||||
void MainFrame::ShowExist()
|
||||
{
|
||||
if (!listBox_ || listBox_->IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
wxString firstItem = listBox_->GetString(0);
|
||||
listBox_->SetSelection(0);
|
||||
|
||||
wxString selectedText = firstItem;
|
||||
wxString fullPath = Normalize(configDir_ + wxFileName::GetPathSeparator() + selectedText);
|
||||
|
||||
if (!wxDirExists(fullPath)) {
|
||||
wxMessageBox(wxString::Format(wxT("目录不存在: %s"), fullPath), wxT("错误"), wxOK | wxICON_ERROR, this);
|
||||
return;
|
||||
}
|
||||
|
||||
wxString cmakeContent;
|
||||
curFileTitle_->SetLabel(selectedText);
|
||||
currentFilePath_ = Normalize(fullPath + wxFileName::GetPathSeparator() + wxT("CMakeLists.txt"));
|
||||
|
||||
if (!wxFileExists(currentFilePath_)) {
|
||||
textCtrl_->SetValue(cmakeContent);
|
||||
return;
|
||||
}
|
||||
|
||||
wxFile cmakeFile(currentFilePath_);
|
||||
if (!cmakeFile.IsOpened()) {
|
||||
wxMessageBox(wxT("无法打开CMakeLists.txt文件"), wxT("错误"), wxOK | wxICON_ERROR, this);
|
||||
return;
|
||||
}
|
||||
|
||||
cmakeFile.ReadAll(&cmakeContent);
|
||||
cmakeFile.Close();
|
||||
textCtrl_->SetValue(cmakeContent);
|
||||
}
|
||||
|
||||
void MainFrame::OpenDir(const wxString& path)
|
||||
{
|
||||
if (!wxDirExists(path)) {
|
||||
wxMessageBox(wxString::Format(wxT("目录不存在:\n%s"), path), wxT("错误"), wxOK | wxICON_ERROR, this);
|
||||
return;
|
||||
}
|
||||
|
||||
bool success = wxLaunchDefaultApplication(path);
|
||||
|
||||
if (!success) {
|
||||
#ifdef __WXMSW__
|
||||
wxString cmd = wxT("explorer \"") + path + wxT("\"");
|
||||
#elif defined(__WXMAC__)
|
||||
wxString cmd = wxT("open \"") + path + wxT("\"");
|
||||
#else // Linux/Unix
|
||||
wxString cmd = wxT("xdg-open \"") + path + wxT("\"");
|
||||
#endif
|
||||
success = wxExecute(cmd) != 0;
|
||||
}
|
||||
if (!success) {
|
||||
wxMessageBox(wxString::Format(wxT("无法打开目录:\n%s"), path), wxT("错误"), wxOK | wxICON_ERROR, this);
|
||||
}
|
||||
}
|
||||
|
||||
void MainFrame::OpenResDir(wxCommandEvent& event)
|
||||
{
|
||||
OpenDir(configDir_);
|
||||
}
|
||||
|
||||
void MainFrame::OpenPrjDir(wxCommandEvent& event)
|
||||
{
|
||||
OpenDir(textPath_->GetValue());
|
||||
}
|
||||
|
||||
wxString MainFrame::Normalize(const wxString& path)
|
||||
{
|
||||
wxFileName configDirFile(path);
|
||||
configDirFile.Normalize(wxPATH_NORM_ALL);
|
||||
return configDirFile.GetFullPath();
|
||||
}
|
||||
|
||||
void MainFrame::SaveConfig()
|
||||
{
|
||||
if (!wxFileName::DirExists(configDir_)) {
|
||||
if (!wxFileName::Mkdir(configDir_, 0755, wxPATH_MKDIR_FULL)) {
|
||||
wxLogError(wxT("无法创建配置目录: %s"), configDir_);
|
||||
return;
|
||||
}
|
||||
}
|
||||
wxString configFile = configDir_ + wxFileName::GetPathSeparator() + wxT("newproject.ini");
|
||||
wxFileConfig config(wxEmptyString, wxEmptyString, configFile, wxEmptyString, wxCONFIG_USE_LOCAL_FILE);
|
||||
config.Write(wxT("/Paths/TextPath"), textPath_->GetValue());
|
||||
config.Write(wxT("/Paths/ProjectName"), projectName_->GetValue());
|
||||
config.Flush();
|
||||
}
|
||||
|
||||
void MainFrame::LoadConfig()
|
||||
{
|
||||
wxString configFile = configDir_ + wxFileName::GetPathSeparator() + wxT("newproject.ini");
|
||||
if (!wxFileName::FileExists(configFile)) {
|
||||
return;
|
||||
}
|
||||
wxFileConfig config(wxEmptyString, wxEmptyString, configFile, wxEmptyString, wxCONFIG_USE_LOCAL_FILE);
|
||||
wxString textPath, projectName;
|
||||
if (config.Read(wxT("/Paths/TextPath"), &textPath)) {
|
||||
textPath_->SetValue(textPath);
|
||||
}
|
||||
if (config.Read(wxT("/Paths/ProjectName"), &projectName)) {
|
||||
projectName_->SetValue(projectName);
|
||||
}
|
||||
}
|
||||
|
||||
bool MainFrame::CopyDirectory(const wxString& source, const wxString& dest, const wxString& projectName)
|
||||
{
|
||||
wxDir dir(source);
|
||||
wxString filename;
|
||||
bool success = true;
|
||||
|
||||
if (dir.GetFirst(&filename, wxEmptyString, wxDIR_FILES | wxDIR_DIRS)) {
|
||||
do {
|
||||
wxString sourceItem = source + wxFileName::GetPathSeparator() + filename;
|
||||
wxString destItem = dest + wxFileName::GetPathSeparator() + filename;
|
||||
sourceItem = Normalize(sourceItem);
|
||||
destItem = Normalize(destItem);
|
||||
|
||||
if (wxDirExists(sourceItem)) {
|
||||
if (!wxFileName::Mkdir(destItem, 0755, wxPATH_MKDIR_FULL)) {
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!CopyDirectory(sourceItem, destItem, projectName)) {
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (!wxCopyFile(sourceItem, destItem)) {
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (filename == wxT("CMakeLists.txt")) {
|
||||
ProcessCMakeListsFile(destItem, projectName);
|
||||
}
|
||||
}
|
||||
} while (success && dir.GetNext(&filename));
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
void MainFrame::ProcessCMakeListsFile(const wxString& filePath, const wxString& projectName)
|
||||
{
|
||||
wxFile file(filePath, wxFile::read);
|
||||
if (file.IsOpened()) {
|
||||
wxString content;
|
||||
file.ReadAll(&content);
|
||||
file.Close();
|
||||
|
||||
content.Replace(wxT("PJNAME"), projectName);
|
||||
|
||||
wxFile dest(filePath, wxFile::write);
|
||||
if (dest.IsOpened()) {
|
||||
dest.Write(content);
|
||||
dest.Close();
|
||||
} else {
|
||||
wxMessageBox(wxString::Format(wxT("无法打开文件进行修改: %s"), filePath));
|
||||
}
|
||||
} else {
|
||||
wxMessageBox(wxString::Format(wxT("无法读取源文件: %s"), filePath));
|
||||
}
|
||||
}
|
||||
62
src/mainframe.h
Normal file
62
src/mainframe.h
Normal file
@@ -0,0 +1,62 @@
|
||||
#ifndef MAINFRAME_H
|
||||
#define MAINFRAME_H
|
||||
|
||||
#include <wx/button.h>
|
||||
#include <wx/listbox.h>
|
||||
#include <wx/stc/stc.h>
|
||||
#include <wx/textctrl.h>
|
||||
#include <wx/wx.h>
|
||||
|
||||
class MainFrame : public wxFrame
|
||||
{
|
||||
public:
|
||||
explicit MainFrame(const wxString& title);
|
||||
|
||||
private:
|
||||
void InitControl();
|
||||
|
||||
private:
|
||||
void OnNewerClick(wxCommandEvent& event);
|
||||
void OnExitClick(wxCommandEvent& event);
|
||||
void OnSelectPathClick(wxCommandEvent& event);
|
||||
wxString GetConfigDir();
|
||||
void ShowConfig(wxCommandEvent& event);
|
||||
void ShowConfig();
|
||||
void OnListBoxSelected(wxCommandEvent& event);
|
||||
void InitCMakeSyntaxHighlighting();
|
||||
void SaveCurrent(wxCommandEvent& event);
|
||||
void OnRightClick(wxCommandEvent& event);
|
||||
void AddMenu(wxCommandEvent& event);
|
||||
void DelMenu(wxCommandEvent& event);
|
||||
void ShowExist();
|
||||
void OpenResDir(wxCommandEvent& event);
|
||||
void OpenPrjDir(wxCommandEvent& event);
|
||||
wxString Normalize(const wxString& path);
|
||||
void SaveConfig();
|
||||
void LoadConfig();
|
||||
bool CopyDirectory(const wxString& source, const wxString& dest, const wxString& projectName);
|
||||
void ProcessCMakeListsFile(const wxString& filePath, const wxString& projectName);
|
||||
void OpenDir(const wxString& path);
|
||||
|
||||
private:
|
||||
wxListBox* listBox_;
|
||||
wxStyledTextCtrl* textCtrl_;
|
||||
wxButton* btnNewer_;
|
||||
wxButton* btnExit_;
|
||||
wxButton* btnSelectPath_;
|
||||
wxTextCtrl* textPath_;
|
||||
wxString configDir_;
|
||||
wxTextCtrl* projectName_;
|
||||
wxButton* btnRefresh_;
|
||||
wxButton* btnSave_;
|
||||
wxString currentFilePath_;
|
||||
wxStaticText* curFileTitle_;
|
||||
wxButton* btnOpenResDir_;
|
||||
wxButton* btnOpenPrjDir_;
|
||||
|
||||
private:
|
||||
wxWindowID addID_;
|
||||
wxWindowID delID_;
|
||||
};
|
||||
|
||||
#endif // MAINFRAME_H
|
||||
Reference in New Issue
Block a user