File indexing completed on 2024-05-12 16:39:50

0001 /* This file is part of the KDE project
0002    Copyright (C) 2005-2006 Jarosław Staniek <staniek@kde.org>
0003 
0004    This library is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU Library General Public
0006    License as published by the Free Software Foundation; either
0007    version 2 of the License, or (at your option) any later version.
0008 
0009    This library is distributed in the hope that it will be useful,
0010    but WITHOUT ANY WARRANTY; without even the implied warranty of
0011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012    Library General Public License for more details.
0013 
0014    You should have received a copy of the GNU Library General Public License
0015    along with this library; see the file COPYING.LIB.  If not, write to
0016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017  * Boston, MA 02110-1301, USA.
0018 */
0019 
0020 #include "kexiformeventhandler.h"
0021 #include <KexiMainWindowIface.h>
0022 #include <kexipart.h>
0023 #include <kexipartinfo.h>
0024 #include <kexipartitem.h>
0025 #include <kexipartmanager.h>
0026 #include <kexiproject.h>
0027 #include <config-kexi.h>
0028 
0029 #include <KDbTableViewData>
0030 #include <KDbQuerySchema>
0031 
0032 #include <KActionCollection>
0033 
0034 #include <QWidget>
0035 #include <QAction>
0036 #include <QDebug>
0037 
0038 KexiFormEventAction::ActionData::ActionData()
0039 {
0040 }
0041 
0042 bool KexiFormEventAction::ActionData::isEmpty() const
0043 {
0044     return string.isEmpty();
0045 }
0046 
0047 KexiPart::Info* KexiFormEventAction::ActionData::decodeString(
0048     QString& actionType, QString& actionArg, bool *ok) const
0049 {
0050     Q_ASSERT(ok);
0051     const int idx = string.indexOf(':');
0052     *ok = false;
0053     if (idx == -1)
0054         return 0;
0055     const QString _actionType = string.left(idx);
0056     const QString _actionArg = string.mid(idx + 1);
0057     if (_actionType.isEmpty() || _actionArg.isEmpty())
0058         return 0;
0059     KexiPart::Info *info = 0;
0060     if (_actionType != "kaction" && _actionType != "currentForm") {
0061         info = Kexi::partManager().infoForPluginId(QString("org.kexi-project.%1").arg(_actionType));
0062         if (!info)
0063             return 0;
0064     }
0065     actionType = _actionType;
0066     actionArg = _actionArg;
0067     *ok = true;
0068     return info;
0069 }
0070 
0071 //-------------------------------------
0072 
0073 class Q_DECL_HIDDEN KexiFormEventAction::Private
0074 {
0075 public:
0076     Private(const QString& actionName_, const QString& objectName_, const QString actionOption_);
0077 
0078     ~Private();
0079     QString actionName, objectName, actionOption;
0080 };
0081 
0082 KexiFormEventAction::Private::Private(const QString& actionName_, const QString& objectName_, const QString actionOption_)
0083     :actionName(actionName_), objectName(objectName_), actionOption(actionOption_)
0084 {
0085 
0086 }
0087 
0088 KexiFormEventAction::Private::~Private()
0089 {
0090 
0091 }
0092 
0093 KexiFormEventAction::KexiFormEventAction(QObject* parent,
0094         const QString& actionName, const QString& objectName, const QString& actionOption)
0095         : QAction(parent)
0096         ,d(new Private(actionName, objectName, actionOption))
0097 {
0098     connect(this, SIGNAL(triggered()), this, SLOT(trigger()));
0099 }
0100 
0101 KexiFormEventAction::~KexiFormEventAction()
0102 {
0103     delete d;
0104 }
0105 
0106 void KexiFormEventAction::slotTrigger()
0107 {
0108     //qDebug() << d->actionName << d->objectName;
0109     KexiProject* project = KexiMainWindowIface::global()->project();
0110     if (!project)
0111         return;
0112     KexiPart::Part* part = Kexi::partManager().partForPluginId(
0113                                QString("org.kexi-project.%1").arg(d->actionName));
0114     if (!part)
0115         return;
0116     KexiPart::Item* item = project->item(part->info(), d->objectName);
0117     if (!item)
0118         return;
0119     bool actionCancelled = false;
0120     if (d->actionOption.isEmpty()) { // backward compatibility (good defaults)
0121         if (part->info()->isExecuteSupported())
0122             part->execute(item, parent());
0123         else
0124             KexiMainWindowIface::global()->openObject(item, Kexi::DataViewMode, &actionCancelled);
0125     } else {
0126 //! @todo react on failure...
0127         if (d->actionOption == "open")
0128             KexiMainWindowIface::global()->openObject(item, Kexi::DataViewMode, &actionCancelled);
0129         else if (d->actionOption == "execute")
0130             part->execute(item, parent());
0131         else if (d->actionOption == "print") {
0132             if (part->info()->isPrintingSupported())
0133                 KexiMainWindowIface::global()->printItem(item);
0134         }
0135 #ifdef KEXI_QUICK_PRINTING_SUPPORT
0136         else if (d->actionOption == "printPreview") {
0137             if (part->info()->isPrintingSupported())
0138                 KexiMainWindowIface::global()->printPreviewForItem(item);
0139         }
0140         else if (d->actionOption == "pageSetup") {
0141             if (part->info()->isPrintingSupported())
0142                 KexiMainWindowIface::global()->showPageSetupForItem(item);
0143         }
0144 #endif
0145         else if (d->actionOption == "exportToCSV"
0146                    || d->actionOption == "copyToClipboardAsCSV") {
0147             if (part->info()->isDataExportSupported())
0148                 KexiMainWindowIface::global()->executeCustomActionForObject(item, d->actionOption);
0149         } else if (d->actionOption == "new")
0150             KexiMainWindowIface::global()->newObject(part->info(), &actionCancelled);
0151         else if (d->actionOption == "design")
0152             KexiMainWindowIface::global()->openObject(item, Kexi::DesignViewMode, &actionCancelled);
0153         else if (d->actionOption == "editText")
0154             KexiMainWindowIface::global()->openObject(item, Kexi::TextViewMode, &actionCancelled);
0155         else if (d->actionOption == "close") {
0156             tristate res = KexiMainWindowIface::global()->closeObject(item);
0157             if (~res)
0158                 actionCancelled = true;
0159         }
0160     }
0161 }
0162 
0163 //------------------------------------------
0164 
0165 class Q_DECL_HIDDEN KexiFormEventHandler::Private
0166 {
0167 public:
0168     Private();
0169     ~Private()
0170     {
0171 
0172     }
0173 
0174     QWidget *mainWidget;
0175 };
0176 
0177 KexiFormEventHandler::Private::Private() : mainWidget(0)
0178 {
0179 
0180 }
0181 
0182 KexiFormEventHandler::KexiFormEventHandler()
0183     : d(new Private())
0184 {
0185 
0186 }
0187 
0188 KexiFormEventHandler::~KexiFormEventHandler()
0189 {
0190     delete d;
0191 }
0192 
0193 void KexiFormEventHandler::setMainWidgetForEventHandling(QWidget* mainWidget)
0194 {
0195     d->mainWidget = mainWidget;
0196     if (!d->mainWidget)
0197         return;
0198 
0199     //find widgets whose will work as data items
0200 //! @todo look for other widgets too
0201     QList<QWidget*> widgets(d->mainWidget->findChildren<QWidget*>());
0202     foreach(QWidget *widget, widgets) {
0203         if (!widget->inherits("QPushButton") ){
0204             continue;
0205         }
0206         bool ok;
0207         KexiFormEventAction::ActionData data;
0208         data.string = widget->property("onClickAction").toString();
0209         data.option = widget->property("onClickActionOption").toString();
0210         if (data.isEmpty())
0211             continue;
0212 
0213         QString actionType, actionArg;
0214         KexiPart::Info* partInfo = data.decodeString(actionType, actionArg, &ok);
0215         if (!ok)
0216             continue;
0217         //qDebug() << "actionType:" << actionType << "actionArg:" << actionArg;
0218         if (actionType == "kaction" || actionType == "currentForm") {
0219             QAction *action = KexiMainWindowIface::global()->actionCollection()->action(
0220                                   actionArg);
0221             if (!action)
0222                 continue;
0223             QObject::disconnect(widget, SIGNAL(clicked()), action, SLOT(trigger()));   //safety
0224             QObject::connect(widget, SIGNAL(clicked()), action, SLOT(trigger()));
0225         } else if (partInfo) { //'open or execute' action
0226             KexiFormEventAction* action = new KexiFormEventAction(widget, actionType, actionArg,
0227                     data.option);
0228             QObject::disconnect(widget, SIGNAL(clicked()), action, SLOT(slotTrigger()));
0229             QObject::connect(widget, SIGNAL(clicked()), action, SLOT(slotTrigger()));
0230         }
0231     }
0232 }