Skip to content

Code Layout

thedjnK edited this page Apr 30, 2017 · 6 revisions

In UwTerminalX, the code is layed out seperately for each part of the GUI and function of the application, so for example; all functions that are part of the main window are in the main windows source file.

LrdLogger

LrdLogger.h and LrdLogger.cpp are both part of the file logging system, this handles opening a log file, writing data and the UTF-8 BOM to it and closing it. A function exists to allow retrieving the log filesize.

LrdScrollEdit

LrdScrollEdit.h and LrdScrollEdit.cpp are both part of the history-enabled input/output text box, which is based upon a QPlainTextEdit object. The functions in this class handle saving and retrieving the input data when using the up and down arrow keys and the sending/receiving of serial data to/from the main UwxMainWindow class. There is a define which controls the number of previous history items, and is set to 20 by default.

main

Standard Qt main.cpp file which launches the GUI as part of UwxMainWindow.cpp

UwxAutomation

UwxAutomation.h and UwxAutomation.cpp are part of the Automation GUI (UwxAutomation.ui is the Qt designer file for the GUI), the functions in here control sending data to the module when the various automation buttons are clicked, and handles loading/parsing/saving automation files. There is a define that controls if files are saved in UTF-8 format (with the UTF-8 BOM) and another define for the number of automation lines to support, which by default is set to 200.

UwxMainWindow

UwxMainWindow.h and UwxMainWindow.cpp are the main files of the whole project and control all the user interaction with the main GUI and with the serial port itself (UwxMainWindow.ui is the Qt desinger file for the GUI), the functions in here control all mannor of things including the XCompilation/file download state machine, user interaction/command sending from the right click menu, updating of statistics, and passing data to/from other classes.

This class is the most likely one where a change would be made, whether it is to add a new function or change an existing one.

An example would be to add a new function that interacts with the serial port, here is a step-by-step guide:

In UwxMainWindow.h:

Add a new define which includes a description of the function you are adding, to a define with a number on the end that is one higher than the previous mode define, e.g.

#define MODE_MY_MARVELLOUS_FUNCTION 18

In UwxMainWindow.cpp:

In the MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) function, the right click menu is created, add your new function to this menu in the relevant section or create a new section if desired, e.g.

gpSMenu1->addAction(new QAction("Magic Function", this));

In the MainWindow::on_text_TermEditData_customContextMenuRequested function, create a new entry for your menu item or copy an existing one and change the name and add your code, e.g.

else if (qaAction->text() == "Magic Function")
{
	//Description
	if (gspSerialPort.isOpen() == true && gbLoopbackMode == false && gbTermBusy == false)
	{
		//Serial port is open, loopback is disabled and it is not busy doing anything
		gspSerialPort.write("at+magic"); //This is the command to send to the module
		gintQueuedTXBytes += 8; //This is the length of the command you are sending
		DoLineEnd(); //This will send a line ending to the module, depending upon which line ending option has been selected
		gbaDisplayBuffer.append("\nat+magic\n"); //This adds the command text to the display buffer
		if (!gtmrTextUpdateTimer.isActive())
		{
			//This starts the background display update timer
			gtmrTextUpdateTimer.start();
		}
		gpMainLog->WriteLogData("at+magic\n"); //This logs the data that was sent and should match up **exactly** with what was sent.
		//This marks the program as busy and marks what it is currently doing
		gchTermMode = MODE_MY_MARVELLOUS_FUNCTION;
		gchTermMode2 = MODE_MY_MARVELLOUS_FUNCTION;
		gbTermBusy = true;
	}
}

The recieve data code can now be added to the MainWindow::readData function, search for the line containing else if (gbTermBusy == true && gchTermMode2 > 0 && gchTermMode2 < 20) And add a new section after the last function check, 'else if (gchTermMode2 == MODE_COMPILE_LOAD_RUN)', like so:

else if (gchTermMode2 == MODE_MY_MARVELLOUS_FUNCTION)
{
	//Add data to the display buffer
	gbaDisplayBuffer.append("\n-- We got a reponse from the module! --\n");
	if (!gtmrTextUpdateTimer.isActive())
	{
		//This starts the background display update timer
		gtmrTextUpdateTimer.start();
	}
}

There is just one final thing to add, and that's allowing the user to cancel this function by clicking the 'cancel' button. As this function doesn't do anything with a response, for this demonstration clicking the cancel button will just do some cleaning up. Search for the MainWindow::on_btn_Cancel_clicked function, and after the final else if statement; 'else if (gchTermMode == MODE_CHECK_ERROR_CODE_VERSIONS || gchTermMode == MODE_CHECK_UWTERMINALX_VERSIONS)' add:

else if (gchTermMode == MODE_MY_MARVELLOUS_FUNCTION)
{
	//Cancel the marvellous new function
	gbaDisplayBuffer.append("\nThe marvellous new function has been cancelled.\n");
	if (!gtmrTextUpdateTimer.isActive())
	{
		//This starts the background display update timer
		gtmrTextUpdateTimer.start();
	}

	//This cleans up and stops UwTerminalX from processing any response it recieves from the module
	gchTermMode = 0;
	gchTermMode2 = 0;
	gbTermBusy = false;
}

This brief overview shows how to add a simple new function. Refer to the existing code for examples of how to do more complex operations like interacting with the data received from the module and creating a state machine.

UwxPopup

UwxPopup.hand UwxPopup.cpp are part of the Popup message GUI (UwxPopup.ui is the Qt designer file for the GUI), there is really only a single function here which is used to change the message displayed on the GUI.