kexi

kexidataawarepropertyset.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2004-2005 Jaroslaw Staniek <js@iidea.pl>
00003 
00004    This program is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This program is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this program; see the file COPYING.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include "kexidataawarepropertyset.h"
00021 #include "kexitableviewdata.h"
00022 #include "kexidataawareobjectiface.h"
00023 
00024 #include <koproperty/property.h>
00025 #include <kexiviewbase.h>
00026 
00027 #define MAX_FIELDS 101 //nice prime number (default buffer vector size)
00028 
00029 KexiDataAwarePropertySet::KexiDataAwarePropertySet(KexiViewBase *view,
00030     KexiDataAwareObjectInterface* dataObject)
00031  : QObject( view, QCString(view->name())+"KexiDataAwarePropertySet" )
00032  , m_view(view)
00033  , m_dataObject(dataObject)
00034  , m_row(-99)
00035 {
00036     m_sets.setAutoDelete(true);
00037 
00038 //  connect(m_dataObject, SIGNAL(dataSet(KexiTableViewData*)),
00039 //      this, SLOT(slotDataSet(KexiTableViewData*)));
00040     m_dataObject->connectDataSetSignal(this, SLOT(slotDataSet(KexiTableViewData*)));
00041 //  connect(m_dataObject, SIGNAL(cellSelected(int,int)),
00042 //      this, SLOT(slotCellSelected(int,int)));
00043     m_dataObject->connectCellSelectedSignal(this, SLOT(slotCellSelected(int,int)));
00044 //
00045     slotDataSet( m_dataObject->data() );
00046     const bool wasDirty = view->dirty();
00047     clear();
00048     if (!wasDirty)
00049         view->setDirty(false);
00050 }
00051 
00052 KexiDataAwarePropertySet::~KexiDataAwarePropertySet()
00053 {
00054 }
00055 
00056 void KexiDataAwarePropertySet::slotDataSet( KexiTableViewData *data )
00057 {
00058     if (!m_currentTVData.isNull()) {
00059         m_currentTVData->disconnect( this );
00060         clear();
00061     }
00062     m_currentTVData = data;
00063     if (!m_currentTVData.isNull()) {
00064         connect(m_currentTVData, SIGNAL(rowDeleted()), this, SLOT(slotRowDeleted()));
00065         connect(m_currentTVData, SIGNAL(rowsDeleted( const QValueList<int> & )),
00066             this, SLOT(slotRowsDeleted( const QValueList<int> & )));
00067         connect(m_currentTVData, SIGNAL(rowInserted(KexiTableItem*,uint,bool)),
00068             this, SLOT(slotRowInserted(KexiTableItem*,uint,bool)));
00069         connect(m_currentTVData, SIGNAL(reloadRequested()),
00070             this, SLOT(slotReloadRequested()));
00071     }
00072 }
00073 
00074 void KexiDataAwarePropertySet::removeCurrentPropertySet()
00075 {
00076     remove( m_dataObject->currentRow() );
00077 }
00078 
00079 void KexiDataAwarePropertySet::remove(uint row)
00080 {
00081     KoProperty::Set *buf = m_sets.at(row);
00082     if (!buf)
00083         return;
00084     buf->debug();
00085     m_sets.remove(row);
00086     m_view->setDirty();
00087     m_view->propertySetSwitched();
00088 }
00089 
00090 uint KexiDataAwarePropertySet::size() const
00091 {
00092     return m_sets.size();
00093 }
00094 
00095 void KexiDataAwarePropertySet::clear(uint minimumSize)
00096 {
00097     m_sets.clear();
00098     m_sets.resize(QMAX(minimumSize, MAX_FIELDS));
00099     m_view->setDirty(true);
00100     m_view->propertySetSwitched();
00101 }
00102 
00103 void KexiDataAwarePropertySet::slotReloadRequested()
00104 {
00105     clear();
00106 }
00107 
00108 void KexiDataAwarePropertySet::insert(uint row, KoProperty::Set* buf, bool newOne)
00109 {
00110     if (!buf || row >= m_sets.size()) {
00111         kexiwarn << "KexiDataAwarePropertySet::insert() invalid args: rew="<< row<< " buf="<< buf<< endl;
00112         return;
00113     }
00114     if (buf->parent() && buf->parent()!=this) {
00115         kexiwarn << "KexiDataAwarePropertySet::insert() buffer's parent must be NULL or this KexiDataAwarePropertySet" << endl;
00116         return;
00117     }
00118 
00119 //  m_sets.remove(row);//sanity
00120 
00121 /*  //let's move down all buffers that are below
00122     m_sets.setAutoDelete(false);//to avoid auto deleting in insert()
00123     m_sets.resize(m_sets.size()+1);
00124     for (int i=int(m_sets.size()-1); i>(int)row; i--) {
00125         KoProperty::Set *b = m_sets[i-1];
00126         m_sets.insert( i , b );
00127     }*/
00128     m_sets.insert(row, buf);
00129 
00130 //  m_sets.setAutoDelete(true);//revert the flag
00131 
00132     connect(buf,SIGNAL(propertyChanged()), m_view, SLOT(setDirty()));
00133 
00134     if (newOne) {
00135         //add a special property indicating that this is brand new buffer,
00136         //not just changed
00137         KoProperty::Property* prop = new KoProperty::Property("newrow");
00138         prop->setVisible(false);
00139         buf->addProperty( prop );
00140         m_view->setDirty();
00141     }
00142 }
00143 
00144 KoProperty::Set* KexiDataAwarePropertySet::currentPropertySet() const
00145 {
00146     return (m_dataObject->currentRow() >= 0) ? m_sets.at( m_dataObject->currentRow() ) : 0;
00147 }
00148 
00149 void KexiDataAwarePropertySet::slotRowDeleted()
00150 {
00151     m_view->setDirty();
00152     removeCurrentPropertySet();
00153 
00154     //let's move up all buffers that are below that deleted
00155     m_sets.setAutoDelete(false);//to avoid auto deleting in insert()
00156     const int r = m_dataObject->currentRow();
00157     for (int i=r;i<int(m_sets.size()-1);i++) {
00158         KoProperty::Set *b = m_sets[i+1];
00159         m_sets.insert( i , b );
00160     }
00161     m_sets.insert( m_sets.size()-1, 0 );
00162     m_sets.setAutoDelete(true);//revert the flag
00163 
00164     m_view->propertySetSwitched();
00165     emit rowDeleted();
00166 }
00167 
00168 void KexiDataAwarePropertySet::slotRowsDeleted( const QValueList<int> &rows )
00169 {
00170     //let's move most buffers up & delete unwanted
00171     m_sets.setAutoDelete(false);//to avoid auto deleting in insert()
00172     const int orig_size = size();
00173     int prev_r = -1;
00174     int num_removed = 0, cur_r = -1;
00175     for (QValueList<int>::ConstIterator r_it = rows.constBegin(); r_it!=rows.constEnd() && *r_it < orig_size; ++r_it) {
00176         cur_r = *r_it;// - num_removed;
00177         if (prev_r>=0) {
00178 //          kdDebug() << "move " << prev_r+num_removed-1 << ".." << cur_r-1 << " to " << prev_r+num_removed-1 << ".." << cur_r-2 << endl;
00179             int i=prev_r;
00180             KoProperty::Set *b = m_sets.take(i+num_removed);
00181             kdDebug() << "buffer " << i+num_removed << " deleted" << endl;
00182             delete b;
00183             num_removed++;
00184             for (; (i+num_removed)<cur_r; i++) {
00185                 m_sets.insert( i, m_sets[i+num_removed] );
00186                 kdDebug() << i << " <- " << i+num_removed << endl;
00187             }
00188         }
00189         prev_r = cur_r - num_removed;
00190     }
00191     //move remaining buffers up
00192     if (cur_r>=0) {
00193         KoProperty::Set *b = m_sets.take(cur_r);
00194         kdDebug() << "buffer " << cur_r << " deleted" << endl;
00195         delete b;
00196         num_removed++;
00197         for (int i=prev_r; (i+num_removed)<orig_size; i++) {
00198             m_sets.insert( i, m_sets[i+num_removed] );
00199             kdDebug() << i << " <- " << i+num_removed << endl;
00200         }
00201     }
00202     //finally: clear last rows
00203     for (int i=orig_size-num_removed; i<orig_size; i++) {
00204         kdDebug() << i << " <- zero" << endl;
00205         m_sets.insert( i, 0 );
00206     }
00207     m_sets.setAutoDelete(true);//revert the flag
00208 
00209     if (num_removed>0)
00210         m_view->setDirty();
00211     m_view->propertySetSwitched();
00212 }
00213 
00214 //void KexiDataAwarePropertySet::slotEmptyRowInserted(KexiTableItem*, uint /*index*/)
00215 void KexiDataAwarePropertySet::slotRowInserted(KexiTableItem*, uint row, bool /*repaint*/)
00216 {
00217     m_view->setDirty();
00218 
00219     //let's move down all buffers that are below
00220     m_sets.setAutoDelete(false);//to avoid auto deleting in insert()
00221 //  const int r = m_dataObject->currentRow();
00222     m_sets.resize(m_sets.size()+1);
00223     for (int i=int(m_sets.size())-1; i>(int)row; i--) {
00224         KoProperty::Set *b = m_sets[i-1];
00225         m_sets.insert( i , b );
00226     }
00227     m_sets.insert( row, 0 );
00228     m_sets.setAutoDelete(true);//revert the flag
00229 
00230     m_view->propertySetSwitched();
00231 
00232     emit rowInserted();
00233 }
00234 
00235 void KexiDataAwarePropertySet::slotCellSelected(int, int row)
00236 {
00237     if(row == m_row)
00238         return;
00239     m_row = row;
00240     m_view->propertySetSwitched();
00241 }
00242 
00243 KoProperty::Set* KexiDataAwarePropertySet::listForItem(KexiTableItem& item)
00244 {
00245     if (m_currentTVData.isNull())
00246         return 0;
00247     int idx = m_currentTVData->findRef(&item);
00248     if (idx<0)
00249         return 0;
00250     return m_sets[idx];
00251 }
00252 
00253 #include "kexidataawarepropertyset.moc"
00254 
KDE Home | KDE Accessibility Home | Description of Access Keys