summaryrefslogtreecommitdiff
path: root/library
diff options
context:
space:
mode:
Diffstat (limited to 'library')
-rw-r--r--library/binary.cpp10
-rw-r--r--library/custom_grid.cpp293
-rw-r--r--library/custom_grid.h72
-rw-r--r--library/db_file.cpp2
-rw-r--r--library/dir_lock.cpp79
-rw-r--r--library/pch.h14
6 files changed, 278 insertions, 192 deletions
diff --git a/library/binary.cpp b/library/binary.cpp
index d4d35e92..cbcef238 100644
--- a/library/binary.cpp
+++ b/library/binary.cpp
@@ -106,16 +106,6 @@ bool ffs3::filesHaveSameContent(const Zstring& filename1, const Zstring& filenam
}
//------------------------------------------------------------------------------------------------
-//#warning
-// static wxLongLong blorg = wxGetLocalTimeMillis();
-// if (wxGetLocalTimeMillis() - blorg > 5000)
-// {
-// blorg = wxGetLocalTimeMillis();
-// wxMessageBox(numberToZstring<size_t>(bufferSize).c_str());
-// }
-
-
-
if (length1 != length2 || ::memcmp(&memory1[0], &memory2[0], length1) != 0)
return false;
diff --git a/library/custom_grid.cpp b/library/custom_grid.cpp
index b510717f..e7a724a0 100644
--- a/library/custom_grid.cpp
+++ b/library/custom_grid.cpp
@@ -599,9 +599,6 @@ void CustomGrid::initSettings(CustomGridLeft* gridLeft,
m_gridRight = gridRight;
m_gridMiddle = gridMiddle;
- //set underlying grid data
- setGridDataTable(gridDataView);
-
//enhance grid functionality; identify leading grid by keyboard input or scroll action
Connect(wxEVT_KEY_DOWN, wxEventHandler(CustomGrid::onGridAccess), NULL, this);
Connect(wxEVT_SCROLLWIN_TOP, wxEventHandler(CustomGrid::onGridAccess), NULL, this);
@@ -626,7 +623,8 @@ void CustomGrid::initSettings(CustomGridLeft* gridLeft,
void CustomGrid::release() //release connection to ffs3::GridView
{
- setGridDataTable(NULL);
+ assert(getGridDataTable());
+ getGridDataTable()->setGridDataTable(NULL); //kind of "disable" griddatatable; don't delete it with SetTable(NULL)! May be used by wxGridCellStringRenderer
}
@@ -955,6 +953,13 @@ void CustomGrid::adjustGridHeights(wxEvent& event)
}
+void CustomGrid::updateGridSizes()
+{
+ if(getGridDataTable())
+ getGridDataTable()->updateGridSizes();
+}
+
+
void CustomGrid::setSortMarker(SortMarker marker)
{
m_marker = marker;
@@ -1175,7 +1180,48 @@ CustomGridRim::CustomGridRim(wxWindow *parent,
const wxSize& size,
long style,
const wxString& name) :
- CustomGrid(parent, id, pos, size, style, name), fileIconsAreEnabled(false) {}
+ CustomGrid(parent, id, pos, size, style, name), fileIconsAreEnabled(false), otherGrid(NULL)
+{
+ Connect(wxEVT_GRID_COL_SIZE, wxGridSizeEventHandler(CustomGridRim::OnResizeColumn), NULL, this); //row-based tooltip
+}
+
+
+void CustomGridRim::setOtherGrid(CustomGridRim* other) //call during initialization!
+{
+ otherGrid = other;
+}
+
+
+void CustomGridRim::OnResizeColumn(wxGridSizeEvent& event)
+{
+ //Resize columns on both sides in parallel
+ const int thisCol = event.GetRowOrCol();
+
+ if (!otherGrid || thisCol < 0 || thisCol >= GetNumberCols()) return;
+
+ const xmlAccess::ColumnTypes thisColType = getTypeAtPos(thisCol);
+
+ for (int i = 0; i < otherGrid->GetNumberCols(); ++i)
+ if (otherGrid->getTypeAtPos(i) == thisColType)
+ {
+ otherGrid->SetColSize(i, GetColSize(thisCol));
+ otherGrid->ForceRefresh();
+ break;
+ }
+}
+
+
+//this method is called when grid view changes: useful for parallel updating of multiple grids
+void CustomGridRim::alignOtherGrids(CustomGrid* gridLeft, CustomGrid* gridMiddle, CustomGrid* gridRight)
+{
+ if (!otherGrid) return;
+
+ int x = 0;
+ int y = 0;
+ GetViewStart(&x, &y);
+ gridMiddle->Scroll(-1, y);
+ otherGrid->Scroll(x, y);
+}
template <SelectedSide side>
@@ -1217,21 +1263,25 @@ void CustomGridRim::setTooltip(const wxMouseEvent& event)
}
}
- wxToolTip* tt = GetGridWindow()->GetToolTip();
- if (!tt)
- //wxWidgets bug: tooltip multiline property is defined by first tooltip text containing newlines or not (same is true for maximum width)
- GetGridWindow()->SetToolTip(new wxToolTip(wxT("a b\n\
- a b"))); //ugly, but is working (on Windows)
- tt = GetGridWindow()->GetToolTip(); //should be bound by now
- if (tt && tt->GetTip() != toolTip)
- tt->SetTip(toolTip);
-}
+ wxToolTip* tt = GetGridWindow()->GetToolTip();
-void CustomGridRim::updateGridSizes()
-{
- assert(getGridDataTable());
- getGridDataTable()->updateGridSizes();
+ const wxString currentTip = tt ? tt->GetTip() : wxString();
+ if (toolTip != currentTip)
+ {
+ if (toolTip.IsEmpty())
+ GetGridWindow()->SetToolTip(NULL); //wxGTK doesn't allow wxToolTip with empty text!
+ else
+ {
+ //wxWidgets bug: tooltip multiline property is defined by first tooltip text containing newlines or not (same is true for maximum width)
+ if (!tt)
+ GetGridWindow()->SetToolTip(new wxToolTip(wxT("a b\n\
+ a b"))); //ugly, but is working (on Windows)
+ tt = GetGridWindow()->GetToolTip(); //should be bound by now
+ if (tt)
+ tt->SetTip(toolTip);
+ }
+ }
}
@@ -1353,8 +1403,8 @@ void CustomGridRim::setColumnAttributes(const xmlAccess::ColumnAttributes& attr)
newPositions.push_back(columnSettings[i].type);
//set column positions
- assert(getGridDataTable());
- getGridDataTable()->setupColumns(newPositions);
+ if (getGridDataTableRim())
+ getGridDataTableRim()->setupColumns(newPositions);
//set column width (set them after setupColumns!)
for (size_t i = 0; i < newPositions.size(); ++i)
@@ -1379,8 +1429,10 @@ void CustomGridRim::setColumnAttributes(const xmlAccess::ColumnAttributes& attr)
xmlAccess::ColumnTypes CustomGridRim::getTypeAtPos(size_t pos) const
{
- assert(getGridDataTable());
- return getGridDataTable()->getTypeAtPos(pos);
+ if (getGridDataTableRim())
+ return getGridDataTableRim()->getTypeAtPos(pos);
+ else
+ return xmlAccess::DIRECTORY;
}
@@ -1408,13 +1460,6 @@ wxString CustomGridRim::getTypeName(xmlAccess::ColumnTypes colType)
}
-CustomGridTableRim* CustomGridRim::getGridDataTable()
-{
- //let the non-const call the const version: see Meyers Effective C++
- return const_cast<CustomGridTableRim*>(static_cast<const CustomGridRim*>(this)->getGridDataTable());
-}
-
-
void CustomGridRim::autoSizeColumns() //performance optimized column resizer (analog to wxGrid::AutoSizeColumns()
{
for (int col = 0; col < GetNumberCols(); ++col)
@@ -1474,9 +1519,9 @@ void CustomGridRim::enableFileIcons(const bool value)
fileIconsAreEnabled = value;
if (value)
- SetDefaultRenderer(new GridCellRenderer<true>(loadIconSuccess, getGridDataTable())); //SetDefaultRenderer takes ownership!
+ SetDefaultRenderer(new GridCellRenderer<true>(loadIconSuccess, getGridDataTableRim())); //SetDefaultRenderer takes ownership!
else
- SetDefaultRenderer(new GridCellRenderer<false>(loadIconSuccess, getGridDataTable()));
+ SetDefaultRenderer(new GridCellRenderer<false>(loadIconSuccess, getGridDataTableRim()));
Refresh();
}
@@ -1504,13 +1549,22 @@ CustomGridRim::VisibleRowRange CustomGridRim::getVisibleRows()
}
+inline
+CustomGridTableRim* CustomGridRim::getGridDataTableRim() const
+{
+ return dynamic_cast<CustomGridTableRim*>(getGridDataTable()); //I'm tempted to use a static cast here...
+}
+
+
void CustomGridRim::getIconsToBeLoaded(std::vector<Zstring>& newLoad) //loads all (not yet) drawn icons
{
newLoad.clear();
if (fileIconsAreEnabled) //don't check too often! give worker thread some time to fetch data
{
- const CustomGridTableRim* gridDataTable = getGridDataTable();
+ const CustomGridTableRim* gridDataTable = getGridDataTableRim();
+ if (!gridDataTable) return;
+
const VisibleRowRange rowsOnScreen = getVisibleRows();
const int totalCols = const_cast<CustomGridTableRim*>(gridDataTable)->GetNumberCols();
const int totalRows = const_cast<CustomGridTableRim*>(gridDataTable)->GetNumberRows();
@@ -1596,54 +1650,46 @@ CustomGridLeft::CustomGridLeft(wxWindow *parent,
const wxSize& size,
long style,
const wxString& name) :
- CustomGridRim(parent, id, pos, size, style, name),
- gridDataTable(NULL)
+ CustomGridRim(parent, id, pos, size, style, name)
{
GetGridWindow()->Connect(wxEVT_MOTION, wxMouseEventHandler(CustomGridLeft::OnMouseMovement), NULL, this); //row-based tooltip
}
-void CustomGridLeft::OnMouseMovement(wxMouseEvent& event)
-{
- CustomGridRim::setTooltip<LEFT_SIDE>(event);
- event.Skip();
-}
-
-
bool CustomGridLeft::CreateGrid(int numRows, int numCols, wxGrid::wxGridSelectionModes selmode)
{
//use custom wxGridTableBase class for management of large sets of formatted data.
//This is done in CreateGrid instead of SetTable method since source code is generated and wxFormbuilder invokes CreatedGrid by default.
- gridDataTable = new CustomGridTableLeft;
- SetTable(gridDataTable, true, wxGrid::wxGridSelectRows); //give ownership to wxGrid: gridDataTable is deleted automatically in wxGrid destructor
-
+ SetTable(new CustomGridTableLeft, true, wxGrid::wxGridSelectRows); //give ownership to wxGrid: gridDataTable is deleted automatically in wxGrid destructor
return true;
}
-void CustomGridLeft::setGridDataTable(const GridView* gridDataView)
+void CustomGridLeft::initSettings(CustomGridLeft* gridLeft, //create connection with ffs3::GridView
+ CustomGridMiddle* gridMiddle,
+ CustomGridRight* gridRight,
+ const ffs3::GridView* gridDataView)
{
//set underlying grid data
- assert(gridDataTable);
- gridDataTable->setGridDataTable(gridDataView);
+ assert(getGridDataTable());
+ getGridDataTable()->setGridDataTable(gridDataView);
+
+ CustomGridRim::setOtherGrid(gridRight);
+
+ CustomGridRim::initSettings(gridLeft, gridMiddle, gridRight, gridDataView);
}
-const CustomGridTableRim* CustomGridLeft::getGridDataTable() const
+void CustomGridLeft::OnMouseMovement(wxMouseEvent& event)
{
- return gridDataTable;
+ CustomGridRim::setTooltip<LEFT_SIDE>(event);
+ event.Skip();
}
-//this method is called when grid view changes: useful for parallel updating of multiple grids
-void CustomGridLeft::alignOtherGrids(CustomGrid* gridLeft, CustomGrid* gridMiddle, CustomGrid* gridRight)
+CustomGridTable* CustomGridLeft::getGridDataTable() const
{
- int x = 0;
- int y = 0;
- GetViewStart(&x, &y);
-
- gridMiddle->Scroll(-1, y); //scroll in y-direction only
- gridRight->Scroll(x, y);
+ return static_cast<CustomGridTable*>(GetTable()); //one of the few cases where no dynamic_cast is required!
}
@@ -1654,51 +1700,44 @@ CustomGridRight::CustomGridRight(wxWindow *parent,
const wxSize& size,
long style,
const wxString& name) :
- CustomGridRim(parent, id, pos, size, style, name),
- gridDataTable(NULL)
+ CustomGridRim(parent, id, pos, size, style, name)
{
GetGridWindow()->Connect(wxEVT_MOTION, wxMouseEventHandler(CustomGridRight::OnMouseMovement), NULL, this); //row-based tooltip
}
-void CustomGridRight::OnMouseMovement(wxMouseEvent& event)
-{
- CustomGridRim::setTooltip<RIGHT_SIDE>(event);
- event.Skip();
-}
-
-
bool CustomGridRight::CreateGrid(int numRows, int numCols, wxGrid::wxGridSelectionModes selmode)
{
- gridDataTable = new CustomGridTableRight;
- SetTable(gridDataTable, true, wxGrid::wxGridSelectRows); //give ownership to wxGrid: gridDataTable is deleted automatically in wxGrid destructor
-
+ SetTable(new CustomGridTableRight, true, wxGrid::wxGridSelectRows); //give ownership to wxGrid: gridDataTable is deleted automatically in wxGrid destructor
return true;
}
-void CustomGridRight::setGridDataTable(const GridView* gridDataView)
+void CustomGridRight::initSettings(CustomGridLeft* gridLeft, //create connection with ffs3::GridView
+ CustomGridMiddle* gridMiddle,
+ CustomGridRight* gridRight,
+ const ffs3::GridView* gridDataView)
{
//set underlying grid data
- assert(gridDataTable);
- gridDataTable->setGridDataTable(gridDataView);
+ assert(getGridDataTable());
+ getGridDataTable()->setGridDataTable(gridDataView);
+
+ CustomGridRim::setOtherGrid(gridLeft);
+
+ CustomGridRim::initSettings(gridLeft, gridMiddle, gridRight, gridDataView);
}
-const CustomGridTableRim* CustomGridRight::getGridDataTable() const
+void CustomGridRight::OnMouseMovement(wxMouseEvent& event)
{
- return gridDataTable;
+ CustomGridRim::setTooltip<RIGHT_SIDE>(event);
+ event.Skip();
}
-//this method is called when grid view changes: useful for parallel updating of multiple grids
-void CustomGridRight::alignOtherGrids(CustomGrid* gridLeft, CustomGrid* gridMiddle, CustomGrid* gridRight)
+CustomGridTable* CustomGridRight::getGridDataTable() const
{
- int x = 0;
- int y = 0;
- GetViewStart(&x, &y);
- gridLeft->Scroll(x, y);
- gridMiddle->Scroll(-1, y);
+ return static_cast<CustomGridTable*>(GetTable()); //one of the few cases where no dynamic_cast is required!
}
@@ -1706,7 +1745,7 @@ void CustomGridRight::alignOtherGrids(CustomGrid* gridLeft, CustomGrid* gridMidd
class GridCellRendererMiddle : public wxGridCellStringRenderer
{
public:
- GridCellRendererMiddle(const CustomGridMiddle* middleGrid) : m_gridMiddle(middleGrid) {};
+ GridCellRendererMiddle(const CustomGridMiddle& middleGrid) : m_gridMiddle(middleGrid) {};
virtual void Draw(wxGrid& grid,
wxGridCellAttr& attr,
@@ -1716,7 +1755,7 @@ public:
bool isSelected);
private:
- const CustomGridMiddle* const m_gridMiddle;
+ const CustomGridMiddle& m_gridMiddle;
};
@@ -1744,7 +1783,6 @@ CustomGridMiddle::CustomGridMiddle(wxWindow *parent,
selectionPos(BLOCKPOS_CHECK_BOX),
highlightedRow(-1),
highlightedPos(BLOCKPOS_CHECK_BOX),
- gridDataTable(NULL),
toolTip(new CustomTooltip)
{
SetLayoutDirection(wxLayout_LeftToRight); //
@@ -1765,38 +1803,55 @@ CustomGridMiddle::~CustomGridMiddle() {} //non-inline destructor for std::auto_p
bool CustomGridMiddle::CreateGrid(int numRows, int numCols, wxGrid::wxGridSelectionModes selmode)
{
- gridDataTable = new CustomGridTableMiddle;
- SetTable(gridDataTable, true, wxGrid::wxGridSelectRows); //give ownership to wxGrid: gridDataTable is deleted automatically in wxGrid destructor
+ SetTable(new CustomGridTableMiddle, 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(this)); //SetDefaultRenderer takes ownership!
+ SetDefaultRenderer(new GridCellRendererMiddle(*this)); //SetDefaultRenderer takes ownership!
return true;
}
-#ifdef FFS_WIN //get rid of scrollbars; Windows: overwrite virtual method
-void CustomGridMiddle::SetScrollbar(int orientation, int position, int thumbSize, int range, bool refresh)
-{
- wxWindow::SetScrollbar(orientation, 0, 0, 0, refresh);
-}
-#endif
-
-
-void CustomGridMiddle::setGridDataTable(const GridView* gridDataView) //called once on startup
+void CustomGridMiddle::initSettings(CustomGridLeft* gridLeft, //create connection with ffs3::GridView
+ CustomGridMiddle* gridMiddle,
+ CustomGridRight* gridRight,
+ const ffs3::GridView* gridDataView)
{
//set underlying grid data
- assert(gridDataTable);
- gridDataTable->setGridDataTable(gridDataView);
+ assert(getGridDataTable());
+ getGridDataTable()->setGridDataTable(gridDataView);
#ifdef FFS_LINUX //get rid of scrollbars; Linux: change policy for GtkScrolledWindow
GtkWidget* gridWidget = wxWindow::m_widget;
GtkScrolledWindow* scrolledWindow = GTK_SCROLLED_WINDOW(gridWidget);
gtk_scrolled_window_set_policy(scrolledWindow, GTK_POLICY_NEVER, GTK_POLICY_NEVER);
#endif
+
+ CustomGrid::initSettings(gridLeft, gridMiddle, gridRight, gridDataView);
}
+CustomGridTable* CustomGridMiddle::getGridDataTable() const
+{
+ return static_cast<CustomGridTable*>(GetTable()); //one of the few cases where no dynamic_cast is required!
+}
+
+
+inline
+CustomGridTableMiddle* CustomGridMiddle::getGridDataTableMiddle() const
+{
+ return static_cast<CustomGridTableMiddle*>(getGridDataTable());
+}
+
+
+#ifdef FFS_WIN //get rid of scrollbars; Windows: overwrite virtual method
+void CustomGridMiddle::SetScrollbar(int orientation, int position, int thumbSize, int range, bool refresh)
+{
+ wxWindow::SetScrollbar(orientation, 0, 0, 0, refresh);
+}
+#endif
+
+
void CustomGridMiddle::OnMouseMovement(wxMouseEvent& event)
{
const int rowOld = highlightedRow;
@@ -1836,14 +1891,17 @@ void CustomGridMiddle::OnLeaveWindow(wxMouseEvent& event)
void CustomGridMiddle::showToolTip(int rowNumber, wxPoint pos)
{
- const FileSystemObject* const fsObj = gridDataTable->getRawData(rowNumber);
+ if (!getGridDataTableMiddle())
+ return;
+
+ const FileSystemObject* const fsObj = getGridDataTableMiddle()->getRawData(rowNumber);
if (fsObj == NULL) //if invalid row...
{
toolTip->hide();
return;
}
- if (gridDataTable->syncPreviewIsActive()) //synchronization preview
+ if (getGridDataTableMiddle()->syncPreviewIsActive()) //synchronization preview
{
const SyncOperation syncOp = fsObj->getSyncOperation();
switch (syncOp)
@@ -1963,6 +2021,9 @@ void CustomGridMiddle::OnLeftMouseUp(wxMouseEvent& event)
int CustomGridMiddle::mousePosToRow(wxPoint pos, BlockPosition* block)
{
+ if (!getGridDataTableMiddle())
+ return 0;
+
int row = -1;
int x = -1;
int y = -1;
@@ -1978,9 +2039,9 @@ int CustomGridMiddle::mousePosToRow(wxPoint pos, BlockPosition* block)
if (row >= 0)
{
- const FileSystemObject* const fsObj = gridDataTable->getRawData(row);
+ const FileSystemObject* const fsObj = getGridDataTableMiddle()->getRawData(row);
if ( fsObj != NULL && //if valid row...
- gridDataTable->syncPreviewIsActive() &&
+ getGridDataTableMiddle()->syncPreviewIsActive() &&
fsObj->getSyncOperation() != SO_EQUAL) //in sync-preview equal files shall be treated as in cmp result, i.e. as full checkbox
{
// cell:
@@ -2012,8 +2073,8 @@ int CustomGridMiddle::mousePosToRow(wxPoint pos, BlockPosition* block)
void CustomGridMiddle::enableSyncPreview(bool value)
{
- assert(gridDataTable);
- gridDataTable->enableSyncPreview(value);
+ assert(getGridDataTableMiddle());
+ getGridDataTableMiddle()->enableSyncPreview(value);
if (value)
GetGridColLabelWindow()->SetToolTip(_("Synchronization Preview"));
@@ -2022,13 +2083,6 @@ void CustomGridMiddle::enableSyncPreview(bool value)
}
-void CustomGridMiddle::updateGridSizes()
-{
- assert(gridDataTable);
- gridDataTable->updateGridSizes();
-}
-
-
void GridCellRendererMiddle::Draw(wxGrid& grid,
wxGridCellAttr& attr,
wxDC& dc,
@@ -2037,12 +2091,12 @@ void GridCellRendererMiddle::Draw(wxGrid& grid,
bool isSelected)
{
//retrieve grid data
- const FileSystemObject* const fsObj = m_gridMiddle->gridDataTable->getRawData(row);
+ const FileSystemObject* const fsObj = m_gridMiddle.getGridDataTableMiddle() ? m_gridMiddle.getGridDataTableMiddle()->getRawData(row) : NULL;
if (fsObj != NULL) //if valid row...
{
if (rect.GetWidth() > CHECK_BOX_WIDTH)
{
- const bool rowIsHighlighted = row == m_gridMiddle->highlightedRow;
+ const bool rowIsHighlighted = row == m_gridMiddle.highlightedRow;
wxRect rectShrinked(rect);
@@ -2055,7 +2109,7 @@ void GridCellRendererMiddle::Draw(wxGrid& grid,
//HIGHLIGHTNING (checkbox):
if ( rowIsHighlighted &&
- m_gridMiddle->highlightedPos == CustomGridMiddle::BLOCKPOS_CHECK_BOX)
+ m_gridMiddle.highlightedPos == CustomGridMiddle::BLOCKPOS_CHECK_BOX)
{
if (fsObj->isActive())
dc.DrawLabel(wxEmptyString, GlobalResources::getInstance().getImageByName(wxT("checkboxTrueFocus")), rectShrinked, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
@@ -2074,14 +2128,14 @@ void GridCellRendererMiddle::Draw(wxGrid& grid,
wxGridCellRenderer::Draw(grid, attr, dc, rectShrinked, row, col, isSelected);
//print remaining block
- if (m_gridMiddle->gridDataTable->syncPreviewIsActive()) //synchronization preview
+ if (m_gridMiddle.getGridDataTableMiddle()->syncPreviewIsActive()) //synchronization preview
{
//print sync direction into second block
//HIGHLIGHTNING (sync direction):
if ( rowIsHighlighted &&
- m_gridMiddle->highlightedPos != CustomGridMiddle::BLOCKPOS_CHECK_BOX) //don't allow changing direction for "=="-files
- switch (m_gridMiddle->highlightedPos)
+ m_gridMiddle.highlightedPos != CustomGridMiddle::BLOCKPOS_CHECK_BOX) //don't allow changing direction for "=="-files
+ switch (m_gridMiddle.highlightedPos)
{
case CustomGridMiddle::BLOCKPOS_CHECK_BOX:
break;
@@ -2153,9 +2207,12 @@ void CustomGridMiddle::DrawColLabel(wxDC& dc, int col)
{
CustomGrid::DrawColLabel(dc, col);
+ if (!getGridDataTableMiddle())
+ return;
+
const wxRect rect(GetColLeft(col), 0, GetColWidth(col), GetColLabelSize());
- if (gridDataTable->syncPreviewIsActive())
+ if (getGridDataTableMiddle()->syncPreviewIsActive())
dc.DrawLabel(wxEmptyString, GlobalResources::getInstance().getImageByName(wxT("syncViewSmall")), rect, wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL);
else
dc.DrawLabel(wxEmptyString, GlobalResources::getInstance().getImageByName(wxT("cmpViewSmall")), rect, wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL);
diff --git a/library/custom_grid.h b/library/custom_grid.h
index 206841dd..193b403d 100644
--- a/library/custom_grid.h
+++ b/library/custom_grid.h
@@ -16,6 +16,7 @@
#include "../file_hierarchy.h"
+class CustomGridTable;
class CustomGridTableRim;
class CustomGridTableLeft;
class CustomGridTableRight;
@@ -62,10 +63,10 @@ public:
virtual ~CustomGrid() {}
- void initSettings(CustomGridLeft* gridLeft, //create connection with ffs3::GridView
- CustomGridMiddle* gridMiddle,
- CustomGridRight* gridRight,
- const ffs3::GridView* gridDataView);
+ virtual void initSettings(CustomGridLeft* gridLeft, //create connection with ffs3::GridView
+ CustomGridMiddle* gridMiddle,
+ CustomGridRight* gridRight,
+ const ffs3::GridView* gridDataView);
void release(); //release connection to ffs3::GridView
@@ -80,6 +81,9 @@ public:
DESCENDING
};
+ //notify wxGrid that underlying table size has changed
+ void updateGridSizes();
+
typedef std::pair<SortColumn, SortDirection> SortMarker;
void setSortMarker(SortMarker marker);
@@ -90,9 +94,9 @@ protected:
virtual void DrawColLabel(wxDC& dc, int col);
std::pair<int, int> mousePosToCell(wxPoint pos); //returns (row/column) pair
-private:
- virtual void setGridDataTable(const ffs3::GridView* gridDataView) = 0;
+ virtual CustomGridTable* getGridDataTable() const = 0;
+private:
//this method is called when grid view changes: useful for parallel updating of multiple grids
void OnPaintGrid(wxEvent& event);
@@ -147,9 +151,6 @@ public:
long style,
const wxString& name);
- //notify wxGrid that underlying table size has changed
- void updateGridSizes();
-
//set visibility, position and width of columns
static xmlAccess::ColumnAttributes getDefaultColumnAttributes();
xmlAccess::ColumnAttributes getColumnAttributes();
@@ -159,7 +160,6 @@ public:
static wxString getTypeName(xmlAccess::ColumnTypes colType);
void autoSizeColumns(); //performance optimized column resizer
- void autoSizeColumns(int col, bool doRefresh = true); //
void enableFileIcons(const bool value);
@@ -167,9 +167,15 @@ protected:
template <ffs3::SelectedSide side>
void setTooltip(const wxMouseEvent& event);
+void setOtherGrid(CustomGridRim* other); //call during initialization!
+
private:
- CustomGridTableRim* getGridDataTable();
- virtual const CustomGridTableRim* getGridDataTable() const = 0;
+ CustomGridTableRim* getGridDataTableRim() const;
+
+void OnResizeColumn(wxGridSizeEvent& event);
+
+ //this method is called when grid view changes: useful for parallel updating of multiple grids
+ virtual void alignOtherGrids(CustomGrid* gridLeft, CustomGrid* gridMiddle, CustomGrid* gridRight);
//asynchronous icon loading
void getIconsToBeLoaded(std::vector<Zstring>& newLoad); //loads all (not yet) drawn icons
@@ -188,6 +194,7 @@ private:
bool fileIconsAreEnabled;
xmlAccess::ColumnAttributes columnSettings; //set visibility, position and width of columns
+ CustomGridRim* otherGrid; //sibling grid on other side
};
@@ -203,15 +210,14 @@ public:
virtual bool CreateGrid(int numRows, int numCols, wxGrid::wxGridSelectionModes selmode = wxGrid::wxGridSelectCells);
+ virtual void initSettings(CustomGridLeft* gridLeft, //create connection with ffs3::GridView
+ CustomGridMiddle* gridMiddle,
+ CustomGridRight* gridRight,
+ const ffs3::GridView* gridDataView);
+
private:
void OnMouseMovement(wxMouseEvent& event);
- virtual void setGridDataTable(const ffs3::GridView* gridDataView);
- virtual const CustomGridTableRim* getGridDataTable() const;
-
- //this method is called when grid view changes: useful for parallel updating of multiple grids
- virtual void alignOtherGrids(CustomGrid* gridLeft, CustomGrid* gridMiddle, CustomGrid* gridRight);
-
- CustomGridTableLeft* gridDataTable;
+ virtual CustomGridTable* getGridDataTable() const;
};
@@ -227,15 +233,14 @@ public:
virtual bool CreateGrid(int numRows, int numCols, wxGrid::wxGridSelectionModes selmode = wxGrid::wxGridSelectCells);
+ virtual void initSettings(CustomGridLeft* gridLeft, //create connection with ffs3::GridView
+ CustomGridMiddle* gridMiddle,
+ CustomGridRight* gridRight,
+ const ffs3::GridView* gridDataView);
+
private:
void OnMouseMovement(wxMouseEvent& event);
- virtual void setGridDataTable(const ffs3::GridView* gridDataView);
- virtual const CustomGridTableRim* getGridDataTable() const;
-
- //this method is called when grid view changes: useful for parallel updating of multiple grids
- virtual void alignOtherGrids(CustomGrid* gridLeft, CustomGrid* gridMiddle, CustomGrid* gridRight);
-
- CustomGridTableRight* gridDataTable;
+ virtual CustomGridTable* getGridDataTable() const;
};
@@ -255,18 +260,21 @@ public:
virtual bool CreateGrid(int numRows, int numCols, wxGrid::wxGridSelectionModes selmode = wxGrid::wxGridSelectCells);
- void enableSyncPreview(bool value);
+ virtual void initSettings(CustomGridLeft* gridLeft, //create connection with ffs3::GridView
+ CustomGridMiddle* gridMiddle,
+ CustomGridRight* gridRight,
+ const ffs3::GridView* gridDataView);
- //notify wxGrid that underlying table size has changed
- void updateGridSizes();
+ void enableSyncPreview(bool value);
private:
+ virtual CustomGridTable* getGridDataTable() const;
+ CustomGridTableMiddle* getGridDataTableMiddle() const;
+
#ifdef FFS_WIN //get rid of scrollbars; Windows: overwrite virtual method
virtual void SetScrollbar(int orientation, int position, int thumbSize, int range, bool refresh = true);
#endif
- virtual void setGridDataTable(const ffs3::GridView* gridDataView);
-
//this method is called when grid view changes: useful for parallel updating of multiple grids
virtual void alignOtherGrids(CustomGrid* gridLeft, CustomGrid* gridMiddle, CustomGrid* gridRight);
@@ -297,8 +305,6 @@ private:
int highlightedRow;
BlockPosition highlightedPos;
- CustomGridTableMiddle* gridDataTable;
-
std::auto_ptr<CustomTooltip> toolTip;
};
diff --git a/library/db_file.cpp b/library/db_file.cpp
index 195d7df6..a0f5099c 100644
--- a/library/db_file.cpp
+++ b/library/db_file.cpp
@@ -33,8 +33,6 @@ const int FILE_FORMAT_VER = 4;
//-------------------------------------------------------------------------------------------------------------------------------
-//yet another layer of indirection: Since 32/64 bit builds are binary incompatible, we want them to write into "distinct parts" of the db-file
-//just like we were actually accessing different files
class FileInputStreamDB : public FileInputStream
{
public:
diff --git a/library/dir_lock.cpp b/library/dir_lock.cpp
index 54ae8636..f4ed8e07 100644
--- a/library/dir_lock.cpp
+++ b/library/dir_lock.cpp
@@ -12,8 +12,11 @@
#include "../shared/system_constants.h"
#include "../shared/guid.h"
#include "../shared/file_io.h"
+#include "../shared/assert_static.h"
#include <utility>
#include "../shared/serialize.h"
+#include <boost/cstdint.hpp>
+#include "../shared/build_info.h"
#ifdef FFS_WIN
#include <tlhelp32.h>
@@ -205,20 +208,37 @@ Zstring deleteAbandonedLockName(const Zstring& lockfilename)
namespace
{
inline
-wxString readString(wxInputStream& stream) //read string from file stream
+std::string readString(wxInputStream& stream) //read string from file stream
{
- const size_t strLength = util::readNumber<size_t>(stream);
- boost::scoped_array<wxChar> buffer(new wxChar[strLength]);
- stream.Read(buffer.get(), sizeof(wxChar) * strLength);
- return wxString(buffer.get(), strLength);
+ const boost::uint32_t strLength = util::readNumber<boost::uint32_t>(stream);
+ std::string output;
+ if (strLength > 0)
+ {
+ output.resize(strLength);
+ stream.Read(&output[0], strLength);
+ }
+ return output;
}
inline
-void writeString(wxOutputStream& stream, const wxString& str) //write string to filestream
+void writeString(wxOutputStream& stream, const std::string& str) //write string to filestream
+{
+ const boost::uint32_t strLength = static_cast<boost::uint32_t>(str.length());
+ util::writeNumber<boost::uint32_t>(stream, strLength);
+ stream.Write(str.c_str(), strLength);
+}
+
+
+std::string getComputerId() //returns empty string on error
{
- util::writeNumber<size_t>(stream, str.length());
- stream.Write(str.c_str(), sizeof(wxChar) * str.length());
+ const wxString fhn = ::wxGetFullHostName();
+ if (fhn.empty()) return std::string();
+#ifdef FFS_WIN
+ return "Windows " + std::string(fhn.ToUTF8());
+#elif defined FFS_LINUX
+ return "Linux " + std::string(fhn.ToUTF8());
+#endif
}
@@ -227,36 +247,42 @@ struct LockInformation
LockInformation()
{
#ifdef FFS_WIN
- processId = ::GetCurrentProcessId();
+ procDescr.processId = ::GetCurrentProcessId();
#elif defined FFS_LINUX
- processId = ::getpid();
+ procDescr.processId = ::getpid();
#endif
- computerId = ::wxGetFullHostName();
+ procDescr.computerId = getComputerId();
}
LockInformation(wxInputStream& stream) : //read
lockId(util::UniqueId(stream))
{
- processId = util::readNumber<ProcessId>(stream);
- computerId = readString(stream);
+ procDescr.processId = static_cast<ProcessId>(util::readNumber<boost::uint64_t>(stream)); //possible loss of precision (32/64 bit process) covered by buildId
+ procDescr.computerId = readString(stream);
}
void toStream(wxOutputStream& stream) const //write
{
+ assert_static(sizeof(ProcessId) <= sizeof(boost::uint64_t)); //ensure portability
+
lockId.toStream(stream);
- util::writeNumber<ProcessId>(stream, processId);
- writeString(stream, computerId);
+ util::writeNumber<boost::uint64_t>(stream, procDescr.processId);
+ writeString(stream, procDescr.computerId);
}
#ifdef FFS_WIN
- typedef DWORD ProcessId;
+ typedef DWORD ProcessId; //same size on 32 and 64 bit windows!
#elif defined FFS_LINUX
typedef pid_t ProcessId;
#endif
- util::UniqueId lockId;
- ProcessId processId;
- wxString computerId;
+ util::UniqueId lockId; //16 byte portable construct
+
+ struct ProcessDescription
+ {
+ ProcessId processId;
+ std::string computerId;
+ } procDescr;
};
@@ -267,16 +293,17 @@ enum ProcessStatus
PROC_STATUS_RUNNING,
PROC_STATUS_NO_IDEA
};
-ProcessStatus getProcessStatus(LockInformation::ProcessId procId, const wxString& computerId)
+ProcessStatus getProcessStatus(const LockInformation::ProcessDescription& procDescr)
{
- if (::wxGetFullHostName() != computerId || computerId.empty())
+ if ( procDescr.computerId != getComputerId() ||
+ procDescr.computerId.empty()) //both names are empty
return PROC_STATUS_NO_IDEA; //lock owned by different computer
#ifdef FFS_WIN
//note: ::OpenProcess() is no option as it may successfully return for crashed processes!
HANDLE snapshot = ::CreateToolhelp32Snapshot(
TH32CS_SNAPPROCESS, //__in DWORD dwFlags,
- procId); //__in DWORD th32ProcessID
+ 0); //__in DWORD th32ProcessID
if (snapshot == INVALID_HANDLE_VALUE)
return PROC_STATUS_NO_IDEA;
boost::shared_ptr<void> dummy(snapshot, ::CloseHandle);
@@ -290,7 +317,7 @@ ProcessStatus getProcessStatus(LockInformation::ProcessId procId, const wxString
do
{
- if (processEntry.th32ProcessID == procId)
+ if (processEntry.th32ProcessID == procDescr.processId)
return PROC_STATUS_RUNNING; //process still running
}
while(::Process32Next(snapshot, &processEntry));
@@ -298,10 +325,10 @@ ProcessStatus getProcessStatus(LockInformation::ProcessId procId, const wxString
return PROC_STATUS_NOT_RUNNING;
#elif defined FFS_LINUX
- if (procId <= 0 || procId >= 65536)
+ if (procDescr.processId <= 0 || procDescr.processId >= 65536)
return PROC_STATUS_NO_IDEA; //invalid process id
- return ffs3::dirExists(Zstr("/proc/") + Zstring::fromNumber(procId)) ? PROC_STATUS_RUNNING : PROC_STATUS_NOT_RUNNING;
+ return ffs3::dirExists(Zstr("/proc/") + Zstring::fromNumber(procDescr.processId)) ? PROC_STATUS_RUNNING : PROC_STATUS_NOT_RUNNING;
#endif
}
@@ -339,7 +366,7 @@ void waitOnDirLock(const Zstring& lockfilename, DirLockCallback* callback) //thr
try
{
const LockInformation lockInfo = retrieveLockInfo(lockfilename); //throw (FileError, ErrorNotExisting)
- const bool lockOwnderDead = getProcessStatus(lockInfo.processId, lockInfo.computerId) == PROC_STATUS_NOT_RUNNING; //convenience optimization: if we know the owning process crashed, we needn't wait DETECT_EXITUS_INTERVAL sec
+ const bool lockOwnderDead = getProcessStatus(lockInfo.procDescr) == PROC_STATUS_NOT_RUNNING; //convenience optimization: if we know the owning process crashed, we needn't wait DETECT_EXITUS_INTERVAL sec
wxULongLong fileSizeOld;
wxLongLong lockSilentStart = wxGetLocalTimeMillis();
diff --git a/library/pch.h b/library/pch.h
index 798319c7..f7ff59ab 100644
--- a/library/pch.h
+++ b/library/pch.h
@@ -29,16 +29,24 @@ do NOT use in release build!
//STL headers
#include <string>
-#include <algorithm>
#include <vector>
-#include <queue>
-#include <stack>
#include <set>
#include <map>
+#include <queue>
+#include <deque>
+#include <stack>
+#include <list>
+#include <algorithm>
+#include <functional>
+#include <iterator>
+#include <numeric>
#include <memory>
+#include <utility>
#include <fstream>
+#include <iostream>
#include <sstream>
#include <new>
+#include <stdexcept>
//other wxWidgets headers
#include <wx/log.h>
bgstack15