File size: 11,463 Bytes
985c397 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 | // SPDX-License-Identifier: LGPL-2.1-or-later
/***************************************************************************
* Copyright (c) 2015 Eivind Kvedalen <eivind@kvedalen.name> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef PROPERTYSHEET_H
#define PROPERTYSHEET_H
#ifdef _MSC_VER
# ifdef PropertySheet
# undef PropertySheet // Microsoft's #define conflicts with the use below
# endif
#endif
#include <map>
#include <App/DocumentObject.h>
#include <App/PropertyLinks.h>
#include <Mod/Spreadsheet/SpreadsheetGlobal.h>
#include "Cell.h"
namespace Spreadsheet
{
class Sheet;
class PropertySheet;
class SheetObserver;
class SpreadsheetExport PropertySheet: public App::PropertyExpressionContainer,
private App::AtomicPropertyChangeInterface<PropertySheet>
{
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
explicit PropertySheet(Sheet* _owner = nullptr);
~PropertySheet() override;
std::map<App::ObjectIdentifier, const App::Expression*> getExpressions() const override;
void setExpressions(std::map<App::ObjectIdentifier, App::ExpressionPtr>&& exprs) override;
void onRelabeledDocument(const App::Document& doc) override;
void onRenameDynamicProperty(const App::Property& prop, const char* oldName) override;
void updateElementReference(
App::DocumentObject* feature,
bool reverse = false,
bool notify = false
) override;
bool referenceChanged() const override;
bool adjustLink(const std::set<App::DocumentObject*>& inList) override;
Property* CopyOnImportExternal(const std::map<std::string, std::string>& nameMap) const override;
Property* CopyOnLabelChange(
App::DocumentObject* obj,
const std::string& ref,
const char* newLabel
) const override;
Property* CopyOnLinkReplace(
const App::DocumentObject* parent,
App::DocumentObject* oldObj,
App::DocumentObject* newObj
) const override;
void breakLink(App::DocumentObject* obj, bool clear) override;
void afterRestore() override;
void onContainerRestored() override;
Property* Copy() const override;
void Paste(const Property& from) override;
void Save(Base::Writer& writer) const override;
void Restore(Base::XMLReader& reader) override;
void getLinksTo(
std::vector<App::ObjectIdentifier>& identifiers,
App::DocumentObject* obj,
const char* subname = nullptr,
bool all = false
) const override;
void copyCells(Base::Writer& writer, const std::vector<App::Range>& ranges) const;
void pasteCells(Base::XMLReader& reader, App::Range dstRange);
Cell* createCell(App::CellAddress address);
void setValue()
{}
void setContent(App::CellAddress address, const char* value);
void setAlignment(App::CellAddress address, int _alignment);
void setStyle(App::CellAddress address, const std::set<std::string>& _style);
void setForeground(App::CellAddress address, const Base::Color& color);
void setBackground(App::CellAddress address, const Base::Color& color);
void setDisplayUnit(App::CellAddress address, const std::string& unit);
void setAlias(App::CellAddress address, const std::string& alias);
void setComputedUnit(App::CellAddress address, const Base::Unit& unit);
void setSpans(App::CellAddress address, int rows, int columns);
void clear(App::CellAddress address, bool toClearAlias = true);
void clear();
Cell* getValue(App::CellAddress key);
const Cell* getValue(App::CellAddress key) const;
Cell* getValueFromAlias(const std::string& alias);
const Cell* getValueFromAlias(const std::string& alias) const;
bool isValidAlias(const std::string& candidate);
// checks whether candidate is of form A1, C4, etc.
bool isValidCellAddressName(const std::string& candidate);
std::vector<App::CellAddress> getUsedCells() const;
std::tuple<App::CellAddress, App::CellAddress> getUsedRange() const;
std::vector<App::CellAddress> getNonEmptyCells() const;
std::tuple<App::CellAddress, App::CellAddress> getNonEmptyRange() const;
Sheet* sheet() const
{
return owner;
}
const std::set<App::CellAddress>& getDirty()
{
return dirty;
}
void setDirty(App::CellAddress address);
void setDirty();
void clearDirty(App::CellAddress key)
{
dirty.erase(key);
}
void clearDirty()
{
dirty.clear();
purgeTouched();
}
bool isDirty() const
{
return dirty.size() > 0;
}
void pasteCells(const std::map<App::CellAddress, std::string>& cells, int rowOffset, int colOffset);
void insertRows(int row, int count);
std::vector<App::CellAddress> getRows(int row, int count) const;
void removeRows(int row, int count);
void insertColumns(int col, int count);
std::vector<App::CellAddress> getColumns(int column, int count) const;
void removeColumns(int col, int count);
unsigned int getMemSize() const override;
bool mergeCells(App::CellAddress from, App::CellAddress to);
void splitCell(App::CellAddress address);
void getSpans(App::CellAddress address, int& rows, int& cols) const;
bool hasSpan() const;
App::CellAddress getAnchor(App::CellAddress address) const;
bool isMergedCell(App::CellAddress address) const;
bool isHidden(App::CellAddress address) const;
const std::set<App::CellAddress>& getDeps(const std::string& name) const;
const std::set<std::string>& getDeps(App::CellAddress pos) const;
void recomputeDependencies(App::CellAddress key);
PyObject* getPyObject() override;
void setPyObject(PyObject*) override;
PyObject* getPyValue(PyObject* key);
void invalidateDependants(const App::DocumentObject* docObj);
void renameObjectIdentifiers(const std::map<App::ObjectIdentifier, App::ObjectIdentifier>& paths);
void deletedDocumentObject(const App::DocumentObject* docObj);
void documentSet();
App::CellAddress getCellAddress(const char* addr, bool silent = false) const;
App::Range getRange(const char* range, bool silent = false) const;
std::string getRow(int offset = 0) const;
std::string getColumn(int offset = 0) const;
void setPathValue(const App::ObjectIdentifier& path, const boost::any& value) override;
const boost::any getPathValue(const App::ObjectIdentifier& path) const override;
unsigned getBindingBorder(App::CellAddress address) const;
bool isBindingPath(
const App::ObjectIdentifier& path,
App::CellAddress* from = nullptr,
App::CellAddress* to = nullptr,
bool* href = nullptr
) const;
enum BindingType
{
BindingNone,
BindingNormal,
BindingHiddenRef,
};
BindingType getBinding(
const App::Range& range,
App::ExpressionPtr* pStart = nullptr,
App::ExpressionPtr* pEnd = nullptr,
App::ObjectIdentifier* pTarget = nullptr
) const;
protected:
void hasSetValue() override;
void hasSetChildValue(App::Property& prop) override;
void onBreakLink(App::DocumentObject* obj) override;
void onAddDep(App::DocumentObject* obj) override;
void onRemoveDep(App::DocumentObject* obj) override;
private:
PropertySheet(const PropertySheet& other);
PropertySheet& operator=(const PropertySheet&);
/* friends */
friend class AtomicPropertyChange;
friend class SheetObserver;
friend class Cell;
friend class Sheet;
Cell* cellAt(App::CellAddress address);
Cell* nonNullCellAt(App::CellAddress address);
const Cell* cellAt(App::CellAddress address) const;
bool colSortFunc(const App::CellAddress& a, const App::CellAddress& b);
bool rowSortFunc(const App::CellAddress& a, const App::CellAddress& b);
/*! Set of cells that have been marked dirty */
std::set<App::CellAddress> dirty;
/*! Cell data in this property */
std::map<App::CellAddress, Cell*> data;
/*! Merged cells; cell -> anchor cell */
std::map<App::CellAddress, App::CellAddress> mergedCells;
/*! Owner of this property */
Sheet* owner;
void clearAlias(App::CellAddress address);
void moveAlias(App::CellAddress currPos, App::CellAddress newPos);
void moveCell(
App::CellAddress currPos,
App::CellAddress newPos,
std::map<App::ObjectIdentifier, App::ObjectIdentifier>& renames
);
/*
* Cell dependency tracking
*/
void addDependencies(App::CellAddress key);
void removeDependencies(App::CellAddress key);
void slotChangedObject(const App::DocumentObject& obj, const App::Property& prop);
void recomputeDependants(const App::DocumentObject* obj, const char* propName);
/*! Cell dependencies, i.e when a change occurs to property given in key,
the set of addresses needs to be recomputed.
*/
std::map<std::string, std::set<App::CellAddress>> propertyNameToCellMap;
/*! Properties this cell depends on */
std::map<App::CellAddress, std::set<std::string>> cellToPropertyNameMap;
/*! Cell dependencies, i.e when a change occurs to documentObject given in key,
the set of addresses needs to be recomputed.
*/
std::map<std::string, std::set<App::CellAddress>> documentObjectToCellMap;
/*! DocumentObject this cell depends on */
std::map<App::CellAddress, std::set<std::string>> cellToDocumentObjectMap;
/*! Mapping of cell position to alias property */
std::map<App::CellAddress, std::string> aliasProp;
/*! Mapping of alias property to cell position */
std::map<std::string, App::CellAddress> revAliasProp;
/*! The associated python object */
Py::SmartPtr PythonObject;
std::map<const App::DocumentObject*, fastsignals::scoped_connection> depConnections;
int updateCount = 0;
bool restoring = false;
};
} // namespace Spreadsheet
#endif // PROPERTYSHEET_H
|