Writen a new class from scratch to replace wxGrid

Originally committed to SVN as r62.
This commit is contained in:
Rodrigo Braz Monteiro 2006-02-18 21:55:58 +00:00
parent c84a44dc59
commit f4daf0e020
6 changed files with 823 additions and 346 deletions

619
core/base_grid.cpp Normal file
View File

@ -0,0 +1,619 @@
// Copyright (c) 2006, Rodrigo Braz Monteiro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Aegisub Group nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// -----------------------------------------------------------------------------
//
// AEGISUB
//
// Website: http://aegisub.cellosoft.com
// Contact: mailto:zeratul@cellosoft.com
//
#pragma once
////////////
// Includes
#include "base_grid.h"
#include "utils.h"
#include "ass_file.h"
#include "ass_dialogue.h"
#include "ass_style.h"
#include "options.h"
#include "vfr.h"
#include "subs_edit_box.h"
#include "frame_main.h"
///////////////
// Constructor
BaseGrid::BaseGrid(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name)
: wxWindow(parent, id, pos, size, style, name)
{
// Misc variables
lastRow = -1;
yPos = 0;
bmp = NULL;
// Set font
wxString fontname = Options.AsText(_T("Font Face"));
if (fontname == _T("")) fontname = _T("Tahoma");
font.SetFaceName(fontname);
font.SetPointSize(Options.AsInt(_T("Grid font size")));
font.SetWeight(wxFONTWEIGHT_NORMAL);
// Set line height
{
wxClientDC dc(this);
dc.SetFont(font);
int fw,fh;
dc.GetTextExtent(_T("#TWFfgGhH"), &fw, &fh, NULL, NULL, &font);
lineHeight = fh+4;
}
// Set scrollbar
scrollBar = new wxScrollBar(this,GRID_SCROLLBAR,wxDefaultPosition,wxDefaultSize,wxSB_VERTICAL);
scrollBar->SetScrollbar(0,10,100,10);
// Set column widths
SetColumnWidths();
}
//////////////
// Destructor
BaseGrid::~BaseGrid() {
delete bmp;
}
////////////////
// Select a row
void BaseGrid::SelectRow(int row, bool addToSelected, bool select) {
if (!addToSelected) ClearSelection();
try {
bool cur = selMap.at(row);
if (select != cur) {
selMap.at(row) = select;
Refresh(false);
}
}
catch (...) {}
}
///////////////
// Begin batch
void BaseGrid::BeginBatch() {
//Freeze();
}
/////////////
// End batch
void BaseGrid::EndBatch() {
//Thaw();
}
//////////////////////
// Makes cell visible
void BaseGrid::MakeCellVisible(int row, int col) {
}
///////////////////////
// Unselects all cells
void BaseGrid::ClearSelection() {
int rows = selMap.size();
for (int i=0;i<rows;i++) {
selMap[i] = false;
}
Refresh(false);
}
/////////////////////////
// Is cell in selection?
bool BaseGrid::IsInSelection(int row, int col) const {
(void) col;
try {
return selMap.at(row);
}
catch (...) {
return false;
}
}
//////////////////////
// Get number of rows
int BaseGrid::GetRows() const {
return diagMap.size();
}
/////////////////////
// Auto size columns
void BaseGrid::AutoSizeColumn(int col, bool setAsMin) {
(void) col;
(void) setAsMin;
SetColumnWidths();
}
///////////////
// Event table
BEGIN_EVENT_TABLE(BaseGrid,wxWindow)
EVT_PAINT(BaseGrid::OnPaint)
EVT_SIZE(BaseGrid::OnSize)
EVT_COMMAND_SCROLL(GRID_SCROLLBAR,BaseGrid::OnScroll)
EVT_MOUSE_EVENTS(BaseGrid::OnMouseEvent)
END_EVENT_TABLE()
///////////////
// Paint event
void BaseGrid::OnPaint (wxPaintEvent &event) {
// Prepare
wxPaintDC dc(this);
bool direct = false;
if (direct) {
DrawImage(dc);
}
else {
// Get size and pos
int w = 0;
int h = 0;
GetClientSize(&w,&h);
// Prepare bitmap
if (bmp) {
if (bmp->GetWidth() < w || bmp->GetHeight() < h) {
delete bmp;
bmp = NULL;
}
}
if (!bmp) bmp = new wxBitmap(w,h);
// Draw bitmap
wxMemoryDC bmpDC;
bmpDC.SelectObject(*bmp);
DrawImage(bmpDC);
dc.Blit(0,0,w,h,&bmpDC,0,0);
}
}
//////////////
// Draw image
void BaseGrid::DrawImage(wxDC &dc) {
dc.BeginDrawing();
// Get size and pos
int w = 0;
int h = 0;
GetClientSize(&w,&h);
// Set font
dc.SetFont(font);
// Clear background
dc.SetBackground(wxBrush(wxColour(255,255,255)));
dc.Clear();
// Draw labels
dc.SetPen(*wxTRANSPARENT_PEN);
dc.SetBrush(wxBrush(wxColour(196,236,201)));
dc.DrawRectangle(0,lineHeight,colWidth[0],h-lineHeight);
// Visible lines
int drawPerScreen = h/lineHeight + 1;
int nDraw = MID(0,drawPerScreen,GetRows()-yPos);
int maxH = (nDraw+1) * lineHeight;
// Row colors
std::vector<wxBrush> rowColors;
rowColors.push_back(wxBrush(wxColour(255,255,255)));
rowColors.push_back(wxBrush(wxColour(165,207,231)));
rowColors.push_back(wxBrush(Options.AsColour(_T("Grid selection background"))));
// First grid row
bool drawGrid = true;
if (drawGrid) {
dc.SetPen(wxPen(wxColour(128,128,128)));
dc.DrawLine(0,0,w,0);
dc.SetPen(*wxTRANSPARENT_PEN);
}
// Draw rows
int dx = 0;
int dy = 0;
int curColor = 0;
AssDialogue *curDiag;
for (int i=0;i<nDraw+1;i++) {
// Prepare
int curRow = i+yPos-1;
curDiag = GetDialogue(curRow);
dx = 0;
dy = i*lineHeight;
// Text array
wxArrayString strings;
// Header
if (i == 0) {
strings.Add(_("#"));
strings.Add(_("L"));
strings.Add(_("Start"));
strings.Add(_("End"));
strings.Add(_("Style"));
strings.Add(_("Actor"));
strings.Add(_("Effect"));
strings.Add(_("Left"));
strings.Add(_("Right"));
strings.Add(_("Vert"));
strings.Add(_("Text"));
curColor = 1;
}
// Lines
else if (curDiag) {
// Set fields
strings.Add(wxString::Format(_T("%i"),curRow+1));
strings.Add(wxString::Format(_T("%i"),curDiag->Layer));
strings.Add(curDiag->Start.GetASSFormated());
strings.Add(curDiag->End.GetASSFormated());
strings.Add(curDiag->Style);
strings.Add(curDiag->Actor);
strings.Add(curDiag->Effect);
strings.Add(curDiag->GetMarginString(1));
strings.Add(curDiag->GetMarginString(2));
strings.Add(curDiag->GetMarginString(3));
// Set text
int mode = Options.AsInt(_T("Grid Hide Overrides"));
wxString value = _T("");
// Hid overrides
if (mode == 1 || mode == 2) {
wxString replaceWith = Options.AsText(_T("Grid hide overrides char"));
curDiag->ParseASSTags();
size_t n = curDiag->Blocks.size();
for (size_t i=0;i<n;i++) {
AssDialogueBlock *block = curDiag->Blocks.at(i);
AssDialogueBlockPlain *plain = AssDialogueBlock::GetAsPlain(block);
if (plain) {
value += plain->GetText();
}
else {
if (mode == 1) {
value += replaceWith;
}
}
}
}
// Show overrides
else value = curDiag->Text;
// Cap length and set text
if (value.Length() > 128) value = value.Left(128) + _T("...");
strings.Add(value);
// Set color
curColor = 0;
if (IsInSelection(curRow,0)) curColor = 2;
}
else {
for (int j=0;j<11;j++) strings.Add(_T("?"));
}
// Draw row background color
if (curColor) {
dc.SetBrush(rowColors[curColor]);
dc.DrawRectangle((curColor == 1) ? 0 : colWidth[0],i*lineHeight+1,w,lineHeight);
}
// Draw text
wxRect cur;
bool isCenter;
for (int j=0;j<11;j++) {
// Is center?
isCenter = !(j == 4 || j == 5 || j == 6 || j == 10);
// Calculate clipping
cur = wxRect(dx+4,dy,colWidth[j]-6,lineHeight);
// Set clipping
dc.DestroyClippingRegion();
dc.SetClippingRegion(cur);
// Draw
dc.DrawLabel(strings[j],cur,isCenter ? wxALIGN_CENTER : (wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT));
dx += colWidth[j];
}
// Draw grid
dc.DestroyClippingRegion();
if (drawGrid) {
dc.SetPen(wxPen(wxColour(128,128,128)));
dc.DrawLine(0,dy+lineHeight,w,dy+lineHeight);
dc.SetPen(*wxTRANSPARENT_PEN);
}
}
// Draw grid columns
dx = 0;
if (drawGrid) {
dc.SetPen(wxPen(wxColour(128,128,128)));
for (int i=0;i<10;i++) {
dx += colWidth[i];
dc.DrawLine(dx,0,dx,maxH);
}
dc.DrawLine(0,0,0,maxH);
dc.DrawLine(w-1,0,w-1,h);
}
// Draw currently active line border
dc.SetPen(wxPen(wxColour(255,91,239)));
dc.SetBrush(*wxTRANSPARENT_BRUSH);
dy = (editBox->linen+1-yPos) * lineHeight;
dc.DrawRectangle(0,dy,w,lineHeight+1);
// Done
dc.EndDrawing();
}
///////////
// On size
void BaseGrid::OnSize(wxSizeEvent &event) {
AdjustScrollbar();
SetColumnWidths();
Refresh(false);
}
/////////////
// On scroll
void BaseGrid::OnScroll(wxScrollEvent &event) {
int newPos = event.GetPosition();
if (yPos != newPos) {
yPos = newPos;
Refresh(false);
}
}
////////////////
// Mouse events
void BaseGrid::OnMouseEvent(wxMouseEvent &event) {
// Window size
int w,h;
GetClientSize(&w,&h);
// Modifiers
bool shift = event.m_shiftDown;
bool alt = event.m_altDown;
bool ctrl = event.m_controlDown;
// Click type
bool click = event.ButtonDown(wxMOUSE_BTN_LEFT);
bool hold = event.ButtonIsDown(wxMOUSE_BTN_LEFT);
// Row that mouse is over
int row = event.GetY()/lineHeight + yPos - 1;
bool validRow = row >= 0 && row < GetRows();
if (!validRow) row = -1;
// Click
if ((click || hold) && validRow) {
// Toggle selected
if (click && ctrl && !shift) {
SelectRow(row,true,!IsInSelection(row,0));
}
// Block select
if ((click && shift && !ctrl) || (hold)) {
if (lastRow != -1) {
// Set boundaries
int i1 = row;
int i2 = lastRow;
if (i1 > i2) {
int aux = i1;
i1 = i2;
i2 = aux;
}
// Toggle each
bool notFirst = false;
for (int i=i1;i<=i2;i++) {
SelectRow(i,notFirst,true);
notFirst = true;
}
}
}
// Normal click
if (click && !shift && !ctrl && !alt) {
editBox->SetToLine(row);
parentFrame->SetSelectionFlag(validRow);
SelectRow(row,false);
lastRow = row;
}
return;
}
// Popup
if (event.ButtonDown(wxMOUSE_BTN_RIGHT)) {
OnPopupMenu();
}
// Mouse wheel
if (event.GetWheelRotation() != 0) {
int step = 3 * event.GetWheelRotation() / event.GetWheelDelta();
yPos = MID(0,yPos - step,GetRows()+2 - h/lineHeight);
scrollBar->SetThumbPosition(yPos);
Refresh(false);
return;
}
event.Skip();
}
////////////////////
// Adjust scrollbar
void BaseGrid::AdjustScrollbar() {
// Set size
int w,h,sw,sh;
GetClientSize(&w,&h);
scrollBar->Freeze();
scrollBar->GetSize(&sw,&sh);
scrollBar->SetSize(w-sw-4,0,sw,h-4);
// Set parameters
int drawPerScreen = h/lineHeight;
int rows = GetRows();
scrollBar->SetScrollbar(yPos,drawPerScreen,rows+2,drawPerScreen-2,true);
scrollBar->Enable(drawPerScreen < rows);
scrollBar->Thaw();
}
/////////////////////
// Set column widths
void BaseGrid::SetColumnWidths() {
// Width/height
int w = 0;
int h = 0;
GetClientSize(&w,&h);
// DC for text extents test
wxClientDC dc(this);
dc.SetFont(font);
int fw,fh;
//dc.GetTextExtent(_T("#TWFfgGhH"), &fw, &fh, NULL, NULL, &font);
// O(1) widths
dc.GetTextExtent(_T("0000"), &fw, &fh, NULL, NULL, &font);
int marginLen = fw + 10;
dc.GetTextExtent(wxString::Format(_T("%i"),GetRows()), &fw, &fh, NULL, NULL, &font);
int labelLen = fw + 10;
int startLen = 0;
int endLen = 0;
if (!byFrame) {
AssTime time;
dc.GetTextExtent(time.GetASSFormated(), &fw, &fh, NULL, NULL, &font);
startLen = fw;
endLen = fw;
}
// O(n) widths
int layerLen = 0;
int actorLen = 0;
int effectLen = 0;
AssDialogue *curDiag;
for (int i=0;i<GetRows();i++) {
curDiag = GetDialogue(i);
if (curDiag) {
// Layer
dc.GetTextExtent(wxString::Format(_T("%i"),curDiag->Layer), &fw, &fh, NULL, NULL, &font);
if (fw > layerLen) layerLen = fw;
// Actor
dc.GetTextExtent(curDiag->Actor, &fw, &fh, NULL, NULL, &font);
if (fw > actorLen) actorLen = fw;
// Effect
dc.GetTextExtent(curDiag->Effect, &fw, &fh, NULL, NULL, &font);
if (fw > effectLen) effectLen = fw;
// Times
if (byFrame) {
dc.GetTextExtent(wxString::Format(_T("%i"),VFR_Output.CorrectFrameAtTime(curDiag->Start.GetMS(),true)), &fw, &fh, NULL, NULL, &font);
if (fw > startLen) startLen = fw;
dc.GetTextExtent(wxString::Format(_T("%i"),VFR_Output.CorrectFrameAtTime(curDiag->End.GetMS(),true)), &fw, &fh, NULL, NULL, &font);
if (fw > endLen) endLen = fw;
}
}
}
layerLen += 10;
if (actorLen) actorLen += 10;
if (effectLen) effectLen += 10;
startLen += 10;
endLen += 10;
// Style length
int styleLen = 0;
AssStyle *curStyle;
if (AssFile::top) {
for (entryIter curIter=AssFile::top->Line.begin();curIter!=AssFile::top->Line.end();curIter++) {
curStyle = AssEntry::GetAsStyle(*curIter);
if (curStyle) {
dc.GetTextExtent(curStyle->name, &fw, &fh, NULL, NULL, &font);
if (fw > styleLen) styleLen = fw;
}
}
}
styleLen += 10;
// Set column widths
colWidth[0] = labelLen;
colWidth[1] = layerLen;
colWidth[2] = startLen;
colWidth[3] = endLen;
colWidth[4] = styleLen;
colWidth[5] = actorLen;
colWidth[6] = effectLen;
colWidth[7] = marginLen;
colWidth[8] = marginLen;
colWidth[9] = marginLen;
// Set size of last
int total = 0;
for (int i=0;i<10;i++) total+= colWidth[i];
colWidth[10] = w-total;
}
//////////////////////////
// Gets dialogue from map
AssDialogue *BaseGrid::GetDialogue(int n) {
try {
return AssEntry::GetAsDialogue(*(diagMap.at(n)));
}
catch (...) {
return NULL;
}
}

