mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-06 14:29:54 +08:00
203 lines
4.9 KiB
C++
203 lines
4.9 KiB
C++
#ifndef VTABLE_H
|
|
#define VTABLE_H
|
|
|
|
#include <QTextBlock>
|
|
|
|
#include "markdownhighlighterdata.h"
|
|
|
|
class VEditor;
|
|
|
|
class VTable
|
|
{
|
|
public:
|
|
enum Alignment {
|
|
None,
|
|
Left,
|
|
Center,
|
|
Right
|
|
};
|
|
|
|
VTable(VEditor *p_editor, const VTableBlock &p_block);
|
|
|
|
VTable(VEditor *p_editor, int p_nrBodyRow, int p_nrCol, VTable::Alignment p_alignment);
|
|
|
|
bool isValid() const;
|
|
|
|
void format();
|
|
|
|
// Write a formatted table.
|
|
void write();
|
|
|
|
private:
|
|
struct Cell
|
|
{
|
|
Cell()
|
|
: m_offset(-1),
|
|
m_length(0),
|
|
m_cursorCoreOffset(-1),
|
|
m_deleted(false)
|
|
{
|
|
}
|
|
|
|
void clear()
|
|
{
|
|
m_offset = -1;
|
|
m_length = 0;
|
|
m_text.clear();
|
|
m_formattedText.clear();
|
|
m_cursorCoreOffset = -1;
|
|
m_deleted = false;
|
|
}
|
|
|
|
// Start offset within block, including the starting border |.
|
|
int m_offset;
|
|
|
|
// Length of this cell, till next border |.
|
|
int m_length;
|
|
|
|
// Text like "| vnote ".
|
|
QString m_text;
|
|
|
|
// Formatted text, such as "| vnote ".
|
|
// It is empty if it does not need formatted.
|
|
QString m_formattedText;
|
|
|
|
// If cursor is within this cell, this will not be -1.
|
|
int m_cursorCoreOffset;
|
|
|
|
// Whether this cell need to be deleted.
|
|
bool m_deleted;
|
|
};
|
|
|
|
struct Row
|
|
{
|
|
Row()
|
|
{
|
|
}
|
|
|
|
bool isValid() const
|
|
{
|
|
return !m_cells.isEmpty();
|
|
}
|
|
|
|
void clear()
|
|
{
|
|
m_block = QTextBlock();
|
|
m_preText.clear();
|
|
m_cells.clear();
|
|
}
|
|
|
|
QString toString() const
|
|
{
|
|
QString cells;
|
|
for (auto & cell : m_cells) {
|
|
cells += QString(" (%1, %2 [%3])").arg(cell.m_offset)
|
|
.arg(cell.m_length)
|
|
.arg(cell.m_text);
|
|
}
|
|
|
|
return QString("row %1 %2").arg(m_block.blockNumber()).arg(cells);
|
|
}
|
|
|
|
QTextBlock m_block;
|
|
// Text before table row.
|
|
QString m_preText;
|
|
QVector<Cell> m_cells;
|
|
};
|
|
|
|
// Used to hold info about a cell when formatting a column.
|
|
struct CellInfo
|
|
{
|
|
CellInfo()
|
|
: m_coreOffset(0),
|
|
m_coreLength(0),
|
|
m_coreWidth(0)
|
|
{
|
|
}
|
|
|
|
// The offset of the core content within the cell.
|
|
// Will be 0 if it is an empty cell.
|
|
int m_coreOffset;
|
|
|
|
// The length of the core content.
|
|
// Will be 0 if it is an empty cell.
|
|
int m_coreLength;
|
|
|
|
// Pixel width of the core content.
|
|
int m_coreWidth;
|
|
};
|
|
|
|
void parseFromTableBlock(const VTableBlock &p_block);
|
|
|
|
void clear();
|
|
|
|
bool parseOneRow(const QTextBlock &p_block,
|
|
const QVector<int> &p_borders,
|
|
int &p_borderIdx,
|
|
Row &p_row) const;
|
|
|
|
int calculateColumnCount() const;
|
|
|
|
// When called with i, the (i - 1) column must have been formatted.
|
|
void formatOneColumn(int p_idx, int p_cursorRowIdx, int p_cursorPib);
|
|
|
|
void fetchCellInfoOfColumn(int p_idx,
|
|
QVector<CellInfo> &p_cellsInfo,
|
|
int &p_targetWidth) const;
|
|
|
|
void calculateBasicWidths(const QTextBlock &p_block, int p_borderPos);
|
|
|
|
int calculateTextWidth(const QTextBlock &p_block, int p_pib, int p_length) const;
|
|
|
|
bool isHeaderRow(int p_idx) const;
|
|
|
|
bool isDelimiterRow(int p_idx) const;
|
|
|
|
// @p_nrSpaces: number of spaces to fill core content.
|
|
QString generateFormattedText(const QString &p_core,
|
|
int p_nrSpaces = 0,
|
|
Alignment p_align = Alignment::Left) const;
|
|
|
|
VTable::Alignment getColumnAlignment(int p_idx) const;
|
|
|
|
bool isDelimiterCellWellFormatted(const Cell &p_cell,
|
|
const CellInfo &p_info,
|
|
int p_targetWidth) const;
|
|
|
|
bool isCellWellFormatted(const Row &p_row,
|
|
const Cell &p_cell,
|
|
const CellInfo &p_info,
|
|
int p_targetWidth,
|
|
Alignment p_align) const;
|
|
|
|
void writeExist();
|
|
|
|
void writeNonExist();
|
|
|
|
// Prune unwanted columns beyond the header row.
|
|
void pruneColumns(int p_nrCols);
|
|
|
|
VTable::Row *header() const;
|
|
|
|
VTable::Row *delimiter() const;
|
|
|
|
VEditor *m_editor;
|
|
|
|
// Whether this table exist already.
|
|
bool m_exist;
|
|
|
|
// Header, delimiter, and body.
|
|
QVector<Row> m_rows;
|
|
|
|
int m_spaceWidth;
|
|
int m_minusWidth;
|
|
int m_colonWidth;
|
|
int m_defaultDelimiterWidth;
|
|
|
|
static const QString c_defaultDelimiter;
|
|
|
|
static const QChar c_borderChar;
|
|
};
|
|
|
|
#endif // VTABLE_H
|