00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kexidatasourcecombobox.h"
00021
00022 #include <kdebug.h>
00023 #include <kiconloader.h>
00024 #include <klistbox.h>
00025
00026 #include <kexi.h>
00027 #include <kexiproject.h>
00028 #include <keximainwindow.h>
00029 #include <kexipart.h>
00030 #include <kexipartmanager.h>
00031 #include <kexipartinfo.h>
00032 #include <kexipartitem.h>
00033
00034 #include <kexidb/connection.h>
00035
00036 #ifdef KEXI_SHOW_UNIMPLEMENTED
00037 #define ADD_DEFINEQUERY_ROW
00038 #endif
00039
00041 class KexiDataSourceComboBox::Private
00042 {
00043 public:
00044 Private()
00045 : tablesCount(0)
00046 , prevIndex(-1)
00047 , showTables(true)
00048 , showQueries(true)
00049 {
00050 }
00051 int firstTableIndex() const {
00052 int index = 1;
00053 #ifdef ADD_DEFINEQUERY_ROW
00054 index++;
00055 #endif
00056 return index;
00057 }
00058 int firstQueryIndex() const {
00059 return firstTableIndex() + tablesCount;
00060 }
00061
00062 QGuardedPtr<KexiProject> prj;
00063 QPixmap tableIcon, queryIcon;
00064 int tablesCount;
00065 int prevIndex;
00066 bool showTables : 1;
00067 bool showQueries : 1;
00068 };
00069
00070
00071
00072 KexiDataSourceComboBox::KexiDataSourceComboBox(QWidget *parent, const char *name)
00073 : KComboBox(true, parent, name)
00074 , d(new Private())
00075 {
00076 setInsertionPolicy(NoInsertion);
00077 setCompletionMode(KGlobalSettings::CompletionPopupAuto);
00078 setSizeLimit( 16 );
00079 connect(this, SIGNAL(activated(int)), this, SLOT(slotActivated(int)));
00080 connect(this, SIGNAL(returnPressed(const QString &)), this, SLOT(slotReturnPressed(const QString &)));
00081
00082 d->tableIcon = SmallIcon("table");
00083 d->queryIcon = SmallIcon("query");
00084 }
00085
00086 KexiDataSourceComboBox::~KexiDataSourceComboBox()
00087 {
00088 delete d;
00089 }
00090
00091 KexiProject* KexiDataSourceComboBox::project() const
00092 {
00093 return d->prj;
00094 }
00095
00096 void KexiDataSourceComboBox::setProject(KexiProject *prj, bool showTables, bool showQueries)
00097 {
00098 if ((KexiProject*)d->prj == prj)
00099 return;
00100
00101 if (d->prj) {
00102 disconnect(d->prj, 0, this, 0);
00103 }
00104 d->prj = prj;
00105 d->showTables = showTables;
00106 d->showQueries = showQueries;
00107 clear();
00108 d->tablesCount = 0;
00109 if (!d->prj)
00110 return;
00111
00112
00113 connect(d->prj, SIGNAL(newItemStored(KexiPart::Item&)),
00114 this, SLOT(slotNewItemStored(KexiPart::Item&)));
00115 connect(d->prj, SIGNAL(itemRemoved(const KexiPart::Item&)),
00116 this, SLOT(slotItemRemoved(const KexiPart::Item&)));
00117 connect(d->prj, SIGNAL(itemRenamed(const KexiPart::Item&, const QCString&)),
00118 this, SLOT(slotItemRenamed(const KexiPart::Item&, const QCString&)));
00119
00120 KexiDB::Connection *conn = d->prj->dbConnection();
00121 if (!conn)
00122 return;
00123
00124
00125 insertItem("");
00126 #ifdef ADD_DEFINEQUERY_ROW
00127
00128 insertItem(i18n("Define Query..."));
00129 #endif
00130
00131 KCompletion *comp = completionObject();
00132
00133 if (d->showTables) {
00134
00135 KexiPart::Info* partInfo = Kexi::partManager().infoForMimeType("kexi/table");
00136 if (!partInfo)
00137 return;
00138 KexiPart::ItemList list;
00139 prj->getSortedItems(list, partInfo);
00140 list.sort();
00141 d->tablesCount = 0;
00142 for (KexiPart::ItemListIterator it(list); it.current(); ++it, d->tablesCount++) {
00143 insertItem(d->tableIcon, it.current()->name());
00144 comp->addItem(it.current()->name());
00145 }
00146 }
00147
00148 if (d->showQueries) {
00149
00150 KexiPart::Info* partInfo = Kexi::partManager().infoForMimeType("kexi/query");
00151 if (!partInfo)
00152 return;
00153 KexiPart::ItemList list;
00154 prj->getSortedItems(list, partInfo);
00155 list.sort();
00156 for (KexiPart::ItemListIterator it(list); it.current(); ++it) {
00157 insertItem(d->queryIcon, it.current()->name());
00158 comp->addItem(it.current()->name());
00159 }
00160 }
00161
00162 setCurrentItem(0);
00163 }
00164
00165 void KexiDataSourceComboBox::setDataSource(const QString& mimeType, const QString& name)
00166 {
00167 if (name.isEmpty()) {
00168 clearEdit();
00169 setCurrentItem(0);
00170 d->prevIndex = -1;
00171 emit dataSourceChanged();
00172 return;
00173 }
00174
00175 QString mt(mimeType);
00176 if (mimeType.isEmpty())
00177 mt="kexi/table";
00178 int i = findItem(mt, name);
00179 if (i==-1) {
00180 if (mimeType.isEmpty())
00181 i = findItem("kexi/query", name);
00182 if (i==-1) {
00183 setCurrentItem(0);
00184 return;
00185 }
00186 }
00187 setCurrentItem(i);
00188 slotActivated(i);
00189 }
00190
00191 void KexiDataSourceComboBox::slotNewItemStored(KexiPart::Item& item)
00192 {
00193 QString name(item.name());
00194
00195 if (item.mimeType()=="kexi/table") {
00196 int i = 1;
00197 #ifdef ADD_DEFINEQUERY_ROW
00198 i++;
00199 #endif
00200 for (; i < d->firstQueryIndex() && name>=text(i); i++)
00201 ;
00202 insertItem(d->tableIcon, name, i);
00203 completionObject()->addItem(name);
00204 d->tablesCount++;
00205 }
00206 else if (item.mimeType()=="kexi/query") {
00207 int i;
00208 for (i=d->firstQueryIndex(); i<count() && name>=text(i); i++)
00209 ;
00210 insertItem(d->queryIcon, name, i);
00211 completionObject()->addItem(name);
00212 }
00213 }
00214
00215 int KexiDataSourceComboBox::findItem(const QString& mimeType, const QString& name)
00216 {
00217 int i, end;
00218 if (mimeType=="kexi/table") {
00219 i = 0;
00220 #ifdef ADD_DEFINEQUERY_ROW
00221 i++;
00222 #endif
00223 end = d->firstQueryIndex();
00224 }
00225 else if (mimeType=="kexi/query") {
00226 i = d->firstQueryIndex();
00227 end = count();
00228 }
00229 else
00230 return -1;
00231
00232 QString nameString(name);
00233
00234 for (; i<end; i++)
00235 if (text(i)==nameString)
00236 return i;
00237
00238 return -1;
00239 }
00240
00241 void KexiDataSourceComboBox::slotItemRemoved(const KexiPart::Item& item)
00242 {
00243 const int i = findItem(item.mimeType(), item.name());
00244 if (i==-1)
00245 return;
00246 removeItem(i);
00247 completionObject()->removeItem(item.name());
00248 if (item.mimeType()=="kexi/table")
00249 d->tablesCount--;
00250 #if 0
00251 if (currentItem()==i) {
00252 if (i==(count()-1))
00253 setCurrentItem(i-1);
00254 else
00255 setCurrentItem(i);
00256 }
00257 #endif
00258 }
00259
00260 void KexiDataSourceComboBox::slotItemRenamed(const KexiPart::Item& item, const QCString& oldName)
00261 {
00262 const int i = findItem(item.mimeType(), QString(oldName));
00263 if (i==-1)
00264 return;
00265 changeItem(item.name(), i);
00266 completionObject()->removeItem(QString(oldName));
00267 completionObject()->addItem(item.name());
00268 setCurrentText(oldName);
00269 }
00270
00271 void KexiDataSourceComboBox::slotActivated( int index )
00272 {
00273 if (index >= d->firstTableIndex() && index < count() && d->prevIndex!=currentItem()) {
00274 d->prevIndex = currentItem();
00275 emit dataSourceChanged();
00276 }
00277 }
00278
00279 QString KexiDataSourceComboBox::selectedMimeType() const
00280 {
00281 if (selectedName().isEmpty())
00282 return "";
00283 const int index = currentItem();
00284 if (index >= d->firstTableIndex() && index < (int)d->firstQueryIndex())
00285 return "kexi/table";
00286 else if (index >= (int)d->firstQueryIndex() && index < count())
00287 return "kexi/query";
00288 return "";
00289 }
00290
00291 QString KexiDataSourceComboBox::selectedName() const
00292 {
00293 if (isSelectionValid())
00294 return text(currentItem());
00295 return currentText();
00296 }
00297
00298 bool KexiDataSourceComboBox::isSelectionValid() const
00299 {
00300 const int index = currentItem();
00301 return index >= d->firstTableIndex() && index < count() && text(index)==currentText();
00302 }
00303
00304 void KexiDataSourceComboBox::slotReturnPressed(const QString & text)
00305 {
00306
00307 bool changed = false;
00308 if (text.isEmpty() && 0!=currentItem()) {
00309 setCurrentItem(0);
00310 changed = true;
00311 }
00312 else {
00313 QListBoxItem *item = listBox()->findItem( text, Qt::ExactMatch );
00314 if (item) {
00315 int index = listBox()->index( item );
00316
00317 if (index>=0 && index!=currentItem()) {
00318 setCurrentItem( index );
00319 changed = true;
00320 }
00321 }
00322 }
00323 if (changed)
00324 emit dataSourceChanged();
00325 }
00326
00327 void KexiDataSourceComboBox::focusOutEvent( QFocusEvent *e )
00328 {
00329 KComboBox::focusOutEvent( e );
00330 slotReturnPressed(currentText());
00331 }
00332
00333 #include "kexidatasourcecombobox.moc"