kspread
Binding.cppGo to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "Binding.h"
00022 #include "BindingModel.h"
00023
00024 #include <QRect>
00025
00026 #include <kdebug.h>
00027
00028 #include "CellStorage.h"
00029 #include "Map.h"
00030 #include "Sheet.h"
00031 #include "Value.h"
00032
00033 using namespace KSpread;
00034
00035 class Binding::Private : public QSharedData
00036 {
00037 public:
00038 Private() : model(0) {}
00039 ~Private() { delete model; }
00040
00041 BindingModel* model;
00042 };
00043
00044
00045 Binding::Binding()
00046 : d(new Private)
00047 {
00048 }
00049
00050 Binding::Binding(const Region& region)
00051 : d(new Private)
00052 {
00053 Q_ASSERT(region.isValid());
00054 d->model = new BindingModel(this);
00055 d->model->setRegion(region);
00056 }
00057
00058 Binding::Binding(const Binding& other)
00059 : d(other.d)
00060 {
00061 }
00062
00063 Binding::~Binding()
00064 {
00065 }
00066
00067 bool Binding::isEmpty() const
00068 {
00069 return d->model->region().isEmpty();
00070 }
00071
00072 QAbstractItemModel* Binding::model() const
00073 {
00074 return d->model;
00075 }
00076
00077 const KSpread::Region& Binding::region() const
00078 {
00079 return d->model->region();
00080 }
00081
00082 void Binding::setRegion(const Region& region)
00083 {
00084 d->model->setRegion(region);
00085 }
00086
00087 void Binding::update(const Region& region)
00088 {
00089 QRect rect;
00090 Region changedRegion;
00091 const QPoint offset = d->model->region().firstRange().topLeft();
00092 const QRect range = d->model->region().firstRange();
00093 const Sheet* sheet = d->model->region().firstSheet();
00094 Region::ConstIterator end(region.constEnd());
00095 for (Region::ConstIterator it = region.constBegin(); it != end; ++it)
00096 {
00097 if (sheet != (*it)->sheet())
00098 continue;
00099 rect = range & (*it)->rect();
00100 rect.translate( -offset.x(), -offset.y() );
00101 if (rect.isValid())
00102 {
00103 d->model->emitDataChanged(rect);
00104 changedRegion.add(rect, (*it)->sheet());
00105 }
00106 }
00107 d->model->emitChanged(changedRegion);
00108 }
00109
00110 void Binding::operator=(const Binding& other)
00111 {
00112 d = other.d;
00113 }
00114
00115 bool Binding::operator==(const Binding& other) const
00116 {
00117 return d == other.d;
00118 }
00119
00120 bool Binding::operator<(const Binding& other) const
00121 {
00122 return d < other.d;
00123 }
00124
00125 QHash<QString, QVector<QRect> > BindingModel::cellRegion() const
00126 {
00127 QHash<QString, QVector<QRect> > answer;
00128 Region::ConstIterator end = m_region.constEnd();
00129 for (Region::ConstIterator it = m_region.constBegin(); it != end; ++it) {
00130 if (!(*it)->isValid()) {
00131 continue;
00132 }
00133 answer[(*it)->name()].append((*it)->rect());
00134 }
00135 return answer;
00136 }
00137
00138 bool BindingModel::setCellRegion(const QString& regionName)
00139 {
00140 Q_ASSERT(m_region.isValid());
00141 Q_ASSERT(m_region.firstSheet());
00142 const Map* const map = m_region.firstSheet()->map();
00143 const Region region = Region(regionName, map);
00144 if (!region.isValid()) {
00145 kDebug() << qPrintable(regionName) << "is not a valid region.";
00146 return false;
00147 }
00148
00149 Region::ConstIterator end = m_region.constEnd();
00150 for (Region::ConstIterator it = m_region.constBegin(); it != end; ++it) {
00151 if (!(*it)->isValid()) {
00152 continue;
00153 }
00154
00155 (*it)->sheet()->cellStorage()->setBinding(Region((*it)->rect(), (*it)->sheet()), Binding());
00156 }
00157
00158 m_region = region;
00159 end = m_region.constEnd();
00160 for (Region::ConstIterator it = m_region.constBegin(); it != end; ++it) {
00161 if (!(*it)->isValid()) {
00162 continue;
00163 }
00164 (*it)->sheet()->cellStorage()->setBinding(Region((*it)->rect(), (*it)->sheet()), *m_binding);
00165 }
00166 return true;
00167 }
00168
00169
00171
00172 BindingModel::BindingModel(Binding* binding, QObject *parent)
00173 : QAbstractTableModel(parent)
00174 , m_binding(binding)
00175 {
00176 }
00177
00178 bool BindingModel::isCellRegionValid(const QString& regionName) const
00179 {
00180 Q_CHECK_PTR(m_region.firstSheet());
00181 Q_CHECK_PTR(m_region.firstSheet()->map());
00182 return Region(regionName, m_region.firstSheet()->map()).isValid();
00183 }
00184
00185 QString BindingModel::regionAddress() const
00186 {
00187 return m_region.name();
00188 }
00189
00190 void BindingModel::emitChanged(const Region& region)
00191 {
00192 emit changed(region);
00193 }
00194
00195 void BindingModel::emitDataChanged(const QRect& rect)
00196 {
00197 const QPoint tl = rect.topLeft();
00198 const QPoint br = rect.bottomRight();
00199 kDebug() << "emit QAbstractItemModel::dataChanged(" << index(tl.y(), tl.x()) << ", " << index(br.y(), br.x()) << ");";
00200 emit dataChanged(index(tl.y(), tl.x()), index(br.y(), br.x()));
00201 }
00202
00203 QVariant BindingModel::data(const QModelIndex& index, int role) const
00204 {
00205 if ((m_region.isEmpty()) || (role != Qt::EditRole && role != Qt::DisplayRole))
00206 return QVariant();
00207 const QPoint offset = m_region.firstRange().topLeft();
00208 const Sheet* sheet = m_region.firstSheet();
00209 const Value value = sheet->cellStorage()->value(offset.x() + index.column(),
00210 offset.y() + index.row());
00211
00212
00213
00214
00215
00216 QVariant variant;
00217 switch (value.type())
00218 {
00219 case Value::Float:
00220 case Value::Integer:
00221 if (value.format() == Value::fmt_DateTime ||
00222 value.format() == Value::fmt_Date ||
00223 value.format() == Value::fmt_Time)
00224 {
00225 variant.setValue<QDateTime>(value.asDateTime(sheet->map()->calculationSettings()));
00226 break;
00227 }
00228 case Value::Boolean:
00229 case Value::Complex:
00230 case Value::Array:
00231 variant.setValue<double>(numToDouble (value.asFloat()));
00232 break;
00233 case Value::String:
00234 case Value::Error:
00235 variant.setValue<QString>(value.asString());
00236 break;
00237 case Value::Empty:
00238 case Value::CellRange:
00239 default:
00240 break;
00241 }
00242
00243 return variant;
00244 }
00245
00246 const KSpread::Region& BindingModel::region() const
00247 {
00248 return m_region;
00249 }
00250
00251 QVariant BindingModel::headerData(int section, Qt::Orientation orientation, int role) const
00252 {
00253 if ( (m_region.isEmpty()) || (role != Qt::EditRole && role != Qt::DisplayRole))
00254 return QVariant();
00255 const QPoint offset = m_region.firstRange().topLeft();
00256 const int col = (orientation == Qt::Vertical) ? offset.x() : offset.x() + section;
00257 const int row = (orientation == Qt::Vertical) ? offset.y() + section : offset.y();
00258 const Sheet* sheet = m_region.firstSheet();
00259 const Value value = sheet->cellStorage()->value(col, row);
00260 return value.asVariant();
00261 }
00262
00263 int BindingModel::rowCount(const QModelIndex& parent) const
00264 {
00265 Q_UNUSED(parent);
00266 return m_region.isEmpty() ? 0 : m_region.firstRange().height();
00267 }
00268
00269 int BindingModel::columnCount(const QModelIndex& parent) const
00270 {
00271 Q_UNUSED(parent);
00272 return m_region.isEmpty() ? 0 : m_region.firstRange().width();
00273 }
00274
00275 void BindingModel::setRegion(const Region& region)
00276 {
00277 m_region = region;
00278 }
00279
00280 #include "BindingModel.moc"
|