12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280 |
- /*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
- #include "LUAEditorView.hxx"
- #include <AzToolsFramework/UI/UICore/ProgressShield.hxx>
- #include <Source/LUA/moc_LUAEditorView.cpp>
- #include "LUAEditorContextMessages.h"
- #include "LUAEditorContextInterface.h"
- #include "LUAEditorViewMessages.h"
- #include "LUAEditorMainWindow.hxx"
- #include "LUABreakpointTrackerMessages.h"
- #include "LUAEditorSyntaxHighlighter.hxx"
- #include "LUAEditorStyleMessages.h"
- #include <Source/LUA/ui_LUAEditorView.h>
- #include <AzToolsFramework/SourceControl/SourceControlAPI.h>
- #include <QFileInfo>
- #include <QTimer>
- #include <QMessageBox>
- #include <QMimeData>
- namespace LUAEditor
- {
- struct FindOperationImpl
- {
- AZ_CLASS_ALLOCATOR(FindOperationImpl, AZ::SystemAllocator);
- QTextCursor m_cursor;
- QString m_searchString;
- bool m_isRegularExpression;
- bool m_isCaseSensitiveSearch;
- bool m_wholeWord;
- bool m_wrap;
- bool m_searchDown;
- };
- LUAViewWidget::FindOperation::FindOperation()
- : m_impl(nullptr)
- {
- }
- LUAViewWidget::FindOperation::FindOperation(FindOperation&& other)
- {
- m_impl = nullptr;
- *this = AZStd::move(other);
- }
- LUAViewWidget::FindOperation::FindOperation(FindOperationImpl* impl)
- {
- m_impl = impl;
- }
- LUAViewWidget::FindOperation::~FindOperation()
- {
- delete m_impl;
- }
- LUAViewWidget::FindOperation& LUAViewWidget::FindOperation::operator=(FindOperation&& other)
- {
- if (m_impl)
- {
- delete m_impl;
- }
- m_impl = other.m_impl;
- other.m_impl = nullptr;
- return *this;
- }
- LUAViewWidget::FindOperation::operator bool()
- {
- return m_impl && !m_impl->m_cursor.isNull();
- }
- //////////////////////////////////////////////////////////////////////////
- //LUADockWidget
- LUADockWidget::LUADockWidget(QWidget* parent, Qt::WindowFlags flags)
- : QDockWidget("LUADockWidget", parent, flags)
- {
- connect(this, &LUADockWidget::dockLocationChanged, this, &LUADockWidget::OnDockLocationChanged);
- }
- void LUADockWidget::closeEvent(QCloseEvent* event)
- {
- if (QMainWindow* pQMainWindow = qobject_cast<QMainWindow*>(parentWidget()))
- {
- if (LUAEditorMainWindow* pLUAEditorMainWindow = qobject_cast<LUAEditorMainWindow*>(pQMainWindow->parentWidget()))
- {
- pLUAEditorMainWindow->RequestCloseDocument(m_assetId);
- event->accept();
- }
- }
- }
- void LUADockWidget::OnDockLocationChanged(Qt::DockWidgetArea newArea)
- {
- (void)newArea;
- if (QMainWindow* pQMainWindow = qobject_cast<QMainWindow*>(parentWidget()))
- {
- if (LUAEditorMainWindow* pLUAEditorMainWindow = qobject_cast<LUAEditorMainWindow*>(pQMainWindow->parentWidget()))
- {
- pLUAEditorMainWindow->OnDockWidgetLocationChanged(m_assetId);
- }
- }
- }
- //////////////////////////////////////////////////////////////////////////
- //LUAViewWidget
- LUAViewWidget::LUAViewWidget(QWidget* pParent /*=NULL*/)
- : QWidget(pParent)
- , m_gui(azcreate(Ui::LUAEditorView, ()))
- , m_pLUADockWidget(NULL)
- , m_pLoadingProgressShield(NULL)
- , m_pSavingProgressShield(NULL)
- , m_pRequestingEditProgressShield(NULL)
- , m_PullRequestQueued(false)
- , m_AutoCompletionEnabled(true)
- {
- m_gui->setupUi(this);
- setAcceptDrops(true);
- m_gui->m_luaTextEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
- m_gui->m_breakpoints->SetTextEdit(m_gui->m_luaTextEdit);
- m_gui->m_folding->SetTextEdit(m_gui->m_luaTextEdit);
- m_Highlighter = aznew LUASyntaxHighlighter(m_gui->m_luaTextEdit->document());
- QTextDocument* doc = m_gui->m_luaTextEdit->document();
- QTextOption option = doc->defaultTextOption();
- option.setFlags(option.flags() | QTextOption::ShowTabsAndSpaces);
- doc->setDefaultTextOption(option);
- connect(m_gui->m_luaTextEdit, &LUAEditorPlainTextEdit::modificationChanged, this, &LUAViewWidget::modificationChanged);
- connect(m_gui->m_luaTextEdit, &LUAEditorPlainTextEdit::cursorPositionChanged, this, &LUAViewWidget::UpdateBraceHighlight);
- connect(m_gui->m_luaTextEdit, &LUAEditorPlainTextEdit::Scrolled, m_gui->m_folding, static_cast<void(FoldingWidget::*)()>(&FoldingWidget::update));
- connect(m_gui->m_luaTextEdit, &LUAEditorPlainTextEdit::blockCountChanged, m_gui->m_breakpoints, &LUAEditorBreakpointWidget::OnBlockCountChange);
- connect(m_gui->m_luaTextEdit->document(), &QTextDocument::contentsChange, m_gui->m_breakpoints, &LUAEditorBreakpointWidget::OnCharsRemoved);
- connect(m_gui->m_luaTextEdit, &LUAEditorPlainTextEdit::FocusChanged, this, &LUAViewWidget::OnPlainTextFocusChanged);
- connect(m_gui->m_luaTextEdit->document(), &QTextDocument::contentsChange, m_gui->m_folding, &FoldingWidget::OnContentChanged);
- connect(m_gui->m_luaTextEdit, &LUAEditorPlainTextEdit::ZoomIn, this, &LUAViewWidget::OnZoomIn);
- connect(m_gui->m_luaTextEdit, &LUAEditorPlainTextEdit::ZoomOut, this, &LUAViewWidget::OnZoomOut);
- connect(m_gui->m_luaTextEdit, &LUAEditorPlainTextEdit::cursorPositionChanged, m_gui->m_folding, static_cast<void(FoldingWidget::*)()>(&FoldingWidget::update));
- connect(m_gui->m_luaTextEdit, &LUAEditorPlainTextEdit::cursorPositionChanged, m_gui->m_breakpoints, static_cast<void(LUAEditorBreakpointWidget::*)()>(&LUAEditorBreakpointWidget::update));
- connect(m_gui->m_luaTextEdit, &LUAEditorPlainTextEdit::Scrolled, m_gui->m_breakpoints, static_cast<void(LUAEditorBreakpointWidget::*)()>(&LUAEditorBreakpointWidget::update));
- connect(this, &LUAViewWidget::RegainFocus, this, &LUAViewWidget::RegainFocusFinal, Qt::QueuedConnection);
-
- connect(m_gui->m_folding, &FoldingWidget::TextBlockFoldingChanged, m_gui->m_breakpoints, static_cast<void(LUAEditorBreakpointWidget::*)()>(&LUAEditorBreakpointWidget::update));
- connect(m_gui->m_folding, &FoldingWidget::TextBlockFoldingChanged, m_gui->m_luaTextEdit, static_cast<void(LUAEditorPlainTextEdit::*)()>(&LUAEditorPlainTextEdit::update));
- connect(m_Highlighter, &LUASyntaxHighlighter::LUANamesInScopeChanged, m_gui->m_luaTextEdit, &LUAEditorPlainTextEdit::OnScopeNamesUpdated);
- connect(m_gui->m_breakpoints, &LUAEditorBreakpointWidget::toggleBreakpoint, this, &LUAViewWidget::BreakpointToggle);
- connect(m_gui->m_breakpoints, &LUAEditorBreakpointWidget::breakpointLineMove, this, &LUAViewWidget::OnBreakpointLineMoved);
- connect(m_gui->m_breakpoints, &LUAEditorBreakpointWidget::breakpointDelete, this, &LUAViewWidget::OnBreakpointLineDeleted);
- CreateStyleSheet();
- this->setMinimumSize(300, 300);
- SetReadonly(true);
- m_gui->m_luaTextEdit->SetGetLuaName([&](const QTextCursor& cursor) {return m_Highlighter->GetLUAName(cursor); });
- UpdateFont();
- LUABreakpointTrackerMessages::Handler::BusConnect();
- }
- void LUAViewWidget::Initialize(const DocumentInfo& initialInfo)
- {
- m_Info = initialInfo;
- if (!m_pLoadingProgressShield)
- {
- m_pLoadingProgressShield = aznew AzToolsFramework::ProgressShield(this);
- }
- m_pLoadingProgressShield->setProgress(0, 0, AZStd::string::format("Loading '%s'...", initialInfo.m_displayName.c_str()).c_str());
- m_pLoadingProgressShield->show();
- }
- void LUAViewWidget::CreateStyleSheet()
- {
- auto colors = AZ::UserSettings::CreateFind<SyntaxStyleSettings>(AZ_CRC_CE("LUA Editor Text Settings"), AZ::UserSettings::CT_GLOBAL);
- auto styleSheet = QString(R"(QPlainTextEdit:focus
- {
- background-color: %1;
- selection-background-color: %6;
- selection-color: %5;
- }
- QPlainTextEdit:!focus
- {
- background-color: %2;
- selection-color: %5;
- selection-background-color: %6;
- }
- QPlainTextEdit[readOnly="true"]:focus
- {
- background-color: %3;
- selection-color: %5;
- selection-background-color: %6;
- }
- QPlainTextEdit[readOnly="true"]:!focus
- {
- background-color: %4;
- selection-color: %5;
- selection-background-color: %6;
- }
- )");
- styleSheet = styleSheet.arg(colors->GetTextFocusedBackgroundColor().name())
- .arg(colors->GetTextUnfocusedBackgroundColor().name())
- .arg(colors->GetTextReadOnlyFocusedBackgroundColor().name())
- .arg(colors->GetTextReadOnlyUnfocusedBackgroundColor().name())
- .arg(colors->GetTextSelectedColor().name())
- .arg(colors->GetTextSelectedBackgroundColor().name());
- m_gui->m_luaTextEdit->setStyleSheet(styleSheet);
- styleSheet = QString(R"(LUAEditor--FoldingWidget:enabled {
- background-color: %1;
- }
- LUAEditor--FoldingWidget:!enabled {
- background-color: %2;
- }
- )");
- styleSheet = styleSheet.arg(colors->GetFoldingFocusedBackgroundColor().name())
- .arg(colors->GetFoldingUnfocusedBackgroundColor().name());
- m_gui->m_folding->setStyleSheet(styleSheet);
- }
- LUAViewWidget::~LUAViewWidget()
- {
- m_gui->m_breakpoints->PreDestruction();
- delete m_Highlighter;
- azdestroy(m_gui);
- LUABreakpointTrackerMessages::Handler::BusDisconnect();
- }
- template<typename Callable>
- void LUAViewWidget::UpdateCursor(Callable callable)
- {
- auto cursor = m_gui->m_luaTextEdit->textCursor();
- callable(cursor);
- m_gui->m_luaTextEdit->setTextCursor(cursor);
- }
- void LUAViewWidget::OnDocumentInfoUpdated(const DocumentInfo& newInfo)
- {
- AZ_Assert(newInfo.m_assetId == m_Info.m_assetId, "Asset ID mismatch.");
- //this is the the initial unmodified state
- bool modifiedValue = newInfo.m_bIsModified;
- //data loading///////////////////////////////////////////////
- if ((newInfo.m_bDataIsLoaded) && (!m_Info.m_bDataIsLoaded))
- {
- // load the data now that its ready!
- if (!newInfo.m_bUntitledDocument)
- {
- const char* buffer = NULL;
- AZStd::size_t actualSize = 0;
- Context_DocumentManagement::Bus::Broadcast(
- &Context_DocumentManagement::Bus::Events::GetDocumentData, newInfo.m_assetId, &buffer, actualSize);
- m_gui->m_luaTextEdit->setPlainText(buffer);
- LUAViewMessages::Bus::Broadcast(&LUAViewMessages::Bus::Events::OnDataLoadedAndSet, newInfo, this);
- }
- //remove the loading shield
- if (m_pLoadingProgressShield)
- {
- delete m_pLoadingProgressShield;
- m_pLoadingProgressShield = NULL;
- UpdateFont(); // Loading over, inner document need the latest font settings
- }
- // scan the breakpoint store from our context and pre-set the markers to get in sync
- const LUAEditor::BreakpointMap* myData = NULL;
- LUAEditor::LUABreakpointRequestMessages::Bus::BroadcastResult(
- myData, &LUAEditor::LUABreakpointRequestMessages::Bus::Events::RequestBreakpoints);
- AZ_Assert(myData, "LUAEditor::LUABreakpointRequestMessages::Bus, RequestBreakpoints failed to return any data.");
- BreakpointsUpdate(*myData);
- UpdateCurrentEditingLine(newInfo.m_PresetLineAtOpen);
- //AZ_TracePrintf("LUA", "Document Loaded Regain\n");
- emit RegainFocus();
- }
- if ((!newInfo.m_bDataIsLoaded) && (m_Info.m_bDataIsLoaded))
- {
- // wait for new data.
- if (!m_pLoadingProgressShield)
- {
- m_pLoadingProgressShield = aznew AzToolsFramework::ProgressShield(this);
- }
- m_pLoadingProgressShield->setProgress(0, 0, AZStd::string::format("Loading... ").c_str());
- m_pLoadingProgressShield->show();
- }
- //data saving/////////////////////////////
- if ((!newInfo.m_bIsBeingSaved) && (m_Info.m_bIsBeingSaved))
- {
- //remove the saving shield!
- if (m_pSavingProgressShield)
- {
- delete m_pSavingProgressShield;
- m_pSavingProgressShield = NULL;
- }
- }
- if ((newInfo.m_bDataIsWritten) && (!m_Info.m_bDataIsWritten))
- {
- m_gui->m_luaTextEdit->document()->setModified(false);
- }
- if ((newInfo.m_bIsBeingSaved) && (!m_Info.m_bIsBeingSaved))
- {
- // show the saving shield!
- if (!m_pSavingProgressShield)
- {
- m_pSavingProgressShield = aznew AzToolsFramework::ProgressShield(this);
- }
- m_pSavingProgressShield->setProgress(0, 0, AZStd::string::format("Saving... ").c_str());
- m_pSavingProgressShield->show();
- }
- //requesting edit (checking out)/////////////////////////////
- if ((!newInfo.m_bSourceControl_BusyRequestingEdit) && (m_Info.m_bSourceControl_BusyRequestingEdit))
- {
- //remove the checking out shield
- if (m_pRequestingEditProgressShield)
- {
- delete m_pRequestingEditProgressShield;
- m_pRequestingEditProgressShield = NULL;
- }
- }
- if ((newInfo.m_bSourceControl_BusyRequestingEdit) && (!m_Info.m_bSourceControl_BusyRequestingEdit))
- {
- // wait for edit request.
- if (!m_pRequestingEditProgressShield)
- {
- m_pRequestingEditProgressShield = aznew AzToolsFramework::ProgressShield(this);
- }
- m_pRequestingEditProgressShield->setProgress(0, 0, AZStd::string::format("Checking Out... ").c_str());
- m_pRequestingEditProgressShield->show();
- }
- //update view properties//////////////////////////////////////////////
- if ((newInfo.m_bSourceControl_CanWrite) && (newInfo.m_bDataIsLoaded))
- {
- if (m_gui->m_luaTextEdit->isReadOnly())
- {
- SetReadonly(false);
- update();
- }
- }
- else
- {
- // in all other cases we are waiting for more.
- if (!m_gui->m_luaTextEdit->isReadOnly())
- {
- SetReadonly(true);
- update();
- }
- }
- QString statusString(tr("P4:"));
- {
- // this flag goes true when a file's read-only status should be verified
- bool checkWriteIsWrong = false;
- if (newInfo.m_sourceControlInfo.m_status == AzToolsFramework::SCS_ProviderIsDown)
- {
- statusString += tr(" Unknown: P4 Down");
- }
- else if (newInfo.m_sourceControlInfo.m_status == AzToolsFramework::SCS_ProviderError)
- {
- statusString += tr(" Unknown: P4 Error");
- }
- else if (newInfo.m_sourceControlInfo.m_status == AzToolsFramework::SCS_CertificateInvalid)
- {
- statusString += tr(" Unknown: P4 SSL Certificate Invalid");
- }
- else if (newInfo.m_sourceControlInfo.m_flags & AzToolsFramework::SCF_OpenByUser)
- {
- if (newInfo.m_sourceControlInfo.m_flags & AzToolsFramework::SCF_PendingAdd)
- {
- statusString += tr(" Adding");
- }
- else if (newInfo.m_sourceControlInfo.m_flags & AzToolsFramework::SCF_PendingDelete)
- {
- statusString += tr(" Deleting");
- }
- else
- {
- QString msg = tr(" Checked Out");
- msg += QString(tr(" By You"));
- // m_StatusUser only has contents if someone other than you has this file checked out, too
- if (newInfo.m_sourceControlInfo.m_StatusUser.length())
- {
- msg += QString(tr(" and Others"));
- }
- statusString += msg;
- }
- }
- else if (newInfo.m_sourceControlInfo.m_flags & AzToolsFramework::SCF_OtherOpen)
- {
- QString msg = tr(" Checked Out");
- msg += QString(tr(" By ")) + newInfo.m_sourceControlInfo.m_StatusUser.c_str();
- statusString += msg;
- checkWriteIsWrong = true;
- }
- else if (!newInfo.m_sourceControlInfo.IsManaged())
- {
- statusString += tr(" Not Tracked");
- }
- else
- {
- statusString += tr(" Not Checked Out");
- checkWriteIsWrong = true;
- }
- if (checkWriteIsWrong)
- {
- QFileInfo fi(newInfo.m_sourceControlInfo.m_filePath.c_str());
- if (fi.exists() && fi.isWritable())
- {
- statusString += tr(" But Writable?");
- }
- }
- if ((!newInfo.m_bSourceControl_BusyRequestingEdit) && (!m_Info.m_bSourceControl_BusyGettingStats))
- {
- //remove the checking out shield
- if (m_pRequestingEditProgressShield)
- {
- delete m_pRequestingEditProgressShield;
- m_pRequestingEditProgressShield = NULL;
- }
- }
- }
- emit sourceControlStatusUpdated(statusString);
- //save new state
- m_Info = newInfo;
- m_gui->m_luaTextEdit->document()->setModified(modifiedValue);
- UpdateModifyFlag();
- }
- void LUAViewWidget::OnPlainTextFocusChanged(bool hasFocus)
- {
- if (!m_gui->m_folding || !m_gui->m_breakpoints)
- {
- return;
- }
- if (hasFocus)
- {
- m_gui->m_breakpoints->setEnabled(true);
- m_gui->m_folding->setEnabled(true);
- LUAEditorMainWindowMessages::Bus::Broadcast(&LUAEditorMainWindowMessages::Bus::Events::OnFocusInEvent, m_Info.m_assetId);
- }
- else
- {
- m_gui->m_breakpoints->setEnabled(false);
- m_gui->m_folding->setEnabled(false);
- LUAEditorMainWindowMessages::Bus::Broadcast(&LUAEditorMainWindowMessages::Bus::Events::OnFocusOutEvent, m_Info.m_assetId);
- }
- }
- void LUAViewWidget::RegainFocusFinal()
- {
- //AZ_TracePrintf("LUA", "RegainFocusFinal\n");
- show();
- activateWindow();
- setFocus(Qt::MouseFocusReason);
- }
- void LUAViewWidget::OnVisibilityChanged(bool vc)
- {
- if (vc)
- {
- if (!m_pLUADockWidget->isFloating())
- {
- RegainFocusFinal();
- }
- }
- }
- void LUAViewWidget::OnBreakpointLineMoved(int fromLineNumber, int toLineNumber)
- {
- auto breakpoint = m_Breakpoints.find(fromLineNumber);
- if (breakpoint != m_Breakpoints.end())
- {
- Context_DebuggerManagement::Bus::Broadcast(
- &Context_DebuggerManagement::Bus::Events::MoveBreakpoint, breakpoint->second.m_editorId, toLineNumber);
- }
- }
- void LUAViewWidget::OnBreakpointLineDeleted(int removedLineNumber)
- {
- auto breakpoint = m_Breakpoints.find(removedLineNumber);
- if (breakpoint != m_Breakpoints.end())
- {
- Context_DebuggerManagement::Bus::Broadcast(
- &Context_DebuggerManagement::Bus::Events::DeleteBreakpoint, breakpoint->second.m_editorId);
- }
- }
- void LUAViewWidget::modificationChanged(bool m)
- {
- Context_DocumentManagement::Bus::Broadcast(&Context_DocumentManagement::Bus::Events::NotifyDocumentModified, m_Info.m_assetId, m);
- UpdateModifyFlag();
- }
- void LUAViewWidget::UpdateModifyFlag() {
- QString displayName = QString::fromUtf8(m_Info.m_displayName.c_str());
- if (m_gui->m_luaTextEdit->document()->isModified())
- {
- displayName += "*";
- }
- this->luaDockWidget()->setWindowTitle(displayName);
- }
- void LUAViewWidget::UpdateCurrentExecutingLine(int lineNumber)
- {
- m_gui->m_breakpoints->SetCurrentlyExecutingLine(lineNumber);
- }
- void LUAViewWidget::UpdateCurrentEditingLine(int lineNumber)
- {
- SetCursorPosition(lineNumber, 0);
- }
- void LUAViewWidget::SyncToBreakpointLine(int line, AZ::Uuid existingID)
- {
- auto existingBreakPont = AZStd::find_if(m_Breakpoints.begin(), m_Breakpoints.end(), [&](const AZStd::pair<int, BreakpointData>& _data)
- {
- return _data.second.m_editorId == existingID;
- });
- if (existingBreakPont != m_Breakpoints.end())
- {
- m_gui->m_breakpoints->RemoveBreakpoint(existingBreakPont->first);
- if (existingBreakPont->first != line)
- {
- m_Breakpoints.insert(AZStd::make_pair(line, BreakpointData(existingID, line)));
- m_gui->m_breakpoints->AddBreakpoint(line);
- m_Breakpoints.erase(existingBreakPont);
- }
- }
- else
- {
- m_Breakpoints.insert(AZStd::make_pair(line, BreakpointData(existingID, line)));
- m_gui->m_breakpoints->AddBreakpoint(line);
- }
- }
- //////////////////////////////////////////////////////////////////////////
- //Debugger Messages, from the LUAEditor::LUABreakpointTrackerMessages::Bus
- void LUAViewWidget::BreakpointsUpdate(const LUAEditor::BreakpointMap& uniqueBreakpoints)
- {
- (void)uniqueBreakpoints;
- if (!m_PullRequestQueued)
- {
- QTimer::singleShot(1, this, &LUAViewWidget::PullFreshBreakpoints);
- m_PullRequestQueued = true;
- return;
- }
- }
- void LUAViewWidget::PullFreshBreakpoints()
- {
- m_PullRequestQueued = false;
- m_Breakpoints.clear();
- m_gui->m_breakpoints->ClearBreakpoints();
- const LUAEditor::BreakpointMap* myData = NULL;
- LUAEditor::LUABreakpointRequestMessages::Bus::BroadcastResult(
- myData, &LUAEditor::LUABreakpointRequestMessages::Bus::Events::RequestBreakpoints);
- AZ_Assert(myData, "Nobody responded to the request breakpoints message.");
- // and slam down a new set
- for (LUAEditor::BreakpointMap::const_iterator it = myData->begin(); it != myData->end(); ++it)
- {
- const LUAEditor::Breakpoint& bp = it->second;
- if (m_Info.m_assetName == bp.m_assetName)
- {
- SyncToBreakpointLine(bp.m_documentLine, bp.m_breakpointId);
- }
- }
- }
- void LUAViewWidget::BreakpointHit(const LUAEditor::Breakpoint& bp)
- {
- if (bp.m_assetName == this->m_Info.m_assetName)
- {
- //AZ_TracePrintf("LUA", "Matching LUAViewWidget::BreakpointHit\n");
- SetCursorPosition(bp.m_documentLine, 0);
- emit RegainFocus();
- }
- }
- void LUAViewWidget::BreakpointResume()
- {
- m_gui->m_breakpoints->update();
- }
- void LUAViewWidget::BreakpointToggle(int line)
- {
- auto breakpoint = m_Breakpoints.find(line);
- if (breakpoint == m_Breakpoints.end())
- {
- Context_DebuggerManagement::Bus::Broadcast(&Context_DebuggerManagement::Bus::Events::CreateBreakpoint, m_Info.m_assetId, line);
- }
- else
- {
- Context_DebuggerManagement::Bus::Broadcast(
- &Context_DebuggerManagement::Bus::Events::DeleteBreakpoint, breakpoint->second.m_editorId);
- }
- }
- void LUAViewWidget::keyPressEvent(QKeyEvent* ev)
- {
- if (m_gui->m_luaTextEdit->isReadOnly())
- {
- bool isUseful = false;
- switch (ev->key())
- {
- case Qt::Key_Return:
- case Qt::Key_Enter:
- case Qt::Key_Backspace:
- case Qt::Key_Delete:
- isUseful = true;
- break;
- }
- bool isModified = false;
- if (ev->modifiers() & (Qt::ControlModifier | Qt::AltModifier))
- {
- // every Ctrl+ key combination is "modified" except for Ctrl+V, which should cause a check-out request
- if (((ev->key() != Qt::Key_V) && (ev->modifiers() & Qt::ControlModifier)))
- {
- isModified = true;
- }
- }
- if ((!isModified) && (isascii(ev->key()) || isUseful))
- {
- QMessageBox msgBox;
- msgBox.setText("Checkout This File To Edit?");
- msgBox.setInformativeText(m_Info.m_assetName.c_str());
- msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
- msgBox.setDefaultButton(QMessageBox::Ok);
- msgBox.setIcon(QMessageBox::Warning);
- int ret = msgBox.exec();
- if (ret == QMessageBox::Ok)
- {
- LUAEditorMainWindowMessages::Bus::Broadcast(
- &LUAEditorMainWindowMessages::Bus::Events::OnRequestCheckOut, m_Info.m_assetId);
- }
- }
- }
- ev->accept();
- QWidget::keyPressEvent(ev);
- }
- void LUAViewWidget::dropEvent(QDropEvent* e)
- {
- if (e->mimeData()->hasUrls())
- {
- LUADockWidget* ldw = luaDockWidget();
- if (ldw)
- {
- if (QMainWindow* pQMainWindow = qobject_cast<QMainWindow*>(ldw->parentWidget()))
- {
- if (LUAEditorMainWindow* pLUAEditorMainWindow = qobject_cast<LUAEditorMainWindow*>(pQMainWindow->parentWidget()))
- {
- e->setDropAction(Qt::CopyAction);
- pLUAEditorMainWindow->dropEvent(e);
- e->accept();
- }
- }
- }
- }
- else
- {
- QWidget::dropEvent(e);
- }
- }
- bool LUAViewWidget::IsReadOnly() const
- {
- return m_gui->m_luaTextEdit->isReadOnly();
- }
- bool LUAViewWidget::IsModified() const
- {
- return m_gui->m_luaTextEdit->document()->isModified();
- }
- void LUAViewWidget::SelectAll()
- {
- m_gui->m_luaTextEdit->selectAll();
- }
- bool LUAViewWidget::HasSelectedText() const
- {
- return m_gui->m_luaTextEdit->textCursor().hasSelection();
- }
- void LUAViewWidget::RemoveSelectedText()
- {
- auto cursor = m_gui->m_luaTextEdit->textCursor();
- if (!cursor.isNull() && cursor.hasSelection())
- {
- cursor.deleteChar();
- }
- }
- void LUAViewWidget::ReplaceSelectedText(const QString& newText)
- {
- auto cursor = m_gui->m_luaTextEdit->textCursor();
- if (!cursor.isNull())
- {
- cursor.insertText(newText);
- }
- }
- QString LUAViewWidget::GetSelectedText() const
- {
- return m_gui->m_luaTextEdit->textCursor().selectedText();
- }
- int LUAViewWidget::CalcDocPosition(int line, int column)
- {
- // Offset line number by one, because line number starts from 1, not 0.
- line = line - 1;
- if (line < 0)
- {
- line = column = 0;
- }
- int blockCount = m_gui->m_luaTextEdit->document()->blockCount();
- if (line > blockCount - 1)
- {
- line = blockCount - 1;
- column = INT_MAX;
- }
- auto block = m_gui->m_luaTextEdit->document()->findBlockByLineNumber(line);
- if (!block.isValid())
- {
- return m_gui->m_luaTextEdit->document()->characterCount() - 1;
- }
- column = AZStd::max(column, 0);
- column = AZStd::min(column, block.length() - 1);
- return block.position() + column;
- }
- void LUAViewWidget::GetCursorPosition(int& line, int& column) const
- {
- auto cursor = m_gui->m_luaTextEdit->textCursor();
- if (cursor.isNull())
- {
- line = 0;
- column = 0;
- }
- else
- {
- line = cursor.blockNumber() + 1; // offset by one because line number start from 1
- column = cursor.positionInBlock();
- }
- }
- void LUAViewWidget::SetCursorPosition(int line, int column)
- {
- UpdateCursor([&](QTextCursor& cursor)
- {
- cursor.setPosition(CalcDocPosition(line, column));
- });
- }
- void LUAViewWidget::MoveCursor(int relativePosition)
- {
- UpdateCursor([&](QTextCursor& cursor)
- {
- cursor.movePosition(relativePosition > 0 ? QTextCursor::MoveOperation::Right : QTextCursor::MoveOperation::Left,
- QTextCursor::MoveMode::MoveAnchor, abs(relativePosition));
- });
- }
- LUAViewWidget::FindOperation LUAViewWidget::FindFirst(const QString& searchString, bool isRegularExpression, bool isCaseSensitiveSearch, bool wholeWord, bool wrap, bool searchDown) const
- {
- FindOperation start(aznew FindOperationImpl);
- start.m_impl->m_cursor = m_gui->m_luaTextEdit->textCursor();
- start.m_impl->m_searchString = searchString;
- start.m_impl->m_isRegularExpression = isRegularExpression;
- start.m_impl->m_isCaseSensitiveSearch = isCaseSensitiveSearch;
- start.m_impl->m_wholeWord = wholeWord;
- start.m_impl->m_wrap = wrap;
- start.m_impl->m_searchDown = searchDown;
- FindNext(start);
- return start;
- }
- void LUAViewWidget::FindNext(FindOperation& operation) const
- {
- if (!operation)
- {
- return;
- }
- int flags = 0;
- if (operation.m_impl->m_wholeWord)
- {
- flags |= QTextDocument::FindFlag::FindWholeWords;
- }
- if (operation.m_impl->m_isCaseSensitiveSearch)
- {
- flags |= QTextDocument::FindFlag::FindCaseSensitively;
- }
- if (!operation.m_impl->m_searchDown)
- {
- flags |= QTextDocument::FindFlag::FindBackward;
- }
- if (operation.m_impl->m_isRegularExpression)
- {
- QRegExp regEx;
- regEx.setCaseSensitivity(operation.m_impl->m_isCaseSensitiveSearch ? Qt::CaseSensitivity::CaseSensitive : Qt::CaseSensitivity::CaseInsensitive);
- regEx.setPattern(operation.m_impl->m_searchString);
- operation.m_impl->m_cursor = m_gui->m_luaTextEdit->document()->find(regEx, operation.m_impl->m_cursor, static_cast<QTextDocument::FindFlag>(flags));
- if (!operation && operation.m_impl->m_wrap)
- {
- if (operation.m_impl->m_searchDown)
- {
- operation.m_impl->m_cursor.setPosition(0);
- }
- else
- {
- operation.m_impl->m_cursor.setPosition(m_gui->m_luaTextEdit->document()->characterCount() - 1);
- }
- operation.m_impl->m_cursor = m_gui->m_luaTextEdit->document()->find(regEx, operation.m_impl->m_cursor, static_cast<QTextDocument::FindFlag>(flags));
- }
- }
- else
- {
- operation.m_impl->m_cursor = m_gui->m_luaTextEdit->document()->find(operation.m_impl->m_searchString, operation.m_impl->m_cursor, static_cast<QTextDocument::FindFlag>(flags));
- if (!operation && operation.m_impl->m_wrap)
- {
- if (operation.m_impl->m_searchDown)
- {
- operation.m_impl->m_cursor.setPosition(0);
- }
- else
- {
- operation.m_impl->m_cursor.setPosition(m_gui->m_luaTextEdit->document()->characterCount() - 1);
- }
- operation.m_impl->m_cursor = m_gui->m_luaTextEdit->document()->find(operation.m_impl->m_searchString, operation.m_impl->m_cursor, static_cast<QTextDocument::FindFlag>(flags));
- }
- }
- if (operation)
- {
- m_gui->m_luaTextEdit->setTextCursor(operation.m_impl->m_cursor);
- }
- }
- QString LUAViewWidget::GetLineText(int line) const
- {
- auto block = m_gui->m_luaTextEdit->document()->findBlockByLineNumber(line);
- return block.text();
- }
- bool LUAViewWidget::GetSelection(int& lineStart, int& columnStart, int& lineEnd, int& columnEnd) const
- {
- auto doc = m_gui->m_luaTextEdit->document();
- auto cursor = m_gui->m_luaTextEdit->textCursor();
- if (cursor.isNull())
- {
- lineStart = columnStart = lineEnd = columnEnd = -1;
- return false;
- }
- auto startPos = cursor.selectionStart();
- auto endPos = cursor.selectionEnd();
- auto startBlock = doc->findBlock(startPos);
- lineStart = startBlock.blockNumber();
- columnStart = startPos - startBlock.position();
- auto endBlock = doc->findBlock(endPos);
- lineEnd = endBlock.blockNumber();
- columnEnd = endPos - endBlock.position();
- return true;
- }
- void LUAViewWidget::SetSelection(int lineStart, int columnStart, int lineEnd, int columnEnd)
- {
- auto startPos = CalcDocPosition(lineStart, columnStart);
- auto endPos = CalcDocPosition(lineEnd, columnEnd);
- UpdateCursor([&](QTextCursor& cursor)
- {
- // Go back to front to keep cursor position consistent
- cursor.setPosition(endPos);
- cursor.setPosition(startPos, QTextCursor::MoveMode::KeepAnchor);
- });
- }
- QString LUAViewWidget::GetText()
- {
- return m_gui->m_luaTextEdit->toPlainText();
- }
- void LUAViewWidget::Cut()
- {
- m_gui->m_luaTextEdit->cut();
- }
- void LUAViewWidget::Copy()
- {
- m_gui->m_luaTextEdit->copy();
- }
- template<typename Callable>
- //callabe sig (QString&, QTextBlock&)
- QString LUAViewWidget::AcumulateSelectedLines(int& startLine, int& endLine, Callable callable)
- {
- int startColumn;
- int endColumn;
- GetSelection(startLine, startColumn, endLine, endColumn);
- AZ_Assert(startLine <= endLine, "assume selection is always forward");
- auto cursor = m_gui->m_luaTextEdit->textCursor();
- QString newText;
- for (int i = startLine; i <= endLine; ++i)
- {
- auto block = m_gui->m_luaTextEdit->document()->findBlockByNumber(i);
- if (block.isValid())
- {
- callable(newText, block);
- }
- }
- return newText;
- }
- template<typename Callable>
- void LUAViewWidget::CommentHelper(Callable callable)
- {
- int startLine;
- int endLine;
- auto newText = AcumulateSelectedLines(startLine, endLine, callable);
- SetSelection(startLine + 1, 0, endLine + 2, 0);
- RemoveSelectedText();
- SetCursorPosition(startLine + 1, 0);
- ReplaceSelectedText(newText);
- SetSelection(startLine + 1, 0, endLine + 1, INT_MAX);
- }
- void LUAViewWidget::CommentSelectedLines()
- {
- CommentHelper([&](QString& newText, QTextBlock& block)
- {
- newText.append("-- ");
- newText.append(block.text());
- newText.append("\n");
- });
- }
- void LUAViewWidget::UncommentSelectedLines()
- {
- CommentHelper([&](QString& newText, QTextBlock& block)
- {
- auto blockText = block.text();
- if (blockText.startsWith("--"))
- {
- int removeCount = 2;
- if (blockText.at(2).isSpace())
- {
- ++removeCount;
- }
- blockText.remove(0, removeCount);
- }
- newText.append(blockText);
- newText.append("\n");
- });
- }
- void LUAViewWidget::MoveSelectedLinesUp()
- {
- int startLine;
- int endLine;
- auto currText = AcumulateSelectedLines(startLine, endLine, [&](QString& newText, QTextBlock& block)
- {
- newText.append(block.text());
- newText.append("\n");
- });
- currText.remove(currText.count() - 1, 1);
- if (startLine == 0)
- {
- return;
- }
- auto upText = GetLineText(startLine -1);
- SetSelection(startLine, 0, startLine, INT_MAX);
- RemoveSelectedText();
- SetSelection(startLine + 1, 0, endLine + 1, INT_MAX);
- RemoveSelectedText();
- SetCursorPosition(startLine , 0);
- ReplaceSelectedText(currText);
- SetCursorPosition(endLine + 1, 0);
- ReplaceSelectedText(upText);
- SetSelection(startLine, 0, endLine, INT_MAX);
- }
- void LUAViewWidget::MoveSelectedLinesDn()
- {
- int startLine;
- int endLine;
- auto newText = AcumulateSelectedLines(startLine, endLine, [&](QString& newText, QTextBlock& block)
- {
- newText.append(block.text());
- newText.append("\n");
- });
- if (endLine == m_gui->m_luaTextEdit->document()->blockCount() - 1)
- {
- return;
- }
- //hack if we are going to be the new last line
- if (endLine == m_gui->m_luaTextEdit->document()->blockCount() - 2)
- {
- newText.remove(newText.length() - 1, 1);
- newText.prepend("\n");
- }
- SetSelection(startLine + 1, 0, endLine + 2, 0);
- RemoveSelectedText();
- SetCursorPosition(startLine + 2, 0);
- ReplaceSelectedText(newText);
- SetSelection(startLine + 2, 0, endLine + 2, INT_MAX);
- }
- void LUAViewWidget::SetReadonly(bool readonly)
- {
- m_gui->m_luaTextEdit->setReadOnly(readonly);
- m_gui->m_luaTextEdit->style()->unpolish(m_gui->m_luaTextEdit);
- m_gui->m_luaTextEdit->style()->polish(m_gui->m_luaTextEdit);
- if (readonly)
- {
- // For readonly documents we set the TextSelectableByKeyboard to display a solid cursor.
- m_gui->m_luaTextEdit->setTextInteractionFlags(m_gui->m_luaTextEdit->textInteractionFlags() | Qt::TextSelectableByKeyboard);
- }
- }
- template<typename Callable>
- void LUAViewWidget::FindMatchingBrace(Callable callable)
- {
- auto doc = m_gui->m_luaTextEdit->document();
- auto cursor = m_gui->m_luaTextEdit->textCursor();
- int bracePos = cursor.position();
- QChar braceChar {
- QChar::Null
- };
- bool openingBrace {
- true
- };
- auto detect = [&]()
- {
- auto testChar = doc->characterAt(bracePos);
- if (testChar == '{' || testChar == '[' || testChar == '(')
- {
- braceChar = testChar;
- openingBrace = true;
- }
- if (testChar == '}' || testChar == ']' || testChar == ')')
- {
- braceChar = testChar;
- openingBrace = false;
- }
- };
- detect();
- if (braceChar == QChar::Null && bracePos > 0) //try previous char too so we can detect on either side of brace
- {
- --bracePos;
- detect();
- }
- if (braceChar != QChar::Null) //found one
- {
- int startPos = bracePos;
- QChar endChar {
- QChar::Null
- };
- if (braceChar == '{')
- {
- endChar = '}';
- }
- if (braceChar == '}')
- {
- endChar = '{';
- }
- if (braceChar == '[')
- {
- endChar = ']';
- }
- if (braceChar == ']')
- {
- endChar = '[';
- }
- if (braceChar == '(')
- {
- endChar = ')';
- }
- if (braceChar == ')')
- {
- endChar = '(';
- }
- int step {
- openingBrace ? 1 : -1
- };
- int level {
- 0
- };
- bracePos += step;
- auto testChar = doc->characterAt(bracePos);
- while (testChar != QChar::Null)
- {
- if (testChar == braceChar)
- {
- ++level;
- }
- else if (testChar == endChar)
- {
- --level;
- if (level < 0)
- {
- if (step > 0)
- {
- ++bracePos;
- }
- else
- {
- ++startPos;
- }
- callable(startPos, bracePos);
- return;
- }
- }
- bracePos += step;
- testChar = doc->characterAt(bracePos);
- }
- callable(startPos, -1); //had an opening brace, but no matching close brace
- }
- }
- void LUAViewWidget::SelectToMatchingBrace()
- {
- auto cursor = m_gui->m_luaTextEdit->textCursor();
- FindMatchingBrace([&](int startPos, int endPos)
- {
- if (endPos >= 0)
- {
- cursor.setPosition(startPos);
- cursor.setPosition(endPos, QTextCursor::MoveMode::KeepAnchor);
- m_gui->m_luaTextEdit->setTextCursor(cursor);
- }
- });
- }
- void LUAViewWidget::UpdateBraceHighlight()
- {
- m_Highlighter->SetBracketHighlighting(-1, -1);
- FindMatchingBrace([&](int startPos, int endPos)
- {
- if (endPos > 0 && endPos < startPos)
- {
- AZStd::swap(startPos, endPos);
- }
- m_Highlighter->SetBracketHighlighting(startPos, endPos - 1);
- });
- auto cursor = m_gui->m_luaTextEdit->textCursor();
- auto text = m_gui->m_luaTextEdit->document()->toPlainText();
- m_gui->m_luaTextEdit->setExtraSelections(m_Highlighter->HighlightMatchingNames(cursor, text));
- m_gui->m_luaTextEdit->update();
- }
- void LUAViewWidget::focusInEvent(QFocusEvent* pEvent)
- {
- QWidget::focusInEvent(pEvent);
- m_gui->m_luaTextEdit->setFocus();
- }
- void LUAViewWidget::FoldAll()
- {
- m_gui->m_folding->FoldAll();
- }
- void LUAViewWidget::UnfoldAll()
- {
- m_gui->m_folding->UnfoldAll();
- }
- void LUAViewWidget::UpdateFont()
- {
- auto syntaxSettings = AZ::UserSettings::CreateFind<SyntaxStyleSettings>(AZ_CRC_CE("LUA Editor Text Settings"), AZ::UserSettings::CT_GLOBAL);
- syntaxSettings->SetZoomPercent(m_zoomPercent);
- const auto& font = syntaxSettings->GetFont();
- m_gui->m_luaTextEdit->SetTabSize(syntaxSettings->GetTabSize());
- m_gui->m_luaTextEdit->SetUseSpaces(syntaxSettings->UseSpacesInsteadOfTabs());
- m_gui->m_luaTextEdit->UpdateFont(font, syntaxSettings->GetTabSize());
- m_gui->m_breakpoints->SetFont(font);
- m_gui->m_folding->SetFont(font);
- m_gui->m_luaTextEdit->update();
- m_gui->m_breakpoints->update();
- m_gui->m_folding->update();
- m_Highlighter->rehighlight();
- CreateStyleSheet();
- m_gui->m_luaTextEdit->repaint();
- }
- void LUAViewWidget::OnZoomIn()
- {
- m_zoomPercent = AZStd::min(m_zoomPercent + m_zoomPercent / 5, 500);
- UpdateFont();
- }
- void LUAViewWidget::OnZoomOut()
- {
- m_zoomPercent = AZStd::max(m_zoomPercent - m_zoomPercent / 5, 50);
- UpdateFont();
- }
- void LUAViewWidget::ResetZoom()
- {
- m_zoomPercent = 100;
- UpdateFont();
- }
- }
|