kdelibs/kross/ui/view.cpp
Ivailo Monev 82fc15f54b generic: use CMake moc instead of automoc4 by default
for compatibilty reasons automoc4 support is not removed but it
shall be in the future. automoc4 has not been maintained for a
while (last commit is from 2011) and the stable release is from
2009.

CMake version >= 2.8.6 provides the functionality for mocking so
I see no reason to not make use of it.
2015-02-27 07:40:26 +00:00

561 lines
19 KiB
C++

/***************************************************************************
* view.cpp
* This file is part of the KDE project
* copyright (c) 2005-2006 Cyrille Berger <cberger@cberger.net>
* copyright (C) 2006-2007 Sebastian Sauer <mail@dipe.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
* You should have received a copy of the GNU Library General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
***************************************************************************/
#include "view.h"
#include "model.h"
#include <kross/core/manager.h>
#include <kross/core/action.h>
#include <kross/core/actioncollection.h>
#include <kross/core/interpreter.h>
#include <QtCore/QFileInfo>
#include <QtCore/QDir>
#include <QtGui/QBoxLayout>
#include <QtGui/QHeaderView>
#include <QtGui/QTreeView>
#include <QtGui/QLabel>
#include <kapplication.h>
//#include <kdeversion.h>
#include <kconfig.h>
#include <kstandarddirs.h>
#include <kmessagebox.h>
#include <kpushbutton.h>
#include <kfiledialog.h>
#include <kmenu.h>
#include <kpagedialog.h>
#include <kaction.h>
#include <kactioncollection.h>
#include <kcombobox.h>
#include <kicondialog.h>
#include <klocale.h>
#include <klineedit.h>
#include <kurlrequester.h>
//#include <ktar.h>
//#include <kio/netaccess.h>
using namespace Kross;
/*********************************************************************************
* ActionCollectionEditor
*/
namespace Kross {
/// \internal d-pointer class.
class ActionCollectionEditor::Private
{
public:
enum Type { ActionType, CollectionType };
const Type type;
union {
Action* action;
ActionCollection* collection;
};
QString name() const {
return type == ActionType ? action->name() : collection->name();
}
QString text() const {
return type == ActionType ? action->text() : collection->text();
}
QString description() const {
return type == ActionType ? action->description() : collection->description();
}
QString iconName() const {
return type == ActionType ? action->iconName() : collection->iconName();
}
bool isEnabled() const {
return type == ActionType ? action->isEnabled() : collection->isEnabled();
}
KLineEdit* nameedit;
KLineEdit* textedit;
KLineEdit* commentedit;
KLineEdit* iconedit;
KComboBox* interpreteredit;
KUrlRequester* fileedit;
//QCheckBox* enabledcheckbox;
explicit Private(Action* a) : type(ActionType), action(a) { Q_ASSERT(a); }
explicit Private(ActionCollection* c) : type(CollectionType), collection(c) { Q_ASSERT(c); }
};
}
ActionCollectionEditor::ActionCollectionEditor(Action* action, QWidget* parent)
: QWidget(parent), d(new Private(action))
{
initGui();
}
ActionCollectionEditor::ActionCollectionEditor(ActionCollection* collection, QWidget* parent)
: QWidget(parent), d(new Private(collection))
{
initGui();
}
ActionCollectionEditor::~ActionCollectionEditor()
{
delete d;
}
Action* ActionCollectionEditor::action() const
{
return d->type == Private::ActionType ? d->action : 0;
}
ActionCollection* ActionCollectionEditor::collection() const
{
return d->type == Private::CollectionType ? d->collection : 0;
}
QLineEdit* ActionCollectionEditor::nameEdit() const { return d->nameedit; }
QLineEdit* ActionCollectionEditor::textEdit() const { return d->textedit; }
QLineEdit* ActionCollectionEditor::commentEdit() const { return d->commentedit; }
QLineEdit* ActionCollectionEditor::iconEdit() const { return d->iconedit; }
QComboBox* ActionCollectionEditor::interpreterEdit() const { return d->interpreteredit; }
KUrlRequester* ActionCollectionEditor::fileEdit() const { return d->fileedit; }
void ActionCollectionEditor::initGui()
{
QVBoxLayout* mainlayout = new QVBoxLayout();
setLayout(mainlayout);
QWidget* w = new QWidget(this);
mainlayout->addWidget(w);
QGridLayout* gridlayout = new QGridLayout();
gridlayout->setMargin(0);
//gridlayout->setSpacing(0);
w->setLayout(gridlayout);
QLabel* namelabel = new QLabel(i18n("Name:"), w);
gridlayout->addWidget(namelabel, 0, 0);
d->nameedit = new KLineEdit(w);
namelabel->setBuddy(d->nameedit);
d->nameedit->setText( d->name() );
d->nameedit->setEnabled(false);
gridlayout->addWidget(d->nameedit, 0, 1);
QLabel* textlabel = new QLabel(i18n("Text:"), w);
gridlayout->addWidget(textlabel, 1, 0);
d->textedit = new KLineEdit(w);
textlabel->setBuddy(d->textedit);
d->textedit->setText( d->text() );
gridlayout->addWidget(d->textedit, 1, 1);
QLabel* commentlabel = new QLabel(i18n("Comment:"), w);
gridlayout->addWidget(commentlabel, 2, 0);
d->commentedit = new KLineEdit(w);
commentlabel->setBuddy(d->commentedit);
d->commentedit->setText( d->description() );
gridlayout->addWidget(d->commentedit, 2, 1);
QLabel* iconlabel = new QLabel(i18n("Icon:"), w);
gridlayout->addWidget(iconlabel, 3, 0);
QWidget* iconbox = new QWidget(w);
QHBoxLayout* iconlayout = new QHBoxLayout();
iconlayout->setMargin(0);
iconbox->setLayout(iconlayout);
d->iconedit = new KLineEdit(iconbox);
iconlabel->setBuddy(d->iconedit);
d->iconedit->setText( d->iconName() );
iconlayout->addWidget(d->iconedit, 1);
KIconButton* iconbutton = new KIconButton(iconbox);
iconbutton->setIcon( d->iconName() );
connect(iconbutton, SIGNAL(iconChanged(QString)), d->iconedit, SLOT(setText(QString)));
iconlayout->addWidget(iconbutton);
gridlayout->addWidget(iconbox, 3, 1);
//QFrame* hr1 = new QFrame(w);
//hr1->setFrameStyle(QFrame::HLine | QFrame::Sunken);
//gridlayout->addWidget(hr1, 4, 0, -1, -1, Qt::AlignVCenter);
if( d->type == Private::ActionType ) {
QLabel* interpreterlabel = new QLabel(i18n("Interpreter:"), w);
gridlayout->addWidget(interpreterlabel, 4, 0);
d->interpreteredit = new KComboBox(w);
interpreterlabel->setBuddy(d->interpreteredit);
d->interpreteredit->setMaxVisibleItems(10);
d->interpreteredit->insertItems(0, Manager::self().interpreters());
d->interpreteredit->setEditable(true);
//c->lineEdit()->setText( d->action->interpreter() );
int idx = Manager::self().interpreters().indexOf( d->action->interpreter() );
if( idx >= 0 )
d->interpreteredit->setCurrentIndex(idx);
else
d->interpreteredit->setEditText( d->action->interpreter() );
gridlayout->addWidget(d->interpreteredit, 4, 1);
QLabel* filelabel = new QLabel(i18n("File:"), w);
gridlayout->addWidget(filelabel, 5, 0);
d->fileedit = new KUrlRequester(w);
filelabel->setBuddy(d->fileedit);
QStringList mimetypes;
foreach(const QString &interpretername, Manager::self().interpreters()) {
InterpreterInfo* info = Manager::self().interpreterInfo(interpretername);
Q_ASSERT( info );
mimetypes.append( info->mimeTypes().join(" ").trimmed() );
}
//InterpreterInfo* info = Manager::self().interpreterInfo( Manager::self().interpreternameForFile( d->action->file() ) );
//const QString defaultmime = info ? info->mimeTypes().join(" ").trimmed() : QString();
d->fileedit->fileDialog()->setMimeFilter(mimetypes /*, defaultmime*/);
d->fileedit->setMode( KFile::File | KFile::ExistingOnly | KFile::LocalOnly );
d->fileedit->setUrl(KUrl(d->action->file()) );
gridlayout->addWidget(d->fileedit, 5, 1);
}
else {
d->interpreteredit = 0;
d->fileedit = 0;
}
//d->enabledcheckbox = new QCheckBox(this);
//d->enabledcheckbox->setText( i18n("Enabled") );
//d->enabledcheckbox->setChecked( d->isEnabled() );
//mainlayout->addWidget(d->enabledcheckbox);
mainlayout->addStretch(1);
}
bool ActionCollectionEditor::isValid()
{
//TODO check also if such a name already exist.
return ! d->nameedit->text().isEmpty();
}
void ActionCollectionEditor::commit()
{
switch( d->type ) {
case Private::ActionType: {
d->action->setText( d->textedit->text() );
d->action->setDescription( d->commentedit->text() );
d->action->setIconName( d->iconedit->text() );
d->action->setInterpreter( d->interpreteredit->currentText() );
d->action->setFile( d->fileedit->url().path() );
//d->action->setEnabled( d->enabledcheckbox->isChecked() );
} break;
case Private::CollectionType: {
d->collection->setText( d->textedit->text() );
d->collection->setDescription( d->commentedit->text() );
d->collection->setIconName( d->iconedit->text() );
//d->collection->setEnabled( d->enabledcheckbox->isChecked() );
} break;
default: break;
}
}
/*********************************************************************************
* ActionCollectionView
*/
namespace Kross {
/// \internal d-pointer class.
class ActionCollectionView::Private
{
public:
bool modified;
KActionCollection* collection;
QMap< QString, KPushButton* > buttons;
explicit Private() : modified(false) {}
};
}
ActionCollectionView::ActionCollectionView(QWidget* parent)
: QTreeView(parent)
, d(new Private())
{
header()->hide();
setSelectionMode(QAbstractItemView::SingleSelection);
setAlternatingRowColors(true);
setRootIsDecorated(true);
setSortingEnabled(false);
setItemsExpandable(true);
//setDragEnabled(true);
//setAcceptDrops(true);
setDropIndicatorShown(true);
setDragDropMode(QAbstractItemView::InternalMove);
d->collection = new KActionCollection(this);
KAction* runaction = new KAction(KIcon("system-run"), i18n("Run"), this);
runaction->setObjectName("run");
runaction->setToolTip( i18n("Execute the selected script.") );
runaction->setEnabled(false);
d->collection->addAction("run", runaction);
connect(runaction, SIGNAL(triggered()), this, SLOT(slotRun()));
KAction* stopaction = new KAction(KIcon("process-stop"), i18n("Stop"), this);
stopaction->setObjectName("stop");
stopaction->setToolTip( i18n("Stop execution of the selected script.") );
stopaction->setEnabled(false);
d->collection->addAction("stop", stopaction);
connect(stopaction, SIGNAL(triggered()), this, SLOT(slotStop()));
KAction* editaction = new KAction(KIcon("document-properties"), i18n("Edit..."), this);
editaction->setObjectName("edit");
editaction->setToolTip( i18n("Edit selected script.") );
editaction->setEnabled(false);
d->collection->addAction("edit", editaction);
connect(editaction, SIGNAL(triggered()), this, SLOT(slotEdit()));
KAction* addaction = new KAction(KIcon("list-add"), i18n("Add..."), this);
addaction->setObjectName("add");
addaction->setToolTip( i18n("Add a new script.") );
//addaction->setEnabled(false);
d->collection->addAction("add", addaction);
connect(addaction, SIGNAL(triggered()), this, SLOT(slotAdd()) );
KAction* removeaction = new KAction(KIcon("list-remove"), i18n("Remove"), this);
removeaction->setObjectName("remove");
removeaction->setToolTip( i18n("Remove selected script.") );
removeaction->setEnabled(false);
d->collection->addAction("remove", removeaction);
connect(removeaction, SIGNAL(triggered()), this, SLOT(slotRemove()) );
connect(this, SIGNAL(enabledChanged(QString)), this, SLOT(slotEnabledChanged(QString)));
//expandAll();
}
ActionCollectionView::~ActionCollectionView()
{
delete d;
}
void ActionCollectionView::setModel(QAbstractItemModel* m)
{
QTreeView::setModel(m);
d->modified = false;
QItemSelectionModel* selectionmodel = new QItemSelectionModel(m, this);
setSelectionModel(selectionmodel);
connect(selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
this, SLOT(slotSelectionChanged()));
connect(m, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
this, SLOT(slotDataChanged(QModelIndex,QModelIndex)));
}
bool ActionCollectionView::isModified() const
{
return d->modified;
}
void ActionCollectionView::setModified(bool modified)
{
d->modified = modified;
}
KActionCollection* ActionCollectionView::actionCollection() const
{
return d->collection;
}
KPushButton* ActionCollectionView::button(const QString& actionname) const
{
return d->buttons.contains(actionname) ? d->buttons[actionname] : 0;
}
QItemSelection ActionCollectionView::itemSelection() const
{
QAbstractProxyModel* proxymodel = dynamic_cast< QAbstractProxyModel* >( model() );
QItemSelection selection = selectionModel()->selection();
return proxymodel ? proxymodel->mapSelectionToSource(selection) : selection;
}
KPushButton* ActionCollectionView::createButton(QWidget* parentWidget, const QString& actionname)
{
QAction* action = d->collection->action(actionname);
if( ! action ) return 0;
//if( d->buttons.contains(actionname) ) delete d->buttons[];
KPushButton* btn = new KPushButton(parentWidget);
btn->setText( action->text() );
btn->setToolTip( action->toolTip() );
btn->setIcon( KIcon(action->icon()) );
btn->setEnabled( action->isEnabled() );
if( parentWidget && parentWidget->layout() )
parentWidget->layout()->addWidget(btn);
QObject::connect(btn, SIGNAL(clicked()), action, SLOT(trigger()));
d->buttons.insert( actionname, btn );
return btn;
}
void ActionCollectionView::slotEnabledChanged(const QString& actionname)
{
if( d->buttons.contains( actionname ) ) {
QAction* action = d->collection->action( actionname );
d->buttons[ actionname ]->setEnabled( action ? action->isEnabled() : false );
}
}
void ActionCollectionView::slotSelectionChanged()
{
bool startenabled = selectionModel()->hasSelection();
bool stopenabled = false;
bool hasselection = selectionModel()->selectedIndexes().count() > 0;
foreach(const QModelIndex &index, itemSelection().indexes()) {
Action* action = ActionCollectionModel::action(index);
if( startenabled && ! action )
startenabled = false;
if( ! stopenabled )
stopenabled = (action && ! action->isFinalized());
}
QAction* runaction = d->collection->action("run");
if( runaction ) {
runaction->setEnabled(startenabled);
emit enabledChanged("run");
}
QAction* stopaction = d->collection->action("stop");
if( stopaction ) {
stopaction->setEnabled(stopenabled);
emit enabledChanged("stop");
}
QAction* editaction = d->collection->action("edit");
if( editaction ) {
editaction->setEnabled(hasselection);
emit enabledChanged("edit");
}
QAction* removeaction = d->collection->action("remove");
if( removeaction ) {
removeaction->setEnabled(hasselection);
emit enabledChanged("remove");
}
}
void ActionCollectionView::slotDataChanged(const QModelIndex&, const QModelIndex&)
{
d->modified = true;
}
void ActionCollectionView::slotRun()
{
if( ! selectionModel() ) return;
QAction* stopaction = d->collection->action("stop");
foreach(const QModelIndex &index, itemSelection().indexes()) {
if( ! index.isValid() )
continue;
if( stopaction ) {
stopaction->setEnabled(true);
emit enabledChanged("stop");
}
Action* action = ActionCollectionModel::action(index);
if( ! action )
continue;
connect(action, SIGNAL(finished(Kross::Action*)), SLOT(slotSelectionChanged()));
action->trigger();
}
slotSelectionChanged();
}
void ActionCollectionView::slotStop()
{
if( ! selectionModel() ) return;
foreach(const QModelIndex &index, itemSelection().indexes()) {
if( ! index.isValid() )
continue;
Action* action = ActionCollectionModel::action(index);
if( ! action )
continue;
//connect(action, SIGNAL(started(Kross::Action*)), SLOT(slotSelectionChanged()));
//connect(action, SIGNAL(finished(Kross::Action*)), SLOT(slotSelectionChanged()));
action->finalize();
}
slotSelectionChanged();
}
void ActionCollectionView::slotEdit()
{
if( ! selectionModel() ) return;
Action* action = 0;
ActionCollection* collection = 0;
foreach(const QModelIndex &index, itemSelection().indexes()) {
if( ! index.isValid() ) continue;
if( Action* a = ActionCollectionModel::action(index) )
action = a;
else if( ActionCollection* c = ActionCollectionModel::collection(index) )
collection = c;
else
continue;
break;
}
if( (! action) && (! collection) ) return;
KPageDialog* dialog = new KPageDialog( this );
dialog->setCaption( i18n("Edit") );
dialog->setButtons( KDialog::Ok | KDialog::Cancel );
//dialog->enableButtonOk( false );
dialog->setFaceType( KPageDialog::Plain ); //Auto Plain List Tree Tabbed
ActionCollectionEditor* editor =
action ? new ActionCollectionEditor(action, dialog->mainWidget())
: new ActionCollectionEditor(collection, dialog->mainWidget());
dialog->addPage(editor, i18nc("@title:group Script properties", "General"));
//dialog->addPage(new QWidget(this), i18n("Security"));
dialog->resize( QSize(580, 200).expandedTo( dialog->minimumSizeHint() ) );
int result = dialog->exec();
if( result == QDialog::Accepted /*&& dialog->result() == KDialog::Ok*/ ) {
editor->commit();
}
dialog->delayedDestruct();
}
void ActionCollectionView::slotAdd()
{
//TODO
KMessageBox::sorry(0, "TODO");
//ScriptManagerAddWizard wizard(this, collection);
//int result = wizard.exec();
#if 0
if( ! selectionModel() ) return;
ActionCollection* collection = 0;
foreach(QModelIndex index, itemSelection().indexes()) {
if( ! index.isValid() ) continue;
if( ActionCollectionModel::action(index) ) {
//TODO propably add the item right after the current selected one?
QModelIndex parent = index;
while( parent.isValid() && ! collection ) {
parent = d->view->model()->parent(parent);
collection = ActionCollectionModel::collection(parent);
}
if( collection ) break; // job done
}
else if( ActionCollection* c = ActionCollectionModel::collection(index) ) {
collection = c;
break; // job done
}
}
ScriptManagerAddWizard wizard(this, collection);
int result = wizard.exec();
Q_UNUSED(result);
#endif
}
void ActionCollectionView::slotRemove()
{
if( ! selectionModel() ) return;
KMessageBox::sorry(0, "TODO");
}
#include "moc_view.cpp"