From e16e086cc79a9c070fdd82b0b5e15eb07a516391 Mon Sep 17 00:00:00 2001 From: David Kinder Date: Wed, 2 Jul 2014 12:57:55 +0100 Subject: [PATCH] More Public Library work --- Inform7/ExtensionFrame.cpp | 86 +++++++++++++++++++++++++++++++------- Inform7/ExtensionFrame.h | 4 +- Inform7/Inform.cpp | 36 ++++++++++------ Inform7/Inform.h | 5 ++- Inform7/ProjectFrame.cpp | 51 +++++++++++++++------- Inform7/ProjectFrame.h | 2 +- Inform7/ReportHtml.cpp | 11 +++++ Inform7/ReportHtml.h | 1 + Inform7/SearchWindow.cpp | 2 +- Inform7/TabExtensions.cpp | 9 ++++ Inform7/TabExtensions.h | 1 + Inform7/TabResults.cpp | 3 -- 12 files changed, 161 insertions(+), 50 deletions(-) diff --git a/Inform7/ExtensionFrame.cpp b/Inform7/ExtensionFrame.cpp index 1a6d84d..31427d7 100644 --- a/Inform7/ExtensionFrame.cpp +++ b/Inform7/ExtensionFrame.cpp @@ -6,6 +6,7 @@ #include "TextFormat.h" #include "NewDialogs.h" #include "Dialogs.h" +#include "OSLayer.h" #include "Build.h" #ifdef _DEBUG @@ -420,9 +421,13 @@ bool ExtensionFrame::InstallExtensions(CWnd* parent) return false; // Iterate over the selected extensions + CStringW lastExt; + int installed = 0, total = 0; POSITION pos = dialog.GetStartPosition(); while (pos != NULL) { + total++; + // Get the first line of the extension CString path = dialog.GetNextPathName(pos); CStringW extLine = ReadExtensionFirstLine(path); @@ -474,13 +479,19 @@ bool ExtensionFrame::InstallExtensions(CWnd* parent) // Copy the extension if (::CopyFile(path,target,FALSE)) + { DeleteOldExtension(target); + lastExt.Format(L"\"%s\" by %s (%s)",(LPCWSTR)extName,(LPCWSTR)extAuthor,(LPCWSTR)extVersion); + installed++; + } } // Update the extensions menu and documentation + HANDLE process = theApp.RunCensus(true); + ShowInstalledMessage(parent,installed,total,lastExt); theApp.FindExtensions(); theApp.SendAllFrames(InformApp::Extensions,0); - theApp.RunCensus(true); + theApp.WaitForProcessEnd(process); return true; } @@ -581,18 +592,23 @@ void ExtensionFrame::DownloadExtensions(CFrameWnd* parent, CStringArray* urls) { { CWaitCursor wc; - parent->SetMessageText("Downloading extensions"); - int installed = 0; - for (int i = 0; i < urls->GetSize(); i++) + CStringW lastExt; + int installed = 0, total = urls->GetSize(); + for (int i = 0; i < total; i++) { - parent->SendMessage(WM_PROGRESS, - (int)(100 * ((double)i / (double)urls->GetSize()))); + SetDownloadProgress(parent,total,i,installed); CString url = urls->GetAt(i); if (url.Left(8) != "library:") continue; + // Get the ID of the download + int idIdx = url.Find("?id="); + if (idIdx <= 0) + continue; + int id = atoi(((LPCSTR)url)+idIdx+4); + // Determine the path for downloaded extension files CString downPath; ::GetTempPath(MAX_PATH,downPath.GetBuffer(MAX_PATH)); @@ -630,6 +646,8 @@ void ExtensionFrame::DownloadExtensions(CFrameWnd* parent, CStringArray* urls) if (::CopyFile(downPath,target,FALSE)) { DeleteOldExtension(target); + theApp.SendAllFrames(InformApp::DownloadedExt,id); + lastExt.Format(L"\"%s\" by %s (%s)",(LPCWSTR)extName,(LPCWSTR)extAuthor,(LPCWSTR)extVersion); installed++; } } @@ -638,20 +656,17 @@ void ExtensionFrame::DownloadExtensions(CFrameWnd* parent, CStringArray* urls) // Delete the downloaded file ::DeleteFile(downPath); } + SetDownloadProgress(parent,total,total,installed); - parent->SendMessage(WM_PROGRESS,100); - CString msg; - msg.Format("Downloaded and installed %d extension%s",installed,(installed != 1) ? "s" : ""); - parent->SetMessageText(msg); - msg.Format("Attempted to download %d extensions, %d failed.",urls->GetSize(),urls->GetSize()-installed); - parent->MessageBox(msg,INFORM_TITLE,MB_ICONINFORMATION|MB_OK); + // Notify the user of what happened + theApp.RunCensus(false); + ShowInstalledMessage(parent,installed,total,lastExt); parent->SendMessage(WM_PROGRESS,-1); } - // Update the extensions menu and documentation + // Update the extensions menu theApp.FindExtensions(); theApp.SendAllFrames(InformApp::Extensions,0); - theApp.RunCensus(true); } CStringW ExtensionFrame::ReadExtensionFirstLine(const char* path) @@ -804,6 +819,49 @@ void ExtensionFrame::DeleteOldExtension(CString path) ::DeleteFile(path); } +void ExtensionFrame::SetDownloadProgress(CFrameWnd* parent, int total, int current, int installed) +{ + parent->SendMessage(WM_PROGRESS,(int)(100 * ((double)current / (double)total))); + + CString status; + status.Format("Installed %d of %d",installed,total); + if (current > installed) + status.AppendFormat(" (%d failed)",current-installed); + parent->SetMessageText(status); +} + +void ExtensionFrame::ShowInstalledMessage(CWnd* parent, int installed, int total, LPCWSTR lastExt) +{ + CStringW msg; + if (total > installed) + { + // One or more errors + if (installed > 0) + { + if (installed == 1) + msg.Format(L"One extension installed successfully, %d failed.",total-installed); + else + msg.Format(L"%d extensions installed successfully, %d failed.",installed,total-installed); + } + else + { + if (total > 1) + msg.Format(L"Failed to install %d extensions.",total); + else + msg = "Failed to install extension."; + } + } + else + { + // No errors + if (installed > 1) + msg.Format(L"Installation complete.\n\n%d extensions installed successfully.",installed); + else + msg.Format(L"Installation complete.\n\nExtension %s installed successfully.",lastExt); + } + theOS.MessageBox(parent,msg,L_INFORM_TITLE,MB_ICONINFORMATION|MB_OK); +} + CString ExtensionFrame::GetDisplayName(bool showEdited) { CString name = m_extension; diff --git a/Inform7/ExtensionFrame.h b/Inform7/ExtensionFrame.h index 349108b..0fbbcc0 100644 --- a/Inform7/ExtensionFrame.h +++ b/Inform7/ExtensionFrame.h @@ -61,7 +61,9 @@ class ExtensionFrame : public MenuBarFrameWnd static ExtensionFrame* NewFrame(const ProjectSettings& settings); static bool RemoveI7X(CString& path); static void DeleteOldExtension(CString path); - + static void SetDownloadProgress(CFrameWnd* parent, int total, int current, int installed); + static void ShowInstalledMessage(CWnd* parent, int installed, int total, LPCWSTR lastExt); + void OpenFile(const char* path); void SetFromRegistryPath(const char* path); bool IsProjectEdited(void); diff --git a/Inform7/Inform.cpp b/Inform7/Inform.cpp index 644f203..b0ca201 100644 --- a/Inform7/Inform.cpp +++ b/Inform7/Inform.cpp @@ -772,9 +772,14 @@ void InformApp::RunMessagePump(void) MSG msg; while (::PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)) { - if (PumpMessage() == FALSE) + if (msg.message == WM_COMMAND) + ::PeekMessage(&msg,NULL,0,0,PM_REMOVE); + else if (PumpMessage() == FALSE) exit(ExitInstance()); } + + if (IsWaitCursor()) + RestoreWaitCursor(); } int InformApp::RunCommand(const char* dir, CString& command, OutputSink& output) @@ -866,7 +871,7 @@ int InformApp::RunCommand(const char* dir, CString& command, OutputSink& output) return result; } -void InformApp::RunCensus(bool wait) +HANDLE InformApp::RunCensus(bool wait) { CString command, dir = GetAppDir(); command.Format("\"%s\\Compilers\\ni\" -rules \"%s\\Inform7\\Extensions\" -census", @@ -886,20 +891,25 @@ void InformApp::RunCensus(bool wait) if (created) { + ::CloseHandle(process.hThread); if (wait) - { - DWORD result = STILL_ACTIVE; - while (result == STILL_ACTIVE) - { - ::MsgWaitForMultipleObjects(0,NULL,FALSE,INFINITE,QS_ALLINPUT); - RunMessagePump(); - ::GetExitCodeProcess(process.hProcess,&result); - } - } + return process.hProcess; + else + ::CloseHandle(process.hProcess); + } + return 0; +} - ::CloseHandle(process.hProcess); - ::CloseHandle(process.hThread); +void InformApp::WaitForProcessEnd(HANDLE process) +{ + DWORD result = STILL_ACTIVE; + while (result == STILL_ACTIVE) + { + ::MsgWaitForMultipleObjects(0,NULL,FALSE,INFINITE,QS_ALLINPUT); + RunMessagePump(); + ::GetExitCodeProcess(process,&result); } + ::CloseHandle(process); } void InformApp::WriteLog(const char* msg) diff --git a/Inform7/Inform.h b/Inform7/Inform.h index 41e1965..327543a 100644 --- a/Inform7/Inform.h +++ b/Inform7/Inform.h @@ -15,6 +15,7 @@ // Title #define INFORM_TITLE "Inform" +#define L_INFORM_TITLE L"Inform" // Registry locations #define REGISTRY_PATH_BROWSER "Software\\David Kinder\\Inform\\WebBrowser" @@ -104,6 +105,7 @@ class InformApp : public CWinApp Extensions, Preferences, Spelling, + DownloadedExt }; void SendAllFrames(Changed changed, int value); @@ -122,7 +124,8 @@ class InformApp : public CWinApp void RunMessagePump(void); int RunCommand(const char* dir, CString& command, OutputSink& output); - void RunCensus(bool wait); + HANDLE RunCensus(bool wait); + void WaitForProcessEnd(HANDLE process); void WriteLog(const char* msg); bool IsWaitCursor(void); diff --git a/Inform7/ProjectFrame.cpp b/Inform7/ProjectFrame.cpp index a4cc231..1c742ff 100644 --- a/Inform7/ProjectFrame.cpp +++ b/Inform7/ProjectFrame.cpp @@ -128,7 +128,7 @@ static UINT indicators[] = }; ProjectFrame::ProjectFrame() - : m_compiling(false), m_I6debug(false), m_game(m_skein), m_focus(0), + : m_busy(false), m_I6debug(false), m_game(m_skein), m_focus(0), m_loadFilter(1), m_menuGutter(0), m_menuTextGap(0,0) { } @@ -865,9 +865,11 @@ LRESULT ProjectFrame::OnProjectEdited(WPARAM wparam, LPARAM lparam) LRESULT ProjectFrame::OnExtDownload(WPARAM urls, LPARAM) { + m_busy = true; CStringArray* libraryUrls = (CStringArray*)urls; ExtensionFrame::DownloadExtensions(this,libraryUrls); delete libraryUrls; + m_busy = false; return 0; } @@ -933,6 +935,10 @@ void ProjectFrame::SendChanged(InformApp::Changed changed, int value) ((TabSource*)GetPanel(0)->GetTab(Panel::Tab_Source))->UpdateSpellCheck(); ((TabSource*)GetPanel(1)->GetTab(Panel::Tab_Source))->UpdateSpellCheck(); break; + case InformApp::DownloadedExt: + for (int i = 0; i < 2; i++) + ((TabExtensions*)GetPanel(i)->GetTab(Panel::Tab_Extensions))->DownloadedExt(value); + break; } } @@ -976,19 +982,19 @@ void ProjectFrame::OnFileOpenExt(UINT nID) void ProjectFrame::OnFileClose() { - if (!m_compiling) + if (!m_busy) SendMessage(WM_CLOSE); } void ProjectFrame::OnFileSave() { - if (!m_compiling) + if (!m_busy) SaveProject(m_projectDir); } void ProjectFrame::OnFileSaveAs() { - if (!m_compiling) + if (!m_busy) { // Ask for a project to save as ProjectDirDialog dialog(false,m_projectDir,"Save the project",this); @@ -1022,7 +1028,7 @@ void ProjectFrame::OnFormatElasticTabStops() void ProjectFrame::OnUpdateCompile(CCmdUI *pCmdUI) { - pCmdUI->Enable(!m_compiling); + pCmdUI->Enable(!m_busy); } void ProjectFrame::OnPlayGo() @@ -1057,8 +1063,16 @@ void ProjectFrame::OnPlayStop() void ProjectFrame::OnPlayRefresh() { + // Get the current focus window + HWND focus = GetFocus()->GetSafeHwnd(); + + // Compile the project and show the index if (CompileProject(0)) GetPanel(ChoosePanel(Panel::Tab_Index))->SetActiveTab(Panel::Tab_Index); + + // Return the focus to its original point if still visible + if (::IsWindow(focus) && ::IsWindowVisible(focus)) + ::SetFocus(focus); } void ProjectFrame::OnPlayLoad() @@ -1095,7 +1109,10 @@ void ProjectFrame::OnReplayLast() void ProjectFrame::OnUpdateReplayBlessed(CCmdUI *pCmdUI) { - pCmdUI->Enable(SendMessage(WM_CANPLAYALL) != 0); + bool enable = !m_busy; + if (enable) + enable = SendMessage(WM_CANPLAYALL) != 0; + pCmdUI->Enable(enable); } void ProjectFrame::OnReplayBlessed() @@ -1234,7 +1251,7 @@ void ProjectFrame::OnReplayDifferSkein() void ProjectFrame::OnUpdateReleaseGame(CCmdUI *pCmdUI) { - pCmdUI->Enable(!m_compiling); + pCmdUI->Enable(!m_busy); } void ProjectFrame::OnReleaseGame(UINT nID) @@ -1688,14 +1705,11 @@ bool ProjectFrame::CompileProject(int release) } // Start compiling ... - m_compiling = true; + m_busy = true; // Get the current focus window HWND focus = GetFocus()->GetSafeHwnd(); - // Make the error panel visible - GetPanel(ChoosePanel(Panel::Tab_Results))->SetActiveTab(Panel::Tab_Results); - // Notify panels that compilation is starting GetPanel(0)->CompileProject(TabInterface::CompileStart,0); GetPanel(1)->CompileProject(TabInterface::CompileStart,0); @@ -1710,8 +1724,9 @@ bool ProjectFrame::CompileProject(int release) // Run Inform 6 if (code == 0) { - SetMessageText("Running Inform 6"); code = theApp.RunCommand(m_projectDir+"\\Build",InformCommandLine(release >= 2),*this); + if (code != 0) + SetMessageText("Creating the story file with Inform 6 has failed"); GetPanel(0)->CompileProject(TabInterface::RanInform6,code); GetPanel(1)->CompileProject(TabInterface::RanInform6,code); @@ -1722,16 +1737,15 @@ bool ProjectFrame::CompileProject(int release) final.Format("\nCompiler finished with code %d\n",code); Output(final); - // Update the status bar - SetMessageText(code == 0 ? - "The story has been successfully compiled" : "The story has not been compiled"); + // Make the results panel visible + GetPanel(ChoosePanel(Panel::Tab_Results))->SetActiveTab(Panel::Tab_Results); // Return the focus to its original point if still visible if (::IsWindow(focus) && ::IsWindowVisible(focus)) ::SetFocus(focus); // Finished compiling - m_compiling = false; + m_busy = false; return (code == 0); } @@ -1969,6 +1983,11 @@ void ProjectFrame::Output(const char* msg) SetMessageText(progress); SendMessage(WM_PROGRESS,percent); } + else if (sscanf(line,"++ Ended: %[^^]",progress) == 1) + { + SetMessageText(progress); + SendMessage(WM_PROGRESS,-1); + } } else { diff --git a/Inform7/ProjectFrame.h b/Inform7/ProjectFrame.h index b1f7ca5..aa70453 100644 --- a/Inform7/ProjectFrame.h +++ b/Inform7/ProjectFrame.h @@ -196,7 +196,7 @@ class ProjectFrame : CString m_projectDir; ProjectSettings m_settings; - bool m_compiling; + bool m_busy; bool m_I6debug; CString m_outputFileLoc; diff --git a/Inform7/ReportHtml.cpp b/Inform7/ReportHtml.cpp index 931a52c..fb6fcab 100644 --- a/Inform7/ReportHtml.cpp +++ b/Inform7/ReportHtml.cpp @@ -470,6 +470,17 @@ CString ReportHtml::GetURL(void) return m_url; } +void ReportHtml::Invoke(LPCWSTR method, VARIANT* arg) +{ + IDispatch* disp = GetHtmlDocument(); + CComQIPtr doc(disp); + disp->Release(); + + CComPtr script; + doc->get_Script(&script); + script.Invoke1(method,arg); +} + // COM object for the root Javascript external object BEGIN_DISPATCH_MAP(ScriptExternal,CCmdTarget) diff --git a/Inform7/ReportHtml.h b/Inform7/ReportHtml.h index 82e6ae7..9c01361 100644 --- a/Inform7/ReportHtml.h +++ b/Inform7/ReportHtml.h @@ -59,6 +59,7 @@ class ReportHtml : public CHtmlView void SetFocusFlag(bool focus); void Navigate(const char* url, bool focus, const wchar_t* find = NULL); CString GetURL(void); + void Invoke(LPCWSTR method, VARIANT* arg); protected: ReportHtml(); diff --git a/Inform7/SearchWindow.cpp b/Inform7/SearchWindow.cpp index ed0060c..35205cb 100644 --- a/Inform7/SearchWindow.cpp +++ b/Inform7/SearchWindow.cpp @@ -224,7 +224,7 @@ void SearchWindow::Search(Source* source, LPCWSTR text, CRect& windowRect) CStringW msg; msg.Format(L"Nothing was found when searching for '%s'",text); - theOS.MessageBox(m_parent,msg,L"Inform",MB_ICONWARNING|MB_OK); + theOS.MessageBox(m_parent,msg,L_INFORM_TITLE,MB_ICONWARNING|MB_OK); return; } diff --git a/Inform7/TabExtensions.cpp b/Inform7/TabExtensions.cpp index 4fc0439..e6af924 100644 --- a/Inform7/TabExtensions.cpp +++ b/Inform7/TabExtensions.cpp @@ -115,6 +115,15 @@ void TabExtensions::Show(const char* url) UpdateActiveTab(); } +void TabExtensions::DownloadedExt(int id) +{ + if (GetActiveTab() == ExtTab_Library) + { + CComVariant vid(id); + m_html->Invoke(L"downloadSucceeded",&vid); + } +} + void TabExtensions::SourceLink(const char* url) { } diff --git a/Inform7/TabExtensions.h b/Inform7/TabExtensions.h index 68f1708..cb4f1c1 100644 --- a/Inform7/TabExtensions.h +++ b/Inform7/TabExtensions.h @@ -23,6 +23,7 @@ class TabExtensions : public TabBase, void PrefsChanged(CRegKey& key); void Show(const char* url); + void DownloadedExt(int id); // Implementation of ReportHtml::LinkConsumer void SourceLink(const char* url); diff --git a/Inform7/TabResults.cpp b/Inform7/TabResults.cpp index e4aa8b5..c640195 100644 --- a/Inform7/TabResults.cpp +++ b/Inform7/TabResults.cpp @@ -119,9 +119,6 @@ void TabResults::CompileProject(CompileStage stage, int code) m_report->Navigate("about:blank",false); m_console.ClearText(); m_inform6 = NoError; - - // Switch to the console tab - SetActiveTab(ResTab_Console,false); break; case RanNaturalInform: