kexi

kexibrowser.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2002, 2003 Lucijan Busch <lucijan@gmx.at>
00003    Copyright (C) 2003-2006 Jaroslaw Staniek <js@iidea.pl>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include "kexibrowser.h"
00022 #include "kexibrowser_p.h"
00023 #include "kexibrowseritem.h"
00024 
00025 #include <qheader.h>
00026 #include <qpoint.h>
00027 #include <qpixmapcache.h>
00028 #include <qtoolbutton.h>
00029 #include <qtooltip.h>
00030 #include <qwhatsthis.h>
00031 
00032 #include <kapplication.h>
00033 #include <kiconloader.h>
00034 #include <kdebug.h>
00035 #include <klocale.h>
00036 #include <kpopupmenu.h>
00037 #include <klistview.h>
00038 #include <kmessagebox.h>
00039 #include <klineedit.h>
00040 #include <kimageeffect.h>
00041 #include <kconfig.h>
00042 
00043 #include <kexi.h>
00044 #include <kexipart.h>
00045 #include <kexipartinfo.h>
00046 #include <kexipartitem.h>
00047 #include <kexiproject.h>
00048 #include <kexidialogbase.h>
00049 #include <keximainwindow.h>
00050 #include <kexiutils/identifier.h>
00051 #include <widget/utils/kexiflowlayout.h>
00052 #include <widget/kexismalltoolbutton.h>
00053 #include <kexidb/utils.h>
00054 
00055 /*
00056 class KexiBrowserView : public QWidget
00057 {
00058     KexiBrowserView*(
00059 };
00060 
00061 KexiBrowserView::KexiBrowserView(KexiMainWindow *mainWin)
00062  : QWidget(mainWin, "KexiBrowserView")
00063 {
00064     QVBoxLayout *lyr = new QVBoxLayout(this);
00065     KexiFlowLayout *buttons_flyr = new KexiFlowLayout(lyr);
00066     m_browser = KexiBrowser(this, mainWin);
00067     lyr->addWidget(m_browser);
00068     setFocusProxy(m_browser);
00069 }*/
00070 
00071 KexiBrowser::KexiBrowser(QWidget* parent, KexiMainWindow *mainWin, int features)
00072  : QWidget(parent, "KexiBrowser")
00073  , m_mainWin(mainWin)
00074  , m_features(features)
00075  , m_actions( new KActionCollection(this) )
00076  , m_baseItems(199, false)
00077  , m_normalItems(199)
00078  , m_prevSelectedPart(0)
00079  , m_singleClick(false)
00080 // , m_nameEndsWithAsterisk(false)
00081  , m_readOnly(false)
00082 // , m_enableExecuteArea(true)
00083 {
00084     setCaption(i18n("Project Navigator"));
00085     setIcon(*m_mainWin->icon());
00086 
00087     QVBoxLayout *lyr = new QVBoxLayout(this);
00088     KexiFlowLayout *buttons_flyr = new KexiFlowLayout(lyr);
00089 
00090     m_list = new KexiBrowserListView(this);
00091     lyr->addWidget(m_list);
00092     m_list->installEventFilter(this);
00093     m_list->renameLineEdit()->installEventFilter(this);
00094     connect( kapp, SIGNAL( settingsChanged(int) ), SLOT( slotSettingsChanged(int) ) );
00095     slotSettingsChanged(0);
00096 
00097     m_list->header()->hide();
00098     m_list->addColumn("");
00099     m_list->setShowToolTips(true);
00100     m_list->setSorting(0);
00101     m_list->sort();
00102     m_list->setAllColumnsShowFocus(true);
00103     m_list->setTooltipColumn(0);
00104     m_list->renameLineEdit()->setValidator( new KexiUtils::IdentifierValidator(this) );
00105     m_list->setResizeMode(QListView::LastColumn);
00106     connect(m_list, SIGNAL(contextMenu(KListView *, QListViewItem *, const QPoint &)),
00107         this, SLOT(slotContextMenu(KListView*, QListViewItem *, const QPoint&)));
00108     connect(m_list, SIGNAL(selectionChanged(QListViewItem*)), this,
00109         SLOT(slotSelectionChanged(QListViewItem*)));
00110     
00111     KConfig *config = kapp->config();
00112     config->setGroup("MainWindow");
00113     if ((m_features & SingleClickOpensItemOptionEnabled) 
00114         && config->readBoolEntry("SingleClickOpensItem", false))
00115     {
00116         connect(m_list, SIGNAL(executed(QListViewItem*)), this,
00117             SLOT(slotExecuteItem(QListViewItem*)));
00118     }
00119     else {
00120         connect(m_list, SIGNAL(doubleClicked(QListViewItem*)), this,
00121             SLOT(slotExecuteItem(QListViewItem*)));
00122         m_list->enableExecuteArea = false;
00123     }
00124 
00125     // actions
00126     m_openAction = new KAction(i18n("&Open"), "fileopen", 0/*Qt::Key_Enter conflict!*/, this, 
00127         SLOT(slotOpenObject()), this, "open_object");
00128     m_openAction->setToolTip(i18n("Open object"));
00129     m_openAction->setWhatsThis(i18n("Opens object selected in the list"));
00130 
00131 //  m_openAction->plug(m_toolbar);
00132     KexiSmallToolButton *btn;
00133     if (m_features & Toolbar) {
00134         btn = new KexiSmallToolButton(this, m_openAction);
00135         buttons_flyr->add(btn);
00136     }
00137 
00138     if (m_mainWin->userMode()) {
00140         m_deleteAction = 0;
00141         m_renameAction = 0;
00142         m_designAction = 0;
00143         m_editTextAction = 0;
00144         m_newObjectAction = 0;
00145         m_newObjectPopup = 0;
00146     }
00147     else {
00148         m_deleteAction = new KAction(i18n("&Delete"), "editdelete", 0/*Qt::Key_Delete*/, 
00149             this, SLOT(slotRemove()), m_actions, "edit_delete");
00151         m_deleteAction->setToolTip(i18n("&Delete").replace("&",""));
00152 
00153         m_renameAction = new KAction(i18n("&Rename"), "", 0, 
00154             this, SLOT(slotRename()), m_actions, "edit_rename");
00155 #ifdef KEXI_SHOW_UNIMPLEMENTED
00156         //todo  plugSharedAction("edit_cut",SLOT(slotCut()));
00157         //todo  plugSharedAction("edit_copy",SLOT(slotCopy()));
00158         //todo  plugSharedAction("edit_paste",SLOT(slotPaste()));
00159 #endif
00160 
00161         m_designAction = new KAction(i18n("&Design"), "edit", 0/*Qt::CTRL + Qt::Key_Enter conflict!*/, this, 
00162             SLOT(slotDesignObject()), this, "design_object");
00163         m_designAction->setToolTip(i18n("Design object"));
00164         m_designAction->setWhatsThis(i18n("Starts designing of the object selected in the list"));
00165         if (m_features & Toolbar) {
00166             btn = new KexiSmallToolButton(this, m_designAction);
00167             buttons_flyr->add(btn);
00168         }
00169 
00170         m_editTextAction = new KAction(i18n("Open in &Text View"), "", 0, this, 
00171             SLOT(slotEditTextObject()), this, "editText_object");
00172         m_editTextAction->setToolTip(i18n("Open object in text view"));
00173         m_editTextAction->setWhatsThis(i18n("Opens selected object in the list in text view"));
00174 
00175         m_newObjectAction = new KAction("", "filenew", 0, this, SLOT(slotNewObject()), this, "new_object");
00176         if (m_features & Toolbar) {
00177             m_newObjectToolButton = new KexiSmallToolButton(this, "", QIconSet(), "new_object");
00178             m_newObjectPopup = new KPopupMenu(this, "newObjectPopup");
00179             connect(m_newObjectPopup, SIGNAL(aboutToShow()), this, SLOT(slotNewObjectPopupAboutToShow()));
00180         //  KexiPart::Part* part = Kexi::partManager().part("kexi/table");
00181         //  m_newObjectPopup->insertItem( SmallIconSet(part->info()->createItemIcon()), part->instanceName() );
00182             m_newObjectToolButton->setPopup(m_newObjectPopup);
00183             m_newObjectToolButton->setPopupDelay(QApplication::startDragTime());
00184             connect(m_newObjectToolButton, SIGNAL(clicked()), this, SLOT(slotNewObject()));
00185             buttons_flyr->add(m_newObjectToolButton);
00186 
00187             m_deleteObjectToolButton = new KexiSmallToolButton(this, m_deleteAction);
00188             m_deleteObjectToolButton->setTextLabel("");
00189             buttons_flyr->add(m_deleteObjectToolButton);
00190         }
00191     }
00192 
00193     m_executeAction = new KAction(i18n("Execute"), "player_play", 0, this,
00194         SLOT(slotExecuteObject()), this, "data_execute");
00195 
00196     m_exportActionMenu = new KActionMenu(i18n("Export"));
00197     m_dataExportAction = new KAction(i18n("Export->To File as Data &Table... ", "To &File as Data Table..."), 
00198         "table", 0, this, SLOT(slotExportAsDataTable()), this, "exportAsDataTable");
00199     m_dataExportAction->setWhatsThis(
00200         i18n("Exports data from the currently selected table or query data to a file."));
00201     m_exportActionMenu->insert( m_dataExportAction );
00202 
00203     m_printAction = new KAction(i18n("&Print..."), "fileprint", 0, this, 
00204         SLOT(slotPrintItem()), this, "printItem");
00205     m_printAction->setWhatsThis(
00206         i18n("Prints data from the currently selected table or query."));
00207     m_pageSetupAction = new KAction(i18n("Page Setup..."), "", 0, this, 
00208         SLOT(slotPageSetupForItem()), this, "pageSetupForItem");
00209     m_pageSetupAction->setWhatsThis(
00210         i18n("Shows page setup for printing the active table or query."));
00211 
00212     if (m_mainWin->userMode()) {
00214         m_partPopup = 0;
00215     }
00216     else {
00217         m_partPopup = new KPopupMenu(this, "partPopup");
00218         m_partPopupTitle_id = m_partPopup->insertTitle("");
00219         m_newObjectAction->plug(m_partPopup);
00220 #ifdef KEXI_SHOW_UNIMPLEMENTED
00221         m_partPopup->insertSeparator();
00222         plugSharedAction("edit_paste", m_partPopup);
00223 #endif
00224     }
00225 
00226     if (m_features & ContextMenus) {
00227         //init popups
00228         m_itemPopup = new KPopupMenu(this, "itemPopup");
00229         m_itemPopupTitle_id = m_itemPopup->insertTitle("");
00230         m_openAction->plug(m_itemPopup);
00231         m_openAction_id = m_itemPopup->idAt(m_itemPopup->count()-1);
00232 
00233         if (m_designAction) {
00234             m_designAction->plug(m_itemPopup);
00235             m_designAction_id = m_itemPopup->idAt(m_itemPopup->count()-1);
00236         }
00237 
00238         if (m_editTextAction) {
00239             m_editTextAction->plug(m_itemPopup);
00240             m_editTextAction_id = m_itemPopup->idAt(m_itemPopup->count()-1);
00241         }
00242 
00243         if (m_newObjectAction) {
00244             m_newObjectAction->plug(m_itemPopup);
00245             m_itemPopup->insertSeparator();
00246         }
00247 #ifdef KEXI_SHOW_UNIMPLEMENTED
00248     //todo  plugSharedAction("edit_cut", m_itemPopup);
00249     //todo  plugSharedAction("edit_copy", m_itemPopup);
00250     //todo  m_itemPopup->insertSeparator();
00251 #endif
00252         m_executeAction->plug(m_itemPopup);
00253         m_executeAction_id = m_itemPopup->idAt(m_itemPopup->count()-1);
00254 
00255         m_exportActionMenu->plug(m_itemPopup);
00256         m_exportActionMenu_id = m_exportActionMenu->menuId(0);
00257         m_itemPopup->insertSeparator();
00258         m_exportActionMenu_id_sep = m_itemPopup->idAt(m_itemPopup->count()-1);
00259 
00260         m_printAction->plug(m_itemPopup);
00261         m_printAction_id = m_itemPopup->idAt(m_itemPopup->count()-1);
00262 
00263         m_pageSetupAction->plug(m_itemPopup);
00264         m_pageSetupAction_id = m_itemPopup->idAt(m_itemPopup->count()-1);
00265         if (m_renameAction || m_deleteAction) {
00266             m_itemPopup->insertSeparator();
00267             m_pageSetupAction_id_sep = m_itemPopup->idAt(m_itemPopup->count()-1);
00268         }
00269         else {
00270             m_pageSetupAction_id_sep = -1;
00271         }
00272 
00273         if (m_renameAction)
00274             m_renameAction->plug(m_itemPopup);
00275         if (m_deleteAction)
00276             m_deleteAction->plug(m_itemPopup);
00277     }
00278     else {
00279         m_itemPopup = 0;
00280     }
00281 
00282     if (!(m_features & Writable)) {
00283         setReadOnly(true);
00284     }
00285 }
00286 
00287 KexiBrowser::~KexiBrowser()
00288 {
00289 }
00290 
00291 void KexiBrowser::setProject(KexiProject* prj, const QString& itemsMimeType,
00292     QString* partManagerErrorMessages)
00293 {
00294     clear();
00295     m_itemsMimeType = itemsMimeType;
00296     m_list->setRootIsDecorated(m_itemsMimeType.isEmpty());
00297 
00298     KexiPart::PartInfoList *pl = Kexi::partManager().partInfoList();
00299     for (KexiPart::Info *info = pl->first(); info; info = pl->next()) {
00300         if (!info->isVisibleInNavigator())
00301             continue;
00302         if (!m_itemsMimeType.isEmpty() && info->mimeType()!=m_itemsMimeType.latin1())
00303             continue;
00304 
00305 //      kdDebug() << "KexiMainWindowImpl::initNavigator(): adding " << it->groupName() << endl;
00306 
00307 /*          KexiPart::Part *p=Kexi::partManager().part(it);
00308         if (!p) {
00309             //TODO: js - OPTIONALLY: show error
00310             continue;
00311         }
00312         p->createGUIClient(this);*/
00313 
00314         //load part - we need this to have GUI merged with part's actions
00316         KexiPart::Part *p=Kexi::partManager().part(info);
00317         if (p) {
00318             KexiBrowserItem *groupItem = 0;
00319             if (m_itemsMimeType.isEmpty()) {
00320                 groupItem = addGroup(*info);
00321                 if (!groupItem)
00322                     continue;
00323             }
00324             //lookup project's objects (part items)
00326             KexiPart::ItemDict *item_dict = prj->items(info);
00327             if (!item_dict)
00328                 continue;
00329             for (KexiPart::ItemDictIterator item_it( *item_dict ); item_it.current(); ++item_it)
00330                 addItem(*item_it.current(), groupItem, info);
00331             if (!m_itemsMimeType.isEmpty())
00332                 break; //the only group added, so our work is completed
00333         }
00334         else {
00335             //add this error to the list that will be displayed later
00336             QString msg, details;
00337             KexiDB::getHTMLErrorMesage(&Kexi::partManager(), msg, details);
00338             if (!msg.isEmpty() && partManagerErrorMessages) {
00339                 if (partManagerErrorMessages->isEmpty()) {
00340                     *partManagerErrorMessages = QString("<qt><p>")
00341                         +i18n("Errors encountered during loading plugins:")+"<ul>";
00342                 }
00343                 partManagerErrorMessages->append( QString("<li>") + msg );
00344                 if (!details.isEmpty())
00345                     partManagerErrorMessages->append(QString("<br>")+details);
00346                 partManagerErrorMessages->append("</li>");
00347             }
00348         }
00349     }
00350     if (partManagerErrorMessages && !partManagerErrorMessages->isEmpty())
00351         partManagerErrorMessages->append("</ul></p>");
00352 }
00353 
00354 QString KexiBrowser::itemsMimeType() const
00355 {
00356     return m_itemsMimeType;
00357 }
00358 
00359 KexiBrowserItem *KexiBrowser::addGroup(KexiPart::Info& info)
00360 {
00361     if(!info.isVisibleInNavigator())
00362         return 0;
00363 
00364     KexiBrowserItem *item = new KexiBrowserItem(m_list, &info);
00365     m_baseItems.insert(info.mimeType().lower(), item);
00366     return item;
00367 //  kdDebug() << "KexiBrowser::addGroup()" << endl;
00368 }
00369 
00370 KexiBrowserItem* KexiBrowser::addItem(KexiPart::Item& item)
00371 {
00372     //part object for this item
00373     KexiBrowserItem *parent = item.mimeType().isEmpty() ? 0 : m_baseItems.find(item.mimeType().lower());
00374     return addItem(item, parent, parent->info());
00375 }
00376 
00377 KexiBrowserItem* KexiBrowser::addItem(KexiPart::Item& item, KexiBrowserItem *parent, KexiPart::Info* info)
00378 {
00379 //  if (!parent) //TODO: add "Other" part group for that
00380     //  return 0;
00381 //  kdDebug() << "KexiBrowser::addItem() found parent:" << parent << endl;
00382     KexiBrowserItem *bitem;
00383     if (parent)
00384         bitem = new KexiBrowserItem(parent, info, &item);
00385     else
00386         bitem = new KexiBrowserItem(m_list, info, &item);
00387     m_normalItems.insert(item.identifier(), bitem);
00388     return bitem;
00389 }
00390 
00391 void 
00392 KexiBrowser::slotRemoveItem(const KexiPart::Item &item)
00393 {
00394     KexiBrowserItem *to_remove=m_normalItems.take(item.identifier());
00395     if (!to_remove)
00396         return;
00397 
00398     KexiBrowserItem *it = static_cast<KexiBrowserItem*>(m_list->selectedItem());
00399     
00400     QListViewItem *new_item_to_select = 0;
00401     if (it==to_remove) {//compute item to select if current one will be removed
00402         new_item_to_select = it->itemBelow();//nearest item to select
00403         if (!new_item_to_select || new_item_to_select->parent()!=it->parent()) {
00404             new_item_to_select = it->itemAbove();
00405         }
00406     }
00407     delete to_remove;
00408 
00409     if (new_item_to_select)
00410         m_list->setSelected(new_item_to_select, true);
00411 }
00412 
00413 void
00414 KexiBrowser::slotContextMenu(KListView* /*list*/, QListViewItem *item, const QPoint &pos)
00415 {
00416     if(!item || !(m_features & ContextMenus))
00417         return;
00418     KexiBrowserItem *bit = static_cast<KexiBrowserItem*>(item);
00419     KPopupMenu *pm = 0;
00420     if (bit->item()) {
00421         pm = m_itemPopup;
00422         //update popup title
00423         QString title_text = bit->text(0).stripWhiteSpace();
00424         KexiBrowserItem *par_it = static_cast<KexiBrowserItem*>(bit->parent());
00425         KexiPart::Part* par_part = 0;
00426         if (par_it && par_it->info() && ((par_part = Kexi::partManager().part(par_it->info()))) && !par_part->instanceCaption().isEmpty()) {
00427             //add part type name
00428             title_text +=  (" : " + par_part->instanceCaption());
00429         }
00430         pm->changeTitle(m_itemPopupTitle_id, *bit->pixmap(0), title_text);
00431     }
00432     else if (m_partPopup) {
00433         pm = m_partPopup;
00434         QString title_text = bit->text(0).stripWhiteSpace();
00435         pm->changeTitle(m_partPopupTitle_id, *bit->pixmap(0), title_text);
00436 /*      KexiPart::Part* part = Kexi::partManager().part(bit->info());
00437         if (part)
00438             m_newObjectAction->setText(i18n("&Create Object: %1...").arg( part->instanceName() ));
00439         else
00440             m_newObjectAction->setText(i18n("&Create Object..."));
00441         m_newObjectAction->setIconSet( SmallIconSet(bit->info()->itemIcon()) );*/
00442         m_list->setCurrentItem(item);
00443         m_list->repaintItem(item);
00444     }
00445     if (pm)
00446         pm->exec(pos);
00447 }
00448 
00449 void
00450 KexiBrowser::slotExecuteItem(QListViewItem *vitem)
00451 {
00452 //  kdDebug() << "KexiBrowser::slotExecuteItem()" << endl;
00453     KexiBrowserItem *it = static_cast<KexiBrowserItem*>(vitem);
00454     if (!it)
00455         return;
00456     if (!it->item() && !m_singleClick /*annoying when in single click mode*/) {
00457         m_list->setOpen( vitem, !vitem->isOpen() );
00458         return;
00459     }
00460     if (it->info()->isExecuteSupported())
00461         emit executeItem( it->item() );
00462     else
00463         emit openOrActivateItem( it->item(), Kexi::DataViewMode );
00464 }
00465 
00466 void
00467 KexiBrowser::slotSelectionChanged(QListViewItem* i)
00468 {
00469     KexiBrowserItem *it = static_cast<KexiBrowserItem*>(i);
00470     if (!it)
00471         return;
00472     KexiPart::Part* part = Kexi::partManager().part(it->info());
00473     if (!part) {
00474         it = static_cast<KexiBrowserItem*>(it->parent());
00475         if (it) {
00476             part = Kexi::partManager().part(it->info());
00477         }
00478     }
00479 
00480     const bool gotitem = it && it->item();
00481     //bool gotgroup = it && !it->item();
00482 //TODO: also check if the item is not read only
00483     if (m_deleteAction) {
00484         m_deleteAction->setEnabled(gotitem && !m_readOnly);
00485         if (m_features & Toolbar) {
00486             m_deleteObjectToolButton->setEnabled(gotitem && !m_readOnly);
00487         }
00488     }
00489 #ifdef KEXI_SHOW_UNIMPLEMENTED
00490 //todo  setAvailable("edit_cut",gotitem);
00491 //todo  setAvailable("edit_copy",gotitem);
00492 //todo  setAvailable("edit_edititem",gotitem);
00493 #endif
00494 
00495     m_openAction->setEnabled(gotitem && part && (part->supportedViewModes() & Kexi::DataViewMode));
00496     if (m_designAction)
00497         m_designAction->setEnabled(gotitem && part && (part->supportedViewModes() & Kexi::DesignViewMode));
00498     if (m_editTextAction)
00499         m_editTextAction->setEnabled(gotitem && part && (part->supportedViewModes() & Kexi::TextViewMode));
00500 
00501     if (m_features & ContextMenus) {
00502         m_itemPopup->setItemVisible(m_openAction_id, m_openAction->isEnabled());
00503         if (m_designAction)
00504             m_itemPopup->setItemVisible(m_designAction_id, m_designAction->isEnabled());
00505         if (m_editTextAction)
00506             m_itemPopup->setItemVisible(m_editTextAction_id, part && m_editTextAction->isEnabled());
00507         if (m_executeAction)
00508             m_itemPopup->setItemVisible(m_executeAction_id, gotitem && it->info()->isExecuteSupported());
00509         if (m_exportActionMenu) {
00510             m_itemPopup->setItemVisible(m_exportActionMenu_id, gotitem && it->info()->isDataExportSupported());
00511             m_itemPopup->setItemVisible(m_exportActionMenu_id_sep, gotitem && it->info()->isDataExportSupported());
00512         }
00513         if (m_printAction)
00514             m_itemPopup->setItemVisible(m_printAction_id, gotitem && it->info()->isPrintingSupported());
00515         if (m_pageSetupAction) {
00516             m_itemPopup->setItemVisible(m_pageSetupAction_id, gotitem && it->info()->isPrintingSupported());
00517             if (m_pageSetupAction_id_sep!=-1)
00518                 m_itemPopup->setItemVisible(m_pageSetupAction_id_sep, gotitem && it->info()->isPrintingSupported());
00519         }
00520     }
00521 
00522     if (m_prevSelectedPart != part) {
00523         m_prevSelectedPart = part;
00524         if (part) {
00525             if (m_newObjectAction) {
00526                 m_newObjectAction->setText(i18n("&Create Object: %1...").arg( part->instanceCaption() ));
00527                 m_newObjectAction->setIcon( part->info()->createItemIcon() );
00528                 if (m_features & Toolbar) {
00529                     m_newObjectToolButton->setIconSet( part->info()->createItemIcon() );
00530                     QToolTip::add(m_newObjectToolButton, 
00531                         i18n("Create object: %1").arg( part->instanceCaption().lower() ));
00532                     QWhatsThis::add(m_newObjectToolButton, 
00533                         i18n("Creates a new object: %1").arg( part->instanceCaption().lower() ));
00534                 }
00535             }
00536         } else {
00537             if (m_newObjectAction) {
00538                 m_newObjectAction->setText(i18n("&Create Object..."));
00539     //          m_newObjectToolbarAction->setIconSet( SmallIconSet("filenew") );
00540     //          m_newObjectToolbarAction->setText(m_newObjectAction->text());
00541                 if (m_features & Toolbar) {
00542                     m_newObjectToolButton->setIconSet( "filenew" );
00543                     QToolTip::add(m_newObjectToolButton, i18n("Create object"));
00544                     QWhatsThis::add(m_newObjectToolButton, i18n("Creates a new object"));
00545                 }
00546             }
00547         }
00548     }
00549     emit selectionChanged(it ? it->item() : 0);
00550 }
00551 
00552 void KexiBrowser::installEventFilter ( const QObject * filterObj )
00553 {
00554     if (!filterObj)
00555         return;
00556     m_list->installEventFilter ( filterObj );
00557     QWidget::installEventFilter ( filterObj );
00558 }
00559 
00560 bool KexiBrowser::eventFilter ( QObject *o, QEvent * e )
00561 {
00562     if (o==m_list && e->type()==QEvent::Resize) {
00563         kdDebug() << "resize!" << endl;
00564     }
00565     if (o==m_list->renameLineEdit()) {
00566         if (e->type()==QEvent::Hide) 
00567             itemRenameDone();
00568     }
00569     else if (e->type()==QEvent::KeyPress) {
00570         QKeyEvent *ke = static_cast<QKeyEvent*>(e);
00571         if (ke->key()==Qt::Key_Enter || ke->key()==Qt::Key_Return) {
00572             if (0==(ke->state() & (Qt::ShiftButton|Qt::ControlButton|Qt::AltButton))) {
00573                 QListViewItem *it = m_list->selectedItem();
00574                 if (it)
00575                     slotExecuteItem(it);
00576             }
00577             else if (Qt::ControlButton==(ke->state() & (Qt::ShiftButton|Qt::ControlButton|Qt::AltButton))) {
00578                 slotDesignObject();
00579             }
00580         }
00581     }
00582     else if (e->type()==QEvent::AccelOverride) {
00583         QKeyEvent *ke = static_cast<QKeyEvent*>(e);
00584         //override delete action
00585         if (ke->key()==Qt::Key_Delete && ke->state()==Qt::NoButton) {
00586             slotRemove();
00587             ke->accept();
00588             return true;
00589         }
00590         //override rename action
00591         if (ke->key()==Qt::Key_F2 && ke->state()==Qt::NoButton) {
00592             slotRename();
00593             ke->accept();
00594             return true;
00595         }
00596 /*      else if (ke->key()==Qt::Key_Enter || ke->key()==Qt::Key_Return) {
00597             if (ke->state()==ControlButton) {
00598                 slotDesignObject();
00599             }
00600             else if (ke->state()==0 && !m_list->renameLineEdit()->isVisible()) {
00601                 QListViewItem *it = m_list->selectedItem();
00602                 if (it)
00603                     slotExecuteItem(it);
00604             }
00605             ke->accept();
00606             return true;
00607         }*/
00608     }
00609     return false;
00610 }
00611 
00612 void KexiBrowser::slotRemove()
00613 {
00614     if (!m_deleteAction || !m_deleteAction->isEnabled() || !(m_features & Writable))
00615         return;
00616     KexiBrowserItem *it = static_cast<KexiBrowserItem*>(m_list->selectedItem());
00617     if (!it || !it->item())
00618         return;
00619     emit removeItem( it->item() );
00620 }
00621 
00622 void KexiBrowser::slotNewObject()
00623 {
00624     if (!m_newObjectAction || !(m_features & Writable))
00625         return;
00626     KexiBrowserItem *it = static_cast<KexiBrowserItem*>(m_list->selectedItem());
00627     if (!it || !it->info())
00628         return;
00629     emit newItem( it->info() );
00630 }
00631 
00632 void KexiBrowser::slotOpenObject()
00633 {
00634     KexiBrowserItem *it = static_cast<KexiBrowserItem*>(m_list->selectedItem());
00635     if (!it || !it->item())
00636         return;
00637     emit openItem( it->item(), Kexi::DataViewMode );
00638 }
00639 
00640 void KexiBrowser::slotDesignObject()
00641 {
00642     if (!m_designAction)
00643         return;
00644     KexiBrowserItem *it = static_cast<KexiBrowserItem*>(m_list->selectedItem());
00645     if (!it || !it->item())
00646         return;
00647     emit openItem( it->item(), Kexi::DesignViewMode );
00648 }
00649 
00650 void KexiBrowser::slotEditTextObject()
00651 {
00652     if (!m_editTextAction)
00653         return;
00654     KexiBrowserItem *it = static_cast<KexiBrowserItem*>(m_list->selectedItem());
00655     if (!it || !it->item())
00656         return;
00657     emit openItem( it->item(), Kexi::TextViewMode );
00658 }
00659 
00660 void KexiBrowser::slotCut()
00661 {
00662     if (!(m_features & Writable))
00663         return;
00664 //  KEXI_UNFINISHED_SHARED_ACTION("edit_cut");
00665     //TODO
00666 }
00667 
00668 void KexiBrowser::slotCopy()
00669 {
00670 //  KEXI_UNFINISHED_SHARED_ACTION("edit_copy");
00671     //TODO
00672 }
00673 
00674 void KexiBrowser::slotPaste()
00675 {
00676     if (!(m_features & Writable))
00677         return;
00678 //  KEXI_UNFINISHED_SHARED_ACTION("edit_paste");
00679     //TODO
00680 }
00681 
00682 void KexiBrowser::slotRename()
00683 {
00684     if (!m_renameAction || !(m_features & Writable))
00685         return;
00686     KexiBrowserItem *it = static_cast<KexiBrowserItem*>(m_list->selectedItem());
00687     if (it)
00688         m_list->rename(it, 0);
00689 }
00690 
00691 void KexiBrowser::itemRenameDone()
00692 {
00693     if (!(m_features & Writable))
00694         return;
00695     KexiBrowserItem *it = static_cast<KexiBrowserItem*>(m_list->selectedItem());
00696     if (!it)
00697         return;
00698     QString txt = it->text(0).stripWhiteSpace();
00699     bool ok = it->item()->name().lower()!=txt.lower(); //the new name must be different
00700     if (ok) {
00701         /* TODO */
00702         emit renameItem(it->item(), txt, ok);
00703     }
00704     if (!ok) {
00705         txt = it->item()->name(); //revert
00706     }
00707     //"modified" flag has been removed before editing: readd it
00708     if (m_list->nameEndsWithAsterisk) {
00709         txt += "*";
00710         m_list->nameEndsWithAsterisk = false;
00711     }
00712     it->setText(0, txt);
00713     it->parent()->sort();
00714     setFocus();
00715 }
00716 
00717 void KexiBrowser::setFocus()
00718 {
00719     if (!m_list->selectedItem() && m_list->firstChild())//select first
00720         m_list->setSelected(m_list->firstChild(), true);
00721     m_list->setFocus();
00722 }
00723 
00724 void KexiBrowser::updateItemName( KexiPart::Item& item, bool dirty )
00725 {
00726     if (!(m_features & Writable))
00727         return;
00728     KexiBrowserItem *bitem = m_normalItems[item.identifier()];
00729     if (!bitem)
00730         return;
00731     bitem->setText( 0, item.name() + (dirty ? "*" : "") );
00732 }
00733 
00734 void KexiBrowser::slotSettingsChanged(int)
00735 {
00736     m_singleClick = KGlobalSettings::singleClick();
00737 }
00738 
00739 void KexiBrowser::selectItem(KexiPart::Item& item)
00740 {
00741     KexiBrowserItem *bitem = m_normalItems[item.identifier()];
00742     if (!bitem)
00743         return;
00744     m_list->setSelected(bitem, true);
00745     m_list->ensureItemVisible(bitem);
00746     m_list->setCurrentItem(bitem);
00747 }
00748 
00749 void KexiBrowser::clearSelection()
00750 {
00751     m_list->clearSelection();
00752     QListViewItem *item = m_list->firstChild();
00753     if (item) {
00754         m_list->ensureItemVisible(item);
00755     }
00756 }
00757 
00758 void KexiBrowser::slotNewObjectPopupAboutToShow()
00759 {
00760     if ((m_features & Toolbar) && m_newObjectPopup && m_newObjectPopup->count()==0) {
00761         //preload items
00762         KexiPart::PartInfoList *list = Kexi::partManager().partInfoList(); //this list is properly sorted
00763         for (KexiPart::PartInfoListIterator it(*list); it.current(); ++it) {
00764             //add an item to "New object" toolbar popup 
00765             KAction *action = m_mainWin->actionCollection()->action( 
00766                 KexiPart::nameForCreateAction(*it.current()) );
00767             if (action) {
00768                 action->plug(m_newObjectPopup);
00769             }
00770             else {
00772             }
00773         }
00774     }
00775 }
00776 
00777 void KexiBrowser::slotExecuteObject()
00778 {
00779     if (!m_executeAction)
00780         return;
00781     KexiPart::Item* item = selectedPartItem();
00782     if (item)
00783         emit executeItem( item );
00784 }
00785 
00786 void KexiBrowser::slotExportAsDataTable()
00787 {
00788     if (!m_dataExportAction)
00789         return;
00790     KexiPart::Item* item = selectedPartItem();
00791     if (item)
00792         emit exportItemAsDataTable( item );
00793 }
00794 
00795 KexiPart::Item* KexiBrowser::selectedPartItem() const
00796 {
00797     KexiBrowserItem *it = static_cast<KexiBrowserItem*>(m_list->selectedItem());
00798     return it ? it->item() : 0;
00799 }
00800 
00801 bool KexiBrowser::actionEnabled(const QCString& actionName) const
00802 {
00803     if (actionName=="project_export_data_table" && (m_features & ContextMenus))
00804         return m_itemPopup->isItemVisible(m_exportActionMenu_id);
00805     kdWarning() << "KexiBrowser::actionEnabled() no such action: " << actionName << endl;
00806     return false;
00807 }
00808 
00809 void KexiBrowser::slotPrintItem()
00810 {
00811     if (!m_printAction)
00812         return;
00813     KexiPart::Item* item = selectedPartItem();
00814     if (item)
00815         emit printItem( item );
00816 }
00817 
00818 void KexiBrowser::slotPageSetupForItem()
00819 {
00820     if (!m_pageSetupAction)
00821         return;
00822     KexiPart::Item* item = selectedPartItem();
00823     if (item)
00824         emit pageSetupForItem( item );
00825 }
00826 
00827 
00828 void KexiBrowser::setReadOnly(bool set)
00829 {
00830     m_readOnly = set;
00831     if (m_deleteAction)
00832         m_deleteAction->setEnabled(!m_readOnly);
00833     if (m_renameAction)
00834         m_renameAction->setEnabled(!m_readOnly);
00835     if (m_newObjectAction) {
00836         m_newObjectAction->setEnabled(!m_readOnly);
00837         if (m_features & Toolbar) {
00838             m_newObjectPopup->setEnabled(!m_readOnly);
00839             m_newObjectToolButton->setEnabled(!m_readOnly);
00840         }
00841     }
00842 }
00843 
00844 bool KexiBrowser::isReadOnly() const
00845 {
00846     return m_readOnly;
00847 }
00848 
00849 void KexiBrowser::clear()
00850 {
00851     m_list->clear();
00852 }
00853 
00854 //--------------------------------------------
00855 KexiBrowserListView::KexiBrowserListView(QWidget *parent)
00856  : KListView(parent, "KexiBrowserListView")
00857  , nameEndsWithAsterisk(false)
00858  , enableExecuteArea(true)
00859 {
00860 }
00861 
00862 KexiBrowserListView::~KexiBrowserListView()
00863 {
00864 }
00865 
00866 void KexiBrowserListView::rename(QListViewItem *item, int c)
00867 {
00868     if (renameLineEdit()->isVisible())
00869         return;
00870     KexiBrowserItem *it = static_cast<KexiBrowserItem*>(item);
00871     if (it->item() && c==0) {
00872         //only edit 1st column for items, not item groups
00873 //TODO: also check it this item is not read-only
00874 //      item->setText(0, item->text(0).mid(1,item->text(0).length()-2));
00875         //remove "modified" flag for editing
00876         nameEndsWithAsterisk = item->text(0).endsWith("*");
00877         if (nameEndsWithAsterisk)
00878             item->setText(0, item->text(0).left(item->text(0).length()-1));
00879         KListView::rename(item, c);
00880         adjustColumn(0);
00881     }
00882 }
00883 
00884 bool KexiBrowserListView::isExecuteArea( const QPoint& point )
00885 {
00886     return enableExecuteArea && KListView::isExecuteArea(point);
00887 }
00888 
00889 #include "kexibrowser.moc"
00890 #include "kexibrowser_p.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys