From 36a607184fda9aefe63eb3b901cf05906743c754 Mon Sep 17 00:00:00 2001 From: AmadeusK525 Date: Thu, 27 May 2021 11:51:01 -0300 Subject: [PATCH] - Implemented "Recent Documents" list, with the latest documents being inserted in it and their word count. When double-clicked, the document opens in the amStoryWriter. - Changed tables to save memory: Now there is a 'last_session' table and a 'sessions' table. They have different things in them and 'last_session' only has 1 entry, forever. - Fixed bugs in amStoryWriter and amStoryWriterNotebook when selecting tabs in the wxAuiNotebook. - Changed the left pane notebook to be a wxAuiNotebook so it could use a wxAuiSimpleTabArt (the main notebook also uses this art now), because that can be a lot better integrated with the Dark Theme. - Started emulating a page view in the main notebook in amStoryWriterNotebook, with the wxRTC being restricted to a maximum width. - Fixed a bug in the hot-tracking wxDVC when using headers. --- Amadeus.sln | 19 +++++ Amadeus.vcxproj | 4 +- Amadeus.vcxproj.filters | 6 +- src/BookElements.cpp | 28 +++++++ src/BookElements.h | 2 + src/MainFrame.cpp | 6 +- src/Overview.cpp | 83 +++++++++++++++------ src/Overview.h | 3 + src/ProjectManager.cpp | 152 ++++++++++++++++++++++++------------- src/ProjectManager.h | 3 +- src/StoryWriter.cpp | 161 ++++++++++++++++++++++++---------------- src/StoryWriter.h | 6 +- src/amUtility.h | 39 ++++------ 13 files changed, 337 insertions(+), 175 deletions(-) diff --git a/Amadeus.sln b/Amadeus.sln index 1ce2b52..dc6cad9 100644 --- a/Amadeus.sln +++ b/Amadeus.sln @@ -4,6 +4,7 @@ VisualStudioVersion = 16.0.30406.217 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Amadeus", "Amadeus.vcxproj", "{853D1FD7-20AB-586C-9699-9680F84AC985}" ProjectSection(ProjectDependencies) = postProject + {A16D3832-0F42-57CE-8F48-50E06649ADE8} = {A16D3832-0F42-57CE-8F48-50E06649ADE8} {3FCC50C2-81E9-5DB2-B8D8-2129427568B1} = {3FCC50C2-81E9-5DB2-B8D8-2129427568B1} {6744DAD8-9C70-574A-BFF2-9F8DDDB24A75} = {6744DAD8-9C70-574A-BFF2-9F8DDDB24A75} EndProjectSection @@ -12,6 +13,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "base", "F:\wxWidgets\build\ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core", "F:\wxWidgets\build\msw\wx_core.vcxproj", "{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "aui", "F:\wxWidgets\build\msw\wx_aui.vcxproj", "{A16D3832-0F42-57CE-8F48-50E06649ADE8}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -72,6 +75,22 @@ Global {6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Release|Win32.Build.0 = Release|Win32 {6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Release|x64.ActiveCfg = Release|x64 {6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Release|x64.Build.0 = Release|x64 + {A16D3832-0F42-57CE-8F48-50E06649ADE8}.Debug|Win32.ActiveCfg = Debug|Win32 + {A16D3832-0F42-57CE-8F48-50E06649ADE8}.Debug|Win32.Build.0 = Debug|Win32 + {A16D3832-0F42-57CE-8F48-50E06649ADE8}.Debug|x64.ActiveCfg = Debug|x64 + {A16D3832-0F42-57CE-8F48-50E06649ADE8}.Debug|x64.Build.0 = Debug|x64 + {A16D3832-0F42-57CE-8F48-50E06649ADE8}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 + {A16D3832-0F42-57CE-8F48-50E06649ADE8}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 + {A16D3832-0F42-57CE-8F48-50E06649ADE8}.DLL Debug|x64.ActiveCfg = DLL Debug|x64 + {A16D3832-0F42-57CE-8F48-50E06649ADE8}.DLL Debug|x64.Build.0 = DLL Debug|x64 + {A16D3832-0F42-57CE-8F48-50E06649ADE8}.DLL Release|Win32.ActiveCfg = DLL Release|Win32 + {A16D3832-0F42-57CE-8F48-50E06649ADE8}.DLL Release|Win32.Build.0 = DLL Release|Win32 + {A16D3832-0F42-57CE-8F48-50E06649ADE8}.DLL Release|x64.ActiveCfg = DLL Release|x64 + {A16D3832-0F42-57CE-8F48-50E06649ADE8}.DLL Release|x64.Build.0 = DLL Release|x64 + {A16D3832-0F42-57CE-8F48-50E06649ADE8}.Release|Win32.ActiveCfg = Release|Win32 + {A16D3832-0F42-57CE-8F48-50E06649ADE8}.Release|Win32.Build.0 = Release|Win32 + {A16D3832-0F42-57CE-8F48-50E06649ADE8}.Release|x64.ActiveCfg = Release|x64 + {A16D3832-0F42-57CE-8F48-50E06649ADE8}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Amadeus.vcxproj b/Amadeus.vcxproj index a5aa655..930db78 100644 --- a/Amadeus.vcxproj +++ b/Amadeus.vcxproj @@ -201,7 +201,7 @@ wxmsw$(wxShortVersionString)u_html.lib;wxbase$(wxShortVersionString)u_xml.lib;wxmsw$(wxShortVersionString)u_richtext.lib;wxmsw$(wxShortVersionString)u_aui.lib;wxmsw$(wxShortVersionString)u_core.lib;wxbase$(wxShortVersionString)u.lib;wxjpeg.lib;wxpng.lib;wxzlib.lib;wxregexu.lib;wxexpat.lib;kernel32.lib;user32.lib;gdi32.lib;comdlg32.lib;winspool.lib;winmm.lib;shell32.lib;shlwapi.lib;comctl32.lib;ole32.lib;oleaut32.lib;uuid.lib;rpcrt4.lib;advapi32.lib;version.lib;wsock32.lib;wininet.lib;%(AdditionalDependencies);wxmsw28u_wxsf.lib;wxsqlite3.lib true - $(WXWIN)\lib\vc_lib;$(WXWIN)\lib\vc_lib\mswu;$(WXWIN)\3rdparty\wxSF\lib\vc_lib;$(WXWIN)\3rdparty\wxsqlite3-4.6.4\lib\vc_lib;%(AdditionalLibraryDirectories) + $(SolutionDir)\src\Notebook;$(WXWIN)\lib\vc_lib;$(WXWIN)\lib\vc_lib\mswu;$(WXWIN)\3rdparty\wxSF\lib\vc_lib;$(WXWIN)\3rdparty\wxsqlite3-4.6.4\lib\vc_lib;%(AdditionalLibraryDirectories) true Windows MachineX86 @@ -460,9 +460,9 @@ - + diff --git a/Amadeus.vcxproj.filters b/Amadeus.vcxproj.filters index b9ea730..d46e5e6 100644 --- a/Amadeus.vcxproj.filters +++ b/Amadeus.vcxproj.filters @@ -124,9 +124,6 @@ Header Files - - Header Files - Header Files @@ -190,6 +187,9 @@ Header Files + + Header Files + diff --git a/src/BookElements.cpp b/src/BookElements.cpp index d61ef4f..3fd894e 100644 --- a/src/BookElements.cpp +++ b/src/BookElements.cpp @@ -3,6 +3,8 @@ #include #include +#include + #include "MyApp.h" #include "wxmemdbg.h" @@ -30,6 +32,11 @@ Document::~Document() CleanUp(); } +bool Document::IsStory() +{ + return type == Document_Chapter || type == Document_Scene || type == Document_Other; +} + bool Document::HasRedNote() { for ( Note*& pNote : notes ) @@ -41,6 +48,27 @@ bool Document::HasRedNote() return false; } +int Document::GetWordCount() +{ + amProjectSQLDatabase* pDb = amGetManager()->GetStorage(); + wxSQLite3ResultSet result = pDb->ExecuteQuery("SELECT plain_text FROM documents WHERE id = " + std::to_string(id)); + + int count = 0; + + if ( result.NextRow() ) + { + std::string content = result.GetAsString("plain_text"); + + if ( !content.empty() ) + { + std::stringstream sstream(content); + count = std::distance(std::istream_iterator(sstream), std::istream_iterator()); + } + } + + return count; +} + void Document::Save(wxSQLite3Database* db) { try diff --git a/src/BookElements.h b/src/BookElements.h index 2c760cb..3f44656 100644 --- a/src/BookElements.h +++ b/src/BookElements.h @@ -79,8 +79,10 @@ struct Document virtual ~Document(); void SetId(int id) { this->id = id; } + bool IsStory(); bool HasRedNote(); + int GetWordCount(); void Save(wxSQLite3Database* db); bool Update(wxSQLite3Database* db, bool updateContent, bool updateNotes); diff --git a/src/MainFrame.cpp b/src/MainFrame.cpp index 903f64d..df8d99a 100644 --- a/src/MainFrame.cpp +++ b/src/MainFrame.cpp @@ -81,7 +81,7 @@ amMainFrame::amMainFrame(const wxString& title, amProjectManager* manager, const m_selPanel->SetBackgroundColour(wxColour(40, 40, 40)); m_selPanel->SetDoubleBuffered(true); - wxFont font(wxFontInfo(13).Family(wxFONTFAMILY_MODERN).Bold().AntiAliased()); + wxFont font(wxFontInfo(12).Family(wxFONTFAMILY_MODERN).Bold().AntiAliased()); for ( int i = 0; i < 5; i++ ) m_mainButtons.push_back(nullptr); @@ -102,12 +102,12 @@ amMainFrame::amMainFrame(const wxString& title, amProjectManager* manager, const button->SetForegroundColour(wxColour(245, 245, 245)); button->Bind(wxEVT_ENTER_WINDOW, amOnEnterDarkButton); button->Bind(wxEVT_LEAVE_WINDOW, amOnLeaveDarkButton); - m_buttonSizer->Add(button, wxSizerFlags(1).Expand().Border(wxTOP | wxLEFT | wxRIGHT, 5)); + m_buttonSizer->Add(button, wxSizerFlags(1).Expand().Border(wxALL, 2)); } m_mainButtons[0]->SetBackgroundColour(wxDarkenColour(wxColour(130, 0, 0), 28)); - m_buttonSizer->AddStretchSpacer(2); + m_buttonSizer->AddStretchSpacer(3); m_selPanel->SetSizer(m_buttonSizer); m_mainBook = new wxSimplebook(m_mainSplitter); diff --git a/src/Overview.cpp b/src/Overview.cpp index 3ddc234..9913863 100644 --- a/src/Overview.cpp +++ b/src/Overview.cpp @@ -113,31 +113,42 @@ amOverview::amOverview(wxWindow* parent, amProjectManager* manager) : wxPanel(pa sizer->Add(m_bookPicker, wxSizerFlags(1).Top()); sizer->Add(m_stBookTitle, wxSizerFlags(1).Top()); -// m_recentDocumentsModel = new StoryTreeModel; -// -//#ifdef __WXMSW__ -// m_recentDocumentsDVC = m_recentDocumentsHandler.Create(this, -1, m_recentDocumentsModel.get(), -// wxBORDER_NONE | wxDV_MULTIPLE); -//#else -// m_recentDocumentsDVC = new wxDataViewCtrl(m_secondPanel, -1, wxDefaultPosition, wxDefaultSize, -// wxDV_SINGLE | wxBORDER_NONE); -// m_recentDocumentsDVC->AssociateModel(&m_recentDocumentsModel); -//#endif -// -// m_recentDocumentsDVC->SetBackgroundColour(wxColour(90, 90, 90)); -// //m_recentDocumentsDVC->Bind(wxEVT_DATAVIEW_ITEM_ACTIVATED, &amElementShowcase::OnDocumentActivated, this); -// -// wxDataViewColumn* pColumn = new wxDataViewColumn(_("Documents"), new wxDataViewIconTextRenderer(wxDataViewIconTextRenderer::GetDefaultType(), -// wxDATAVIEW_CELL_EDITABLE), 0, FromDIP(200), wxALIGN_LEFT); -// m_recentDocumentsDVC->AppendColumn(pColumn); -// -// pColumn = new wxDataViewColumn(_("Words"), new wxDataViewTextRenderer(wxDataViewTextRenderer::GetDefaultType(), -// wxDATAVIEW_CELL_INERT), 1, FromDIP(80), wxALIGN_CENTER); -// m_recentDocumentsDVC->AppendColumn(pColumn); + wxStaticText* pRecentDocumentsLabel = new wxStaticText(this, -1, _("Recent Documents:")); + pRecentDocumentsLabel->SetBackgroundColour(wxColour(40, 40, 40)); + pRecentDocumentsLabel->SetForegroundColour(wxColour(240,240,240)); + pRecentDocumentsLabel->SetFont(wxFontInfo(10).Bold()); + + m_recentDocumentsModel = new StoryTreeModel; + +#ifdef __WXMSW__ + m_recentDocumentsDVC = m_recentDocumentsHandler.Create(this, -1, m_recentDocumentsModel.get(), + wxBORDER_NONE | wxDV_MULTIPLE); +#else + m_recentDocumentsDVC = new wxDataViewCtrl(m_secondPanel, -1, wxDefaultPosition, wxDefaultSize, + wxDV_SINGLE | wxBORDER_NONE); + m_recentDocumentsDVC->AssociateModel(&m_recentDocumentsModel); +#endif + + m_recentDocumentsDVC->SetBackgroundColour(wxColour(90, 90, 90)); + m_recentDocumentsDVC->SetMinSize(wxSize(FromDIP(250), -1)); + m_recentDocumentsDVC->Bind(wxEVT_DATAVIEW_ITEM_ACTIVATED, &amOverview::OnRecentDocument, this); + + wxDataViewColumn* pColumn = new wxDataViewColumn(_("Document name"), new wxDataViewIconTextRenderer(wxDataViewIconTextRenderer::GetDefaultType(), + wxDATAVIEW_CELL_EDITABLE), 0, FromDIP(170), wxALIGN_LEFT); + m_recentDocumentsDVC->AppendColumn(pColumn); + + pColumn = new wxDataViewColumn(_("Words"), new wxDataViewTextRenderer(wxDataViewTextRenderer::GetDefaultType(), + wxDATAVIEW_CELL_INERT), 1, FromDIP(80), wxALIGN_CENTER); + m_recentDocumentsDVC->AppendColumn(pColumn); + + wxBoxSizer* pRecentDocumentsSizer = new wxBoxSizer(wxVERTICAL); + pRecentDocumentsSizer->Add(pRecentDocumentsLabel, wxSizerFlags(0).Expand()); + pRecentDocumentsSizer->Add(m_recentDocumentsDVC, wxSizerFlags(1)); m_mainSizer = new wxBoxSizer(wxVERTICAL); m_mainSizer->Add(sizer, wxSizerFlags(0).Expand()); - //m_mainSizer->Add(m_recentDocumentsDVC, wxSizerFlags(1).Left().Border(wxALL, 10)); + m_mainSizer->AddSpacer(10); + m_mainSizer->Add(pRecentDocumentsSizer, wxSizerFlags(1).Left()); SetSizer(m_mainSizer); Layout(); @@ -154,9 +165,37 @@ void amOverview::SetBookData(Book* book) m_stBookTitle->Wrap(m_stBookTitle->GetSize().x); Layout(); + LoadRecentDocuments(book); + Thaw(); } +void amOverview::LoadRecentDocuments(Book* book) +{ + Freeze(); + + m_recentDocumentsModel->ClearAll(); + + for ( Document*& pDocument : book->vRecentDocuments ) + { + wxDataViewItem docItem = m_recentDocumentsModel->AddDocument(pDocument, wxDataViewItem(nullptr)); + } + + Thaw(); +} + +void amOverview::OnRecentDocument(wxDataViewEvent& event) +{ + StoryTreeModelNode* pNode = (StoryTreeModelNode*)event.GetItem().GetID(); + if ( !pNode ) + return; + + if ( pNode->GetDocument() ) + m_manager->OpenDocument(pNode->GetDocument()); + + event.Skip(); +} + void amOverview::LoadBookContainer() { wxVector& books = m_manager->GetBooks(); diff --git a/src/Overview.h b/src/Overview.h index add8981..31660f7 100644 --- a/src/Overview.h +++ b/src/Overview.h @@ -73,8 +73,11 @@ class amOverview : public wxPanel amOverview(wxWindow* parent, amProjectManager* manager); void SetBookData(Book* book); + void LoadRecentDocuments(Book* book); void LoadBookContainer(); + + void OnRecentDocument(wxDataViewEvent& event); }; #endif \ No newline at end of file diff --git a/src/ProjectManager.cpp b/src/ProjectManager.cpp index 63aab4c..b62589d 100644 --- a/src/ProjectManager.cpp +++ b/src/ProjectManager.cpp @@ -184,16 +184,23 @@ void amProjectSQLDatabase::CreateAllTables() ///////////////////// PROJECT TABLES /////////////////////// wxArrayString tProject; + tProject.Add("id INTEGER PRIMARY KEY"); tProject.Add("name TEXT"); tProject.Add("version TEXT"); tProject.Add("preferences TEXT"); wxArrayString tSessions; - tSessions.Add("selected_book_id INTEGER"); - tSessions.Add("recent_documents TEXT"); + tSessions.Add("id INTEGER PRIMARY KEY"); + tSessions.Add("total_word_count INTEGER"); + tSessions.Add("story_word_count INTEGER"); tSessions.Add("date TEXT"); - tSessions.Add("session_attributes TEXT"); - tSessions.Add("FOREIGN KEY (selected_book_id) REFERENCES books(id)"); + + wxArrayString tLastSession; + tLastSession.Add("id INTEGER PRIMARY KEY"); + tLastSession.Add("selected_book_id INTEGER"); + tLastSession.Add("session_attributes TEXT"); + tLastSession.Add("recent_documents TEXT"); + tLastSession.Add("FOREIGN KEY (selected_book_id) REFERENCES books(id)"); try { @@ -221,6 +228,7 @@ void amProjectSQLDatabase::CreateAllTables() //CreateTable("project", tProject); CreateTable("sessions", tSessions); + CreateTable("last_session", tLastSession); Commit(); } @@ -634,6 +642,7 @@ void amSessionAttributes::MarkSerializableDataMembers() XS_SERIALIZE_INT(nCharacterSashPos, "character-sash-pos"); XS_SERIALIZE_INT(nLocationSashPos, "location-sash-pos"); XS_SERIALIZE_INT(nItemSashPos, "item-sash-pos"); + XS_SERIALIZE_INT(nOutlineFilesSashPos, "outline-files-sash-pos"); } @@ -713,66 +722,103 @@ bool amProjectManager::SaveSessionToDb() { try { - amSessionAttributes attr; - attr.nMainFrameSashPos = m_mainFrame->GetMainSplitter()->GetSashPosition(); - attr.nCharacterSashPos = m_elementNotebook->m_characterPage->GetSashPosition(); - attr.nLocationSashPos = m_elementNotebook->m_locationPage->GetSashPosition(); - attr.nItemSashPos = m_elementNotebook->m_itemPage->GetSashPosition(); + // Saving last session + { + amSessionAttributes attr; + attr.nMainFrameSashPos = m_mainFrame->GetMainSplitter()->GetSashPosition(); + attr.nCharacterSashPos = m_elementNotebook->m_characterPage->GetSashPosition(); + attr.nLocationSashPos = m_elementNotebook->m_locationPage->GetSashPosition(); + attr.nItemSashPos = m_elementNotebook->m_itemPage->GetSashPosition(); + attr.nOutlineFilesSashPos = m_outline->GetOutlineFiles()->GetSashPosition(); + + wxXmlDocument attrDoc; + wxXmlNode* pAttrRootNode = new wxXmlNode(nullptr, wxXML_ELEMENT_NODE, "Session-Attributes"); + attrDoc.SetRoot(pAttrRootNode); + pAttrRootNode->AddChild(attr.SerializeObject(nullptr)); + + wxStringOutputStream attrStream; + attrDoc.Save(attrStream); + + wxXmlDocument doc; + wxXmlNode* pDocsRootNode = new wxXmlNode(nullptr, wxXML_ELEMENT_NODE, "Recent-Documents"); + doc.SetRoot(pDocsRootNode); + + for ( Book*& pBook : m_project.books ) + { + wxXmlNode* pBookNode = new wxXmlNode(wxXML_ELEMENT_NODE, "Book"); + pBookNode->AddAttribute("name", pBook->title); + pBookNode->AddAttribute("id", std::to_string(pBook->id)); - wxXmlDocument attrDoc; - wxXmlNode* pAttrRootNode = new wxXmlNode(nullptr, wxXML_ELEMENT_NODE, "Session-Attributes"); - attrDoc.SetRoot(pAttrRootNode); - pAttrRootNode->AddChild(attr.SerializeObject(nullptr)); + for ( Document*& pDocument : pBook->vRecentDocuments ) + { + wxXmlNode* pDocNode = new wxXmlNode(wxXML_ELEMENT_NODE, "Document"); + pDocNode->AddChild(new wxXmlNode(wxXML_TEXT_NODE, pDocument->name)); + pDocNode->AddAttribute("id", std::to_string(pDocument->id)); - wxStringOutputStream attrStream; - attrDoc.Save(attrStream); + pBookNode->AddChild(pDocNode); + } - wxXmlDocument doc; - wxXmlNode* pDocsRootNode = new wxXmlNode(nullptr, wxXML_ELEMENT_NODE, "Recent-Documents"); - doc.SetRoot(pDocsRootNode); + pDocsRootNode->AddChild(pBookNode); + } - for ( Book*& pBook : m_project.books ) - { - wxXmlNode* pBookNode = new wxXmlNode(pDocsRootNode, wxXML_ELEMENT_NODE, "Book"); - pBookNode->AddAttribute("name", pBook->title); - pBookNode->AddAttribute("id", std::to_string(pBook->id)); + wxStringOutputStream docStream; + doc.Save(docStream); - for ( auto it = pBook->vRecentDocuments.rbegin(); - it != pBook->vRecentDocuments.rend(); it++ ) + + wxSQLite3ResultSet result = m_storage.ExecuteQuery("SELECT id FROM last_session;"); + wxSQLite3StatementBuffer sqlBuffer; + if ( result.NextRow() ) { - wxXmlNode* pDocNode = new wxXmlNode(pBookNode, wxXML_ELEMENT_NODE, "Document"); - pDocNode->AddChild(new wxXmlNode(wxXML_TEXT_NODE, (*it)->name)); - pDocNode->AddAttribute("id", std::to_string((*it)->id)); - } - } + wxString strUpdate = "UPDATE last_session SET selected_book_id = "; + strUpdate << GetCurrentBook()->id << ", recent_documents = '%q', session_attributes = '%q';"; - wxStringOutputStream docStream; - doc.Save(docStream); + sqlBuffer.Format((const char*)strUpdate, (const char*)docStream.GetString().ToUTF8(), + (const char*)attrStream.GetString().ToUTF8()); + } + else + { + wxString strInsert = "INSERT INTO last_session (selected_book_id, recent_documents, session_attributes) VALUES ("; + strInsert << GetCurrentBook()->id << ", '%q', '%q')"; - wxString strDate = wxDateTime::Now().FormatDate(); + sqlBuffer.Format((const char*)strInsert, (const char*)docStream.GetString().ToUTF8(), + (const char*)attrStream.GetString().ToUTF8()); + } - wxSQLite3ResultSet result = m_storage.ExecuteQuery("SELECT date FROM sessions WHERE date = '" + strDate + "';"); - wxSQLite3StatementBuffer sqlBuffer; + m_storage.ExecuteUpdate(sqlBuffer); + } - if ( result.NextRow() ) + // Saving persistent session attributes { - wxString strUpdate = "UPDATE sessions SET selected_book_id = "; - strUpdate << GetCurrentBook()->id << ", recent_documents = '%q', session_attributes = '%q'" - " WHERE date = '" << strDate << "';"; + int totalWordCount = 0, storyWordCount = 0; + for ( Book*& pBook : m_project.books ) + { + for ( Document*& pDocument : pBook->documents ) + { + int wordCount = pDocument->GetWordCount(); + totalWordCount += wordCount; + + if ( pDocument->IsStory() ) + storyWordCount += wordCount; + } + } - sqlBuffer.Format((const char*)strUpdate, (const char*)docStream.GetString().ToUTF8(), - (const char*)attrStream.GetString().ToUTF8()); - } - else - { - wxString strInsert = "INSERT INTO sessions (selected_book_id, recent_documents, session_attributes, date) VALUES ("; - strInsert << GetCurrentBook()->id << ", '%q', '%q', '%q')"; + wxString strDate = wxDateTime::Now().FormatDate(); + wxSQLite3ResultSet result = m_storage.ExecuteQuery("SELECT id FROM sessions WHERE date = '" + strDate + "';"); + wxString update; - sqlBuffer.Format((const char*)strInsert, (const char*)docStream.GetString().ToUTF8(), - (const char*)attrStream.GetString().ToUTF8(), (const char*)strDate.ToUTF8()); - } + if ( result.NextRow() ) + { + update << "UPDATE sessions SET total_word_count = " << totalWordCount + << ", story_word_count = " << storyWordCount << " WHERE date = '" << strDate << "';"; + } + else + { + update << "INSERT INTO sessions (total_word_count, story_word_count, date) VALUES (" << totalWordCount + << ", " << storyWordCount << ", '" << strDate << "');"; + } - m_storage.ExecuteUpdate(sqlBuffer); + m_storage.ExecuteUpdate(update); + } } catch ( wxSQLite3Exception& e ) { @@ -1145,7 +1191,7 @@ void amProjectManager::LoadCharacterRelations() bool amProjectManager::LoadLastSession() { - wxSQLite3ResultSet result = m_storage.ExecuteQuery("SELECT * FROM sessions ORDER BY rowid DESC;"); + wxSQLite3ResultSet result = m_storage.ExecuteQuery("SELECT * FROM last_session;"); if ( result.NextRow() ) { wxStringInputStream sstream(result.GetAsString("recent_documents")); @@ -1161,7 +1207,7 @@ bool amProjectManager::LoadLastSession() while ( pDocNode ) { - pBook->vRecentDocuments.push_back(GetDocumentById(wxAtoi(pDocNode->GetAttribute("id")))); + pBook->PushRecentDocument(GetDocumentById(wxAtoi(pDocNode->GetAttribute("id")))); pDocNode = pDocNode->GetNext(); } @@ -1201,6 +1247,8 @@ void amProjectManager::LoadSessionAttr(const amSessionAttributes& attr) if ( attr.nItemSashPos != -1 ) m_elementNotebook->m_itemPage->SetSashPosition(attr.nItemSashPos, false); + if ( attr.nOutlineFilesSashPos != -1 ) + m_outline->GetOutlineFiles()->SetSashPosition(attr.nOutlineFilesSashPos, false); } void amProjectManager::SetExecutablePath(const wxString& path) diff --git a/src/ProjectManager.h b/src/ProjectManager.h index 7780fc1..50b6f38 100644 --- a/src/ProjectManager.h +++ b/src/ProjectManager.h @@ -77,7 +77,8 @@ struct amSessionAttributes : public xsSerializable int nMainFrameSashPos = -1, nCharacterSashPos = -1, nLocationSashPos = -1, - nItemSashPos = -1; + nItemSashPos = -1, + nOutlineFilesSashPos = -1; amSessionAttributes() { MarkSerializableDataMembers(); } diff --git a/src/StoryWriter.cpp b/src/StoryWriter.cpp index 602aa19..49340db 100644 --- a/src/StoryWriter.cpp +++ b/src/StoryWriter.cpp @@ -75,6 +75,9 @@ wxDataViewItem StoryTreeModel::AddDocument(Document* document, const wxDataViewI parent = parentItem; } + if ( !parent.IsOk() ) + m_otherRoots.push_back(node); + wxDataViewItem item(node); ItemAdded(parent, item); @@ -292,11 +295,20 @@ void StoryTreeModel::ClearAll() } m_vBooks.clear(); + size_t otherRootsCount = m_otherRoots.size(); + for ( int i = 0; i < otherRootsCount; i++ ) + { + DeleteItem(wxDataViewItem(m_otherRoots[0])); + } + m_otherRoots.clear(); + if ( m_trashNode ) { DeleteItem(wxDataViewItem(m_trashNode)); m_trashNode = nullptr; } + + m_handler->SetItemUnderMouse(wxDataViewItem(nullptr)); } void StoryTreeModel::GetValue(wxVariant& variant, @@ -304,22 +316,28 @@ void StoryTreeModel::GetValue(wxVariant& variant, { StoryTreeModelNode* node = (StoryTreeModelNode*)item.GetID(); - wxDataViewIconText it; - it.SetText(node->GetTitle()); - - if ( node->IsBook() ) - it.SetIcon(node->m_icons[0]); - else if ( node->IsDocument() ) - it.SetIcon(node->m_icons[2]); - else if ( node->IsTrash() ) - it.SetIcon(node->m_icons[3]); - switch ( col ) { case 0: + { + wxDataViewIconText it; + it.SetText(node->GetTitle()); + + if ( node->IsBook() ) + it.SetIcon(node->m_icons[0]); + else if ( node->IsDocument() ) + it.SetIcon(node->m_icons[2]); + else if ( node->IsTrash() ) + it.SetIcon(node->m_icons[3]); + variant << it; break; - default: + } + + case 1: + if ( node->IsDocument() ) + variant = std::to_string(node->GetDocument()->GetWordCount()); + break; } } @@ -435,11 +453,18 @@ amStoryWriter::amStoryWriter(wxWindow* parent, amProjectManager* manager, Docume leftSplitter->SetMinimumPaneSize(30); rightSplitter->SetMinimumPaneSize(30); - rightSplitter->SetDoubleBuffered(true); - m_swNotebook = new amStoryWriterNotebook(leftSplitter, this); - wxNotebook* leftNotebook = new wxNotebook(leftSplitter, -1, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); + wxAuiNotebook* leftNotebook = new wxAuiNotebook(leftSplitter, -1, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); + + wxAuiSimpleTabArt* pArt = new wxAuiSimpleTabArt(); + pArt->SetColour(wxColour(50, 50, 50)); + pArt->SetActiveColour(wxColour(30, 30, 30)); + leftNotebook->SetArtProvider(pArt); + + leftNotebook->GetAuiManager().GetArtProvider()->SetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE, 0); + leftNotebook->GetAuiManager().GetArtProvider()->SetMetric(wxAUI_DOCKART_GRADIENT_TYPE, wxAUI_GRADIENT_NONE); + m_leftPanel = new wxPanel(leftNotebook, -1, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); m_leftPanel->SetBackgroundColour(wxColour(45, 45, 45)); @@ -575,7 +600,7 @@ amStoryWriter::amStoryWriter(wxWindow* parent, amProjectManager* manager, Docume m_leftSizer->Add(m_locationPanel, wxSizerFlags(1).Expand()); m_leftSizer->AddSpacer(FromDIP(15)); m_leftSizer->Add(m_itemPanel, wxSizerFlags(1).Expand()); - m_leftSizer->Add(leftButton, wxSizerFlags(0).Right().Border(wxALL, 5)); + m_leftSizer->Add(leftButton, wxSizerFlags(0).Right()); m_leftPanel->SetSizer(m_leftSizer); @@ -604,7 +629,7 @@ amStoryWriter::amStoryWriter(wxWindow* parent, amProjectManager* manager, Docume wxBoxSizer* outlineSizer = new wxBoxSizer(wxVERTICAL); outlineSizer->Add(m_outlineView, wxSizerFlags(1).Expand()); - outlineSizer->Add(leftButton2, wxSizerFlags(0).Right().Border(wxALL, 5)); + outlineSizer->Add(leftButton2, wxSizerFlags(0).Right()); leftPanel2->SetSizer(outlineSizer); @@ -645,10 +670,10 @@ amStoryWriter::amStoryWriter(wxWindow* parent, amProjectManager* manager, Docume wxBoxSizer* storySizer = new wxBoxSizer(wxVERTICAL); storySizer->Add(m_storyView, wxSizerFlags(1).Expand()); - storySizer->Add(leftButton3, wxSizerFlags(0).Right().Border(wxALL, 5)); + storySizer->Add(leftButton3, wxSizerFlags(0).Right()); leftPanel3->SetSizer(storySizer); - + leftNotebook->AddPage(leftPanel3, "Story"); leftNotebook->AddPage(leftPanel2, "Outline"); leftNotebook->AddPage(m_leftPanel, "Elements"); @@ -656,14 +681,18 @@ amStoryWriter::amStoryWriter(wxWindow* parent, amProjectManager* manager, Docume wxPanel* rightPanel = new wxPanel(rightSplitter, -1); rightPanel->SetBackgroundColour(wxColour(60, 60, 60)); - m_synopsys = new wxTextCtrl(rightPanel, -1, "", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxBORDER_NONE); + wxRichTextAttr attr; + attr.SetTextColour(wxColour(245, 245, 245)); + attr.SetFont(wxFontInfo(10)); + + m_synopsys = new wxRichTextCtrl(rightPanel, -1, "", wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); m_synopsys->SetBackgroundColour(wxColour(35, 35, 35)); - m_synopsys->SetFont(wxFontInfo(10)); + m_synopsys->SetBasicStyle(attr); m_synopsys->SetForegroundColour(wxColour(245, 245, 245)); - m_synopsys->SetBackgroundStyle(wxBG_STYLE_PAINT); + //m_synopsys->SetBackgroundStyle(wxBG_STYLE_PAINT); wxStaticText* sumLabel = new wxStaticText(rightPanel, -1, "Synopsys", wxDefaultPosition, wxDefaultSize, wxBORDER_SIMPLE); - sumLabel->SetBackgroundColour(wxColour(150, 0, 0)); + sumLabel->SetBackgroundColour(wxColour(110, 0, 0)); sumLabel->SetFont(wxFont(wxFontInfo(10).Bold().AntiAliased())); sumLabel->SetForegroundColour(wxColour(255, 255, 255)); sumLabel->SetBackgroundStyle(wxBG_STYLE_PAINT); @@ -675,17 +704,18 @@ amStoryWriter::amStoryWriter(wxWindow* parent, amProjectManager* manager, Docume m_noteChecker->SetBackgroundStyle(wxBG_STYLE_PAINT); m_noteLabel = new wxTextCtrl(rightPanel, -1, "New note", wxDefaultPosition, wxDefaultSize, wxBORDER_SIMPLE); - m_noteLabel->SetBackgroundColour(wxColour(245, 245, 245)); + m_noteLabel->SetBackgroundColour(wxColour(80, 80, 80)); + m_noteLabel->SetForegroundColour(wxColour(255, 255, 255)); m_noteLabel->SetFont(wxFont(wxFontInfo(10))); m_noteLabel->SetBackgroundStyle(wxBG_STYLE_PAINT); - m_note = new wxTextCtrl(rightPanel, -1, "", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxBORDER_NONE); - m_note->SetBackgroundColour(wxColour(255, 250, 205)); - m_note->SetFont(wxFont(wxFontInfo(10))); - m_note->SetBackgroundStyle(wxBG_STYLE_PAINT); + m_note = new wxRichTextCtrl(rightPanel, -1, "", wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); + m_note->SetBackgroundColour(wxColour(50, 50, 50)); + m_note->SetBasicStyle(attr); + //m_note->SetBackgroundStyle(wxBG_STYLE_PAINT); wxPanel* nbHolder = new wxPanel(rightPanel, -1, wxDefaultPosition, wxDefaultSize, wxBORDER_SIMPLE); - nbHolder->SetBackgroundColour(wxColour(255, 250, 205)); + nbHolder->SetBackgroundColour(wxColour(30, 30, 30)); m_noteClear = new wxButton(nbHolder, BUTTON_NoteClear, "Clear"); m_noteClear->SetBackgroundColour(wxColour(240, 240, 240)); @@ -711,7 +741,7 @@ amStoryWriter::amStoryWriter(wxWindow* parent, amProjectManager* manager, Docume m_rightSizer->Add(m_noteLabel, wxSizerFlags(0).Expand()); m_rightSizer->Add(m_note, wxSizerFlags(1).Expand()); m_rightSizer->Add(nbHolder, wxSizerFlags(0).Expand()); - m_rightSizer->Add(rightButton, wxSizerFlags(0).Left().Border(wxALL, 5)); + m_rightSizer->Add(rightButton, wxSizerFlags(0).Left()); rightPanel->SetSizer(m_rightSizer); @@ -1219,17 +1249,10 @@ void amStoryWriter::LoadDocument(Document* document) { if ( tab.document == document ) { - for ( int i = 0; i < notebook->GetPageCount(); i++ ) - { - wxWindow* window = notebook->GetPage(i); - if ( window == tab.mainPanel) - { - m_swNotebook->SetCurrentTab(tab, false); - m_statusBar->SetStatusText("Zoom: " + std::to_string((int)(tab.rtc->GetFontScale() * 100)) + "%", 2); - bIsOpen = true; - break; - } - } + m_swNotebook->SetCurrentTab(tab, false); + m_statusBar->SetStatusText("Zoom: " + std::to_string((int)(tab.rtc->GetFontScale() * 100)) + "%", 2); + bIsOpen = true; + break; } } @@ -1243,6 +1266,7 @@ void amStoryWriter::LoadDocument(Document* document) wxRichTextCtrl* rtc = new wxRichTextCtrl(mainPanel, TEXT_Content, "", wxDefaultPosition, wxDefaultSize, wxRE_MULTILINE | wxBORDER_NONE); + rtc->SetMinSize(wxSize(750, -1)); rtc->Bind(wxEVT_RICHTEXT_CHARACTER, &amStoryWriter::OnCharRTC, this); rtc->Bind(wxEVT_RICHTEXT_DELETE, &amStoryWriter::OnCharRTC, this); @@ -1272,8 +1296,8 @@ void amStoryWriter::LoadDocument(Document* document) notePage->SetSizer(notesSizer); notePage->SetScrollRate(15, 15); - wxBoxSizer* mainPanelSizer = new wxBoxSizer(wxHORIZONTAL); - mainPanelSizer->Add(rtc, wxSizerFlags(1).Expand()); + wxBoxSizer* mainPanelSizer = new wxBoxSizer(wxVERTICAL); + mainPanelSizer->Add(rtc, wxSizerFlags(1).CentreHorizontal()); mainPanelSizer->Add(notePage, wxSizerFlags(1).Expand()); mainPanel->SetSizer(mainPanelSizer); @@ -1321,15 +1345,8 @@ void amStoryWriter::SaveActiveTab() void amStoryWriter::CountWords() { - int result = 0; - - if ( !m_activeTab.rtc->IsEmpty() ) - { - std::stringstream stream(m_activeTab.rtc->GetValue().ToStdString()); - result = std::distance(std::istream_iterator(stream), std::istream_iterator()); - } - - m_statusBar->SetStatusText("Number of words: " + std::to_string(result), 1); + int count = m_activeTab.document->GetWordCount(); + m_statusBar->SetStatusText("Number of words: " + std::to_string(count), 1); } void amStoryWriter::OnTimerEvent(wxTimerEvent& event) @@ -1449,14 +1466,14 @@ amStoryWriterToolbar::amStoryWriterToolbar(wxWindow* parent, { SetBackgroundColour(wxColour(30, 30, 30)); - AddCheckTool(TOOL_Bold, "", wxBITMAP_PNG(boldLight), wxBITMAP_PNG(bold), _("Bold")); - AddCheckTool(TOOL_Italic, "", wxBITMAP_PNG(italicLight), wxBITMAP_PNG(italic), _("Italic")); - AddCheckTool(TOOL_Underline, "", wxBITMAP_PNG(underlineLight), wxBITMAP_PNG(underline), _("Underline")); + AddCheckTool(TOOL_Bold, "", wxBITMAP_PNG(boldLight), wxBITMAP_PNG(boldLight).ConvertToDisabled(), _("Bold")); + AddCheckTool(TOOL_Italic, "", wxBITMAP_PNG(italicLight), wxBITMAP_PNG(italicLight).ConvertToDisabled(), _("Italic")); + AddCheckTool(TOOL_Underline, "", wxBITMAP_PNG(underlineLight), wxBITMAP_PNG(underlineLight).ConvertToDisabled(), _("Underline")); AddSeparator(); - AddRadioTool(TOOL_AlignLeft, "", wxBITMAP_PNG(leftAlignLight), wxBITMAP_PNG(leftAlign), _("Align left")); - AddRadioTool(TOOL_AlignCenter, "", wxBITMAP_PNG(centerAlignLight), wxBITMAP_PNG(centerAlign), _("Align center")); - AddRadioTool(TOOL_AlignCenterJust, "", wxBITMAP_PNG(centerJustAlignLight), wxBITMAP_PNG(centerJustAlign), _("Align center and fit")); - AddRadioTool(TOOL_AlignRight, "", wxBITMAP_PNG(rightAlignLight), wxBITMAP_PNG(rightAlign), _("Align right")); + AddRadioTool(TOOL_AlignLeft, "", wxBITMAP_PNG(leftAlignLight), wxBITMAP_PNG(leftAlignLight).ConvertToDisabled(), _("Align left")); + AddRadioTool(TOOL_AlignCenter, "", wxBITMAP_PNG(centerAlignLight), wxBITMAP_PNG(centerAlignLight).ConvertToDisabled(), _("Align center")); + AddRadioTool(TOOL_AlignCenterJust, "", wxBITMAP_PNG(centerJustAlignLight), wxBITMAP_PNG(centerJustAlignLight).ConvertToDisabled(), _("Align center and fit")); + AddRadioTool(TOOL_AlignRight, "", wxBITMAP_PNG(rightAlignLight), wxBITMAP_PNG(rightAlignLight).ConvertToDisabled(), _("Align right")); AddSeparator(); wxArrayString sizes; @@ -1634,39 +1651,46 @@ void amStoryWriterToolbar::OnPageView(wxCommandEvent& WXUNUSED(event)) {} void amStoryWriterToolbar::OnUpdateBold(wxUpdateUIEvent& event) { event.Check(m_currentTab.rtc->IsSelectionBold()); + event.Enable(m_currentTab.rtc && m_currentTab.rtc->IsShown()); } void amStoryWriterToolbar::OnUpdateItalic(wxUpdateUIEvent& event) { event.Check(m_currentTab.rtc->IsSelectionItalics()); + event.Enable(m_currentTab.rtc && m_currentTab.rtc->IsShown()); } void amStoryWriterToolbar::OnUpdateUnderline(wxUpdateUIEvent& event) { event.Check(m_currentTab.rtc->IsSelectionUnderlined()); + event.Enable(m_currentTab.rtc && m_currentTab.rtc->IsShown()); } void amStoryWriterToolbar::OnUpdateAlignLeft(wxUpdateUIEvent& event) { event.Check(m_currentTab.rtc->IsSelectionAligned(wxTEXT_ALIGNMENT_LEFT)); + event.Enable(m_currentTab.rtc && m_currentTab.rtc->IsShown()); } void amStoryWriterToolbar::OnUpdateAlignCenter(wxUpdateUIEvent& event) { event.Check(m_currentTab.rtc->IsSelectionAligned(wxTEXT_ALIGNMENT_CENTER)); + event.Enable(m_currentTab.rtc && m_currentTab.rtc->IsShown()); } void amStoryWriterToolbar::OnUpdateAlignCenterJust(wxUpdateUIEvent& event) { event.Check(m_currentTab.rtc->IsSelectionAligned(wxTEXT_ALIGNMENT_JUSTIFIED)); + event.Enable(m_currentTab.rtc && m_currentTab.rtc->IsShown()); } void amStoryWriterToolbar::OnUpdateAlignRight(wxUpdateUIEvent& event) { event.Check(m_currentTab.rtc->IsSelectionAligned(wxTEXT_ALIGNMENT_RIGHT)); + event.Enable(m_currentTab.rtc && m_currentTab.rtc->IsShown()); } -void amStoryWriterToolbar::OnUpdateFontSize(wxUpdateUIEvent& WXUNUSED(event)) +void amStoryWriterToolbar::OnUpdateFontSize(wxUpdateUIEvent& event) { wxRichTextAttr attr; m_currentTab.rtc->GetStyle(m_currentTab.rtc->GetInsertionPoint(), attr); @@ -1674,6 +1698,8 @@ void amStoryWriterToolbar::OnUpdateFontSize(wxUpdateUIEvent& WXUNUSED(event)) if ( m_fontSize->GetValue() != size ) m_fontSize->SetValue(size); + + event.Enable(m_currentTab.rtc && m_currentTab.rtc->IsShown()); } void amStoryWriterToolbar::OnUpdateNoteView(wxUpdateUIEvent& event) @@ -1703,6 +1729,7 @@ void amStoryWriterToolbar::OnFontSize(wxCommandEvent& event) } } + void amStoryWriterToolbar::OnUpdateZoom(wxUpdateUIEvent& event) { ((wxSlider*)FindControl(TOOL_ContentScale))->SetValue(m_currentTab.rtc->GetFontScale() * 100); @@ -1725,7 +1752,16 @@ amStoryWriterNotebook::amStoryWriterNotebook(wxWindow* parent, amStoryWriter* do m_notebook = new wxAuiNotebook(this, -1, wxDefaultPosition, wxDefaultSize, wxAUI_NB_TAB_SPLIT | wxAUI_NB_CLOSE_ON_ALL_TABS | wxAUI_NB_TAB_MOVE | wxAUI_NB_TAB_EXTERNAL_MOVE | wxAUI_NB_SCROLL_BUTTONS | wxAUI_NB_BOTTOM | wxBORDER_NONE); - m_notebook->GetAuiManager().GetArtProvider()->SetColour(wxAUI_DOCKART_BORDER_COLOUR, wxColour(20, 20, 20)); + + wxAuiSimpleTabArt* pArt = new wxAuiSimpleTabArt(); + pArt->SetColour(wxColour(50, 50, 50)); + pArt->SetActiveColour(wxColour(30, 30, 30)); + m_notebook->SetArtProvider(pArt); + + m_notebook->GetAuiManager().GetArtProvider()->SetColour(wxAUI_DOCKART_BORDER_COLOUR, wxColour(80, 80, 80)); + m_notebook->GetAuiManager().GetArtProvider()->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(40, 40, 40)); + m_notebook->GetAuiManager().GetArtProvider()->SetMetric(wxAUI_DOCKART_SASH_SIZE, 2); + m_notebook->Bind(wxEVT_AUINOTEBOOK_PAGE_CHANGED, &amStoryWriterNotebook::OnSelectionChanged, this); m_notebook->Bind(wxEVT_AUINOTEBOOK_PAGE_CLOSE, &amStoryWriterNotebook::OnPageClosing, this); m_notebook->Bind(wxEVT_AUINOTEBOOK_PAGE_CLOSED, &amStoryWriterNotebook::OnPageClosed, this); @@ -1756,9 +1792,8 @@ void amStoryWriterNotebook::SetCurrentTab(amStoryWriterTab& tab, bool load) for ( int i = 0; i < m_notebook->GetPageCount(); i++ ) { wxWindow* pPage = m_notebook->GetPage(i); - amStoryWriterTab& tabIt = m_swTabs[i]; - if ( pPage == tabIt.mainPanel ) + if ( pPage == tab.mainPanel ) { m_storyWriter->SetActiveTab(tab, load, load); m_contentToolbar->SetCurrentTab(tab); @@ -1805,7 +1840,7 @@ void amStoryWriterNotebook::OnPageClosing(wxAuiNotebookEvent& event) wxWindow* page = m_notebook->GetPage(event.GetSelection()); for ( amStoryWriterTab& tab : m_swTabs ) { - if ( tab.mainPanel ) + if ( tab.mainPanel == page ) { m_closingTab = tab; diff --git a/src/StoryWriter.h b/src/StoryWriter.h index ff4736d..2ce4554 100644 --- a/src/StoryWriter.h +++ b/src/StoryWriter.h @@ -294,9 +294,9 @@ class amStoryWriter : public wxFrame amProjectManager* m_manager = nullptr; amStoryWriterNotebook* m_swNotebook = nullptr; - wxTextCtrl* m_synopsys = nullptr, - * m_note = nullptr, - * m_noteLabel = nullptr; + wxTextCtrl* m_noteLabel = nullptr; + wxRichTextCtrl* m_synopsys = nullptr, + * m_note = nullptr; wxStaticText* m_noteChecker = nullptr; diff --git a/src/amUtility.h b/src/amUtility.h index 4f8688d..2def73d 100644 --- a/src/amUtility.h +++ b/src/amUtility.h @@ -6,6 +6,7 @@ #include #include #include +#include #include @@ -477,6 +478,7 @@ class amHotTrackingDVCHandler : public wxEvtHandler wxWindow* mainWindow = m_dvc->GetMainWindow(); mainWindow->Bind(wxEVT_MOTION, &amHotTrackingDVCHandler::OnDVCMouseMove, this); + mainWindow->Bind(wxEVT_ENTER_WINDOW, &amHotTrackingDVCHandler::OnDVCMouseMove, this); mainWindow->Bind(wxEVT_LEAVE_WINDOW, &amHotTrackingDVCHandler::OnDVCLeaveWindow, this); mainWindow->Bind(wxEVT_LEFT_DOWN, &amHotTrackingDVCHandler::OnDVCClick, this); mainWindow->Bind(wxEVT_RIGHT_DOWN, &amHotTrackingDVCHandler::OnDVCClick, this); @@ -490,50 +492,38 @@ class amHotTrackingDVCHandler : public wxEvtHandler inline wxDataViewItem GetItemUnderMouse() { return m_itemUnderMouse; } inline void SetItemUnderMouse(const wxDataViewItem& item) { m_itemUnderMouse = item; } - inline void CalculateItemRect(wxDataViewItem& item, wxRect& rect) - { - rect = m_dvc->GetItemRect(item); - rect.width += rect.GetLeft(); - rect.SetLeft(0); - } - inline void OnDVCMouseMove(wxMouseEvent& event) { wxDataViewItem item; wxDataViewColumn* column; - m_dvc->HitTest(event.GetPosition(), item, column); - wxRect rect; + wxPoint evtPos = event.GetPosition(); + wxHeaderCtrl* pHeader = m_dvc->GenericGetHeader(); + + if ( pHeader ) + evtPos.y += pHeader->GetSize().y; + + m_dvc->HitTest(evtPos, item, column); if ( item.IsOk() ) { if ( item.GetID() != m_itemUnderMouse.GetID() ) { if ( m_itemUnderMouse.IsOk() ) - { ((amTreeModelNode*)m_itemUnderMouse.GetID())->SetHovering(false); - CalculateItemRect(m_itemUnderMouse, rect); - m_dvc->GetMainWindow()->RefreshRect(rect); - } ((amTreeModelNode*)item.GetID())->SetHovering(true); - CalculateItemRect(item, rect); - m_dvc->GetMainWindow()->RefreshRect(rect); - m_itemUnderMouse = item; } } else { if ( m_itemUnderMouse.IsOk() ) - { ((amTreeModelNode*)m_itemUnderMouse.GetID())->SetHovering(false); - CalculateItemRect(m_itemUnderMouse, rect); - m_dvc->GetMainWindow()->RefreshRect(rect); - } - - m_itemUnderMouse = item; } + m_itemUnderMouse = item; + m_dvc->GetMainWindow()->Refresh(); + event.Skip(); } @@ -542,9 +532,7 @@ class amHotTrackingDVCHandler : public wxEvtHandler if ( m_itemUnderMouse.IsOk() ) { ((amTreeModelNode*)m_itemUnderMouse.GetID())->SetHovering(false); - wxRect rect; - CalculateItemRect(m_itemUnderMouse, rect); - m_dvc->GetMainWindow()->RefreshRect(rect); + m_dvc->GetMainWindow()->Refresh(); } event.Skip(); @@ -692,5 +680,4 @@ class amSFShapeCanvas : public wxSFShapeCanvas } }; - #endif; /*UTILITY_AM_H_*/ \ No newline at end of file