From b94357ba732b85a0a193dd7a9e6673dec559d91b Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 27 Mar 2024 21:02:34 +0700 Subject: [PATCH] Update data options. --- src/spreadsheets/DataOptions.h | 146 +++++++++++++++++++++++-- src/spreadsheets/requests/Common.h | 45 ++++++++ src/spreadsheets/requests/Dimension.h | 40 +++++++ src/spreadsheets/requests/NamedRange.h | 46 +++++++- 4 files changed, 269 insertions(+), 8 deletions(-) diff --git a/src/spreadsheets/DataOptions.h b/src/spreadsheets/DataOptions.h index 29a1b22..60a8a71 100644 --- a/src/spreadsheets/DataOptions.h +++ b/src/spreadsheets/DataOptions.h @@ -354,6 +354,53 @@ namespace GSHEET void clear() { owriter.clearBuf(buf, bufSize); } }; + /** + * Adds a new sheet. When a sheet is added at a given index, all subsequent sheets' indexes are incremented. To add an object sheet, use AddChartRequest instead and specify EmbeddedObjectPosition.sheetId or EmbeddedObjectPosition.newSheet. + */ + class AddSheetRequest : public Printable + { + private: + String buf; + GSheetJSONUtil jut; + + public: + AddSheetRequest() {} + // The properties the new sheet should have. All properties are optional. The sheetId field is optional; if one is not set, an id will be randomly generated. (It is an error to specify the ID of a sheet that already exists.) + AddSheetRequest &properties(const SheetProperties &value) + { + clear(); + jut.addObject(buf, "properties", value.c_str(), false, true); + return *this; + } + const char *c_str() const { return buf.c_str(); } + size_t printTo(Print &p) const { return p.print(buf.c_str()); } + void clear() { buf.remove(0, buf.length()); } + }; + + /** + * Deletes the requested sheet. + */ + class DeleteSheetRequest : public Printable + { + private: + String buf; + GSheetJSONUtil jut; + + public: + DeleteSheetRequest() {} + // The ID of the sheet to delete. + // If the sheet is of DATA_SOURCE type, the associated DataSource is also deleted. + DeleteSheetRequest &properties(int value) + { + clear(); + jut.addObject(buf, "sheetId", String(value), false, true); + return *this; + } + const char *c_str() const { return buf.c_str(); } + size_t printTo(Print &p) const { return p.print(buf.c_str()); } + void clear() { buf.remove(0, buf.length()); } + }; + /** * Updates properties of the sheet with the specified sheetId. */ @@ -382,6 +429,85 @@ namespace GSHEET size_t printTo(Print &p) const { return p.print(buf[0].c_str()); } void clear() { owriter.clearBuf(buf, bufSize); } }; + + /** + * Moves data from the source to the destination. + */ + class CutPasteRequest : public Printable + { + private: + size_t bufSize = 4; + String buf[4]; + GSheetObjectWriter owriter; + GSheetJSONUtil jut; + + CutPasteRequest &setObject(String &buf_n, const String &key, const String &value, bool isString, bool last) + { + owriter.setObject(buf, bufSize, buf_n, key, value, isString, last); + return *this; + } + + public: + CutPasteRequest() {} + // The source data to cut. + CutPasteRequest &source(const GridRange &value) { return setObject(buf[1], "source", value.c_str(), false, true); } + // The top-left coordinate where the data should be pasted. + CutPasteRequest &destination(const GridCoordinate &value) { return setObject(buf[2], "destination", value.c_str(), false, true); } + // What kind of data to paste. All the source data will be cut, regardless of what is pasted. + CutPasteRequest &pasteType(PasteType value) + { + if (value == PASTE_NORMAL) + return setObject(buf[3], "pasteType", "PASTE_NORMAL", true, true); + else if (value == PASTE_VALUES) + return setObject(buf[3], "pasteType", "PASTE_VALUES", true, true); + else if (value == PASTE_FORMAT) + return setObject(buf[3], "pasteType", "PASTE_FORMAT", true, true); + else if (value == PASTE_NO_BORDERS) + return setObject(buf[3], "pasteType", "PASTE_NO_BORDERS", true, true); + else if (value == PASTE_FORMULA) + return setObject(buf[3], "pasteType", "PASTE_FORMULA", true, true); + else if (value == PASTE_DATA_VALIDATION) + return setObject(buf[3], "pasteType", "PASTE_DATA_VALIDATION", true, true); + else if (value == PASTE_CONDITIONAL_FORMATTING) + return setObject(buf[3], "pasteType", "PASTE_CONDITIONAL_FORMATTING", true, true); + return *this; + } + const char *c_str() const { return buf[0].c_str(); } + size_t printTo(Print &p) const { return p.print(buf[0].c_str()); } + void clear() { owriter.clearBuf(buf, bufSize); } + }; + + /** + * Fills in more data based on existing data. + */ + class AutoFillRequest : public Printable + { + private: + size_t bufSize = 4; + String buf[4]; + GSheetObjectWriter owriter; + GSheetJSONUtil jut; + + AutoFillRequest &setObject(String &buf_n, const String &key, const String &value, bool isString, bool last) + { + owriter.setObject(buf, bufSize, buf_n, key, value, isString, last); + return *this; + } + + public: + AutoFillRequest() {} + // True if we should generate data with the "alternate" series. This differs based on the type and amount of source data. + AutoFillRequest &properties(bool value) { return setObject(buf[1], "useAlternateSeries", owriter.getBoolStr(value), false, true); } + // The range to autofill. This will examine the range and detect the location that has data and automatically fill that data in to the rest of the range. + // Union field area + AutoFillRequest &range(const GridRange &value) { return buf[3].length() == 0 ? setObject(buf[2], "range", value.c_str(), false, true) : *this; } + // The source and destination areas to autofill. This explicitly lists the source of the autofill and where to extend that data. + // Union field area + AutoFillRequest &sourceAndDestination(const SourceAndDestination &value) { return buf[2].length() == 0 ? setObject(buf[3], "sourceAndDestination", value.c_str(), false, true) : *this; } + const char *c_str() const { return buf[0].c_str(); } + size_t printTo(Print &p) const { return p.print(buf[0].c_str()); } + void clear() { owriter.clearBuf(buf, bufSize); } + }; // https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/request#Request /** @@ -416,13 +542,19 @@ namespace GSHEET name = "updateNamedRange"; else if (std::is_same::value) name = "repeatCell"; - - name = "addNamedRange"; - name = "deleteNamedRange"; - name = "addSheet"; - name = "deleteSheet"; - name = "autoFill"; - name = "cutPaste"; + else if (std::is_same::value) + name = "addNamedRange"; + else if (std::is_same::value) + name = "deleteNamedRange"; + else if (std::is_same::value) + name = "addSheet"; + else if (std::is_same::value) + name = "deleteSheet"; + else if (std::is_same::value) + name = "autoFill"; + else if (std::is_same::value) + name = "cutPaste"; + name = "copyPaste"; name = "mergeCells"; name = "unmergeCells"; diff --git a/src/spreadsheets/requests/Common.h b/src/spreadsheets/requests/Common.h index 21c8070..95ad84e 100644 --- a/src/spreadsheets/requests/Common.h +++ b/src/spreadsheets/requests/Common.h @@ -192,6 +192,18 @@ namespace GSHEET // If set, the data source table fetches all the columns in the data source at the time of refresh. }; + // What kind of data should be pasted. + enum PasteType + { + PASTE_NORMAL, // Paste values, formulas, formats, and merges. + PASTE_VALUES, // Paste the values ONLY without formats, formulas, or merges. + PASTE_FORMAT, // Paste the format and data validation only. + PASTE_NO_BORDERS, // Like PASTE_NORMAL but without borders. + PASTE_FORMULA, // Paste the formulas only. + PASTE_DATA_VALIDATION, // Paste the data validation only. + PASTE_CONDITIONAL_FORMATTING // Paste the conditional formatting rules only. + }; + /** * Represents a color in the RGBA color space. This representation is designed for simplicity of conversion to/from color representations in various languages over compactness. */ @@ -757,6 +769,36 @@ namespace GSHEET void clear() { owriter.clearBuf(buf, bufSize); } }; + /** + * A coordinate in a sheet. All indexes are zero-based. + */ + class GridCoordinate : public Printable + { + private: + size_t bufSize = 4; + String buf[4]; + GSheetObjectWriter owriter; + GSheetJSONUtil jut; + + GridCoordinate &setObject(String &buf_n, const String &key, const String &value, bool isString, bool last) + { + owriter.setObject(buf, bufSize, buf_n, key, value, isString, last); + return *this; + } + + public: + GridCoordinate() {} + // The sheet this coordinate is on. + GridCoordinate &sheetId(int value) { return setObject(buf[1], "sheetId", String(value), false, true); } + // The row index of the coordinate. + GridCoordinate &rowIndex(int value) { return setObject(buf[2], "rowIndex", String(value), false, true); } + // The column index of the coordinate. + GridCoordinate &columnIndex(int value) { return setObject(buf[3], "columnIndex", String(value), false, true); } + const char *c_str() const { return buf[0].c_str(); } + size_t printTo(Print &p) const { return p.print(buf[0].c_str()); } + void clear() { owriter.clearBuf(buf, bufSize); } + }; + /** * The value of the condition. */ @@ -918,6 +960,7 @@ namespace GSHEET // The display name of the column. It should be unique within a data source. DataSourceColumnReference &name(const String &value) { + clear(); jut.addObject(buf, "name", value, true, true); return *this; } @@ -1101,6 +1144,7 @@ namespace GSHEET // The ID of the data source the formula is associated with. DataSourceFormula &dataSourceId(const String &value) { + clear(); jut.addObject(buf, "dataSourceId", value, true, true); return *this; } @@ -1108,6 +1152,7 @@ namespace GSHEET size_t printTo(Print &p) const { return p.print(buf.c_str()); } void clear() { buf.remove(0, buf.length()); } }; + } #endif \ No newline at end of file diff --git a/src/spreadsheets/requests/Dimension.h b/src/spreadsheets/requests/Dimension.h index 4bf6456..3860497 100644 --- a/src/spreadsheets/requests/Dimension.h +++ b/src/spreadsheets/requests/Dimension.h @@ -16,6 +16,7 @@ namespace GSHEET DOCUMENT, // Document-visible metadata is accessible from any developer project with access to the document. PROJECT, // Project-visible metadata is only visible to and accessible by the developer project that created the metadata. }; + // Indicates which dimension an operation should apply to. enum Dimension { @@ -254,6 +255,45 @@ namespace GSHEET void clear() { owriter.clearBuf(buf, bufSize); } }; + /** + * A combination of a source range and how to extend that source. + */ + class SourceAndDestination : public Printable + { + private: + size_t bufSize = 4; + String buf[4]; + GSheetObjectWriter owriter; + GSheetJSONUtil jut; + + SourceAndDestination &setObject(String &buf_n, const String &key, const String &value, bool isString, bool last) + { + owriter.setObject(buf, bufSize, buf_n, key, value, isString, last); + return *this; + } + + public: + SourceAndDestination() {} + // The location of the data to use as the source of the autofill. + SourceAndDestination &source(const GridRange &value) { return setObject(buf[1], "source", value.c_str(), false, true); } + // The location of the data to use as the source of the autofill. + SourceAndDestination &dimension(Dimension value) + { + if (value == DIMENSION_UNSPECIFIED) + return setObject(buf[2], "dimension", "DIMENSION_UNSPECIFIED", true, true); + else if (value == ROWS) + return setObject(buf[2], "dimension", "ROWS", true, true); + else if (value == COLUMNS) + return setObject(buf[2], "dimension", "COLUMNS", true, true); + return *this; + } + // The number of rows or columns that data should be filled into. Positive numbers expand beyond the last row or last column of the source. Negative numbers expand before the first row or first column of the source. + SourceAndDestination &fillLength(int value) { return setObject(buf[3], "fillLength", String(value), false, true); } + const char *c_str() const { return buf[0].c_str(); } + size_t printTo(Print &p) const { return p.print(buf[0].c_str()); } + void clear() { owriter.clearBuf(buf, bufSize); } + }; + } #endif \ No newline at end of file diff --git a/src/spreadsheets/requests/NamedRange.h b/src/spreadsheets/requests/NamedRange.h index 1f492cb..8012ecb 100644 --- a/src/spreadsheets/requests/NamedRange.h +++ b/src/spreadsheets/requests/NamedRange.h @@ -9,7 +9,7 @@ namespace GSHEET { - + /** * A named range. */ @@ -67,6 +67,50 @@ namespace GSHEET size_t printTo(Print &p) const { return p.print(buf[0].c_str()); } void clear() { owriter.clearBuf(buf, bufSize); } }; + /** + * Adds a named range to the spreadsheet. + */ + class AddNamedRangeRequest : public Printable + { + private: + String buf; + GSheetJSONUtil jut; + + public: + AddNamedRangeRequest() {} + // The named range to add. The namedRangeId field is optional; if one is not set, an id will be randomly generated. (It is an error to specify the ID of a range that already exists.) + AddNamedRangeRequest &name(const NamedRange &value) + { + clear(); + jut.addObject(buf, "namedRange", value.c_str(), false, true); + return *this; + } + const char *c_str() const { return buf.c_str(); } + size_t printTo(Print &p) const { return p.print(buf.c_str()); } + void clear() { buf.remove(0, buf.length()); } + }; + /** + * Removes the named range with the given ID from the spreadsheet. + */ + class DeleteNamedRangeRequest : public Printable + { + private: + String buf; + GSheetJSONUtil jut; + + public: + DeleteNamedRangeRequest() {} + // The ID of the named range to delete. + DeleteNamedRangeRequest &namedRangeId(const String &value) + { + clear(); + jut.addObject(buf, "namedRangeId", value, true, true); + return *this; + } + const char *c_str() const { return buf.c_str(); } + size_t printTo(Print &p) const { return p.print(buf.c_str()); } + void clear() { buf.remove(0, buf.length()); } + }; } #endif \ No newline at end of file