kexidataawarepropertyset.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2004-2005 Jaroslaw Staniek <js@iidea.pl>
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this program; see the file COPYING. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18*/
19
20#include "kexidataawarepropertyset.h"
21#include "kexitableviewdata.h"
22#include "kexidataawareobjectiface.h"
23
24#include <koproperty/property.h>
25#include <kexiviewbase.h>
26
27#define MAX_FIELDS 1009 //nice prime number (default prop. set vector size)
28
31 : TQObject( view, TQCString(view->name())+"KexiDataAwarePropertySet" )
32 , m_view(view)
33 , m_dataObject(dataObject)
34 , m_row(-99)
35{
36 m_sets.setAutoDelete(true);
37
38// connect(m_dataObject, TQ_SIGNAL(dataSet(KexiTableViewData*)),
39// this, TQ_SLOT(slotDataSet(KexiTableViewData*)));
40 m_dataObject->connectDataSetSignal(this, TQ_SLOT(slotDataSet(KexiTableViewData*)));
41// connect(m_dataObject, TQ_SIGNAL(cellSelected(int,int)),
42// this, TQ_SLOT(slotCellSelected(int,int)));
43 m_dataObject->connectCellSelectedSignal(this, TQ_SLOT(slotCellSelected(int,int)));
44//
45 slotDataSet( m_dataObject->data() );
46 const bool wasDirty = view->dirty();
47 clear();
48 if (!wasDirty)
49 view->setDirty(false);
50}
51
52KexiDataAwarePropertySet::~KexiDataAwarePropertySet()
53{
54}
55
57{
58 if (!m_currentTVData.isNull()) {
59 m_currentTVData->disconnect( this );
60 clear();
61 }
62 m_currentTVData = data;
63 if (!m_currentTVData.isNull()) {
64 connect(m_currentTVData, TQ_SIGNAL(rowDeleted()), this, TQ_SLOT(slotRowDeleted()));
65 connect(m_currentTVData, TQ_SIGNAL(rowsDeleted( const TQValueList<int> & )),
66 this, TQ_SLOT(slotRowsDeleted( const TQValueList<int> & )));
67 connect(m_currentTVData, TQ_SIGNAL(rowInserted(KexiTableItem*,uint,bool)),
68 this, TQ_SLOT(slotRowInserted(KexiTableItem*,uint,bool)));
69 connect(m_currentTVData, TQ_SIGNAL(reloadRequested()),
70 this, TQ_SLOT(slotReloadRequested()));
71 }
72}
73
74void KexiDataAwarePropertySet::removeCurrentPropertySet()
75{
76 remove( m_dataObject->currentRow() );
77}
78
80{
81 KoProperty::Set *set = m_sets.at(row);
82 if (!set)
83 return;
84 set->debug();
85 m_sets.remove(row);
86 m_view->setDirty();
87 m_view->propertySetSwitched();
88}
89
90uint KexiDataAwarePropertySet::size() const
91{
92 return m_sets.size();
93}
94
95void KexiDataAwarePropertySet::clear(uint minimumSize)
96{
97 m_sets.clear();
98 m_sets.resize(TQMAX(minimumSize, MAX_FIELDS));
99 m_view->setDirty(true);
100 m_view->propertySetSwitched();
101}
102
107
108void KexiDataAwarePropertySet::insert(uint row, KoProperty::Set* set, bool newOne)
109{
110 if (!set || row >= m_sets.size()) {
111 kexiwarn << "KexiDataAwarePropertySet::insert() invalid args: rew="<< row<< " propertyset="<< set<< endl;
112 return;
113 }
114 if (set->parent() && set->parent()!=this) {
115 kexiwarn << "KexiDataAwarePropertySet::insert() propertyset's parent must be NULL or this KexiDataAwarePropertySet" << endl;
116 return;
117 }
118
119 m_sets.insert(row, set);
120
121 connect(set, TQ_SIGNAL(propertyChanged(KoProperty::Set&, KoProperty::Property&)), m_view, TQ_SLOT(setDirty()));
122
123 if (newOne) {
124 //add a special property indicating that this is brand new set,
125 //not just changed
126 KoProperty::Property* prop = new KoProperty::Property("newrow");
127 prop->setVisible(false);
128 set->addProperty( prop );
129 m_view->setDirty();
130 }
131}
132
133KoProperty::Set* KexiDataAwarePropertySet::currentPropertySet() const
134{
135 return (m_dataObject->currentRow() >= 0) ? m_sets.at( m_dataObject->currentRow() ) : 0;
136}
137
138uint KexiDataAwarePropertySet::currentRow() const
139{
140 return m_dataObject->currentRow();
141}
142
144{
145 m_view->setDirty();
146 removeCurrentPropertySet();
147
148 //let's move up all property sets that are below that deleted
149 m_sets.setAutoDelete(false);//to avoid auto deleting in insert()
150 const int r = m_dataObject->currentRow();
151 for (int i=r;i<int(m_sets.size()-1);i++) {
152 KoProperty::Set *set = m_sets[i+1];
153 m_sets.insert( i , set );
154 }
155 m_sets.insert( m_sets.size()-1, 0 );
156 m_sets.setAutoDelete(true);//revert the flag
157
158 m_view->propertySetSwitched();
159 emit rowDeleted();
160}
161
162void KexiDataAwarePropertySet::slotRowsDeleted( const TQValueList<int> &rows )
163{
164 //let's move most property sets up & delete unwanted
165 m_sets.setAutoDelete(false);//to avoid auto deleting in insert()
166 const int orig_size = size();
167 int prev_r = -1;
168 int num_removed = 0, cur_r = -1;
169 for (TQValueList<int>::ConstIterator r_it = rows.constBegin(); r_it!=rows.constEnd() && *r_it < orig_size; ++r_it) {
170 cur_r = *r_it;// - num_removed;
171 if (prev_r>=0) {
172// kdDebug() << "move " << prev_r+num_removed-1 << ".." << cur_r-1 << " to " << prev_r+num_removed-1 << ".." << cur_r-2 << endl;
173 int i=prev_r;
174 KoProperty::Set *set = m_sets.take(i+num_removed);
175 kdDebug() << "property set " << i+num_removed << " deleted" << endl;
176 delete set;
177 num_removed++;
178 for (; (i+num_removed)<cur_r; i++) {
179 m_sets.insert( i, m_sets[i+num_removed] );
180 kdDebug() << i << " <- " << i+num_removed << endl;
181 }
182 }
183 prev_r = cur_r - num_removed;
184 }
185 //move remaining property sets up
186 if (cur_r>=0) {
187 KoProperty::Set *set = m_sets.take(cur_r);
188 kdDebug() << "property set " << cur_r << " deleted" << endl;
189 delete set;
190 num_removed++;
191 for (int i=prev_r; (i+num_removed)<orig_size; i++) {
192 m_sets.insert( i, m_sets[i+num_removed] );
193 kdDebug() << i << " <- " << i+num_removed << endl;
194 }
195 }
196 //finally: clear last rows
197 for (int i=orig_size-num_removed; i<orig_size; i++) {
198 kdDebug() << i << " <- zero" << endl;
199 m_sets.insert( i, 0 );
200 }
201 m_sets.setAutoDelete(true);//revert the flag
202
203 if (num_removed>0)
204 m_view->setDirty();
205 m_view->propertySetSwitched();
206}
207
208//void KexiDataAwarePropertySet::slotEmptyRowInserted(KexiTableItem*, uint /*index*/)
209void KexiDataAwarePropertySet::slotRowInserted(KexiTableItem*, uint row, bool /*repaint*/)
210{
211 m_view->setDirty();
212
213 //let's move down all property set that are below
214 m_sets.setAutoDelete(false);//to avoid auto deleting in insert()
215// const int r = m_dataObject->currentRow();
216 m_sets.resize(m_sets.size()+1);
217 for (int i=int(m_sets.size())-1; i>(int)row; i--) {
218 KoProperty::Set *set = m_sets[i-1];
219 m_sets.insert( i , set );
220 }
221 m_sets.insert( row, 0 );
222 m_sets.setAutoDelete(true);//revert the flag
223
224 m_view->propertySetSwitched();
225
226 emit rowInserted();
227}
228
230{
231 if(row == m_row)
232 return;
233 m_row = row;
234 m_view->propertySetSwitched();
235}
236
237KoProperty::Set* KexiDataAwarePropertySet::findPropertySetForItem(KexiTableItem& item)
238{
239 if (m_currentTVData.isNull())
240 return 0;
241 int idx = m_currentTVData->findRef(&item);
242 if (idx<0)
243 return 0;
244 return m_sets[idx];
245}
246
247int KexiDataAwarePropertySet::findRowForPropertyValue(const TQCString& propertyName, const TQVariant& value)
248{
249 const int size = m_sets.size();
250 for (int i=0; i<size; i++) {
251 KoProperty::Set *set = m_sets[i];
252 if (!set || !set->contains(propertyName))
253 continue;
254 if (set->property(propertyName).value() == value)
255 return i;
256 }
257 return -1;
258}
259
260#include "kexidataawarepropertyset.moc"
The KexiDataAwareObjectInterface is an interface for record-based data object.
KexiTableViewData * data() const
int findRowForPropertyValue(const TQCString &propertyName, const TQVariant &value)
void slotDataSet(KexiTableViewData *data)
KoProperty::Set * findPropertySetForItem(KexiTableItem &item)
void insert(uint row, KoProperty::Set *set, bool newOne=false)
SetVector m_sets
prop. sets vector
void slotRowDeleted()
Called on row delete in a tableview.
int m_row
used to know if a new row is selected in slotCellSelected()
void slotCellSelected(int, int row)
Called on selecting another cell in a tableview.
KexiDataAwarePropertySet(KexiViewBase *view, KexiDataAwareObjectInterface *dataObject)
void slotReloadRequested()
Called on clearing tableview's data: just clears all property sets.
void slotRowInserted(KexiTableItem *item, uint row, bool repaint)
Called on row insertion in a tableview.
void slotRowsDeleted(const TQValueList< int > &rows)
Called on multiple rows delete in a tableview.
Base class for single view embeddable of in KexiDialogBase.
virtual bool dirty() const
void setDirty(bool set)