113
core/base_grid.h Normal file
View File

@ -0,0 +1,113 @@
// Copyright (c) 2006, Rodrigo Braz Monteiro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Aegisub Group nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// -----------------------------------------------------------------------------
//
// AEGISUB
//
// Website: http://aegisub.cellosoft.com
// Contact: mailto:zeratul@cellosoft.com
//
#pragma once
////////////
// Includes
#include <wx/wx.h>
#include <wx/grid.h>
#include <list>
#include <vector>
//////////////
// Prototypes
class AssEntry;
class AssDialogue;
class SubsEditBox;
class FrameMain;
typedef std::list<AssEntry*>::iterator entryIter;
///////////////////
// Base grid class
class BaseGrid : public wxWindow {
private:
int lineHeight;
int colWidth[16];
int yPos;
int lastRow;
wxFont font;
wxScrollBar *scrollBar;
wxBitmap *bmp;
void OnPaint(wxPaintEvent &event);
void OnSize(wxSizeEvent &event);
void OnScroll(wxScrollEvent &event);
void OnMouseEvent(wxMouseEvent &event);
void AdjustScrollbar();
void SetColumnWidths();
void DrawImage(wxDC &dc);
protected:
FrameMain *parentFrame;
virtual void OnPopupMenu() {}
public:
SubsEditBox *editBox;
bool byFrame;
std::vector<entryIter> diagMap;
std::vector<bool> selMap;
void BeginBatch();
void EndBatch();
void MakeCellVisible(int row, int col);
void SelectRow(int row, bool addToSelected = false, bool select=true);
void ClearSelection();
bool IsInSelection(int row, int col) const;
int GetRows() const;
int GetNumberRows() const { return GetRows(); }
void AutoSizeColumn(int col, bool setAsMin = true);
AssDialogue *GetDialogue(int n);
BaseGrid(wxWindow* parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxWANTS_CHARS, const wxString& name = wxPanelNameStr);
~BaseGrid();
DECLARE_EVENT_TABLE()
};
///////
// IDs
enum {
GRID_SCROLLBAR = 1730
};

View File

@ -58,6 +58,7 @@
#include "export_framerate.h"
#include "ass_export_filter.h"
#include "ass_time.h"
#include "subs_grid.h"
///////////////////
@ -293,7 +294,7 @@ END_EVENT_TABLE()
void AegisubApp::OnMouseWheel(wxMouseEvent &event) {
wxPoint pt;
wxWindow *target = wxFindWindowAtPointer(pt);
if (target == frame->audioBox->audioDisplay) {
if (target == frame->audioBox->audioDisplay || target == frame->SubsBox) {
target->AddPendingEvent(event);
}
else event.Skip();

View File

@ -577,7 +577,6 @@ void SubsEditBox::OnStyleChange(wxCommandEvent &event) {
}
}
grid->AutoSizeColumn(3);
grid->FitColumns();
grid->ass->FlagAsModified();
grid->CommitChanges();
grid->EndBatch();
@ -636,7 +635,6 @@ void SubsEditBox::OnLayerChange(wxCommandEvent &event) {
}
}
grid->AutoSizeColumn(0);
grid->FitColumns();
grid->ass->FlagAsModified();
grid->CommitChanges();
grid->EndBatch();

View File

@ -1,4 +1,4 @@
// Copyright (c) 2005, Rodrigo Braz Monteiro
// Copyright (c) 2006, Rodrigo Braz Monteiro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@ -54,13 +54,10 @@
///////////////
// Event table
BEGIN_EVENT_TABLE(SubtitlesGrid, wxGrid)
BEGIN_EVENT_TABLE(SubtitlesGrid, BaseGrid)
EVT_GRID_CELL_LEFT_CLICK(SubtitlesGrid::OnCellLeftClick)
EVT_GRID_CELL_RIGHT_CLICK(SubtitlesGrid::OnPopupMenu)
EVT_GRID_CELL_CHANGE(SubtitlesGrid::OnCellChange)
EVT_GRID_SELECT_CELL(SubtitlesGrid::OnSelectCell)
EVT_KEY_DOWN(SubtitlesGrid::OnKeyDown)
EVT_PAINT(SubtitlesGrid::OnPaint)
EVT_MENU(MENU_SWAP,SubtitlesGrid::OnSwap)
EVT_MENU(MENU_DUPLICATE,SubtitlesGrid::OnDuplicate)
@ -93,7 +90,7 @@ END_EVENT_TABLE()
///////////////
// Constructor
SubtitlesGrid::SubtitlesGrid(FrameMain* parentFr, wxWindow *parent, wxWindowID id, VideoDisplay *_video, const wxPoint& pos, const wxSize& size, long style, const wxString& name)
: wxGrid(parent,id,pos,size,style,name)
: BaseGrid(parent,id,pos,size,style,name)
{
// Vars
changingCol = false;
@ -114,93 +111,8 @@ SubtitlesGrid::SubtitlesGrid(FrameMain* parentFr, wxWindow *parent, wxWindowID i
RowHeight = h+4;
// Set up
BeginBatch();
EnableDragRowSize(false);
EnableDragColSize(false);
SetRowMinimalAcceptableHeight(h);
SetColLabelSize(18);
SetRowLabelSize(30);
SetDefaultCellAlignment(wxALIGN_CENTRE,wxALIGN_BOTTOM);
CreateGrid(1,10,wxGrid::wxGridSelectRows);
//SetSelectionMode(wxGrid::wxGridSelectRows);
SetSelectionBackground(Options.AsColour(_T("Grid selection background")));
SetSelectionForeground(Options.AsColour(_T("Grid selection foreground")));
// Initialize columns
SetColLabelValue(0,_("L"));
SetColLabelValue(1,_("Start"));
SetColLabelValue(2,_("End"));
SetColLabelValue(3,_("Style"));
SetColLabelValue(4,_("Act"));
SetColLabelValue(5,_("Eff"));
SetColLabelValue(6,_("Lef"));
SetColLabelValue(7,_("Rig"));
SetColLabelValue(8,_("Ver"));
SetColLabelValue(9,_("Dialogue"));
// Set column attributes
wxGridCellAttr *attr;
attr = new wxGridCellAttr();
attr->SetReadOnly(true);
attr->SetFont(font);
SetColAttr(0,attr);
attr = new wxGridCellAttr();
//attr->SetAlignment(wxALIGN_LEFT,wxALIGN_BOTTOM);
attr->SetReadOnly(true);
attr->SetFont(font);
SetColAttr(1,attr);
attr = new wxGridCellAttr();
attr->SetReadOnly(true);
attr->SetFont(font);
SetColAttr(2,attr);
attr = new wxGridCellAttr();
attr->SetAlignment(wxALIGN_LEFT,wxALIGN_BOTTOM);
attr->SetReadOnly(true);
attr->SetFont(font);
SetColAttr(3,attr);
attr = new wxGridCellAttr();
attr->SetAlignment(wxALIGN_LEFT,wxALIGN_BOTTOM);
attr->SetReadOnly(true);
attr->SetFont(font);
SetColAttr(4,attr);
attr = new wxGridCellAttr();
attr->SetAlignment(wxALIGN_LEFT,wxALIGN_BOTTOM);
attr->SetReadOnly(true);
attr->SetFont(font);
SetColAttr(5,attr);
attr = new wxGridCellAttr();
attr->SetReadOnly(true);
attr->SetFont(font);
SetColAttr(6,attr);
attr = new wxGridCellAttr();
attr->SetReadOnly(true);
attr->SetFont(font);
SetColAttr(7,attr);
attr = new wxGridCellAttr();
attr->SetReadOnly(true);
attr->SetFont(font);
SetColAttr(8,attr);
attr = new wxGridCellAttr();
wxString fontname = Options.AsText(_T("Font Face"));
if (fontname != _T("")) {
font.SetFaceName(fontname);
}
attr->SetFont(font);
attr->SetAlignment(wxALIGN_LEFT,wxALIGN_BOTTOM);
attr->SetReadOnly(true);
SetColAttr(9,attr);
// Apply
EndBatch();
//SetSelectionBackground(Options.AsColour(_T("Grid selection background")));
//SetSelectionForeground(Options.AsColour(_T("Grid selection foreground")));
}
@ -214,7 +126,7 @@ SubtitlesGrid::~SubtitlesGrid() {
//////////////
// Popup menu
void SubtitlesGrid::OnPopupMenu(wxGridEvent &event) {
void SubtitlesGrid::OnPopupMenu() {
// Get selections
bool continuous;
wxArrayInt selections = GetSelection(&continuous);
@ -913,97 +825,6 @@ void SubtitlesGrid::OnSelectCell(wxGridEvent &event) {
}
////////////////
// Cell updated
void SubtitlesGrid::OnCellChange (wxGridEvent &event) {
// Some strange wxWidgets thing makes AutoSizeColumn throw this
// event, causing an infinite loop... so, workaround.
if (changingCol) {
event.Skip();
return;
}
throw _T("This shouldn't be used anymore!!");
/* leftovers from in grid editing
// Get position
changingCol = true;
int row = event.GetRow();
int col = event.GetCol();
BeginBatch();
AssDialogue *entry = GetDialogue(row);
long longt;
switch (col) {
// Layer
case 0:
GetCellValue(row,col).ToLong(&longt);
entry->Layer = longt;
AutoSizeColumn(col,false);
break;
// Start time
case 1:
entry->Start.ParseASS(GetCellValue(row,col));
SetCellValue(row,col,entry->Start.GetASSFormated());
break;
// End time
case 2:
entry->End.ParseASS(GetCellValue(row,col));
SetCellValue(row,col,entry->End.GetASSFormated());
break;
// Style
case 3:
entry->Style = GetCellValue(row,col);
AutoSizeColumn(col,false);
break;
// Actor
case 4:
entry->Actor = GetCellValue(row,col);
AutoSizeColumn(col,false);
break;
// Effect
case 5:
entry->Effect = GetCellValue(row,col);
AutoSizeColumn(col,false);
break;
// Margin left
case 6:
entry->SetMarginString(GetCellValue(row,col),1);
SetCellValue(row,col,entry->GetMarginString(1));
break;
// Margin right
case 7:
entry->SetMarginString(GetCellValue(row,col),2);
SetCellValue(row,col,entry->GetMarginString(2));
break;
// Margin vertical
case 8:
entry->SetMarginString(GetCellValue(row,col),3);
SetCellValue(row,col,entry->GetMarginString(3));
break;
// Text
case 9:
entry->Text = GetCellValue(row,col);
entry->ParseASSTags();
break;
}
// Update value on subs
entry->UpdateData();
// Clear up
EndBatch();
changingCol = false;
// Commit
editBox->SetToLine(row);
CommitChanges();
ass->FlagAsModified();
event.Skip();
*/
}
//////////////////////////////////////
// Clears grid and sets it to default
void SubtitlesGrid::LoadDefault (AssFile *_ass) {
@ -1018,8 +839,9 @@ void SubtitlesGrid::LoadDefault (AssFile *_ass) {
///////////////
// Clears grid
void SubtitlesGrid::Clear () {
if (GetNumberRows() > 0) DeleteRows(0,GetNumberRows());
//if (GetNumberRows() > 0) DeleteRows(0,GetNumberRows());
diagMap.clear();
selMap.clear();
}
@ -1045,21 +867,6 @@ void SubtitlesGrid::LoadFromAss (AssFile *_ass,bool keepSelection,bool dontModif
if (!ass) throw _T("Trying to set subs grid to current ass file, but there is none");
}
// Set styles editor
/*wxArrayString styles;
AssStyle *curstyle;
for (entryIter cur=ass->Line.begin();cur != ass->Line.end();cur++) {
curstyle = AssEntry::GetAsStyle(*cur);
if (curstyle) {
styles.Add(curstyle->name);
}
}
if (styles.GetCount() == 0) styles.Add(_T("Default"));
wxGridCellAttr *attr1 = new wxGridCellAttr;
attr1->SetEditor(new wxGridCellChoiceEditor(styles));
attr1->SetAlignment(wxALIGN_LEFT,wxALIGN_BOTTOM);
SetColAttr(3,attr1);*/
// Run through subs adding them
int n = 0;
AssDialogue *curdiag;
@ -1067,9 +874,10 @@ void SubtitlesGrid::LoadFromAss (AssFile *_ass,bool keepSelection,bool dontModif
for (entryIter cur=ass->Line.begin();cur != ass->Line.end();cur++) {
curdiag = AssEntry::GetAsDialogue(*cur);
if (curdiag) {
AppendRows(1);
//AppendRows(1);
SetRowToLine(n,curdiag);
diagMap.push_back(cur);
selMap.push_back(false);
n++;
}
}
@ -1088,8 +896,6 @@ void SubtitlesGrid::LoadFromAss (AssFile *_ass,bool keepSelection,bool dontModif
}
// Finish setting layout
AutoSizeColumns();
FitColumns();
EndBatch();
// Commit
@ -1118,63 +924,63 @@ void SubtitlesGrid::LoadFromAss (AssFile *_ass,bool keepSelection,bool dontModif
/////////////////////////////////////////
// Sets one line to a line from the subs
void SubtitlesGrid::SetRowToLine(int n,AssDialogue *line) {
BeginBatch();
//BeginBatch();
// Times
if (byFrame) {
SetCellValue(n,1,wxString::Format(_T("%i"),VFR_Output.CorrectFrameAtTime(line->Start.GetMS(),true)));
SetCellValue(n,2,wxString::Format(_T("%i"),VFR_Output.CorrectFrameAtTime(line->End.GetMS(),false)));
}
else {
SetCellValue(n,1,line->Start.GetASSFormated());
SetCellValue(n,2,line->End.GetASSFormated());
}
//// Times
//if (byFrame) {
// SetCellValue(n,1,wxString::Format(_T("%i"),VFR_Output.CorrectFrameAtTime(line->Start.GetMS(),true)));
// SetCellValue(n,2,wxString::Format(_T("%i"),VFR_Output.CorrectFrameAtTime(line->End.GetMS(),false)));
//}
//else {
// SetCellValue(n,1,line->Start.GetASSFormated());
// SetCellValue(n,2,line->End.GetASSFormated());
//}
// Fields
SetCellValue(n,0,wxString::Format(_T("%d"),line->Layer));
SetCellValue(n,3,line->Style);
SetCellValue(n,4,line->Actor);
SetCellValue(n,5,line->Effect);
SetCellValue(n,6,wxString::Format(_T("%04d"),line->MarginL));
SetCellValue(n,7,wxString::Format(_T("%04d"),line->MarginR));
SetCellValue(n,8,wxString::Format(_T("%04d"),line->MarginV));
//// Fields
//SetCellValue(n,0,wxString::Format(_T("%d"),line->Layer));
//SetCellValue(n,3,line->Style);
//SetCellValue(n,4,line->Actor);
//SetCellValue(n,5,line->Effect);
//SetCellValue(n,6,wxString::Format(_T("%04d"),line->MarginL));
//SetCellValue(n,7,wxString::Format(_T("%04d"),line->MarginR));
//SetCellValue(n,8,wxString::Format(_T("%04d"),line->MarginV));
// Text
int mode = Options.AsInt(_T("Grid Hide Overrides"));
wxString value = _T("");
//// Text
//int mode = Options.AsInt(_T("Grid Hide Overrides"));
//wxString value = _T("");
// Hid overrides
if (mode == 1 || mode == 2) {
wxString replaceWith = Options.AsText(_T("Grid hide overrides char"));
line->ParseASSTags();
size_t n = line->Blocks.size();
for (size_t i=0;i<n;i++) {
AssDialogueBlock *block = line->Blocks.at(i);
AssDialogueBlockPlain *plain = AssDialogueBlock::GetAsPlain(block);
if (plain) {
value += plain->GetText();
}
else {
if (mode == 1) {
value += replaceWith;
}
}
}
}
//// Hid overrides
//if (mode == 1 || mode == 2) {
// wxString replaceWith = Options.AsText(_T("Grid hide overrides char"));
// line->ParseASSTags();
// size_t n = line->Blocks.size();
// for (size_t i=0;i<n;i++) {
// AssDialogueBlock *block = line->Blocks.at(i);
// AssDialogueBlockPlain *plain = AssDialogueBlock::GetAsPlain(block);
// if (plain) {
// value += plain->GetText();
// }
// else {
// if (mode == 1) {
// value += replaceWith;
// }
// }
// }
//}
// Show overrides
else value = line->Text;
//// Show overrides
//else value = line->Text;
// Cap length and set text
if (value.Length() > 128) value = value.Left(128) + _T("...");
SetCellValue(n,9,value);
//// Cap length and set text
//if (value.Length() > 128) value = value.Left(128) + _T("...");
//SetCellValue(n,9,value);
// Colour
SetRowColour(n,line);
//// Colour
//SetRowColour(n,line);
// Size
SetRowSize(n,RowHeight);
EndBatch();
//// Size
//SetRowSize(n,RowHeight);
//EndBatch();
}
@ -1199,7 +1005,7 @@ void SubtitlesGrid::SetRowColour(int n,AssDialogue *line) {
}
// Set
SetRowAttr(n,attr);
//SetRowAttr(n,attr);
}
@ -1209,7 +1015,7 @@ void SubtitlesGrid::UpdateRowColours() {
BeginBatch();
int rows = GetRows();
for (int i=0;i<rows;i++) {
SetRowColour(i);
//SetRowColour(i);
}
EndBatch();
}
@ -1252,9 +1058,10 @@ void SubtitlesGrid::InsertLine(AssDialogue *line,int n,bool after,bool update) {
}
line->UpdateData();
entryIter newIter = ass->Line.insert(pos,line);
InsertRows(n);
SetRowToLine(n,line);
//InsertRows(n);
//SetRowToLine(n,line);
diagMap.insert(diagMap.begin() + n,newIter);
selMap.insert(selMap.begin() + n,false);
// Update
if (update) {
@ -1628,18 +1435,6 @@ void SubtitlesGrid::SplitLine(int n,int pos,int mode) {
}
//////////////////////////
// Gets dialogue from map
AssDialogue *SubtitlesGrid::GetDialogue(int n) {
try {
return AssEntry::GetAsDialogue(*(diagMap.at(n)));
}
catch (...) {
return NULL;
}
}
//////////////////
// Commit changes
// --------------
@ -1667,46 +1462,6 @@ void SubtitlesGrid::CommitChanges(bool force) {
}
//////////////
// Size event
void SubtitlesGrid::OnSize(wxSizeEvent &event) {
FitColumns();
event.Skip();
}
///////////////
// Paint event
void SubtitlesGrid::OnPaint(wxPaintEvent &event) {
FitColumns();
event.Skip();
}
///////////////
// Fit columns
void SubtitlesGrid::FitColumns() {
int w,h;
GetClientSize(&w,&h);
int i;
int colw=0;
for (i=0;i<GetCols()-1;i++) {
colw += GetColSize(i);
}
colw += GetRowLabelSize();
int idealSize = w-colw;
if (GetColSize(i) != idealSize) SetColSize(i,idealSize);
}
/////////////////////////
// SetScrollbar override
void SubtitlesGrid::SetScrollbar (int orientation, int position, int thumbSize, int range, bool refresh) {
if (orientation != wxHORIZONTAL) wxGrid::SetScrollbar (orientation, position, thumbSize, range, refresh);
else wxGrid::SetScrollbar (orientation, 0, 0, 0);
}
///////////////////////////
// Gets first selected row
int SubtitlesGrid::GetFirstSelRow() {
@ -1749,30 +1504,30 @@ wxArrayInt SubtitlesGrid::GetSelection(bool *cont) {
void SubtitlesGrid::SetByFrame (bool state) {
// Check if it's already the same
if (byFrame == state) return;
BeginBatch();
// Update rows
byFrame = state;
int nrows = GetRows();
AssDialogue *line;
for (int i=0;i<nrows;i++) {
line = GetDialogue(i);
if (byFrame) {
SetCellValue(i,1,wxString::Format(_T("%i"),VFR_Output.CorrectFrameAtTime(line->Start.GetMS(),true)));
SetCellValue(i,2,wxString::Format(_T("%i"),VFR_Output.CorrectFrameAtTime(line->End.GetMS(),false)));
}
else {
SetCellValue(i,1,line->Start.GetASSFormated());
SetCellValue(i,2,line->End.GetASSFormated());
}
}
// Update columns
//AutoSizeColumn(1,false);
//AutoSizeColumn(2,false);
AutoSizeColumns();
FitColumns();
EndBatch();
//// Update rows
//BeginBatch();
//int nrows = GetRows();
//AssDialogue *line;
//for (int i=0;i<nrows;i++) {
// line = GetDialogue(i);
// if (byFrame) {
// SetCellValue(i,1,wxString::Format(_T("%i"),VFR_Output.CorrectFrameAtTime(line->Start.GetMS(),true)));
// SetCellValue(i,2,wxString::Format(_T("%i"),VFR_Output.CorrectFrameAtTime(line->End.GetMS(),false)));
// }
// else {
// SetCellValue(i,1,line->Start.GetASSFormated());
// SetCellValue(i,2,line->End.GetASSFormated());
// }
//}
//// Update columns
////AutoSizeColumn(1,false);
////AutoSizeColumn(2,false);
//AutoSizeColumns();
//FitColumns();
//EndBatch();
}

View File

@ -43,6 +43,7 @@
#include <wx/grid.h>
#include <vector>
#include <list>
#include "base_grid.h"
//////////////
@ -63,20 +64,16 @@ typedef std::list<AssEntry*>::iterator entryIter;
//////////////
// Main class
class SubtitlesGrid: public wxGrid {
class SubtitlesGrid: public BaseGrid {
private:
wxString tempfile;
bool changingCol;
bool ready;
FrameMain *parentFrame;
bool byFrame;
int RowHeight;
public:
AssFile *ass;
SubsEditBox *editBox;
VideoDisplay *video;
std::vector<entryIter> diagMap;
SubtitlesGrid(FrameMain* parentFrame,wxWindow *parent, wxWindowID id, VideoDisplay* video, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxWANTS_CHARS, const wxString& name = wxPanelNameStr);
~SubtitlesGrid();
@ -85,7 +82,7 @@ public:
void OnCellLeftClick(wxGridEvent &event);
void OnCellChange(wxGridEvent &event);
void OnSelectCell(wxGridEvent &event);
void OnPopupMenu(wxGridEvent &event);
void OnPopupMenu();
void OnKeyDown(wxKeyEvent &event);
void OnSwap(wxCommandEvent &event);
@ -112,9 +109,6 @@ public:
void On122Recombine(wxCommandEvent &event);
void On112Recombine(wxCommandEvent &event);
void OnSize(wxSizeEvent &event);
void OnPaint(wxPaintEvent &event);
void LoadDefault(AssFile *ass=NULL);
void Clear();
void SetRowColour(int n,AssDialogue *line=NULL);
@ -138,11 +132,8 @@ public:
void SplitLine(int n,int pos,int mode);
int GetFirstSelRow();
wxArrayInt GetSelection(bool *continuous=NULL);
AssDialogue *GetDialogue(int n);
void SetByFrame (bool state);
void FitColumns ();
void SetScrollbar (int orientation, int position, int thumbSize, int range, bool refresh);
wxString GetTempWorkFile ();
DECLARE_EVENT_TABLE()