//----------------------------------------------------------------------------- // Copyright 2007 Jonathan Westhues // // This file is part of LDmicro. // // LDmicro 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. // // LDmicro 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 LDmicro. If not, see . //------ // // Common controls in the main window. The main window consists of the drawing // area, where the ladder diagram is displayed, plus various controls for // scrolling, I/O list, menus. // Jonathan Westhues, Nov 2004 //----------------------------------------------------------------------------- #include "linuxUI.h" #include //#include //#include #include #include #include #include #include "ldmicro.h" // status bar at the bottom of the screen, to display settings static QLabel* StatusBar[3]; // have to get back to the menus to gray/ungray, check/uncheck things static HMENU FileMenu; static HMENU EditMenu; static HMENU InstructionMenu; static HMENU ProcessorMenu; static HMENU SimulateMenu; static HMENU TopMenu; static HMENU Settings; static HMENU Compile; static HMENU Help; HMENU ScrollWindow; // Menu IDs QAction* NewMenu; QAction* OpenMenu; QAction* SaveMenu; QAction* SaveAsMenu; QAction* ExportMenu; QAction* ExitMenu; QAction* UndoMenu; QAction* RedoMenu; QAction* PushRungUpMenu; QAction* PushRungDownMenu; QAction* InsertRungBeforeMenu; QAction* InsertRungAfterMenu; QAction* DeleteElementMenu; QAction* DeleteRungMenu; QAction* InsertCommentMenu; QAction* InsertContactsMenu; QAction* InsertCoilMenu; QAction* InsertTonMenu; QAction* InsertTofMenu; QAction* InsertRtoMenu; QAction* InsertResMenu; QAction* InsertOsrMenu; QAction* InsertOsfMenu; QAction* InsertCtuMenu; QAction* InsertCtdMenu; QAction* InsertCtcMenu; QAction* InsertAddMenu; QAction* InsertSubMenu; QAction* InsertMulMenu; QAction* InsertDivMenu; QAction* InsertMovMenu; QAction* InsertReadAdcMenu; QAction* InsertSetPwmMenu; QAction* InsertUartSendMenu; QAction* InsertUartRecvMenu; QAction* InsertEquMenu; QAction* InsertNeqMenu; QAction* InsertGrtMenu; QAction* InsertGeqMenu; QAction* InsertLesMenu; QAction* InsertLeqMenu; QAction* InsertOpenMenu; QAction* InsertShortMenu; QAction* InsertMasterRlyMenu; QAction* InsertShiftRegMenu; QAction* InsertLutMenu; QAction* InsertFmtdStrMenu; QAction* InsertPersistMenu; QAction* MakeNormalMenu; QAction* NegateMenu; QAction* MakeSetOnlyMenu; QAction* MakeResetOnlyMenu; QAction* InsertPwlMenu; QAction* McuSettingsMenu; QAction* ProcessorMenuItems[NUM_SUPPORTED_MCUS+1]; HMENU MicroControllerMenu; QAction* SimulationModeMenu; QAction* StartSimulationMenu; QAction* StopSimulationMenu; QAction* SingleCycleMenu; QAction* CompileMenu; QAction* CompileAsMenu; QAction* ManualMenu; QAction* AboutMenu; QActionGroup* ProcessorMenuGroup; // scrollbars for the ladder logic area // static HWND HorizScrollBar; // static HWND VertScrollBar; int ScrollWidth; int ScrollHeight; BOOL NeedHoriz; // listview used to maintain the list of I/O pins with symbolic names, plus // the internal relay too HLIST IoList; static int IoListSelectionPoint; static BOOL IoListOutOfSync; UINT IoListHeight = 100; int IoListTop; // whether the simulation is running in real time static BOOL RealTimeSimulationRunning; //----------------------------------------------------------------------------- // Ubuntu 14 on Vidyut does not handle Menu Shortcuts. // This function adds corresponding action for the shortcuts to the MainWindow //----------------------------------------------------------------------------- #if defined(__UBUNTU_14_) inline void SetKeyboardShortcuts() { MainWindow->addAction(NewMenu); MainWindow->addAction(OpenMenu); MainWindow->addAction(SaveMenu); MainWindow->addAction(SaveAsMenu); MainWindow->addAction(ExportMenu); MainWindow->addAction(UndoMenu); MainWindow->addAction(RedoMenu); MainWindow->addAction(InsertRungBeforeMenu); MainWindow->addAction(InsertRungAfterMenu); MainWindow->addAction(PushRungUpMenu); MainWindow->addAction(PushRungDownMenu); MainWindow->addAction(DeleteElementMenu); MainWindow->addAction(DeleteRungMenu); MainWindow->addAction(InsertCommentMenu); MainWindow->addAction(InsertContactsMenu); MainWindow->addAction(InsertOsrMenu); MainWindow->addAction(InsertOsfMenu); MainWindow->addAction(InsertTonMenu); MainWindow->addAction(InsertTofMenu); MainWindow->addAction(InsertRtoMenu); MainWindow->addAction(InsertCtuMenu); MainWindow->addAction(InsertCtdMenu); MainWindow->addAction(InsertCtcMenu); MainWindow->addAction(InsertEquMenu); MainWindow->addAction(InsertGrtMenu); MainWindow->addAction(InsertGeqMenu); MainWindow->addAction(InsertLesMenu); MainWindow->addAction(InsertLeqMenu); MainWindow->addAction(InsertCoilMenu); MainWindow->addAction(InsertResMenu); MainWindow->addAction(InsertMovMenu); MainWindow->addAction(InsertAddMenu); MainWindow->addAction(InsertSubMenu); MainWindow->addAction(InsertMulMenu); MainWindow->addAction(InsertDivMenu); MainWindow->addAction(InsertReadAdcMenu); MainWindow->addAction(MakeNormalMenu); MainWindow->addAction(NegateMenu); MainWindow->addAction(MakeSetOnlyMenu); MainWindow->addAction(MakeResetOnlyMenu); MainWindow->addAction(CompileMenu); MainWindow->addAction(ManualMenu); MainWindow->addAction(SimulationModeMenu); MainWindow->addAction(StartSimulationMenu); MainWindow->addAction(StopSimulationMenu); MainWindow->addAction(SingleCycleMenu); } #endif //----------------------------------------------------------------------------- // Create the top-level menu bar for the main window. Mostly static, but we // create the "select processor" menu from the list in mcutable.h dynamically. //----------------------------------------------------------------------------- HMENU MakeMainWindowMenus(void) { HMENU FileMenuSeparator; HMENU EditMenuSeparator; HMENU InstructionMenuSeparator; HMENU SimulateMenuSeparator; int i; // Create new menu bar to hold menu and add it to window // Creating various menus FileMenu = new QMenu("&File", MainWindow); EditMenu = new QMenu("&Edit", MainWindow); Settings = new QMenu("&Settings", MainWindow); ProcessorMenu = new QMenu("&Microcontroller", MainWindow); InstructionMenu = new QMenu("&Instructions", MainWindow); SimulateMenu = new QMenu("&Simulate", MainWindow); Compile = new QMenu("&Compile", MainWindow); Help = new QMenu("&Help", MainWindow); // Creating labels for File Menu NewMenu = new QAction("&New", NULL); NewMenu->setShortcuts(QKeySequence::New); // QKeySequence(Qt::CTRL + Qt::Key_N); OpenMenu = new QAction("&Open", NULL); OpenMenu->setShortcuts(QKeySequence::Open); SaveMenu = new QAction("&Save", NULL); SaveMenu->setShortcuts(QKeySequence::Save); SaveAsMenu = new QAction("&Save As", NULL); SaveAsMenu->setShortcuts(QKeySequence::SaveAs); ExportMenu = new QAction("&Export As Text", NULL); ExportMenu->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_E)); ExitMenu = new QAction("&Exit", NULL); // Appending menu items (labels) to File menu and adding separators FileMenu->addAction(NewMenu); FileMenu->addAction(OpenMenu); FileMenu->addAction(SaveMenu); FileMenu->addAction(SaveAsMenu); FileMenu->addSeparator(); FileMenu->addAction(ExportMenu); FileMenu->addSeparator(); FileMenu->addAction(ExitMenu); // Creating labels for Edit Menu UndoMenu = new QAction("&Undo", NULL); UndoMenu->setShortcuts(QKeySequence::Undo); RedoMenu = new QAction("&Redo", NULL); RedoMenu->setShortcuts(QKeySequence::Redo); InsertRungBeforeMenu = new QAction("&Insert Rung Before", NULL); InsertRungBeforeMenu->setShortcut(QKeySequence(Qt::SHIFT + Qt::Key_6)); InsertRungAfterMenu = new QAction("&Insert Rung After", NULL); InsertRungAfterMenu->setShortcut(QKeySequence(Qt::SHIFT + Qt::Key_V)); PushRungUpMenu = new QAction("&Move Selected Rung Up", NULL); PushRungUpMenu->setShortcut(QKeySequence(Qt::SHIFT + Qt::Key_Up)); PushRungDownMenu = new QAction("&Move Selected Rung Down", NULL); PushRungDownMenu->setShortcut(QKeySequence(Qt::SHIFT + Qt::Key_Down)); DeleteElementMenu = new QAction("&Delete Selected Element", NULL); DeleteElementMenu->setShortcut(QKeySequence(Qt::Key_Delete)); DeleteRungMenu = new QAction("&Delete Rung", NULL); DeleteRungMenu->setShortcut(QKeySequence(Qt::SHIFT + Qt::Key_Delete)); // Appending menu items to Edit menu and adding separators EditMenu->addAction(UndoMenu); EditMenu->addAction(RedoMenu); EditMenu->addSeparator(); EditMenu->addAction(InsertRungBeforeMenu); EditMenu->addAction(InsertRungAfterMenu); EditMenu->addAction(PushRungUpMenu); EditMenu->addAction(PushRungDownMenu); EditMenu->addSeparator(); EditMenu->addAction(DeleteElementMenu); EditMenu->addAction(DeleteRungMenu); // Creating labels for Settings Menu McuSettingsMenu = new QAction("&MCU Parameters...", MainWindow); MicroControllerMenu = new QMenu("&Microcontroller", MainWindow); ProcessorMenuGroup = new QActionGroup(MicroControllerMenu); // Appending menu items to Settings menu Settings->addAction(McuSettingsMenu); Settings->addMenu(MicroControllerMenu); // Appending the microcontroller names to "Microcontroller" item for (i = 0; i < NUM_SUPPORTED_MCUS; i++){ ProcessorMenuItems[i] = new QAction(SupportedMcus[i].mcuName, NULL); ProcessorMenuItems[i]->setCheckable(true); ProcessorMenuItems[i]->setActionGroup(ProcessorMenuGroup); MicroControllerMenu->addAction(ProcessorMenuItems[i]); } ProcessorMenuItems[i] = new QAction("(no microcontroller)", NULL); ProcessorMenuItems[i]->setCheckable(true); ProcessorMenuItems[i]->setActionGroup(ProcessorMenuGroup); MicroControllerMenu->addAction(ProcessorMenuItems[i]); // Creating labels for Instruction Menu and adding separators InsertCommentMenu = new QAction("&Insert Comment", MainWindow); InsertCommentMenu->setShortcut(QKeySequence(Qt::Key_Semicolon)); InsertContactsMenu = new QAction("&Insert Contacts", MainWindow); InsertContactsMenu->setShortcut(QKeySequence(Qt::Key_C)); InsertOsrMenu = new QAction("&Insert OSR (One Shot Rising)", MainWindow); InsertOsrMenu->setShortcut(QKeySequence(Qt::Key_Slash)); InsertOsfMenu = new QAction("&Insert OSF (One Shot Falling)", MainWindow); InsertOsfMenu->setShortcut(QKeySequence(Qt::Key_Backslash)); InsertTonMenu = new QAction("&Insert TON (Delayed Turn On)", MainWindow); InsertTonMenu->setShortcut(QKeySequence(Qt::Key_O)); InsertTofMenu = new QAction("&Insert TOF (Delayed Turn Off)", MainWindow); InsertTofMenu->setShortcut(QKeySequence(Qt::Key_F)); InsertRtoMenu = new QAction("&Insert RTO (Retentive Delayed Turn On)", MainWindow); InsertRtoMenu->setShortcut(QKeySequence(Qt::Key_T)); InsertCtuMenu = new QAction("&Insert CTU (Count Up)", MainWindow); InsertCtuMenu->setShortcut(QKeySequence(Qt::Key_U)); InsertCtdMenu = new QAction("&Insert CTD (Count Down)", MainWindow); InsertCtdMenu->setShortcut(QKeySequence(Qt::Key_I)); InsertCtcMenu = new QAction("&Insert CTC (Count Circular)", MainWindow); InsertCtcMenu->setShortcut(QKeySequence(Qt::Key_J)); InsertEquMenu = new QAction("&Insert EQU (Compare for Equals)", MainWindow); InsertEquMenu->setShortcut(QKeySequence(Qt::Key_Equal)); InsertNeqMenu = new QAction("&Insert NEQ (Compare for Not Equals)", MainWindow); InsertGrtMenu = new QAction("&Insert GRT (Compare for Greater Than)", MainWindow); InsertGrtMenu->setShortcut(QKeySequence(Qt::Key_Greater)); InsertGeqMenu = new QAction( "&Insert GEQ (Compare for Greater Than or Equal)", MainWindow); InsertGeqMenu->setShortcut(QKeySequence(Qt::Key_Period)); InsertLesMenu = new QAction( "&Insert LES (Compare for Less Than)", MainWindow); InsertLesMenu->setShortcut(QKeySequence(Qt::Key_Less)); InsertLeqMenu = new QAction( "&Insert LEQ (Compare for Less Than or Equal)", MainWindow); InsertLeqMenu->setShortcut(QKeySequence(Qt::Key_Comma)); InsertOpenMenu = new QAction("&Insert Open Circuit", MainWindow); InsertShortMenu = new QAction("&Insert Short Circuit", MainWindow); InsertMasterRlyMenu = new QAction( "&Insert Master Control Relay", MainWindow); InsertCoilMenu = new QAction("&Insert Coil", MainWindow); InsertCoilMenu->setShortcut(QKeySequence(Qt::Key_L)); InsertResMenu = new QAction("&Insert RES (Counter/RTO Reset)", MainWindow); InsertResMenu->setShortcut(QKeySequence(Qt::Key_E)); InsertMovMenu = new QAction("&Insert MOV (Move)", MainWindow); InsertMovMenu->setShortcut(QKeySequence(Qt::Key_M)); InsertAddMenu = new QAction("&Insert ADD (16-bit Integer Ad)", MainWindow); InsertAddMenu->setShortcut(QKeySequence(Qt::Key_Plus)); InsertSubMenu = new QAction( "&Insert SUB (16-bit Integer Subtract)", MainWindow); InsertSubMenu->setShortcut(QKeySequence(Qt::Key_Minus)); InsertMulMenu = new QAction( "&Insert MUL (16-bit Integer Multiply)", MainWindow); InsertMulMenu->setShortcut(QKeySequence(Qt::Key_Asterisk)); InsertDivMenu = new QAction( "&Insert DIV (16-bit Integer Division)", MainWindow); InsertDivMenu->setShortcut(QKeySequence(Qt::Key_D)); InsertShiftRegMenu = new QAction("&Insert Shift Register", MainWindow); InsertLutMenu = new QAction("&Insert Look-Up Table", MainWindow); InsertPwlMenu = new QAction("&Insert Piecewise Linear", MainWindow); InsertFmtdStrMenu = new QAction( "&Insert Formatted String Over UART", MainWindow); InsertUartSendMenu = new QAction("&Insert UART Send", MainWindow); InsertUartRecvMenu = new QAction("&Insert UART Receive", MainWindow); InsertSetPwmMenu = new QAction("&Insert Set PWM Output", MainWindow); InsertReadAdcMenu = new QAction("&Insert A/D Converter Read", MainWindow); InsertReadAdcMenu->setShortcut(QKeySequence(Qt::Key_P)); InsertPersistMenu = new QAction("&Insert Make Persistent", MainWindow); MakeNormalMenu = new QAction("&Make Normal", MainWindow); MakeNormalMenu->setShortcut(QKeySequence(Qt::Key_A)); NegateMenu = new QAction("&Make Negated", MainWindow); NegateMenu->setShortcut(QKeySequence(Qt::Key_N)); MakeSetOnlyMenu = new QAction("&Make Set-Only", MainWindow); MakeSetOnlyMenu->setShortcut(QKeySequence(Qt::Key_S)); MakeResetOnlyMenu = new QAction("&Make Reset-Only", MainWindow); MakeResetOnlyMenu->setShortcut(QKeySequence(Qt::Key_R)); // Appending menu items to Instruction menu and adding separators InstructionMenu->addAction(InsertCommentMenu); InstructionMenu->addSeparator(); InstructionMenu->addAction(InsertContactsMenu); InstructionMenu->addSeparator(); InstructionMenu->addAction(InsertOsrMenu); InstructionMenu->addSeparator(); InstructionMenu->addAction(InsertOsfMenu); InstructionMenu->addAction(InsertTonMenu); InstructionMenu->addAction(InsertTofMenu); InstructionMenu->addAction(InsertRtoMenu); InstructionMenu->addSeparator(); InstructionMenu->addAction(InsertCtuMenu); InstructionMenu->addAction(InsertCtdMenu); InstructionMenu->addAction(InsertCtcMenu); InstructionMenu->addSeparator(); InstructionMenu->addAction(InsertEquMenu); InstructionMenu->addAction(InsertNeqMenu); InstructionMenu->addAction(InsertGrtMenu); InstructionMenu->addAction(InsertGeqMenu); InstructionMenu->addAction(InsertLesMenu); InstructionMenu->addAction(InsertLeqMenu); InstructionMenu->addSeparator(); InstructionMenu->addAction(InsertOpenMenu); InstructionMenu->addAction(InsertShortMenu); InstructionMenu->addAction(InsertMasterRlyMenu); InstructionMenu->addSeparator(); InstructionMenu->addAction(InsertCoilMenu); InstructionMenu->addAction(InsertResMenu); InstructionMenu->addSeparator(); InstructionMenu->addAction(InsertMovMenu); InstructionMenu->addAction(InsertAddMenu); InstructionMenu->addAction(InsertSubMenu); InstructionMenu->addAction(InsertMulMenu); InstructionMenu->addAction(InsertDivMenu); InstructionMenu->addSeparator(); InstructionMenu->addAction(InsertShiftRegMenu); InstructionMenu->addAction(InsertLutMenu); InstructionMenu->addAction(InsertPwlMenu); InstructionMenu->addAction(InsertFmtdStrMenu); InstructionMenu->addSeparator(); InstructionMenu->addAction(InsertUartSendMenu); InstructionMenu->addAction(InsertUartRecvMenu); InstructionMenu->addAction(InsertSetPwmMenu); InstructionMenu->addAction(InsertReadAdcMenu); InstructionMenu->addAction(InsertPersistMenu); InstructionMenu->addSeparator(); InstructionMenu->addAction(MakeNormalMenu); InstructionMenu->addAction(NegateMenu); InstructionMenu->addAction(MakeSetOnlyMenu); InstructionMenu->addAction(MakeResetOnlyMenu); // Creating labels for Compile Menu CompileMenu = new QAction("&Compile", MainWindow); CompileMenu->setShortcut(QKeySequence(Qt::Key_F5)); CompileAsMenu = new QAction("Compile &As", MainWindow); // Appending menu items to Compile menu Compile->addAction(CompileMenu); Compile->addAction(CompileAsMenu); // Creating labels for Help Menu ManualMenu = new QAction("&Manual", MainWindow); ManualMenu->setShortcut(QKeySequence(Qt::Key_F1)); AboutMenu = new QAction("&About", MainWindow); // Appending menu items to Help menu Help->addAction(ManualMenu); Help->addAction(AboutMenu); // Creating labels for Simulation Menu SimulationModeMenu = new QAction("&Simulation Mode", MainWindow); SimulationModeMenu->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_M)); StartSimulationMenu = new QAction("&Start Real-Time Simulation", MainWindow); StartSimulationMenu->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_R)); StopSimulationMenu = new QAction("&Halt Simulation", MainWindow); StopSimulationMenu->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_H)); SingleCycleMenu = new QAction("&Single Cycle", MainWindow); SingleCycleMenu->setShortcut(QKeySequence(Qt::Key_Space)); // Appending menu items to Simulate menu and adding separators SimulateMenu->addAction(SimulationModeMenu); SimulateMenu->addAction(StartSimulationMenu); SimulateMenu->addAction(StopSimulationMenu); SimulateMenu->addAction(SingleCycleMenu); SimulateMenu->addSeparator(); // Appending the menu item to the menu bar MainMenu->addMenu(FileMenu); MainMenu->addMenu(EditMenu); MainMenu->addMenu(Settings); MainMenu->addMenu(InstructionMenu); MainMenu->addMenu(SimulateMenu); MainMenu->addMenu(Compile); MainMenu->addMenu(Help); #if defined(__UBUNTU_14_) SetKeyboardShortcuts(); #endif return FileMenu; } //----------------------------------------------------------------------------- // Create the standard Windows controls used in the main window: a Listview // for the I/O list, and a status bar for settings. //----------------------------------------------------------------------------- void MakeMainWindowControls(void) { QVBoxLayout* PackBoxMenu = new QVBoxLayout; QSplitter *splitter = new QSplitter(Qt::Orientation::Vertical); MainWindow->setLayout(PackBoxMenu); PackBoxMenu->setMenuBar(MainMenu); IoList = new QTreeWidget(); IoList->setColumnCount(IO_COLUMN_COUNT); IoList->setSelectionMode(QAbstractItemView::SingleSelection); QStringList ColumnNames = {"Name", "Type", "State", "Pin on Processor", "MCU Port"}; IoList->setHeaderLabels(ColumnNames); DrawWindow->setAutoFillBackground(true); QSize DWSize; scrollbar = new QScrollArea(); scrollbar->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); scrollbar->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); scrollbar->setFocusPolicy(Qt::NoFocus); DWSize.setHeight(MainWindow->height() - IoListHeight); DWSize.setWidth(MainWindow->width()); DrawWindow->setMinimumHeight(100); scrollbar->resize(DWSize); scrollbar->setWidget(DrawWindow); splitter->addWidget(scrollbar); DWSize.setWidth(MainWindow->width() - (scrollbar->sizeHint().width()+ MainWindow->sizeHint().width())); DrawWindow->resize(DWSize); DWSize.setHeight(IoListHeight); IoList->resize(DWSize); splitter->addWidget(IoList); QStatusBar* StatusGrid = new QStatusBar(MainWindow); PackBoxMenu->addWidget(splitter); for(int i = 0; i<3;i++) { StatusBar[i] = new QLabel(StatusGrid); StatusBar[i]->setText("LDMicro Started"); StatusGrid->addPermanentWidget(StatusBar[i], 1); } PackBoxMenu->addWidget(StatusGrid); } //----------------------------------------------------------------------------- // Adjust the size and visibility of the scrollbars as necessary, either due // to a change in the size of the program or a change in the size of the // window. //----------------------------------------------------------------------------- /*void RefreshScrollbars(void) { }*/ //----------------------------------------------------------------------------- // Set up the title bar text for the main window; indicate whether we are in // simulation or editing mode, and indicate the filename. //----------------------------------------------------------------------------- void UpdateMainWindowTitleBar(void) { char line[PATH_MAX+100]; if(InSimulationMode) { if(RealTimeSimulationRunning) { strcpy(line, "LDmicro - Simulation (Running)"); } else { strcpy(line, "LDmicro - Simulation (Stopped)"); } } else { strcpy(line, "LDmicro - Program Editor"); } if(strlen(CurrentSaveFile) > 0) { sprintf(line+strlen(line), " - %s", CurrentSaveFile); } else { strcat(line, " - (not yet saved)"); } // gtk_window_set_title (GTK_WINDOW (MainWindow), line); MainWindow->setWindowTitle(line); } //----------------------------------------------------------------------------- // Set the enabled state of the logic menu items to reflect where we are on // the schematic (e.g. can't insert two coils in series). //----------------------------------------------------------------------------- void SetMenusEnabled(BOOL canNegate, BOOL canNormal, BOOL canResetOnly, BOOL canSetOnly, BOOL canDelete, BOOL canInsertEnd, BOOL canInsertOther, BOOL canPushDown, BOOL canPushUp, BOOL canInsertComment) { EnableMenuItem(EditMenu, PushRungUpMenu, canPushUp ? MF_ENABLED : MF_GRAYED); EnableMenuItem(EditMenu, PushRungDownMenu, canPushDown ? MF_ENABLED : MF_GRAYED); EnableMenuItem(EditMenu, DeleteRungMenu, (Prog.numRungs > 1) ? MF_ENABLED : MF_GRAYED); EnableMenuItem(InstructionMenu, NegateMenu, canNegate ? MF_ENABLED : MF_GRAYED); EnableMenuItem(InstructionMenu, MakeNormalMenu, canNormal ? MF_ENABLED : MF_GRAYED); EnableMenuItem(InstructionMenu, MakeResetOnlyMenu, canResetOnly ? MF_ENABLED : MF_GRAYED); EnableMenuItem(InstructionMenu, MakeSetOnlyMenu, canSetOnly ? MF_ENABLED : MF_GRAYED); EnableMenuItem(InstructionMenu, InsertCommentMenu, canInsertComment ? MF_ENABLED : MF_GRAYED); EnableMenuItem(EditMenu, DeleteElementMenu, canDelete ? MF_ENABLED : MF_GRAYED); int t; t = canInsertEnd ? MF_ENABLED : MF_GRAYED; EnableMenuItem(InstructionMenu, InsertCoilMenu, t); EnableMenuItem(InstructionMenu, InsertResMenu, t); EnableMenuItem(InstructionMenu, InsertMovMenu, t); EnableMenuItem(InstructionMenu, InsertAddMenu, t); EnableMenuItem(InstructionMenu, InsertSubMenu, t); EnableMenuItem(InstructionMenu, InsertMulMenu, t); EnableMenuItem(InstructionMenu, InsertDivMenu, t); EnableMenuItem(InstructionMenu, InsertCtcMenu, t); EnableMenuItem(InstructionMenu, InsertPersistMenu, t); EnableMenuItem(InstructionMenu, InsertReadAdcMenu, t); EnableMenuItem(InstructionMenu, InsertSetPwmMenu, t); EnableMenuItem(InstructionMenu, InsertMasterRlyMenu, t); EnableMenuItem(InstructionMenu, InsertShiftRegMenu, t); EnableMenuItem(InstructionMenu, InsertLutMenu, t); EnableMenuItem(InstructionMenu, InsertPwlMenu, t); t = canInsertOther ? MF_ENABLED : MF_GRAYED; EnableMenuItem(InstructionMenu, InsertTonMenu, t); EnableMenuItem(InstructionMenu, InsertTofMenu, t); EnableMenuItem(InstructionMenu, InsertOsrMenu, t); EnableMenuItem(InstructionMenu, InsertOsfMenu, t); EnableMenuItem(InstructionMenu, InsertRtoMenu, t); EnableMenuItem(InstructionMenu, InsertContactsMenu, t); EnableMenuItem(InstructionMenu, InsertCtuMenu, t); EnableMenuItem(InstructionMenu, InsertCtdMenu, t); EnableMenuItem(InstructionMenu, InsertEquMenu, t); EnableMenuItem(InstructionMenu, InsertNeqMenu, t); EnableMenuItem(InstructionMenu, InsertGrtMenu, t); EnableMenuItem(InstructionMenu, InsertGeqMenu, t); EnableMenuItem(InstructionMenu, InsertLesMenu, t); EnableMenuItem(InstructionMenu, InsertLeqMenu, t); EnableMenuItem(InstructionMenu, InsertShortMenu, t); EnableMenuItem(InstructionMenu, InsertOpenMenu, t); EnableMenuItem(InstructionMenu, InsertUartSendMenu, t); EnableMenuItem(InstructionMenu, InsertUartRecvMenu, t); EnableMenuItem(InstructionMenu, InsertFmtdStrMenu, t); } //----------------------------------------------------------------------------- // Set the enabled state of the undo/redo menus. //----------------------------------------------------------------------------- void SetUndoEnabled(BOOL undoEnabled, BOOL redoEnabled) { EnableMenuItem(EditMenu, UndoMenu, undoEnabled ? MF_ENABLED : MF_GRAYED); EnableMenuItem(EditMenu, RedoMenu, redoEnabled ? MF_ENABLED : MF_GRAYED); } //----------------------------------------------------------------------------- // Toggle whether we are in simulation mode. A lot of options are only // available in one mode or the other. //----------------------------------------------------------------------------- void ToggleSimulationMode(void) { InSimulationMode = !InSimulationMode; if(InSimulationMode) { KillTimer(DrawWindow, TIMER_BLINK_CURSOR); EnableMenuItem(SimulateMenu, StartSimulationMenu, MF_ENABLED); EnableMenuItem(SimulateMenu, SingleCycleMenu, MF_ENABLED); EnableMenuItem(FileMenu, OpenMenu, MF_GRAYED); EnableMenuItem(FileMenu, SaveMenu, MF_GRAYED); EnableMenuItem(FileMenu, SaveAsMenu, MF_GRAYED); EnableMenuItem(FileMenu, NewMenu, MF_GRAYED); EnableMenuItem(FileMenu, ExportMenu, MF_GRAYED); EnableMenuItem(TopMenu, EditMenu, MF_GRAYED); EnableMenuItem(TopMenu, Settings, MF_GRAYED); EnableMenuItem(TopMenu, InstructionMenu, MF_GRAYED); EnableMenuItem(TopMenu, Compile, MF_GRAYED); CheckMenuItem(SimulateMenu, SimulationModeMenu, MF_CHECKED); ClearSimulationData(); // simulation.cpp, ldmicro.h // Recheck InSimulationMode, because there could have been a Compile // error, which would have kicked us out of simulation mode. if(UartFunctionUsed() && InSimulationMode) { ShowUartSimulationWindow(); // simulate.cpp } } else { RealTimeSimulationRunning = FALSE; KillTimer(DrawWindow, TIMER_SIMULATE); CursorTimer = SetTimer(DrawWindow, TIMER_BLINK_CURSOR, 500, CursorTimer); EnableMenuItem(SimulateMenu, StartSimulationMenu, MF_GRAYED); EnableMenuItem(SimulateMenu, StopSimulationMenu, MF_GRAYED); EnableMenuItem(SimulateMenu, SingleCycleMenu, MF_GRAYED); EnableMenuItem(FileMenu, OpenMenu, MF_ENABLED); EnableMenuItem(FileMenu, SaveMenu, MF_ENABLED); EnableMenuItem(FileMenu, SaveAsMenu, MF_ENABLED); EnableMenuItem(FileMenu, NewMenu, MF_ENABLED); EnableMenuItem(FileMenu, ExportMenu, MF_ENABLED); EnableMenuItem(TopMenu, EditMenu, MF_ENABLED); EnableMenuItem(TopMenu, Settings, MF_ENABLED); EnableMenuItem(TopMenu, InstructionMenu, MF_ENABLED); EnableMenuItem(TopMenu, Compile, MF_ENABLED); CheckMenuItem(SimulateMenu, SimulationModeMenu, MF_UNCHECKED); if(UartFunctionUsed()) { DestroyUartSimulationWindow(); } } UpdateMainWindowTitleBar(); RefreshControlsToSettings(); } //----------------------------------------------------------------------------- // Cause the status bar and the list view to be in sync with the actual data // structures describing the settings and the I/O configuration. Listview // does callbacks to get the strings it displays, so it just needs to know // how many elements to populate. //----------------------------------------------------------------------------- void RefreshControlsToSettings(void) { QTreeWidgetItem iter; QTreeWidgetItem* selection; if(!IoListOutOfSync) { selection = IoList->currentItem(); IoListSelectionPoint =IoList->indexOfTopLevelItem(selection); } NMHDR h; h.code = LVN_GETDISPINFO; h.hlistFrom = IoList; IoList->clear(); h.hlistIter.clear(); for(int i = 0; i < Prog.io.count; i++) { h.item.iItem = i; IoListProc(&h); } IoList->insertTopLevelItems(0, h.hlistIter); if(IoListSelectionPoint >= 0) { IoList->setCurrentItem(IoList->topLevelItem(IoListSelectionPoint)); } if(Prog.mcu) { StatusBar[0]->setText(Prog.mcu->mcuName); } else { StatusBar[0]->setText("no MCU selected"); } char buf[256]; sprintf(buf, _("cycle time %.2f ms"), (double)Prog.cycleTime/1000.0); StatusBar[1]->setText(buf); if(Prog.mcu && (Prog.mcu->whichIsa == ISA_ANSIC || Prog.mcu->whichIsa == ISA_INTERPRETED)) { strcpy(buf, ""); } else { sprintf(buf, _("processor clock %.4f MHz"), (double)Prog.mcuClock/1000000.0); } StatusBar[2]->setText(buf); for(int i = 0; i < NUM_SUPPORTED_MCUS; i++) { if(&SupportedMcus[i] == Prog.mcu) { CheckMenuItem(ProcessorMenu, ProcessorMenuItems[i], MF_CHECKED); } else { CheckMenuItem(ProcessorMenu, ProcessorMenuItems[i], MF_UNCHECKED); } } // `(no microcontroller)' setting if (!Prog.mcu){ CheckMenuItem(ProcessorMenu, ProcessorMenuItems[NUM_SUPPORTED_MCUS], MF_CHECKED); } else { CheckMenuItem(ProcessorMenu, ProcessorMenuItems[NUM_SUPPORTED_MCUS], MF_UNCHECKED); } } //----------------------------------------------------------------------------- // Regenerate the I/O list, keeping the selection in the same place if // possible. //----------------------------------------------------------------------------- void GenerateIoListDontLoseSelection(void) { QTreeWidgetItem* selection; selection = IoList->currentItem(); IoListSelectionPoint =IoList->indexOfTopLevelItem(selection); IoListSelectionPoint = GenerateIoList(IoListSelectionPoint); // can't just update the listview index; if I/O has been added then the // new selection point might be out of range till we refill it IoListOutOfSync = TRUE; RefreshControlsToSettings(); } //----------------------------------------------------------------------------- // Called when the main window has been resized. Adjust the size of the // status bar and the listview to reflect the new window size. //----------------------------------------------------------------------------- void MainWindowResized(void) { IoListTop = DrawWindow->height(); } //----------------------------------------------------------------------------- // Start real-time simulation. Have to update the controls grayed status // to reflect this. //----------------------------------------------------------------------------- void StartSimulation(void) { RealTimeSimulationRunning = TRUE; EnableMenuItem(SimulateMenu, StartSimulationMenu, MF_GRAYED); EnableMenuItem(SimulateMenu, StopSimulationMenu, MF_ENABLED); StartSimulationTimer(); UpdateMainWindowTitleBar(); } //----------------------------------------------------------------------------- // Stop real-time simulation. Have to update the controls grayed status // to reflect this. //----------------------------------------------------------------------------- void StopSimulation(void) { RealTimeSimulationRunning = FALSE; EnableMenuItem(SimulateMenu, StartSimulationMenu, MF_ENABLED); EnableMenuItem(SimulateMenu, StopSimulationMenu, MF_GRAYED); KillTimer(DrawWindow, TIMER_SIMULATE); UpdateMainWindowTitleBar(); }