1414using SharedUtil::CalcMTASAPath;
1515using std::string;
1616
17- #define CONSOLE_HISTORY_LENGTH 128
18- #define CONSOLE_SIZE 4096
17+ #define CONSOLE_INPUT_HISTORY_LENGTH 128
18+ #define CONSOLE_SIZE 4096
1919
20- #define MAX_CONSOLE_COMMAND_LENGTH 255
20+ #define MAX_CONSOLE_COMMAND_LENGTH 255
2121
22- #define NATIVE_RES_X 1152 .0f
23- #define NATIVE_RES_Y 864 .0f
22+ #define NATIVE_RES_X 1152 .0f
23+ #define NATIVE_RES_Y 864 .0f
2424
2525CConsole::CConsole (CGUI* pManager, CGUIElement* pParent)
2626{
2727 // Store the GUI manager
2828 m_pManager = pManager;
2929
3030 // Create our history
31- m_pConsoleHistory = new CConsoleHistory (CONSOLE_HISTORY_LENGTH );
31+ m_pConsoleHistory = new CEntryHistory (CONSOLE_INPUT_HISTORY_LENGTH );
3232 m_iHistoryIndex = -1 ;
3333 m_iAutoCompleteIndex = -1 ;
3434 m_bIsEnabled = true ;
@@ -52,7 +52,7 @@ CConsole::CConsole(CGUI* pManager, CGUIElement* pParent)
5252 m_pHistory->SetTextChangedHandler (GUI_CALLBACK (&CConsole::History_OnTextChanged, this ));
5353
5454 // Load the console history from a file
55- m_pConsoleHistory->LoadFromFile ();
55+ m_pConsoleHistory->LoadFromFile (MTA_CONSOLE_INPUT_LOG_PATH );
5656}
5757
5858CConsole::~CConsole ()
@@ -111,7 +111,8 @@ void CConsole::Clear()
111111 if (m_pHistory)
112112 {
113113 m_pHistory->SetText (" " );
114- m_strPendingAdd = " " ;
114+ m_strPendingAdd.clear ();
115+ m_strSavedInputText.clear ();
115116 }
116117}
117118
@@ -214,12 +215,13 @@ bool CConsole::Edit_OnTextAccepted(CGUIElement* pElement)
214215 // Get the text object from our input window.
215216 strInput = m_pInput->GetText ();
216217
217- // Add the input text to the console history
218- m_pConsoleHistory->Add (strInput.c_str ());
218+ // If the input isn't empty and isn't identical to the previous entry in history, add it to the history
219+ if (!strInput.empty () && (m_pConsoleHistory->Empty () || m_pConsoleHistory->GetLast () != strInput))
220+ m_pConsoleHistory->Add (strInput.c_str ());
219221
220222 // Clear the input text.
221223 m_pInput->SetText (" " );
222- m_iHistoryIndex = - 1 ;
224+ ResetHistoryChanges () ;
223225
224226 // Add the text to the history buffer.
225227 // Echo ( strInput.c_str () );
@@ -251,7 +253,7 @@ void CConsole::GetCommandInfo(const string& strIn, string& strCmdOut, string& st
251253 else
252254 {
253255 strCmdOut = strIn.c_str ();
254- strCmdLineOut = " " ;
256+ strCmdLineOut. clear () ;
255257 }
256258}
257259
@@ -281,84 +283,67 @@ bool CConsole::GracefullyMoveEditboxCaret(CGUIElement* pElement)
281283 return true ;
282284}
283285
284- void CConsole::SetNextHistoryText ()
286+ void CConsole::ResetHistoryChanges ()
285287{
286- // Don't set history back if we aren't focused.
287- if (!m_pInput-> IsActive ())
288- {
289- return ;
290- }
288+ // Reset history selection, any history changes and our saved input
289+ m_iHistoryIndex = - 1 ;
290+ m_pConsoleHistory-> ResetChanges ();
291+ m_strSavedInputText. clear () ;
292+ }
291293
292- // Next index
293- if (m_iHistoryIndex == CONSOLE_HISTORY_LENGTH)
294- {
295- return ;
296- }
294+ void CConsole::SelectHistoryEntry (int iEntry)
295+ {
296+ int iPreviousHistoryIndex = m_iHistoryIndex;
297297
298- // Index too low?
299- if (m_iHistoryIndex < 0 )
300- {
301- m_iHistoryIndex = 0 ;
302- }
298+ // Check if we're in bounds, otherwise clear selection
299+ if (!m_pConsoleHistory->Empty () && iEntry >= 0 && iEntry < m_pConsoleHistory->Size ())
300+ m_iHistoryIndex = iEntry;
303301 else
304- {
305- ++m_iHistoryIndex;
306- }
302+ m_iHistoryIndex = -1 ;
307303
308- if (m_iHistoryIndex == 0 )
309- {
310- // Get the text object from our input window.
311- string strInput = m_pInput->GetText ();
312- // Add our current text to the console history
313- m_pConsoleHistory->Add (strInput.c_str ());
314- }
304+ SString strInputText = m_pInput->GetText ();
315305
316- // Grab the item and set the input text to it
317- const char * szItem = m_pConsoleHistory->Get (m_iHistoryIndex);
318- if (szItem)
319- {
320- GracefullySetEditboxText (szItem);
321- }
306+ // Save current input as a temporary input value
307+ if (iPreviousHistoryIndex == -1 )
308+ m_strSavedInputText = strInputText;
309+ else
310+ m_pConsoleHistory->Get (iPreviousHistoryIndex)->temp = strInputText;
311+
312+ // If we haven't selected any history entry, use our saved input text
313+ if (m_iHistoryIndex == -1 )
314+ GracefullySetEditboxText (m_strSavedInputText.c_str ());
322315 else
323316 {
324- --m_iHistoryIndex;
317+ SString& strSelectedInputHistoryEntry = m_pConsoleHistory->Get (m_iHistoryIndex)->temp ;
318+ GracefullySetEditboxText (strSelectedInputHistoryEntry.c_str ());
325319 }
326320}
327321
328- void CConsole::SetPreviousHistoryText ()
322+ bool CConsole::SetNextHistoryText ()
329323{
330- // Don't set history back if we aren't focused.
331- if (!m_pInput->IsActive ())
332- {
333- return ;
334- }
324+ // If we can't take input or we're at the end of the list, stop here
325+ if (!m_pInput->IsActive () || m_iHistoryIndex >= m_pConsoleHistory->Size () - 1 )
326+ return false ;
335327
336- // Previous index
337- if (m_iHistoryIndex <= 0 )
338- {
339- // Get the text object from our input window.
340- string strInput = m_pInput->GetText ();
341- const char * szInputText = strInput.c_str ();
342- // Do we currently have some text?
343- if (szInputText && szInputText[0 ])
344- {
345- // Add our current text to the console history
346- m_pConsoleHistory->Add (szInputText);
328+ // Select the previous entry
329+ SelectHistoryEntry (m_iHistoryIndex + 1 );
347330
348- // Clear our current text
349- m_pInput->SetText (" " );
350- --m_iHistoryIndex;
351- }
352- return ;
353- }
331+ return true ;
332+ }
354333
355- // Grab the item and set the input text to it
356- const char * szItem = m_pConsoleHistory->Get (m_iHistoryIndex - 1 );
357- if (szItem)
358- {
359- GracefullySetEditboxText (szItem);
360- --m_iHistoryIndex;
361- }
334+ bool CConsole::SetPreviousHistoryText ()
335+ {
336+ // If we can't take input, stop here
337+ if (!m_pInput->IsActive ())
338+ return false ;
339+
340+ // Select the next entry, or the default entry
341+ if (m_pConsoleHistory->Size () > 0 && m_iHistoryIndex > 0 )
342+ SelectHistoryEntry (m_iHistoryIndex - 1 );
343+ else
344+ SelectHistoryEntry (-1 );
345+
346+ return true ;
362347}
363348
364349void CConsole::ResetAutoCompleteMatch ()
@@ -380,8 +365,9 @@ void CConsole::SetNextAutoCompleteMatch()
380365 {
381366 // Step through the history
382367 int iIndex = -1 ;
383- while (const char * szItem = m_pConsoleHistory->Get (++iIndex))
368+ while (CEntryHistoryItem* pEntryHistoryItem = m_pConsoleHistory->Get (++iIndex))
384369 {
370+ const char * szItem = *pEntryHistoryItem;
385371 if (strlen (szItem) < 3 ) // Skip very short lines
386372 continue ;
387373
@@ -390,7 +376,10 @@ void CConsole::SetNextAutoCompleteMatch()
390376 {
391377 if (m_AutoCompleteList.size ()) // Dont add duplicates of the previously added line
392378 {
393- const char * szPrevItem = m_pConsoleHistory->Get (m_AutoCompleteList.at (m_AutoCompleteList.size () - 1 ));
379+ CEntryHistoryItem* pPrevEntryHistoryItem = m_pConsoleHistory->Get (m_AutoCompleteList.at (m_AutoCompleteList.size () - 1 ));
380+ if (!pPrevEntryHistoryItem)
381+ continue ;
382+ const char * szPrevItem = *pPrevEntryHistoryItem;
394383 if (strcmp (szItem, szPrevItem) == 0 )
395384 continue ;
396385 }
@@ -409,11 +398,12 @@ void CConsole::SetNextAutoCompleteMatch()
409398 m_iAutoCompleteIndex = (m_iAutoCompleteIndex + 1 ) % m_AutoCompleteList.size ();
410399
411400 // Grab the item and set the input text to it
412- const char * szItem = m_pConsoleHistory->Get (m_AutoCompleteList.at (m_iAutoCompleteIndex));
401+ CEntryHistoryItem* pHistoryEntryItem = m_pConsoleHistory->Get (m_AutoCompleteList.at (m_iAutoCompleteIndex));
402+ if (!pHistoryEntryItem)
403+ return ;
404+ const char * szItem = *pHistoryEntryItem;
413405 if (szItem)
414- {
415406 GracefullySetEditboxText (szItem);
416- }
417407}
418408
419409void CConsole::CreateElements (CGUIElement* pParent)
@@ -534,7 +524,7 @@ void CConsole::FlushPendingAdd()
534524 // Make new buffer
535525 SString strBuffer = m_pHistory->GetText ();
536526 strBuffer += m_strPendingAdd;
537- m_strPendingAdd = " " ;
527+ m_strPendingAdd. clear () ;
538528
539529 // Trim new buffer
540530 uint uiBufferLength = strBuffer.length ();
0 commit comments