📄 mainwidget.cpp
字号:
// FILE: mainwidget.cpp// DESCRIPTION: Main widget implementation.// AUTHOR: James Martin (boolean_machine@yahoo.com)#include "hidedefs.h"#include "portdef.h"#include "hplinkdef.h"#include "langdef.h"#include "newprojdlg.h"#include "makemgr.h"#include "confmgr.h"#include "remfiledlg.h"#include "projconfdlg.h"#include "custtooldlg.h"#include "gotolinedlg.h"#include "finddlg.h"#include "aboutdlg.h"#include "editorsettingsdlg.h"#include "globalsettingsdlg.h"#include "hexview.h"#include "srcgen.h"#include "qprogressdialog.h"#include "classbrowser.h"#include "mainwidget.h"#include <qfiledialog.h>#include <qmessagebox.h>#include <qfont.h>#include <qfileinfo.h>#include <qlistbox.h>#include <qinputdialog.h>#include <qpixmap.h>#include <qapplication.h>#include <qdir.h>#include <new>#include <cstdlib>#define STATUS_LINE "Line: "#define STATUS_COL "Col: "#define STATUS_PROJ ""#define DOC_MOD_FLAG "*"#define CUSTTOOL_MAX 8#include "hideicon.xpm"#include "projicon.xpm"// Constructor.MainWidget::MainWidget(QWidget *parent, const char *name) : QVBox(parent, name){ // Initialize data members... m_bOpenFile = m_bOpenProj = false; m_CurCmd = m_HidePath = ""; m_hidemain = NULL; m_BuildMgr = NULL; m_DocList = NULL; m_status = NULL; m_LineNum = NULL; m_menu = NULL; m_menuTools = NULL; m_custtools = 0; setCaption(APP_TITLE); // Make sure this user has a "$HOME/.hide" directory... QString hpath = (QString) getenv("HOME") + FILE_SEP + ".hide"; QFileInfo fi(hpath); if (!fi.exists()) { QDir d; d.mkdir(hpath); d.mkdir((QString) hpath + FILE_SEP + "conf"); d.mkdir((QString) hpath + FILE_SEP + "tmp"); } m_HidePath = hpath; // Check if the HIDEPATH environment variable is set... if (!getenv("HIDEPATH")) { QMessageBox::warning(this, "hIDE", "The HIDEPATH environment variable has not been set."); } // Set the apps main icon. setIcon(QPixmap(const_cast<const char **>(hideicon))); // Create "File" menu... QPopupMenu *file = new QPopupMenu(this, "menu_file"); file->insertItem("&New..", this, SLOT(fileNew()), CTRL+Key_N, MENU_FILE_NEW); file->insertItem("&Open", this, SLOT(fileOpen()), CTRL+Key_O, MENU_FILE_OPEN); file->insertItem("&Save", this, SLOT(fileSave()), CTRL+Key_S, MENU_FILE_SAVE); file->insertItem("Save &As...", this, SLOT(fileSaveAs()), 0, MENU_FILE_SAVEAS); file->insertItem("Save All", this, SLOT(fileSaveAll()), 0, MENU_FILE_SAVEALL); file->insertItem("&Close", this, SLOT(fileClose()), CTRL+Key_Q, MENU_FILE_CLOSE); file->insertItem("Close All", this, SLOT(fileCloseAll()), 0, MENU_FILE_CLOSEALL); // Create "Edit" menu... QPopupMenu *edit = new QPopupMenu(this, "menu_edit"); edit->insertItem("Make &Uppercase", this, SLOT(editUppercase()), CTRL+Key_U, MENU_EDIT_UPPERCASE); edit->insertItem("Make &Lowercase", this, SLOT(editLowercase()), CTRL+Key_L, MENU_EDIT_LOWERCASE); edit->insertSeparator(); edit->insertItem("&Goto Line...", this, SLOT(editGotoLine()), CTRL+Key_G, MENU_EDIT_GOTOLINE); edit->insertItem("&Find...", this, SLOT(editFind()), CTRL+Key_F, MENU_EDIT_FIND); // Create "View" menu... QPopupMenu *view = new QPopupMenu(this, "menu_view"); view->insertItem("&Status Bar", this, SLOT(viewStatusBar()), 0, MENU_VIEW_STATUSBAR); view->insertItem("&Build Window", this, SLOT(viewBuildWnd()), 0, MENU_VIEW_BUILD); view->insertSeparator(); view->insertItem("Big &Edit Mode", this, SLOT(viewBigEdit()), CTRL+Key_B, MENU_VIEW_BIGEDIT); view->insertSeparator(); view->insertItem("&Hex...", this, SLOT(viewHex()), 0, MENU_VIEW_HEX); view->insertSeparator(); view->insertItem("&Next File", this, SLOT(viewNext()), CTRL+Key_N, MENU_VIEW_NEXT); view->insertItem("&Previous File", this, SLOT(viewPrev()), CTRL+Key_P, MENU_VIEW_PREV); view->setCheckable(true); // Create "Project" menu... QPopupMenu *proj = new QPopupMenu(this, "menu_project"); proj->insertItem("&New..", this, SLOT(projNew()), 0, MENU_PROJ_NEW); proj->insertItem("&Open...", this, SLOT(projOpen()), 0, MENU_PROJ_OPEN); proj->insertItem("&Save", this, SLOT(projSave()), 0, MENU_PROJ_SAVE); proj->insertItem("&Close", this, SLOT(projClose()), 0, MENU_PROJ_CLOSE); proj->insertSeparator(); proj->insertItem("&Add File...", this, SLOT(projAddFile()), 0, MENU_PROJ_ADDFILE); proj->insertItem("Add New F&ile...", this, SLOT(projAddNewFile()), 0, MENU_PROJ_ADDNEWFILE); proj->insertItem("&Remove File...", this, SLOT(projRemFile()), 0, MENU_PROJ_REMFILE); proj->insertSeparator(); proj->insertItem("&Build", this, SLOT(projBuild()), Key_F7, MENU_PROJ_BUILD); proj->insertSeparator(); proj->insertItem("&Config...", this, SLOT(projConfig()), 0, MENU_PROJ_CONF); // Create "C\C++" menu... QPopupMenu *cpp = new QPopupMenu(this, "menu_cpp"); cpp->insertItem("&Compile...", this, SLOT(cppCompile()), CTRL+Key_F7, MENU_CPP_COMPILE); cpp->insertItem("&Make", this, SLOT(cppMake()), CTRL+Key_M, MENU_CPP_MAKE); cpp->insertItem("C&lean", this, SLOT(cppClean()), 0, MENU_CPP_CLEAN); // Create "Java" menu... QPopupMenu *java = new QPopupMenu(this, "menu_java"); java->insertItem("&Compile...", this, SLOT(javaCompile()), CTRL+Key_J, MENU_JAVA_COMPILE); java->insertItem("&Execute...", this, SLOT(javaExecute()), CTRL+Key_E, MENU_JAVA_EXE); java->insertItem("Execute (&Applet)...", this, SLOT(javaExecuteApplet()), 0, MENU_JAVA_EXEAPPLET); java->insertItem("&Debug...", this, SLOT(javaDebug()), 0, MENU_JAVA_DEBUG); java->insertItem("&JNI Header", this, SLOT(javaJNI()), 0, MENU_JAVA_JNI); // Create "Settings" menu... QPopupMenu *settings = new QPopupMenu(this, "menu_settings"); settings->insertItem("&Editor...", this, SLOT(settingEditor()), 0, MENU_SETTINGS_EDITOR); settings->insertItem("&Custom Tools...", this, SLOT(settingCustTools()), 0, MENU_SETTINGS_CUSTTOOLS); settings->insertItem("&Global...", this, SLOT(settingGlobal()), 0, MENU_SETTINGS_GLOBAL); // Create "Help" menu... QPopupMenu *help = new QPopupMenu(this, "menu_help"); help->insertItem("&About...", this, SLOT(helpAbout())); // Create the menu bar and add all the menu items... m_menu = new QMenuBar(this, "mainMenubar"); m_menu->insertItem("&File", file); m_menu->insertItem("&Edit", edit); m_menu->insertItem("&View", view); m_menu->insertItem("&Project", proj); initCustTools(); // Create\intialize "Tools" menu. m_menu->insertItem("&C\\C++", cpp); m_menu->insertItem("&Java", java); m_menu->insertItem("&Settings", settings); m_menu->insertItem("&Help", help); m_menu->setItemChecked(MENU_VIEW_STATUSBAR, true); EditorConfMgr ecm; if (!ecm.load()) // Missing "editor" file, set defaults... { ecm.setFontSize(14); ecm.save(); } GlobalConfMgr gcm; if (!gcm.load()) // Missing "global" file, set defaults... { gcm.setOpenLastProj(false); gcm.save(); } // Create the main hIDE working area window. m_hidemain = new HideMain(this, "hidemain", ecm.getFontSize()); m_hidemain->setMaximumHeight(5000); // Initially hide the build window. showBuildWnd(false); // Create the status bar. m_status = new QStatusBar(this, "status_main"); m_status->setMaximumHeight(20); // Create status bar labels... m_ColNum = new QLabel(m_status); m_LineNum = new QLabel(m_status); m_ProjName = new QLabel(m_status); m_SrcType = new QLabel(m_status); m_ColNum->setText(STATUS_COL); m_LineNum->setText(STATUS_LINE); m_ProjName->setText(STATUS_PROJ); m_SrcType->setText(""); // Create project icon... QLabel *lblProj = new QLabel("Project", m_status); lblProj->setPixmap(QPixmap(const_cast<const char **>(projicon))); lblProj->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); // Add the labels to the status bar... m_status->addWidget(m_SrcType, 0, 1); m_status->addWidget(lblProj, 0, 1); m_status->addWidget(m_ProjName, 1, 1); m_status->addWidget(m_LineNum, 1, 1); m_status->addWidget(m_ColNum, 1, 1); m_ColNum->setFixedWidth(60); m_LineNum->setFixedWidth(75); m_ProjName->setFixedWidth(125); m_SrcType->setFixedWidth(90); // Create the build manager object. m_BuildMgr = new BuildMgr; // Map signals\slots... connect(m_hidemain->getSrcList(), SIGNAL(clicked(QListBoxItem*)), this, SLOT(srcSelChanged(QListBoxItem*))); connect(m_hidemain->getSrcList(), SIGNAL(selectionChanged(QListBoxItem*)), this, SLOT(srcSelChanged(QListBoxItem*))); connect(m_hidemain->getEdit(), SIGNAL(textChanged()), this, SLOT(docModified())); connect(m_hidemain->getEdit(), SIGNAL(returnPressed()), this, SLOT(onEnter())); connect(m_hidemain->getEdit(), SIGNAL(cursorPositionChanged(int,int)), this, SLOT(updateLine(int,int))); connect(m_BuildMgr, SIGNAL(compileDone()), this, SLOT(compileDone())); connect(m_BuildMgr, SIGNAL(makeDone()), this, SLOT(makeDone())); connect(m_BuildMgr, SIGNAL(cmdDone()), this, SLOT(cmdDone())); m_DocList = new HideDocList; // Initially disable all tools... enableProjectTools(false); enableBuildTools(false); enableFileTools(false); enableEditTools(false); enableCustTools(false); if (gcm.canOpenLastProj()) openProject(gcm.getLastProj());}// Destructor.MainWidget::~MainWidget(){ if (m_DocList) delete m_DocList; if (m_BuildMgr) delete m_BuildMgr;}// Opens a file in the editor based on a path.void MainWidget::fileOpen(const QString &path){ QString data = ""; QFileInfo fi; char *buff = 0; std::ifstream in((const char *) path); // If the file doesn't exist return... if (!in) return; fi.setFile(path); unsigned size = fi.size(); // Get the size of the file. if (size) { // If allocation fails return... if ((buff = new char[size+1]) == 0) return; memset(buff, 0x00, size+1); in.read(buff, size); data = buff; delete [] buff; } in.close(); HideDoc cur = m_CurDoc; // Back up the current document. // If a document's open, update its data status... if (m_bOpenFile) { m_CurDoc.setData(m_hidemain->getContent()); m_DocList->update(m_CurDoc); } else enableFileTools(true); // Set the newly opened file as the current document. m_CurDoc.set(path, fi.fileName(), data); m_CurDoc.setModified(false); // If the document's already open, restore the original & return... if (!m_DocList->add(m_CurDoc)) { m_CurDoc = cur; return; } // Display the current document in the editor. showDoc(); // Put the documents title in the file listbox. m_hidemain->addDoc(m_CurDoc); m_bOpenFile = true; QListBox *lb = m_hidemain->getSrcList(); lb->setSelected(lb->findItem(m_CurDoc.getName()), true); // Set the window title to contain the document title. setTitle(m_CurDoc.getName()); fi.setFile(m_CurDoc.getName()); if (IS_CPP(fi.extension(0))) { CppBrowser cb(m_hidemain->getClassTree()); cb.enumerate(m_CurDoc.getData()); } else if (IS_JAVA(fi.extension(0))) { JavaBrowser jb(m_hidemain->getClassTree()); jb.enumerate(m_CurDoc.getData()); }}// Save the current document to a path.void MainWidget::fileSave(const QString &path){ QFileInfo fi; QString bytes; std::ofstream out; if (!m_CurDoc.isModified()) { m_status->message((QString) "No save required for " + m_CurDoc.getName(), 5000); return; } out.open((const char *) path); // Open\create the file. // If no file was created, return. if (!out) return; // Update the document object with the contents of the editor. m_CurDoc.setData(m_hidemain->getContent()); // Is being saved so it is no longer considered modified. m_CurDoc.setModified(0); // Update the document object in the list. m_DocList->update(m_CurDoc); // Write the data to the file. out << (const char *) m_CurDoc.getData(); // Close the file output stream. out.close(); // Set the window title to contain the document title. setTitle(m_CurDoc.getName()); fi.setFile(m_CurDoc.getPath()); bytes.setNum(fi.size()); m_status->message((QString) m_CurDoc.getName() + " saved (" + bytes + " bytes written)", 5000); CppBrowser cb(m_hidemain->getClassTree()); cb.enumerate(m_DocList);}void MainWidget::setTitle(){ setCaption(APP_TITLE);}void MainWidget::setTitle(QString msg){ setCaption((QString) APP_TITLE + " - " + msg);}void MainWidget::showDoc(){ QString line = "", ext = ""; bool wuzmod = m_CurDoc.isModified(); QFileInfo fi; // Put the documents data in the editor. m_hidemain->setContent(m_CurDoc); // Restore modification state. m_CurDoc.setModified(wuzmod); line.setNum(m_hidemain->getCurLineNum()); line = (QString) STATUS_LINE + line; m_LineNum->setText(line); if (m_CurCmd != "") return; enableBuildTools(false); // Determine what tools should be enabled (if any)... fi.setFile(m_CurDoc.getPath()); ext = fi.extension(0); if (IS_C(ext) || IS_CPP(ext)) { if (IS_COMPILABLE_C(ext)) m_SrcType->setText("C"); else if (IS_COMPILABLE_CPP(ext)) m_SrcType->setText("C++"); else if (IS_HEADER(ext)) m_SrcType->setText("C\\C++ Header"); enableCppTools(true); } else if (IS_JAVA(ext)) { m_SrcType->setText("Java"); enableJavaTools(true); } else m_SrcType->setText(::getLang(ext)); enableEditTools(true); enableCustTools(true); m_hidemain->getEdit()->setContentsPos(0, 0); // Bug fix. // Determine "View->Next File"\"View->Prev File" status... QListBox *lb = m_hidemain->getSrcList(); int sel = lb->currentItem(); if (sel <= 0) m_menu->setItemEnabled(MENU_VIEW_PREV, false); else if (lb->numRows() > 1) m_menu->setItemEnabled(MENU_VIEW_PREV, true); if (sel < (lb->numRows() - 1)) m_menu->setItemEnabled(MENU_VIEW_NEXT, true); else m_menu->setItemEnabled(MENU_VIEW_NEXT, false); }QString MainWidget::getHPLinkData(){ QString res = ""; QString fpath = ""; std::ifstream in; char line[2056]; if (m_HidePath == "") { res = "HIDEPATH environment variable has not been set."; QMessageBox::warning(this, "hIDE", res); return ""; } fpath = (QString) m_HidePath + FILE_SEP + "tmp" + FILE_SEP + HPL_FILE; in.open((const char *) fpath); if (!in) return ""; while (!in.eof()) { in.getline(line, sizeof(line)); if (in.eof()) break; res += (QString) line + "\n"; } in.close(); return res;}void MainWidget::enableBuildTools(bool enable){ enableCppTools(enable); enableJavaTools(enable);}void MainWidget::enableCppTools(bool enable){ m_menu->setItemEnabled(MENU_CPP_COMPILE, enable); m_menu->setItemEnabled(MENU_CPP_MAKE, enable); m_menu->setItemEnabled(MENU_CPP_CLEAN, enable);}void MainWidget::enableJavaTools(bool enable){ m_menu->setItemEnabled(MENU_JAVA_COMPILE, enable); m_menu->setItemEnabled(MENU_JAVA_EXE, enable); m_menu->setItemEnabled(MENU_JAVA_EXEAPPLET, enable); m_menu->setItemEnabled(MENU_JAVA_DEBUG, enable); m_menu->setItemEnabled(MENU_JAVA_JNI, enable);}void MainWidget::enableProjectTools(bool enable){ m_menu->setItemEnabled(MENU_PROJ_SAVE, enable); m_menu->setItemEnabled(MENU_PROJ_CLOSE, enable); m_menu->setItemEnabled(MENU_PROJ_BUILD, enable); m_menu->setItemEnabled(MENU_PROJ_CONF, enable); m_menu->setItemEnabled(MENU_PROJ_ADDFILE, enable); m_menu->setItemEnabled(MENU_PROJ_ADDNEWFILE, enable); m_menu->setItemEnabled(MENU_PROJ_REMFILE, enable);}void MainWidget::enableFileTools(bool enable){ m_menu->setItemEnabled(MENU_FILE_SAVE, enable); m_menu->setItemEnabled(MENU_FILE_SAVEAS, enable); m_menu->setItemEnabled(MENU_FILE_SAVEALL, enable); m_menu->setItemEnabled(MENU_FILE_CLOSE, enable); m_menu->setItemEnabled(MENU_FILE_CLOSEALL, enable);}// NOTE: Not for just the Edit menu, includes any tool used for docs.void MainWidget::enableEditTools(bool enable){ m_menu->setItemEnabled(MENU_EDIT_UPPERCASE, enable); m_menu->setItemEnabled(MENU_EDIT_LOWERCASE, enable); m_menu->setItemEnabled(MENU_EDIT_GOTOLINE, enable); m_menu->setItemEnabled(MENU_EDIT_FIND, enable); m_menu->setItemEnabled(MENU_VIEW_HEX, enable); m_menu->setItemEnabled(MENU_VIEW_NEXT, enable); m_menu->setItemEnabled(MENU_VIEW_PREV, enable);}void MainWidget::enableCustTools(bool enable){ for (unsigned i=0; i < m_CustToolMgr.getToolList()->count(); i++) m_menu->setItemEnabled((MENU_TOOLS_CUSTBASE+i), enable);}void MainWidget::showBuildWnd(bool show){ if (show) m_hidemain->getBuildEdit()->show(); else m_hidemain->getBuildEdit()->hide(); m_menu->setItemChecked(MENU_VIEW_BUILD, show);}bool MainWidget::initCustTools(){ if (!m_menuTools) { m_menuTools = new QPopupMenu(this, "tools_menu"); m_menu->insertItem("&Tools", m_menuTools); } else m_menuTools->clear(); QStringList *listAliases=0; QString path = ""; unsigned i=0; if (m_HidePath == "") { QMessageBox::warning(this, "hIDE", "Missing HIDEPATH environment variable."); return false; } path = (QString) m_HidePath + FILE_SEP + "conf" + FILE_SEP + "custtools"; if (!m_CustToolMgr.load((const char *) path)) return false; listAliases = m_CustToolMgr.getAliasList(); for (; i < listAliases->count(); i++) { // VERY redundant...does Qt have a function similar // to the JavaScript eval() call? switch (i) { case 0: m_menuTools->insertItem((*listAliases)[0], this, SLOT(toolsCust1()), 0, MENU_TOOLS_CUST1); break; case 1: m_menuTools->insertItem((*listAliases)[1], this, SLOT(toolsCust2()), 0, MENU_TOOLS_CUST2); break; case 2:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -