summaryrefslogtreecommitdiff
path: root/library/CustomGrid.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'library/CustomGrid.cpp')
-rw-r--r--library/CustomGrid.cpp564
1 files changed, 443 insertions, 121 deletions
diff --git a/library/CustomGrid.cpp b/library/CustomGrid.cpp
index faa75b2d..048bc5e0 100644
--- a/library/CustomGrid.cpp
+++ b/library/CustomGrid.cpp
@@ -41,11 +41,14 @@ class CustomGridTable : public wxGridTableBase
public:
CustomGridTable(int initialRows = 0, int initialCols = 0) : //note: initialRows/initialCols MUST match with GetNumberRows()/GetNumberCols() at initialization!!!
wxGridTableBase(),
- COLOR_BLUE( 80, 110, 255),
- COLOR_GREY( 212, 208, 200),
- COLOR_LIGHT_RED( 235, 57, 61),
- COLOR_LIGHT_BLUE( 63, 206, 233),
- COLOR_LIGHT_GREEN(54, 218, 2),
+ COLOR_BLUE( 80, 110, 255),
+ COLOR_GREY( 212, 208, 200),
+ COLOR_CMP_RED( 249, 163, 165),
+ COLOR_CMP_BLUE( 144, 232, 246),
+ COLOR_CMP_GREEN( 147, 253, 159),
+ COLOR_SYNC_BLUE( 201, 203, 247),
+ COLOR_SYNC_GREEN(197, 248, 190),
+ COLOR_YELLOW( 247, 252, 62),
gridDataView(NULL),
lastNrRows(initialRows),
lastNrCols(initialCols) {}
@@ -54,7 +57,7 @@ public:
virtual ~CustomGridTable() {}
- void setGridDataTable(GridView* gridDataView)
+ void setGridDataTable(const GridView* gridDataView)
{
this->gridDataView = gridDataView;
}
@@ -185,17 +188,20 @@ public:
protected:
const wxColour COLOR_BLUE;
const wxColour COLOR_GREY;
- const wxColour COLOR_LIGHT_RED;
- const wxColour COLOR_LIGHT_BLUE;
- const wxColour COLOR_LIGHT_GREEN;
+ const wxColour COLOR_CMP_RED;
+ const wxColour COLOR_CMP_BLUE;
+ const wxColour COLOR_CMP_GREEN;
+ const wxColour COLOR_SYNC_BLUE;
+ const wxColour COLOR_SYNC_GREEN;
+ const wxColour COLOR_YELLOW;
const GridView* gridDataView; //(very fast) access to underlying grid data :)
private:
virtual const wxColour& getRowColor(int row) = 0; //rows that are filtered out are shown in different color
- int lastNrRows;
- int lastNrCols;
+ int lastNrRows;
+ int lastNrCols;
};
@@ -246,8 +252,8 @@ public:
{
switch (getTypeAtPos(col))
{
- case xmlAccess::FULL_NAME:
- return gridLine->fileDescrLeft.fullName.c_str();
+ case xmlAccess::FULL_PATH:
+ return wxString(gridLine->fileDescrLeft.fullName.c_str());
case xmlAccess::FILENAME:
return wxEmptyString;
case xmlAccess::REL_PATH:
@@ -264,8 +270,8 @@ public:
{
switch (getTypeAtPos(col))
{
- case xmlAccess::FULL_NAME:
- return gridLine->fileDescrLeft.fullName.c_str();
+ case xmlAccess::FULL_PATH:
+ return wxString(gridLine->fileDescrLeft.fullName.c_str()).BeforeLast(GlobalResources::FILE_NAME_SEPARATOR);
case xmlAccess::FILENAME: //filename
return wxString(gridLine->fileDescrLeft.relativeName.c_str()).AfterLast(GlobalResources::FILE_NAME_SEPARATOR);
case xmlAccess::REL_PATH: //relative path
@@ -275,7 +281,7 @@ public:
case xmlAccess::SIZE: //file size
return globalFunctions::includeNumberSeparator(gridLine->fileDescrLeft.fileSize.ToString());
case xmlAccess::DATE: //date
- return FreeFileSync::utcTimeToLocalString(gridLine->fileDescrLeft.lastWriteTimeRaw);
+ return FreeFileSync::utcTimeToLocalString(gridLine->fileDescrLeft.lastWriteTimeRaw, gridLine->fileDescrLeft.fullName);
}
}
}
@@ -315,8 +321,8 @@ public:
{
switch (getTypeAtPos(col))
{
- case xmlAccess::FULL_NAME:
- return gridLine->fileDescrRight.fullName.c_str();
+ case xmlAccess::FULL_PATH:
+ return wxString(gridLine->fileDescrRight.fullName.c_str());
case xmlAccess::FILENAME: //filename
return wxEmptyString;
case xmlAccess::REL_PATH: //relative path
@@ -333,8 +339,8 @@ public:
{
switch (getTypeAtPos(col))
{
- case xmlAccess::FULL_NAME:
- return gridLine->fileDescrRight.fullName.c_str();
+ case xmlAccess::FULL_PATH:
+ return wxString(gridLine->fileDescrRight.fullName.c_str()).BeforeLast(GlobalResources::FILE_NAME_SEPARATOR);
case xmlAccess::FILENAME: //filename
return wxString(gridLine->fileDescrRight.relativeName.c_str()).AfterLast(GlobalResources::FILE_NAME_SEPARATOR);
case xmlAccess::REL_PATH: //relative path
@@ -344,7 +350,7 @@ public:
case xmlAccess::SIZE: //file size
return globalFunctions::includeNumberSeparator(gridLine->fileDescrRight.fileSize.ToString());
case xmlAccess::DATE: //date
- return FreeFileSync::utcTimeToLocalString(gridLine->fileDescrRight.lastWriteTimeRaw);
+ return FreeFileSync::utcTimeToLocalString(gridLine->fileDescrRight.lastWriteTimeRaw, gridLine->fileDescrRight.fullName);
}
}
}
@@ -376,7 +382,9 @@ class CustomGridTableMiddle : public CustomGridTable
{
public:
//middle grid is created (first wxWidgets internal call to GetNumberCols()) with one column
- CustomGridTableMiddle() : CustomGridTable(0, GetNumberCols()) {} //attention: static binding to virtual GetNumberCols() in a Constructor!
+ CustomGridTableMiddle() :
+ CustomGridTable(0, GetNumberCols()), //attention: static binding to virtual GetNumberCols() in a Constructor!
+ syncPreviewActive(false) {}
virtual int GetNumberCols()
{
@@ -388,35 +396,21 @@ public:
return wxEmptyString;
}
-
virtual wxString GetValue(int row, int col)
{
- const FileCompareLine* gridLine = getRawData(row);
- if (gridLine)
- {
- switch (gridLine->cmpResult)
- {
- case FILE_LEFT_SIDE_ONLY:
- return wxT("<|");
- case FILE_RIGHT_SIDE_ONLY:
- return wxT("|>");
- case FILE_RIGHT_NEWER:
- return wxT(">>");
- case FILE_LEFT_NEWER:
- return wxT("<<");
- case FILE_DIFFERENT:
- return wxT("!=");
- case FILE_EQUAL:
- return wxT("==");
- default:
- assert (false);
- return wxEmptyString;
- }
- }
- //if data is not found:
return wxEmptyString;
}
+ void enableSyncPreview(bool value)
+ {
+ syncPreviewActive = value;
+ }
+
+ bool syncPreviewIsActive() const
+ {
+ return syncPreviewActive;
+ }
+
private:
virtual const wxColour& getRowColor(int row) //rows that are filtered out are shown in different color
{
@@ -426,23 +420,46 @@ private:
//mark filtered rows
if (!gridLine->selectedForSynchronization)
return COLOR_BLUE;
- else
+
+ if (syncPreviewActive) //synchronization preview
+ {
+ switch (gridLine->direction)
+ {
+ case SYNC_DIR_LEFT:
+ return COLOR_SYNC_BLUE;
+ case SYNC_DIR_RIGHT:
+ return COLOR_SYNC_GREEN;
+ case SYNC_DIR_NONE:
+ return *wxWHITE;
+ case SYNC_UNRESOLVED_CONFLICT:
+ return COLOR_YELLOW;
+ }
+ }
+ else //comparison results view
+ {
switch (gridLine->cmpResult)
{
case FILE_LEFT_SIDE_ONLY:
case FILE_RIGHT_SIDE_ONLY:
- return COLOR_LIGHT_GREEN;
+ return COLOR_CMP_GREEN;
case FILE_LEFT_NEWER:
case FILE_RIGHT_NEWER:
- return COLOR_LIGHT_BLUE;
+ return COLOR_CMP_BLUE;
case FILE_DIFFERENT:
- return COLOR_LIGHT_RED;
- default:
+ return COLOR_CMP_RED;
+ case FILE_EQUAL:
return *wxWHITE;
+ case FILE_CONFLICT:
+ return COLOR_YELLOW;
}
+ }
}
+
+ //fallback
return *wxWHITE;
}
+
+ bool syncPreviewActive; //determines wheter grid shall show compare result or sync preview
};
//########################################################################################################
@@ -748,6 +765,59 @@ void CustomGrid::DrawColLabel(wxDC& dc, int col)
dc.DrawBitmap(*sortMarker, GetColRight(col) - 16 - 2, 2, true); //respect 2-pixel border
}
+
+std::set<int> CustomGrid::getAllSelectedRows() const
+{
+ std::set<int> output;
+
+ const wxArrayInt selectedRows = this->GetSelectedRows();
+ if (!selectedRows.IsEmpty())
+ {
+ for (unsigned int i = 0; i < selectedRows.GetCount(); ++i)
+ output.insert(selectedRows[i]);
+ }
+
+ if (!this->GetSelectedCols().IsEmpty()) //if a column is selected this is means all rows are marked for deletion
+ {
+ for (int k = 0; k < const_cast<CustomGrid*>(this)->GetNumberRows(); ++k) //messy wxGrid implementation...
+ output.insert(k);
+ }
+
+ const wxGridCellCoordsArray singlySelected = this->GetSelectedCells();
+ if (!singlySelected.IsEmpty())
+ {
+ for (unsigned int k = 0; k < singlySelected.GetCount(); ++k)
+ output.insert(singlySelected[k].GetRow());
+ }
+
+ const wxGridCellCoordsArray tmpArrayTop = this->GetSelectionBlockTopLeft();
+ if (!tmpArrayTop.IsEmpty())
+ {
+ wxGridCellCoordsArray tmpArrayBottom = this->GetSelectionBlockBottomRight();
+
+ unsigned int arrayCount = tmpArrayTop.GetCount();
+
+ if (arrayCount == tmpArrayBottom.GetCount())
+ {
+ for (unsigned int i = 0; i < arrayCount; ++i)
+ {
+ const int rowTop = tmpArrayTop[i].GetRow();
+ const int rowBottom = tmpArrayBottom[i].GetRow();
+
+ for (int k = rowTop; k <= rowBottom; ++k)
+ output.insert(k);
+ }
+ }
+ }
+
+ //some exception: also add current cursor row to selection if there are no others... hopefully improving usability
+ if (output.empty() && this->isLeadGrid())
+ output.insert(const_cast<CustomGrid*>(this)->GetCursorRow()); //messy wxGrid implementation...
+
+ return output;
+}
+
+
//############################################################################################
//CustomGrid specializations
@@ -837,6 +907,26 @@ private:
const CustomGridTableRim* const m_gridDataTable;
};
+//----------------------------------------------------------------------------------------
+
+
+void CustomGridRim::initSettings(const bool showFileIcons,
+ CustomGrid* gridLeft,
+ CustomGrid* gridRight,
+ CustomGrid* gridMiddle,
+ const GridView* gridDataView)
+{
+ //these grids will scroll together
+ m_gridLeft = gridLeft;
+ m_gridRight = gridRight;
+ m_gridMiddle = gridMiddle;
+
+ //set underlying grid data
+ assert(gridDataTable);
+ gridDataTable->setGridDataTable(gridDataView);
+
+ enableFileIcons(showFileIcons);
+}
void CustomGridRim::updateGridSizes()
@@ -851,7 +941,7 @@ xmlAccess::ColumnAttributes CustomGridRim::getDefaultColumnAttributes()
xmlAccess::ColumnAttributes defaultColumnSettings;
xmlAccess::ColumnAttrib newEntry;
- newEntry.type = xmlAccess::FULL_NAME;
+ newEntry.type = xmlAccess::FULL_PATH;
newEntry.visible = false;
newEntry.position = 0;
newEntry.width = 150;
@@ -990,8 +1080,8 @@ wxString CustomGridRim::getTypeName(xmlAccess::ColumnTypes colType)
{
switch (colType)
{
- case xmlAccess::FULL_NAME:
- return _("Full name");
+ case xmlAccess::FULL_PATH:
+ return _("Full path");
case xmlAccess::FILENAME:
return _("Filename");
case xmlAccess::REL_PATH:
@@ -1002,13 +1092,14 @@ wxString CustomGridRim::getTypeName(xmlAccess::ColumnTypes colType)
return _("Size");
case xmlAccess::DATE:
return _("Date");
- default:
- return wxEmptyString;
}
-}
+ return wxEmptyString; //dummy
+}
//----------------------------------------------------------------------------------------
+
+
CustomGridLeft::CustomGridLeft(wxWindow *parent,
wxWindowID id,
const wxPoint& pos,
@@ -1029,25 +1120,14 @@ bool CustomGridLeft::CreateGrid(int numRows, int numCols, wxGrid::wxGridSelectio
}
-void CustomGridLeft::initSettings(const bool showFileIcons,
- CustomGrid* gridLeft,
- CustomGrid* gridRight,
- CustomGrid* gridMiddle,
- GridView* gridDataView)
+void CustomGridLeft::enableFileIcons(const bool value)
{
- //these grids will scroll together
- m_gridLeft = gridLeft;
- m_gridRight = gridRight;
- m_gridMiddle = gridMiddle;
-
- //set underlying grid data
- assert(gridDataTable);
- gridDataTable->setGridDataTable(gridDataView);
-
- if (showFileIcons)
+ if (value)
SetDefaultRenderer(new GridCellRenderer<true, true>(gridDataTable)); //SetDefaultRenderer takes ownership!
else
SetDefaultRenderer(new GridCellRenderer<true, false>(gridDataTable));
+
+ Refresh();
}
@@ -1085,25 +1165,14 @@ bool CustomGridRight::CreateGrid(int numRows, int numCols, wxGrid::wxGridSelecti
}
-void CustomGridRight::initSettings(const bool showFileIcons,
- CustomGrid* gridLeft,
- CustomGrid* gridRight,
- CustomGrid* gridMiddle,
- GridView* gridDataView)
+void CustomGridRight::enableFileIcons(const bool value)
{
- //these grids will scroll together
- m_gridLeft = gridLeft;
- m_gridRight = gridRight;
- m_gridMiddle = gridMiddle;
-
- //set underlying grid data
- assert(gridDataTable);
- gridDataTable->setGridDataTable(gridDataView);
-
- if (showFileIcons)
+ if (value)
SetDefaultRenderer(new GridCellRenderer<false, true>(gridDataTable)); //SetDefaultRenderer takes ownership!
else
SetDefaultRenderer(new GridCellRenderer<false, false>(gridDataTable));
+
+ Refresh();
}
@@ -1123,6 +1192,19 @@ void CustomGridRight::DoPrepareDC(wxDC& dc)
//----------------------------------------------------------------------------------------
+//define new event types
+const wxEventType FFS_CHECK_ROWS_EVENT = wxNewEventType(); //attention! do NOT place in header to keep (generated) id unique!
+const wxEventType FFS_SYNC_DIRECTION_EVENT = wxNewEventType();
+
+const int CHECK_BOX_IMAGE = 11; //width of checkbox image
+const int CHECK_BOX_WIDTH = CHECK_BOX_IMAGE + 3; //width of first block
+
+// cell:
+// ----------------------------------
+// | checkbox | left | middle | right|
+// ----------------------------------
+
+
CustomGridMiddle::CustomGridMiddle(wxWindow *parent,
wxWindowID id,
const wxPoint& pos,
@@ -1130,25 +1212,155 @@ CustomGridMiddle::CustomGridMiddle(wxWindow *parent,
long style,
const wxString& name) :
CustomGrid(parent, id, pos, size, style, name),
+ selectionRowBegin(-1),
+ selectionPos(BLOCKPOS_CHECK_BOX),
+ highlightedRow(-1),
+ highlightedPos(BLOCKPOS_CHECK_BOX),
gridDataTable(NULL)
{
- const wxString header = _("Legend");
- wxString toolTip = header + wxT("\n") +
- wxString().Pad(header.Len(), wxChar('-')) + wxT("\n") +
- _("<| file on left side only\n") +
- _("|> file on right side only\n") +
- _("<< left file is newer\n") +
- _(">> right file is newer\n") +
- _("!= files are different\n") +
- _("== files are equal\n\n");
- GetGridWindow()->SetToolTip(toolTip);
+ //connect events for dynamic selection of sync direction
+ GetGridWindow()->Connect(wxEVT_MOTION, wxMouseEventHandler(CustomGridMiddle::OnMouseMovement), NULL, this);
+
+ GetGridWindow()->Connect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(CustomGridMiddle::OnLeaveWindow), NULL, this);
+ GetGridWindow()->Connect(wxEVT_LEFT_UP, wxMouseEventHandler(CustomGridMiddle::OnLeftMouseUp), NULL, this);
+ GetGridWindow()->Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(CustomGridMiddle::OnLeftMouseDown), NULL, this);
+}
+
+
+void CustomGridMiddle::OnMouseMovement(wxMouseEvent& event)
+{
+ const int highlightedRowOld = highlightedRow;
+
+ if (selectionRowBegin == -1) //change highlightning only if currently not dragging mouse
+ {
+ highlightedRow = mousePosToRow(event.GetPosition(), &highlightedPos);
+ if (highlightedRow >= 0) RefreshRow(highlightedRow);
+ if ( highlightedRowOld >= 0 &&
+ highlightedRow != highlightedRowOld)
+ RefreshRow(highlightedRowOld);
+ }
+
+ event.Skip();
+}
+
+
+void CustomGridMiddle::RefreshRow(int row)
+{
+ wxRect rectScrolled(CellToRect(row, 0));
+ CalcScrolledPosition(rectScrolled.x, rectScrolled.y, &rectScrolled.x, &rectScrolled.y);
+
+ GetGridWindow()->Refresh(false, &rectScrolled); //note: CellToRect() and YToRow work on m_gridWindow NOT on the whole grid!
+}
+
+
+void CustomGridMiddle::OnLeaveWindow(wxMouseEvent& event)
+{
+ highlightedRow = -1;
+ highlightedPos = BLOCKPOS_CHECK_BOX;
+ Refresh();
+}
+
+
+void CustomGridMiddle::OnLeftMouseDown(wxMouseEvent& event)
+{
+ selectionRowBegin = mousePosToRow(event.GetPosition(), &selectionPos);
+ event.Skip();
+}
+
+
+void CustomGridMiddle::OnLeftMouseUp(wxMouseEvent& event)
+{
+ const int rowEndFiltering = mousePosToRow(event.GetPosition());
+
+ if (0 <= selectionRowBegin && 0 <= rowEndFiltering)
+ {
+ switch (selectionPos)
+ {
+ case BLOCKPOS_CHECK_BOX:
+ {
+ //create a custom event
+ FFSCheckRowsEvent evt(selectionRowBegin, rowEndFiltering);
+ AddPendingEvent(evt);
+ }
+ break;
+ case BLOCKPOS_LEFT:
+ {
+ //create a custom event
+ FFSSyncDirectionEvent evt(selectionRowBegin, rowEndFiltering, SYNC_DIR_LEFT);
+ AddPendingEvent(evt);
+ }
+ break;
+ case BLOCKPOS_MIDDLE:
+ {
+ //create a custom event
+ FFSSyncDirectionEvent evt(selectionRowBegin, rowEndFiltering, SYNC_DIR_NONE);
+ AddPendingEvent(evt);
+ }
+ break;
+ case BLOCKPOS_RIGHT:
+ {
+ //create a custom event
+ FFSSyncDirectionEvent evt(selectionRowBegin, rowEndFiltering, SYNC_DIR_RIGHT);
+ AddPendingEvent(evt);
+ }
+ break;
+ }
+ }
+ selectionRowBegin = -1;
+ selectionPos = BLOCKPOS_CHECK_BOX;
+
+ ClearSelection();
+ event.Skip();
+}
+
+
+int CustomGridMiddle::mousePosToRow(const wxPoint pos, BlockPosition* block)
+{
+ int row = -1;
+ int x = -1;
+ int y = -1;
+ CalcUnscrolledPosition( pos.x, pos.y, &x, &y );
+ if (x >= 0 && y >= 0)
+ {
+ row = YToRow(y);
+
+ //determine blockposition within cell (optional)
+ if (block)
+ {
+ *block = BLOCKPOS_CHECK_BOX; //default
+ if (gridDataTable->syncPreviewIsActive() &&
+ row >= 0)
+ {
+ // cell:
+ // ----------------------------------
+ // | checkbox | left | middle | right|
+ // ----------------------------------
+
+ const wxRect rect = CellToRect(row, 0);
+ if (rect.GetWidth() > CHECK_BOX_WIDTH)
+ {
+ const double blockWidth = (rect.GetWidth() - CHECK_BOX_WIDTH) / 3.0;
+ if (rect.GetX() + CHECK_BOX_WIDTH <= x && x < rect.GetX() + rect.GetWidth())
+ {
+ if (x - (rect.GetX() + CHECK_BOX_WIDTH) < blockWidth)
+ *block = BLOCKPOS_LEFT;
+ else if (x - (rect.GetX() + CHECK_BOX_WIDTH) < 2 * blockWidth)
+ *block = BLOCKPOS_MIDDLE;
+ else
+ *block = BLOCKPOS_RIGHT;
+ }
+ }
+ }
+ }
+ }
+ return row;
}
void CustomGridMiddle::initSettings(CustomGrid* gridLeft,
CustomGrid* gridRight,
CustomGrid* gridMiddle,
- FreeFileSync::GridView* gridDataView)
+ const FreeFileSync::GridView* gridDataView)
{
//these grids will scroll together
m_gridLeft = gridLeft;
@@ -1174,6 +1386,40 @@ void CustomGridMiddle::SetScrollbar(int orientation, int position, int thumbSize
}
#endif
+
+void CustomGridMiddle::enableSyncPreview(bool value)
+{
+ assert(gridDataTable);
+ gridDataTable->enableSyncPreview(value);
+
+ //update legend
+ wxString toolTip;
+
+ if (gridDataTable->syncPreviewIsActive()) //synchronization preview
+ {
+ const wxString header = _("Synchronization Preview");
+ toolTip = header + wxT("\n") + wxString().Pad(header.Len(), wxChar('-')) + wxT("\n");
+ toolTip += wxString(_("<- copy to left side\n")) +
+ _("-> copy to right side\n") +
+ wxT(" ")+ _("- do not copy\n") +
+ _("flash conflict\n");
+ }
+ else //compare results view
+ {
+ const wxString header = _("Comparison Result");
+ toolTip = header + wxT("\n") + wxString().Pad(header.Len(), wxChar('-')) + wxT("\n");
+ toolTip += wxString(_("<| file on left side only\n")) +
+ _("|> file on right side only\n") +
+ _("<< left file is newer\n") +
+ _(">> right file is newer\n") +
+ _("!= files are different\n") +
+ _("== files are equal\n") +
+ _("flash conflict\n");
+ }
+ GetGridColLabelWindow()->SetToolTip(toolTip);
+}
+
+
void CustomGridMiddle::updateGridSizes()
{
assert(gridDataTable);
@@ -1184,7 +1430,7 @@ void CustomGridMiddle::updateGridSizes()
class GridCellRendererMiddle : public wxGridCellStringRenderer
{
public:
- GridCellRendererMiddle(CustomGridTable* gridDataTable) : m_gridDataTable(gridDataTable) {};
+ GridCellRendererMiddle(const CustomGridMiddle* middleGrid) : m_gridMiddle(middleGrid) {};
virtual void Draw(wxGrid& grid,
@@ -1195,36 +1441,112 @@ public:
bool isSelected)
{
//retrieve grid data
- const FileCompareLine* rowData = m_gridDataTable->getRawData(row);
- if (!rowData) //no valid row
+ const FileCompareLine* const rowData = m_gridMiddle->gridDataTable->getRawData(row);
+ if (rowData) //no valid row
{
- wxGridCellStringRenderer::Draw(grid, attr, dc, rect, row, col, isSelected);
- return;
- }
+ if (rect.GetWidth() > CHECK_BOX_WIDTH)
+ {
+ wxRect rectShrinked(rect);
- const int shift = std::min(11 + 3, rect.GetWidth()); //11 is width of checkbox image
+ //clean first block of rect that will receive image of checkbox
+ rectShrinked.SetWidth(CHECK_BOX_WIDTH);
+ wxGridCellRenderer::Draw(grid, attr, dc, rectShrinked, row, col, isSelected);
- wxRect rectShrinked(rect);
+ //print image into first block
+ rectShrinked.SetX(rect.GetX() + 1);
+ bool selected = rowData->selectedForSynchronization;
- //clean first block of rect that will receive image of checkbox
- rectShrinked.SetWidth(shift);
- wxGridCellRenderer::Draw(grid, attr, dc, rectShrinked, row, col, isSelected);
+ //HIGHLIGHTNING:
+ if ( row == m_gridMiddle->highlightedRow &&
+ m_gridMiddle->highlightedPos == CustomGridMiddle::BLOCKPOS_CHECK_BOX)
+ selected = !selected;
- //print image into first block
- rectShrinked.SetX(rect.GetX() + 1);
- if (rowData->selectedForSynchronization)
- dc.DrawLabel(wxEmptyString, *globalResource.bitmapCheckBoxTrue, rectShrinked, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
- else
- dc.DrawLabel(wxEmptyString, *globalResource.bitmapCheckBoxFalse, rectShrinked, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
+ if (selected)
+ dc.DrawLabel(wxEmptyString, *globalResource.bitmapCheckBoxTrue, rectShrinked, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
+ else
+ dc.DrawLabel(wxEmptyString, *globalResource.bitmapCheckBoxFalse, rectShrinked, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
- //print second block (default): display compare result
- rectShrinked.SetWidth(rect.GetWidth() - shift);
- rectShrinked.SetX(rect.GetX() + shift);
- wxGridCellStringRenderer::Draw(grid, attr, dc, rectShrinked, row, col, isSelected);
+ //clean remaining block of rect that will receive image of checkbox/directions
+ rectShrinked.SetWidth(rect.GetWidth() - CHECK_BOX_WIDTH);
+ rectShrinked.SetX(rect.GetX() + CHECK_BOX_WIDTH);
+ wxGridCellRenderer::Draw(grid, attr, dc, rectShrinked, row, col, isSelected);
+
+ //print remaining block
+ if (m_gridMiddle->gridDataTable->syncPreviewIsActive()) //synchronization preview
+ {
+ //print sync direction into second block
+
+ //HIGHLIGHTNING:
+ if (row == m_gridMiddle->highlightedRow && m_gridMiddle->highlightedPos != CustomGridMiddle::BLOCKPOS_CHECK_BOX)
+ switch (m_gridMiddle->highlightedPos)
+ {
+ case CustomGridMiddle::BLOCKPOS_CHECK_BOX:
+ break;
+ case CustomGridMiddle::BLOCKPOS_LEFT:
+ dc.DrawLabel(wxEmptyString, *globalResource.bitmapSyncDirLeftSmall, rectShrinked, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
+ break;
+ case CustomGridMiddle::BLOCKPOS_MIDDLE:
+ dc.DrawLabel(wxEmptyString, *globalResource.bitmapSyncDirNoneSmall, rectShrinked, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
+ break;
+ case CustomGridMiddle::BLOCKPOS_RIGHT:
+ dc.DrawLabel(wxEmptyString, *globalResource.bitmapSyncDirRightSmall, rectShrinked, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
+ break;
+ }
+ else //default
+ switch (rowData->direction)
+ {
+ case SYNC_DIR_LEFT:
+ dc.DrawLabel(wxEmptyString, *globalResource.bitmapSyncDirLeftSmall, rectShrinked, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
+ break;
+ case SYNC_DIR_RIGHT:
+ dc.DrawLabel(wxEmptyString, *globalResource.bitmapSyncDirRightSmall, rectShrinked, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
+ break;
+ case SYNC_DIR_NONE:
+ dc.DrawLabel(wxEmptyString, *globalResource.bitmapSyncDirNoneSmall, rectShrinked, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
+ break;
+ case SYNC_UNRESOLVED_CONFLICT:
+ dc.DrawLabel(wxEmptyString, *globalResource.bitmapConflictSmall, rectShrinked, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
+ break;
+ }
+ }
+ else //comparison results view
+ {
+ switch (rowData->cmpResult)
+ {
+ case FILE_LEFT_SIDE_ONLY:
+ dc.DrawLabel(wxEmptyString, *globalResource.bitmapLeftOnlySmall, rectShrinked, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
+ break;
+ case FILE_RIGHT_SIDE_ONLY:
+ dc.DrawLabel(wxEmptyString, *globalResource.bitmapRightOnlySmall, rectShrinked, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
+ break;
+ case FILE_LEFT_NEWER:
+ dc.DrawLabel(wxEmptyString, *globalResource.bitmapLeftNewerSmall, rectShrinked, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
+ break;
+ case FILE_RIGHT_NEWER:
+ dc.DrawLabel(wxEmptyString, *globalResource.bitmapRightNewerSmall, rectShrinked, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
+ break;
+ case FILE_DIFFERENT:
+ dc.DrawLabel(wxEmptyString, *globalResource.bitmapDifferentSmall, rectShrinked, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
+ break;
+ case FILE_EQUAL:
+ dc.DrawLabel(wxEmptyString, *globalResource.bitmapEqualSmall, rectShrinked, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
+ break;
+ case FILE_CONFLICT:
+ dc.DrawLabel(wxEmptyString, *globalResource.bitmapConflictSmall, rectShrinked, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
+ break;
+ }
+ }
+
+ return;
+ }
+ }
+
+ //fallback
+ wxGridCellStringRenderer::Draw(grid, attr, dc, rect, row, col, isSelected);
}
private:
- const CustomGridTable* const m_gridDataTable;
+ const CustomGridMiddle* const m_gridMiddle;
};
@@ -1234,7 +1556,7 @@ bool CustomGridMiddle::CreateGrid(int numRows, int numCols, wxGrid::wxGridSelect
SetTable(gridDataTable, true, wxGrid::wxGridSelectRows); //give ownership to wxGrid: gridDataTable is deleted automatically in wxGrid destructor
//display checkboxes (representing bool values) if row is enabled for synchronization
- SetDefaultRenderer(new GridCellRendererMiddle(gridDataTable)); //SetDefaultRenderer takes ownership!
+ SetDefaultRenderer(new GridCellRendererMiddle(this)); //SetDefaultRenderer takes ownership!
return true;
}
bgstack15