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 Copyright (C) 2012 Adam Pigg <adam@piggz.co.uk> 0004 0005 This library is free software; you can redistribute it and/or 0006 modify it under the terms of the GNU Library General Public 0007 License as published by the Free Software Foundation; either 0008 version 2 of the License, or (at your option) any later version. 0009 0010 This library is distributed in the hope that it will be useful, 0011 but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 Library General Public License for more details. 0014 0015 You should have received a copy of the GNU Library General Public License 0016 along with this library; see the file COPYING.LIB. If not, write to 0017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0018 * Boston, MA 02110-1301, USA. 0019 */ 0020 0021 #include "kexiactionselectiondialog.h" 0022 #include "kexiactionselectiondialog_p.h" 0023 0024 #include <kexipartitem.h> 0025 #include <kexiproject.h> 0026 #include <kexipartinfo.h> 0027 #include <kexipart.h> 0028 #include <kexipartmanager.h> 0029 #include <kexiactioncategories.h> 0030 #include <KexiMainWindowIface.h> 0031 #include <KexiIcon.h> 0032 0033 #include <QDebug> 0034 0035 #include <QLabel> 0036 #include <QPushButton> 0037 #include <QGridLayout> 0038 #include <QVBoxLayout> 0039 #include <QPixmap> 0040 #include <QStackedWidget> 0041 #include <QDialogButtonBox> 0042 #include <QAction> 0043 0044 #include <widget/navigator/KexiProjectNavigator.h> 0045 #include <widget/navigator/KexiProjectModel.h> 0046 #include <kexiutils/utils.h> 0047 #include <kexi_global.h> 0048 0049 class ActionSelectorDialogTreeItem : public QTreeWidgetItem 0050 { 0051 public: 0052 enum ActionRole{ 0053 ActionCategoryRole = Qt::UserRole + 1, 0054 ActionDataRole, 0055 ActionPluginIdRole 0056 }; 0057 0058 ActionSelectorDialogTreeItem(const QString &label, QTreeWidget *parent) 0059 : QTreeWidgetItem(parent) { 0060 setText(0, label); 0061 0062 } 0063 0064 ActionSelectorDialogTreeItem(const QString &label, QTreeWidgetItem *parent) 0065 : QTreeWidgetItem(parent) { 0066 setText(0, label); 0067 0068 } 0069 0070 using QTreeWidgetItem::data; 0071 QVariant data(ActionRole role) const 0072 { 0073 return QTreeWidgetItem::data(0, role); 0074 }; 0075 0076 using QTreeWidgetItem::setData; 0077 void setData(ActionRole role, const QVariant &value) { 0078 QTreeWidgetItem::setData(0, role, value); 0079 } 0080 0081 QIcon icon() const { 0082 return QTreeWidgetItem::icon(0); 0083 } 0084 0085 void setIcon(const QIcon& icon) { 0086 QTreeWidgetItem::setIcon(0, icon); 0087 } 0088 0089 }; 0090 0091 //--------------------------------------- 0092 0093 ActionsListViewBase::ActionsListViewBase(QWidget* parent) 0094 : QTreeWidget(parent) 0095 { 0096 setColumnCount(1); 0097 setHeaderHidden(true); 0098 setRootIsDecorated(false); 0099 } 0100 0101 ActionsListViewBase::~ActionsListViewBase() 0102 { 0103 } 0104 0105 QTreeWidgetItem *ActionsListViewBase::itemForAction(const QString& actionName, QTreeWidgetItem* parent) 0106 { 0107 Q_UNUSED(parent); 0108 QTreeWidgetItemIterator it(this); 0109 while (*it) { 0110 ActionSelectorDialogTreeItem* itm = dynamic_cast<ActionSelectorDialogTreeItem*>(*it); 0111 if (itm && itm->data(ActionSelectorDialogTreeItem::ActionDataRole).toString() == actionName) 0112 return itm; 0113 ++it; 0114 } 0115 0116 return 0; 0117 } 0118 0119 void ActionsListViewBase::selectAction(const QString& actionName) 0120 { 0121 //qDebug() << "Selecting action:" << actionName; 0122 QTreeWidgetItem *itm = itemForAction(actionName); 0123 if (itm) { 0124 setCurrentItem(itm); 0125 itm->setSelected(true); 0126 } 0127 } 0128 0129 //--------------------------------------- 0130 0131 KActionsListViewBase::KActionsListViewBase(QWidget* parent) 0132 : ActionsListViewBase(parent) 0133 { 0134 } 0135 0136 KActionsListViewBase::~KActionsListViewBase() {} 0137 0138 void KActionsListViewBase::init() 0139 { 0140 const QPixmap noIcon(KexiUtils::emptyIcon(KIconLoader::Small)); 0141 QList<QAction*> sharedActions(KexiMainWindowIface::global()->allActions()); 0142 const Kexi::ActionCategories *acat = Kexi::actionCategories(); 0143 foreach(QAction *action, sharedActions) { 0144 // qDebug() << (*it)->name() << " " << (*it)->text(); 0145 //! @todo group actions 0146 //! @todo: store QAction * here? 0147 const int actionCategories = acat->actionCategories(action->objectName().toLatin1()); 0148 if (actionCategories == -1) { 0149 qWarning() << "no category declared for action \"" 0150 << action->objectName() << "\"! Fix this!"; 0151 continue; 0152 } 0153 if (!isActionVisible(action->objectName().toLatin1(), actionCategories)) 0154 continue; 0155 QString actionName; 0156 if (!action->toolTip().isEmpty()) { 0157 actionName = action->toolTip().remove("<html>").remove("</html>"); 0158 } else { 0159 actionName = action->text().remove('&'); 0160 } 0161 ActionSelectorDialogTreeItem *pitem = new ActionSelectorDialogTreeItem( 0162 actionName, this); 0163 0164 pitem->setData(ActionSelectorDialogTreeItem::ActionCategoryRole, "kaction"); 0165 pitem->setData(ActionSelectorDialogTreeItem::ActionDataRole, action->objectName()); 0166 0167 pitem->setIcon(action->icon()); 0168 if (pitem->icon().isNull()) 0169 pitem->setIcon(noIcon); 0170 } 0171 setSortingEnabled(true); 0172 } 0173 0174 //--------------------------------------- 0175 0176 //! @internal Used to display KActions (in column 2) 0177 class KActionsListView : public KActionsListViewBase 0178 { 0179 Q_OBJECT 0180 public: 0181 explicit KActionsListView(QWidget* parent) 0182 : KActionsListViewBase(parent) { 0183 } 0184 virtual ~KActionsListView() {} 0185 0186 virtual bool isActionVisible(const char* actionName, int actionCategories) const override { 0187 Q_UNUSED(actionName); 0188 return actionCategories & Kexi::GlobalActionCategory; 0189 } 0190 }; 0191 0192 //! @internal Used to display KActions (in column 2) 0193 class CurrentFormActionsListView : public KActionsListViewBase 0194 { 0195 Q_OBJECT 0196 public: 0197 explicit CurrentFormActionsListView(QWidget* parent) 0198 : KActionsListViewBase(parent) { 0199 } 0200 virtual ~CurrentFormActionsListView() {} 0201 0202 virtual bool isActionVisible(const char* actionName, int actionCategories) const override { 0203 return actionCategories & Kexi::WindowActionCategory 0204 && Kexi::actionCategories()->actionSupportsObjectType(actionName, KexiPart::FormObjectType); 0205 } 0206 }; 0207 0208 //! @internal a list view displaying action categories user can select from (column 1) 0209 class ActionCategoriesListView : public ActionsListViewBase 0210 { 0211 Q_OBJECT 0212 public: 0213 explicit ActionCategoriesListView(QWidget* parent) 0214 : ActionsListViewBase(parent) { 0215 ActionSelectorDialogTreeItem *itm = new ActionSelectorDialogTreeItem(xi18n("No action"), this ); 0216 itm->setData(ActionSelectorDialogTreeItem::ActionCategoryRole, "noaction"); 0217 itm->setData(ActionSelectorDialogTreeItem::ActionDataRole, "noaction"); 0218 const QPixmap noIcon(KexiUtils::emptyIcon(KIconLoader::Small)); 0219 itm->setIcon(noIcon); 0220 0221 itm = new ActionSelectorDialogTreeItem(xi18n("Application actions"), this ); 0222 itm->setData(ActionSelectorDialogTreeItem::ActionCategoryRole, "kaction"); 0223 itm->setData(ActionSelectorDialogTreeItem::ActionDataRole, "kaction"); 0224 itm->setIcon(koIcon("kexi")); 0225 0226 KexiPart::PartInfoList *pl = Kexi::partManager().infoList(); 0227 if (pl) { 0228 foreach(KexiPart::Info *info, *pl) { 0229 KexiPart::Part *part = Kexi::partManager().part(info); 0230 if (!info->isVisibleInNavigator() || !part) 0231 continue; 0232 itm = new ActionSelectorDialogTreeItem(part->info()->name(), this ); 0233 itm->setData(ActionSelectorDialogTreeItem::ActionCategoryRole, "navObject"); 0234 itm->setData(ActionSelectorDialogTreeItem::ActionDataRole, info->typeName()); 0235 itm->setData(ActionSelectorDialogTreeItem::ActionPluginIdRole, info->pluginId()); 0236 itm->setIcon(QIcon::fromTheme(part->info()->iconName())); 0237 } 0238 } 0239 0240 QTreeWidgetItem *fitm = itemForAction("form"); 0241 if (fitm) { 0242 itm = new ActionSelectorDialogTreeItem(xi18nc("Current form's actions", "Current"), fitm); 0243 } else { 0244 itm = new ActionSelectorDialogTreeItem(xi18nc("Current form's actions", "Current"), this); 0245 } 0246 0247 itm->setData(ActionSelectorDialogTreeItem::ActionCategoryRole, "currentForm"); 0248 itm->setData(ActionSelectorDialogTreeItem::ActionDataRole, "currentForm"); 0249 itm->setIcon(KexiIcon("form")); 0250 0251 expandAll(); 0252 setSortingEnabled(false); 0253 } 0254 0255 ~ActionCategoriesListView() { 0256 } 0257 0258 }; 0259 0260 //! @internal Used to display list of actions available to executing (column 3) 0261 class ActionToExecuteListView : public ActionsListViewBase 0262 { 0263 Q_OBJECT 0264 public: 0265 explicit ActionToExecuteListView(QWidget* parent) 0266 : ActionsListViewBase(parent) { 0267 } 0268 0269 ~ActionToExecuteListView() { 0270 } 0271 0272 //! Updates actions 0273 void showActionsForPluginId(const QString& pluginId) { 0274 if (m_currentPluginId == pluginId) 0275 return; 0276 m_currentPluginId = pluginId; 0277 clear(); 0278 KexiPart::Part *part = Kexi::partManager().partForPluginId(m_currentPluginId); 0279 if (!part) 0280 return; 0281 Kexi::ViewModes supportedViewModes = part->info()->supportedViewModes(); 0282 ActionSelectorDialogTreeItem *itm; 0283 const QPixmap noIcon(KexiUtils::emptyIcon(KIconLoader::Small)); 0284 if (supportedViewModes & Kexi::DataViewMode) { 0285 itm = new ActionSelectorDialogTreeItem(xi18n("Open in Data View"), this); 0286 itm->setData(ActionSelectorDialogTreeItem::ActionDataRole , "open"); 0287 itm->setIcon(koIcon("document-open")); 0288 } 0289 if (part->info()->isExecuteSupported()) { 0290 itm = new ActionSelectorDialogTreeItem(xi18n("Execute"), this); 0291 itm->setData(ActionSelectorDialogTreeItem::ActionDataRole , "execute"); 0292 itm->setIcon(koIcon("media-playback-start")); 0293 } 0294 #ifdef KEXI_QUICK_PRINTING_SUPPORT 0295 if (part->info()->isPrintingSupported()) { 0296 itm = new ActionSelectorDialogTreeItem(futureI18n("Print"), this); 0297 itm->setData(ActionSelectorDialogTreeItem::ActionDataRole , "print"); 0298 itm->setIcon(koIcon("document-print")); 0299 QAction *a = KStandardAction::printPreview(0, 0, 0); 0300 itm = new ActionSelectorDialogTreeItem(a->text().remove('&').remove("..."), 0301 this); 0302 itm->setData(ActionSelectorDialogTreeItem::ActionDataRole , "printPreview"); 0303 itm->setIcon(a->icon()); 0304 delete a; 0305 itm = new ActionSelectorDialogTreeItem(futureI18n("Show Page Setup"), this); 0306 itm->setData(ActionSelectorDialogTreeItem::ActionDataRole , "pageSetup"); 0307 itm->setIcon(noIcon); 0308 setItemExpanded(itm, true); 0309 } 0310 #endif 0311 if (part->info()->isDataExportSupported()) { 0312 itm = new ActionSelectorDialogTreeItem( 0313 xi18nc("Note: use multiple rows if needed", "Export to File\nAs Data Table"), this); 0314 itm->setData(ActionSelectorDialogTreeItem::ActionDataRole , "exportToCSV"); 0315 itm->setIcon(KexiIcon("table")); 0316 0317 QTreeWidgetItem *eitem = itm; 0318 0319 itm = new ActionSelectorDialogTreeItem(xi18nc("Note: use multiple rows if needed", "Copy to Clipboard\nAs Data Table"), eitem); 0320 itm->setData(ActionSelectorDialogTreeItem::ActionDataRole , "copyToClipboardAsCSV"); 0321 itm->setIcon(KexiIcon("table")); 0322 } 0323 0324 itm = new ActionSelectorDialogTreeItem(xi18n("Create New Object (%1)", part->info()->name().toLower()), this); 0325 itm->setData(ActionSelectorDialogTreeItem::ActionDataRole , "new"); 0326 itm->setIcon(koIcon("document-new")); 0327 0328 if (supportedViewModes & Kexi::DesignViewMode) { 0329 itm = new ActionSelectorDialogTreeItem(xi18n("Open in Design View"), this); 0330 itm->setData(ActionSelectorDialogTreeItem::ActionDataRole , "design"); 0331 itm->setIcon(koIcon("document-properties")); 0332 } 0333 if (supportedViewModes & Kexi::TextViewMode) { 0334 itm = new ActionSelectorDialogTreeItem(xi18n("Open in Text View"), this); 0335 itm->setData(ActionSelectorDialogTreeItem::ActionDataRole , "editText"); 0336 itm->setIcon(noIcon); 0337 } 0338 0339 itm = new ActionSelectorDialogTreeItem( xi18n("Close View"), this); 0340 itm->setData(ActionSelectorDialogTreeItem::ActionDataRole , "close"); 0341 itm->setIcon(koIcon("window-close")); 0342 0343 expandAll(); 0344 setSortingEnabled(true); 0345 } 0346 0347 QString m_currentPluginId; 0348 }; 0349 0350 //------------------------------------- 0351 0352 //! @internal 0353 class Q_DECL_HIDDEN KexiActionSelectionDialog::Private 0354 { 0355 public: 0356 Private() 0357 : kactionPageWidget(0), kactionListView(0), objectsListView(0) 0358 , currentFormActionsPageWidget(0) 0359 , currentFormActionsListView(0) 0360 , secondAnd3rdColumnMainWidget(0) 0361 , hideActionToExecuteListView(false) { 0362 } 0363 0364 void raiseWidget(QWidget *w) { 0365 secondAnd3rdColumnStack->setCurrentWidget(w); 0366 } 0367 0368 QString selectActionToBeExecutedMessage(const QString& actionType) const { 0369 if (actionType == "noaction") 0370 return QString(); 0371 if (actionType == "kaction" || actionType == "currentForm") 0372 return xi18n("&Select action to be executed after clicking <resource>%1</resource> button:", 0373 actionWidgetName); 0374 // hardcoded, but it's not that bad 0375 if (actionType == "org.kexi-project.macro") 0376 return xi18n("&Select macro to be executed after clicking <resource>%1</resource> button:", 0377 actionWidgetName); 0378 if (actionType == "org.kexi-project.script") 0379 return xi18n("&Select script to be executed after clicking <resource>%1</resource> button:", 0380 actionWidgetName); 0381 //default: org.kexi-project.table/query/form/report... 0382 return xi18n("&Select object to be opened after clicking <resource>%1</resource> button:", 0383 actionWidgetName); 0384 } 0385 0386 // changes 3rd column visibility 0387 void setActionToExecuteSectionVisible(bool visible) { 0388 actionToExecuteListView->setVisible(visible); 0389 actionToExecuteLbl->setVisible(visible); 0390 } 0391 0392 QString actionWidgetName; 0393 ActionCategoriesListView* actionCategoriesListView; //!< for column #1 0394 QWidget *kactionPageWidget; 0395 KActionsListView* kactionListView; //!< for column #2 0396 KexiProjectNavigator* objectsListView; //!< for column #2 0397 QWidget *currentFormActionsPageWidget; //!< for column #2 0398 CurrentFormActionsListView* currentFormActionsListView; //!< for column #2 0399 QWidget *emptyWidget; 0400 QLabel *selectActionToBeExecutedLabel; 0401 QLabel *kactionPageLabel; 0402 QLabel *currentFormActionsPageLabel; 0403 ActionToExecuteListView* actionToExecuteListView; 0404 QLabel *actionToExecuteLbl; 0405 QWidget *secondAnd3rdColumnMainWidget; 0406 QGridLayout *glyr; 0407 QGridLayout *secondAnd3rdColumnGrLyr; 0408 QStackedWidget *secondAnd3rdColumnStack; //, *secondColumnStack; 0409 bool hideActionToExecuteListView; 0410 QDialogButtonBox *buttonBox; 0411 }; 0412 0413 //------------------------------------- 0414 0415 static QLabel *createSelectActionLabel(QWidget *parent, QWidget *buddy) 0416 { 0417 QLabel *lbl = new QLabel(parent); 0418 lbl->setBuddy(buddy); 0419 lbl->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); 0420 lbl->setAlignment(Qt::AlignTop | Qt::AlignLeft); 0421 lbl->setWordWrap(true); 0422 lbl->setMinimumHeight(lbl->fontMetrics().height()*2); 0423 return lbl; 0424 } 0425 0426 //------------------------------------- 0427 0428 KexiActionSelectionDialog::KexiActionSelectionDialog( 0429 QWidget *parent, const KexiFormEventAction::ActionData& action, 0430 const QString& actionWidgetName) 0431 : QDialog(parent) 0432 , d(new Private()) 0433 { 0434 setModal(true); 0435 setObjectName("actionSelectorDialog"); 0436 setWindowTitle(xi18nc("@title:window", "Assigning Action to Button")); 0437 0438 // layout 0439 QVBoxLayout *mainLayout = new QVBoxLayout; 0440 setLayout(mainLayout); 0441 QWidget *mainWidget = new QWidget(this); 0442 mainWidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); 0443 mainLayout->addWidget(mainWidget); 0444 0445 /* lbl 1 0446 +------------+ +-------------------------------+ 0447 | | | [a] | 0448 | 1st column | | +----------- + +------------+ | 0449 | | | | 2nd column | | 3rd column | | 0450 | | | + + + + | 0451 | | | +------------+ +------------+ | 0452 +------------+ +-------------------------------+ 0453 \______________________________________________/ 0454 glyr 0455 [a]- QStackedWidget *secondAnd3rdColumnStack, 0456 - for displaying KActions, the stack contains d->kactionPageWidget QWidget 0457 - for displaying objects, the stack contains secondAnd3rdColumnMainWidget QWidget and 0458 QGridLayout *secondAnd3rdColumnGrLyr 0459 - kactionPageWidget contains only a QVBoxLayout and label+kactionListView 0460 */ 0461 d->glyr = new QGridLayout(mainWidget); // 2x2 0462 KexiUtils::setStandardMarginsAndSpacing(d->glyr); 0463 d->glyr->setRowStretch(1, 1); 0464 0465 // 1st column: action types 0466 d->actionCategoriesListView = new ActionCategoriesListView(mainWidget); 0467 d->actionCategoriesListView->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum); 0468 d->glyr->addWidget(d->actionCategoriesListView, 1, 0); 0469 connect(d->actionCategoriesListView, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), 0470 this, SLOT(slotActionCategorySelected(QTreeWidgetItem*))); 0471 0472 QLabel *lbl = new QLabel(xi18n("Action category:"), mainWidget); 0473 lbl->setBuddy(d->actionCategoriesListView); 0474 lbl->setMinimumHeight(lbl->fontMetrics().height()*2); 0475 lbl->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); 0476 lbl->setAlignment(Qt::AlignTop | Qt::AlignLeft); 0477 lbl->setWordWrap(true); 0478 0479 d->glyr->addWidget(lbl, 0, 0, Qt::AlignTop | Qt::AlignLeft); 0480 0481 // widget stack for 2nd and 3rd column 0482 d->secondAnd3rdColumnStack = new QStackedWidget(mainWidget); 0483 d->secondAnd3rdColumnStack->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); 0484 d->glyr->addWidget(d->secondAnd3rdColumnStack, 0, 1, 2, 1); 0485 0486 d->secondAnd3rdColumnMainWidget = new QWidget(d->secondAnd3rdColumnStack); 0487 d->secondAnd3rdColumnMainWidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); 0488 d->secondAnd3rdColumnGrLyr = new QGridLayout(d->secondAnd3rdColumnMainWidget); 0489 //! @todo KEXI3 QDialog::resizeLayout(d->secondAnd3rdColumnGrLyr, 0, KexiUtils::spacingHint()); 0490 d->secondAnd3rdColumnGrLyr->setRowStretch(1, 2); 0491 d->secondAnd3rdColumnStack->addWidget(d->secondAnd3rdColumnMainWidget); 0492 0493 // 2nd column: list of actions/objects 0494 d->objectsListView = new KexiProjectNavigator(d->secondAnd3rdColumnMainWidget, 0495 KexiProjectNavigator::Borders); 0496 d->secondAnd3rdColumnGrLyr->addWidget(d->objectsListView, 1, 0); 0497 d->secondAnd3rdColumnGrLyr->setColumnStretch(0,1); 0498 d->secondAnd3rdColumnGrLyr->setColumnStretch(1,1); 0499 connect(d->objectsListView, SIGNAL(selectionChanged(KexiPart::Item*)), 0500 this, SLOT(slotItemForOpeningOrExecutingSelected(KexiPart::Item*))); 0501 0502 d->selectActionToBeExecutedLabel = createSelectActionLabel(d->secondAnd3rdColumnMainWidget, 0); 0503 d->secondAnd3rdColumnGrLyr->addWidget( 0504 d->selectActionToBeExecutedLabel, 0, 0, Qt::AlignTop | Qt::AlignLeft); 0505 0506 d->emptyWidget = new QWidget(d->secondAnd3rdColumnStack); 0507 d->secondAnd3rdColumnStack->addWidget(d->emptyWidget); 0508 0509 // 3rd column: actions to execute 0510 d->actionToExecuteListView = new ActionToExecuteListView(d->secondAnd3rdColumnMainWidget); 0511 d->actionToExecuteListView->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum); 0512 0513 connect(d->actionToExecuteListView, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), 0514 this, SLOT(slotActionToExecuteItemExecuted(QTreeWidgetItem*))); 0515 connect(d->actionToExecuteListView, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), 0516 this, SLOT(slotActionToExecuteItemSelected(QTreeWidgetItem*))); 0517 0518 d->secondAnd3rdColumnGrLyr->addWidget(d->actionToExecuteListView, 1, 1); 0519 0520 d->actionToExecuteLbl = createSelectActionLabel(d->secondAnd3rdColumnMainWidget, 0521 d->actionToExecuteListView); 0522 d->actionToExecuteLbl->setText(xi18n("Action to execute:")); 0523 d->secondAnd3rdColumnGrLyr->addWidget(d->actionToExecuteLbl, 0, 1, Qt::AlignTop | Qt::AlignLeft); 0524 0525 // buttons 0526 d->buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel); 0527 QPushButton *okButton = d->buttonBox->button(QDialogButtonBox::Ok); 0528 okButton->setDefault(true); 0529 okButton->setShortcut(Qt::CTRL | Qt::Key_Return); 0530 connect(d->buttonBox, SIGNAL(accepted()), this, SLOT(accept())); 0531 connect(d->buttonBox, SIGNAL(rejected()), this, SLOT(reject())); 0532 d->actionWidgetName = actionWidgetName; 0533 d->buttonBox->button(QDialogButtonBox::Ok)->setText(xi18nc("Assign action", "&Assign")); 0534 //buttonBox->button(QDialogButtonBox::Ok)->setIcon(koIconName("dialog-ok")); 0535 d->buttonBox->button(QDialogButtonBox::Ok)->setToolTip(xi18n("Assign action")); 0536 mainLayout->addWidget(d->buttonBox); 0537 0538 // temporary show all sections to avoid resizing the dialog in the future 0539 d->actionCategoriesListView->selectAction("table"); 0540 d->setActionToExecuteSectionVisible(true); 0541 adjustSize(); 0542 resize(qMax(700, width()), qMax(450, height())); 0543 0544 bool ok; 0545 QString actionType, actionArg; 0546 KexiPart::Info* partInfo = action.decodeString(actionType, actionArg, &ok); 0547 if (ok) { 0548 d->actionCategoriesListView->selectAction(actionType); 0549 if (actionType == "kaction") { 0550 d->kactionListView->selectAction(actionArg); 0551 d->kactionListView->setFocus(); 0552 } else if (actionType == "currentForm") { 0553 d->currentFormActionsListView->selectAction(actionArg); 0554 d->currentFormActionsListView->setFocus(); 0555 } else if (partInfo 0556 && Kexi::partManager().part(partInfo)) // We use the Part Manager 0557 // to determine whether the Kexi-plugin is installed and whether we like to show 0558 // it in our list of actions. 0559 { 0560 KexiPart::Item *item = KexiMainWindowIface::global()->project()->item( 0561 partInfo, actionArg); 0562 if (d->objectsListView && item) { 0563 d->objectsListView->selectItem(*item); 0564 slotItemForOpeningOrExecutingSelected(item); 0565 0566 QString actionOption(action.option); 0567 if (actionOption.isEmpty()) { 0568 actionOption = "open"; // for backward compatibility 0569 } 0570 d->actionToExecuteListView->selectAction(actionOption); 0571 d->objectsListView->setFocus(); 0572 } 0573 } 0574 } else {//invalid assignment or 'noaction' 0575 d->actionCategoriesListView->selectAction("noaction"); 0576 d->actionCategoriesListView->setFocus(); 0577 } 0578 } 0579 0580 KexiActionSelectionDialog::~KexiActionSelectionDialog() 0581 { 0582 delete d; 0583 } 0584 0585 void KexiActionSelectionDialog::slotKActionItemExecuted(QTreeWidgetItem*) 0586 { 0587 accept(); 0588 } 0589 0590 void KexiActionSelectionDialog::slotKActionItemSelected(QTreeWidgetItem*) 0591 { 0592 d->setActionToExecuteSectionVisible(false); 0593 updateOKButtonStatus(); 0594 } 0595 0596 void KexiActionSelectionDialog::slotCurrentFormActionItemExecuted(QTreeWidgetItem*) 0597 { 0598 accept(); 0599 } 0600 0601 void KexiActionSelectionDialog::slotCurrentFormActionItemSelected(QTreeWidgetItem*) 0602 { 0603 d->setActionToExecuteSectionVisible(false); 0604 updateOKButtonStatus(); 0605 } 0606 0607 void KexiActionSelectionDialog::slotItemForOpeningOrExecutingSelected(KexiPart::Item* item) 0608 { 0609 d->setActionToExecuteSectionVisible(item); 0610 } 0611 0612 void KexiActionSelectionDialog::slotActionToExecuteItemExecuted(QTreeWidgetItem* item) 0613 { 0614 if (!item) 0615 return; 0616 ActionSelectorDialogTreeItem *listItem = dynamic_cast<ActionSelectorDialogTreeItem*>(item); 0617 if (listItem && listItem->data(ActionSelectorDialogTreeItem::ActionDataRole).isValid()) 0618 accept(); 0619 } 0620 0621 void KexiActionSelectionDialog::slotActionToExecuteItemSelected(QTreeWidgetItem*) 0622 { 0623 updateOKButtonStatus(); 0624 } 0625 0626 void KexiActionSelectionDialog::slotActionCategorySelected(QTreeWidgetItem* item) 0627 { 0628 ActionSelectorDialogTreeItem *categoryItm = dynamic_cast<ActionSelectorDialogTreeItem*>(item); 0629 // simple case: part-less item, e.g. kaction: 0630 if (categoryItm) { 0631 if (categoryItm->data(ActionSelectorDialogTreeItem::ActionCategoryRole).toString() == "kaction") { 0632 if (!d->kactionPageWidget) { 0633 //create lbl+list view with a vlayout 0634 d->kactionPageWidget = new QWidget(); 0635 d->kactionPageWidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); 0636 QVBoxLayout *vlyr = new QVBoxLayout(d->kactionPageWidget); 0637 vlyr->setSpacing(KexiUtils::spacingHint()); 0638 d->kactionListView = new KActionsListView(d->kactionPageWidget); 0639 d->kactionListView->init(); 0640 d->kactionPageLabel = createSelectActionLabel(d->kactionPageWidget, d->kactionListView); 0641 vlyr->addWidget(d->kactionPageLabel); 0642 vlyr->addWidget(d->kactionListView); 0643 KexiUtils::setMargins(vlyr, 0); 0644 d->secondAnd3rdColumnStack->addWidget(d->kactionPageWidget); 0645 connect(d->kactionListView, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), 0646 this, SLOT(slotKActionItemExecuted(QTreeWidgetItem*))); 0647 connect(d->kactionListView, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), 0648 this, SLOT(slotKActionItemSelected(QTreeWidgetItem*))); 0649 } 0650 d->kactionPageLabel->setText( 0651 d->selectActionToBeExecutedMessage(categoryItm->data(ActionSelectorDialogTreeItem::ActionDataRole).toString())); 0652 d->setActionToExecuteSectionVisible(false); 0653 d->raiseWidget(d->kactionPageWidget); 0654 slotKActionItemSelected(d->kactionListView->currentItem()); //to refresh column #3 0655 } else if (categoryItm->data(ActionSelectorDialogTreeItem::ActionCategoryRole).toString() == "currentForm") { 0656 if (!d->currentFormActionsPageWidget) { 0657 //create lbl+list view with a vlayout 0658 d->currentFormActionsPageWidget = new QWidget(); 0659 d->currentFormActionsPageWidget->setSizePolicy( 0660 QSizePolicy::Minimum, QSizePolicy::Minimum); 0661 QVBoxLayout *vlyr = new QVBoxLayout(d->currentFormActionsPageWidget); 0662 vlyr->setSpacing(KexiUtils::spacingHint()); 0663 d->currentFormActionsListView = new CurrentFormActionsListView( 0664 d->currentFormActionsPageWidget); 0665 d->currentFormActionsListView->init(); 0666 d->currentFormActionsPageLabel = createSelectActionLabel( 0667 d->currentFormActionsPageWidget, d->currentFormActionsListView); 0668 vlyr->addWidget(d->currentFormActionsPageLabel); 0669 vlyr->addWidget(d->currentFormActionsListView); 0670 d->secondAnd3rdColumnStack->addWidget(d->currentFormActionsPageWidget); 0671 KexiUtils::setMargins(vlyr, 0); 0672 connect(d->currentFormActionsListView, SIGNAL(itemActivated(QTreeWidgetItem*,int)), 0673 this, SLOT(slotCurrentFormActionItemExecuted(QTreeWidgetItem*))); 0674 connect(d->currentFormActionsListView, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), 0675 this, SLOT(slotCurrentFormActionItemSelected(QTreeWidgetItem*))); 0676 } 0677 d->currentFormActionsPageLabel->setText( 0678 d->selectActionToBeExecutedMessage(categoryItm->data(ActionSelectorDialogTreeItem::ActionDataRole).toString())); 0679 d->setActionToExecuteSectionVisible(false); 0680 d->raiseWidget(d->currentFormActionsPageWidget); 0681 slotCurrentFormActionItemSelected(d->currentFormActionsListView->currentItem()); //to refresh column #3 0682 } else if (categoryItm->data(ActionSelectorDialogTreeItem::ActionCategoryRole).toString() == "noaction") { 0683 d->raiseWidget(d->emptyWidget); 0684 d->objectsListView->clearSelection(); 0685 //hide column #3 0686 d->setActionToExecuteSectionVisible(false); 0687 } else if (categoryItm->data(ActionSelectorDialogTreeItem::ActionCategoryRole).toString() == "navObject") { 0688 QString pluginId = categoryItm->data(ActionSelectorDialogTreeItem::ActionPluginIdRole).toString(); 0689 d->selectActionToBeExecutedLabel->setText(d->selectActionToBeExecutedMessage(pluginId)); 0690 if (d->objectsListView->itemsPluginId() != pluginId) { 0691 QString errorString; 0692 d->objectsListView->setProject(KexiMainWindowIface::global()->project(), pluginId, &errorString, false); 0693 d->actionToExecuteListView->showActionsForPluginId(pluginId); 0694 d->setActionToExecuteSectionVisible(false); 0695 } 0696 if (d->secondAnd3rdColumnStack->currentWidget() != d->secondAnd3rdColumnMainWidget) { 0697 d->raiseWidget(d->secondAnd3rdColumnMainWidget); 0698 d->objectsListView->clearSelection(); 0699 d->setActionToExecuteSectionVisible(false); 0700 } else { 0701 d->raiseWidget(d->secondAnd3rdColumnMainWidget); 0702 } 0703 d->selectActionToBeExecutedLabel->setBuddy(d->secondAnd3rdColumnMainWidget); 0704 } 0705 0706 d->actionCategoriesListView->update(); 0707 updateOKButtonStatus(); 0708 return; 0709 } 0710 d->actionCategoriesListView->update(); 0711 d->actionToExecuteListView->update(); 0712 updateOKButtonStatus(); 0713 } 0714 0715 KexiFormEventAction::ActionData KexiActionSelectionDialog::currentAction() const 0716 { 0717 KexiFormEventAction::ActionData data; 0718 ActionSelectorDialogTreeItem *categoryItm = dynamic_cast<ActionSelectorDialogTreeItem*>(d->actionCategoriesListView->currentItem()); 0719 0720 if (categoryItm) { 0721 const QString actionCategory = categoryItm->data(ActionSelectorDialogTreeItem::ActionCategoryRole).toString(); 0722 0723 if (actionCategory == "kaction") { 0724 const ActionSelectorDialogTreeItem* actionToExecute = dynamic_cast<ActionSelectorDialogTreeItem*>( 0725 d->kactionListView->currentItem()); 0726 if (actionToExecute) { 0727 data.string = QString("kaction:") 0728 + actionToExecute->data(ActionSelectorDialogTreeItem::ActionDataRole).toString(); 0729 return data; 0730 } 0731 } else if (actionCategory == "currentForm") { 0732 const ActionSelectorDialogTreeItem *actionToExecute = dynamic_cast<ActionSelectorDialogTreeItem*>( 0733 d->currentFormActionsListView->currentItem()); 0734 if (actionToExecute) { 0735 data.string = QString("currentForm:") 0736 + actionToExecute->data(ActionSelectorDialogTreeItem::ActionDataRole).toString(); 0737 return data; 0738 } 0739 } else if (actionCategory == "noaction") { 0740 return data; 0741 } else if (actionCategory == "navObject") { 0742 const ActionSelectorDialogTreeItem *actionToExecute = dynamic_cast<ActionSelectorDialogTreeItem*>( 0743 d->actionToExecuteListView->currentItem()); 0744 if (d->objectsListView && actionToExecute && !actionToExecute->data(ActionSelectorDialogTreeItem::ActionDataRole).toString().isEmpty()) { 0745 KexiPart::Item* partItem = d->objectsListView->selectedPartItem(); 0746 KexiPart::Info* partInfo = partItem ? Kexi::partManager().infoForPluginId(partItem->pluginId()) : 0; 0747 if (partInfo) { 0748 // opening or executing: table:name, query:name, form:name, macro:name, script:name, etc. 0749 data.string = QString("%1:%2").arg(partInfo->typeName()).arg(partItem->name()); 0750 data.option = actionToExecute->data(ActionSelectorDialogTreeItem::ActionDataRole).toString(); 0751 return data; 0752 } 0753 } 0754 } else { 0755 qWarning() << "No current category item"; 0756 } 0757 } 0758 0759 return data; // No Action 0760 } 0761 0762 void KexiActionSelectionDialog::updateOKButtonStatus() 0763 { 0764 ActionSelectorDialogTreeItem *itm = dynamic_cast<ActionSelectorDialogTreeItem*>(d->actionCategoriesListView->currentItem()); 0765 0766 //qDebug() << "Current Action:" << currentAction().string << ":" << currentAction().option; 0767 QPushButton *btn = d->buttonBox->button(QDialogButtonBox::Ok); 0768 btn->setEnabled((itm && itm->data(ActionSelectorDialogTreeItem::ActionCategoryRole).toString() == "noaction") || !currentAction().isEmpty()); 0769 } 0770 0771 #include "kexiactionselectiondialog.moc"