00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "form.h"
00021
00022 #include <QtCore/QByteRef>
00023 #include <QtCore/QBuffer>
00024 #include <QtCore/QRegExp>
00025 #include <QtCore/QFile>
00026 #include <QtCore/QArgument>
00027 #include <QtCore/QMetaEnum>
00028 #include <QtGui/QKeyEvent>
00029 #include <QtGui/QDialog>
00030 #include <QtGui/QBoxLayout>
00031 #include <QtGui/QStackedLayout>
00032 #include <QtGui/QSizePolicy>
00033 #include <QtGui/QApplication>
00034 #include <QtGui/QProgressBar>
00035
00036 #include <QtGui/QTextBrowser>
00037 #include <QUiLoader>
00038 #include <QtDesigner/QFormBuilder>
00039 #include <QTextCursor>
00040 #include <QTextBlock>
00041
00042 #include <kdebug.h>
00043 #include <klocale.h>
00044 #include <kurl.h>
00045 #include <kpushbutton.h>
00046
00047
00048
00049 #include <kicon.h>
00050 #include <kaction.h>
00051 #include <kactioncollection.h>
00052 #include <kmessagebox.h>
00053 #include <kpluginloader.h>
00054 #include <kpluginfactory.h>
00055 #include <kparts/part.h>
00056
00057
00058
00059
00060 #include <kfilewidget.h>
00061 #include <kurlcombobox.h>
00062 #include <kshell.h>
00063 #include <widgets/ksqueezedtextlabel.h>
00064
00065 extern "C"
00066 {
00067 KDE_EXPORT QObject* krossmodule()
00068 {
00069 return new Kross::FormModule();
00070 }
00071 }
00072
00073 using namespace Kross;
00074
00075
00076
00077
00078
00079 namespace Kross {
00080
00082 class FormFileWidget::Private
00083 {
00084 public:
00085 KFileWidget* filewidget;
00086 };
00087
00088 }
00089
00090 FormFileWidget::FormFileWidget(QWidget* parent, const QString& startDirOrVariable)
00091 : QWidget(parent), d(new Private())
00092 {
00093 QVBoxLayout* layout = new QVBoxLayout(this);
00094 layout->setSpacing(0);
00095 layout->setMargin(0);
00096 setLayout(layout);
00097
00098 d->filewidget = new KFileWidget(KUrl(startDirOrVariable), this);
00099 layout->addWidget( d->filewidget );
00100
00101
00102
00103 QObject::connect(d->filewidget, SIGNAL(fileSelected(const QString&)), this, SIGNAL(fileSelected(const QString&)));
00104 QObject::connect(d->filewidget, SIGNAL(fileHighlighted(const QString&)), this, SIGNAL(fileHighlighted(const QString&)));
00105 QObject::connect(d->filewidget, SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged()));
00106 QObject::connect(d->filewidget, SIGNAL(filterChanged(const QString&)), this, SIGNAL(filterChanged(const QString&)));
00107
00108
00109
00110
00111
00112
00113
00114 if( parent && parent->layout() )
00115 parent->layout()->addWidget(this);
00116 setMinimumSize( QSize(480,360) );
00117 }
00118
00119 FormFileWidget::~FormFileWidget()
00120 {
00121 delete d;
00122 }
00123
00124 void FormFileWidget::setMode(const QString& mode)
00125 {
00126 QMetaEnum e = metaObject()->enumerator( metaObject()->indexOfEnumerator("Mode") );
00127 KFileWidget::OperationMode m = (KFileWidget::OperationMode) e.keysToValue( mode.toLatin1() );
00128 d->filewidget->setOperationMode(m);
00129 }
00130
00131 QString FormFileWidget::currentFilter() const
00132 {
00133 return d->filewidget->currentFilter();
00134 }
00135
00136 void FormFileWidget::setFilter(const QString &filter)
00137 {
00138 QString f = filter;
00139 f.replace(QRegExp("([^\\\\]{1,1})/"), "\\1\\/");
00140 d->filewidget->setFilter(f);
00141 }
00142
00143 QString FormFileWidget::currentMimeFilter() const
00144 {
00145 return d->filewidget->currentMimeFilter();
00146 }
00147
00148 void FormFileWidget::setMimeFilter(const QStringList& filter)
00149 {
00150 d->filewidget->setMimeFilter(filter);
00151 }
00152
00153 QString FormFileWidget::selectedFile() const
00154 {
00155 KUrl selectedUrl;
00156 QString locationText = d->filewidget->locationEdit()->currentText();
00157 if( locationText.contains( '/' ) ) {
00158 KUrl u( d->filewidget->baseUrl(), KShell::tildeExpand(locationText) );
00159 selectedUrl = u.isValid() ? u : selectedUrl = d->filewidget->baseUrl();
00160 }
00161 else {
00162 selectedUrl = d->filewidget->baseUrl();
00163 }
00164 QFileInfo fi( selectedUrl.path(), d->filewidget->locationEdit()->currentText() );
00165 return fi.absoluteFilePath();
00166 }
00167
00168
00169
00170
00171
00172 namespace Kross {
00174 class FormProgressDialog::Private
00175 {
00176 public:
00177 QTextBrowser* browser;
00178 QProgressBar* bar;
00179 bool gotCanceled;
00180 QTime time;
00181 void update() {
00182 if( time.elapsed() >= 1000 ) {
00183 time.restart();
00184 qApp->processEvents();
00185 }
00186 }
00187 };
00188 }
00189
00190 FormProgressDialog::FormProgressDialog(const QString& caption, const QString& labelText) : KPageDialog(), d(new Private)
00191 {
00192 d->gotCanceled = false;
00193 d->time.start();
00194
00195 setCaption(caption);
00196 KDialog::setButtons(KDialog::Ok|KDialog::Cancel);
00197 setFaceType(KPageDialog::Plain);
00198 enableButton(KDialog::Ok, false);
00199
00200 setModal(false);
00201 setMinimumWidth(540);
00202 setMinimumHeight(400);
00203
00204 QWidget* widget = new QWidget( mainWidget() );
00205 KPageWidgetItem* item = KPageDialog::addPage(widget, QString());
00206 item->setHeader(labelText);
00207
00208 widget = item->widget();
00209 QVBoxLayout* layout = new QVBoxLayout(widget);
00210 layout->setMargin(0);
00211 widget->setLayout(layout);
00212
00213 d->browser = new QTextBrowser(this);
00214 d->browser->setHtml(labelText);
00215 layout->addWidget(d->browser);
00216
00217 d->bar = new QProgressBar(this);
00218
00219 d->bar->setVisible(false);
00220 layout->addWidget(d->bar);
00221
00222 setSizePolicy( QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding) );
00223 show();
00224 qApp->processEvents();
00225 }
00226
00227 FormProgressDialog::~FormProgressDialog()
00228 {
00229 delete d;
00230 }
00231
00232 void FormProgressDialog::setValue(int progress)
00233 {
00234 if( progress < 0 ) {
00235 if( d->bar->isVisible() ) {
00236 d->bar->setVisible(false);
00237 d->bar->setValue(0);
00238 qApp->processEvents();
00239 }
00240 return;
00241 }
00242 if( ! d->bar->isVisible() )
00243 d->bar->setVisible(true);
00244 d->bar->setValue(progress);
00245 d->update();
00246 }
00247
00248 void FormProgressDialog::setRange(int minimum, int maximum)
00249 {
00250 d->bar->setRange(minimum, maximum);
00251 }
00252
00253 void FormProgressDialog::setText(const QString& text)
00254 {
00255 d->browser->setHtml(text);
00256 d->update();
00257 }
00258
00259 void FormProgressDialog::addText(const QString& text)
00260 {
00261 QTextCursor cursor( d->browser->document()->end() );
00262 cursor.movePosition(QTextCursor::End);
00263 cursor.insertBlock();
00264 cursor.insertHtml(text);
00265 d->browser->moveCursor(QTextCursor::End);
00266 d->browser->ensureCursorVisible();
00267 d->update();
00268 }
00269
00270 void FormProgressDialog::done(int r)
00271 {
00272 if( r == Rejected && ! d->gotCanceled ) {
00273 if( KMessageBox::messageBox(this, KMessageBox::WarningContinueCancel, i18n("Abort?")) == KMessageBox::Continue ) {
00274 d->gotCanceled = true;
00275 enableButton(KDialog::Cancel, false);
00276 emit canceled();
00277 }
00278 return;
00279 }
00280 KPageDialog::done(r);
00281 }
00282
00283 int FormProgressDialog::exec()
00284 {
00285 enableButton(KDialog::Ok, true);
00286 enableButton(KDialog::Cancel, false);
00287 if( d->bar->isVisible() )
00288 d->bar->setValue( d->bar->maximum() );
00289 return KDialog::exec();
00290 }
00291
00292 bool FormProgressDialog::isCanceled()
00293 {
00294 return d->gotCanceled;
00295 }
00296
00297
00298
00299
00300
00301 namespace Kross {
00302
00304 class FormDialog::Private
00305 {
00306 public:
00307 KDialog::ButtonCode buttoncode;
00308 QHash<QString, KPageWidgetItem*> items;
00309 };
00310
00311 }
00312
00313 FormDialog::FormDialog(const QString& caption)
00314 : KPageDialog( )
00315 , d( new Private() )
00316 {
00317 setCaption(caption);
00318 KDialog::setButtons(KDialog::Ok);
00319 setSizePolicy( QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding) );
00320
00321 connect(this, SIGNAL(currentPageChanged(KPageWidgetItem*,KPageWidgetItem*)),
00322 this, SLOT(slotCurrentPageChanged(KPageWidgetItem*)));
00323 }
00324
00325 FormDialog::~FormDialog()
00326 {
00327 delete d;
00328 }
00329
00330 bool FormDialog::setButtons(const QString& buttons)
00331 {
00332 int i = metaObject()->indexOfEnumerator("ButtonCode");
00333 Q_ASSERT( i >= 0 );
00334 QMetaEnum e = metaObject()->enumerator(i);
00335 int v = e.keysToValue( buttons.toUtf8() );
00336 if( v < 0 )
00337 return false;
00338 KDialog::setButtons( (KDialog::ButtonCode) v );
00339 return true;
00340 }
00341
00342 bool FormDialog::setFaceType(const QString& facetype)
00343 {
00344 int i = KPageView::staticMetaObject.indexOfEnumerator("FaceType");
00345 Q_ASSERT( i >= 0 );
00346 QMetaEnum e = KPageView::staticMetaObject.enumerator(i);
00347 int v = e.keysToValue( facetype.toUtf8() );
00348 if( v < 0 )
00349 return false;
00350 KPageDialog::setFaceType( (KPageDialog::FaceType) v );
00351 return true;
00352 }
00353
00354 QString FormDialog::currentPage() const
00355 {
00356 KPageWidgetItem* item = KPageDialog::currentPage();
00357 return item ? item->name() : QString();
00358 }
00359
00360 bool FormDialog::setCurrentPage(const QString& name)
00361 {
00362 if( ! d->items.contains(name) )
00363 return false;
00364 KPageDialog::setCurrentPage( d->items[name] );
00365 return true;
00366 }
00367
00368 QWidget* FormDialog::page(const QString& name) const
00369 {
00370 return d->items.contains(name) ? d->items[name]->widget() : 0;
00371 }
00372
00373 QWidget* FormDialog::addPage(const QString& name, const QString& header, const QString& iconname)
00374 {
00375 QWidget* widget = new QWidget( mainWidget() );
00376 QVBoxLayout* boxlayout = new QVBoxLayout(widget);
00377 boxlayout->setSpacing(0);
00378 boxlayout->setMargin(0);
00379 widget->setLayout(boxlayout);
00380
00381 KPageWidgetItem* item = KPageDialog::addPage(widget, name);
00382 item->setHeader(header.isNull() ? name : header);
00383 if( ! iconname.isEmpty() )
00384 item->setIcon( KIcon(iconname) );
00385 d->items.insert(name, item);
00386
00387 return item->widget();
00388 }
00389
00390 QString FormDialog::result()
00391 {
00392 int i = metaObject()->indexOfEnumerator("ButtonCode");
00393 if( i < 0 ) {
00394 kWarning() << "Kross::FormDialog::setButtons No such enumerator \"ButtonCode\"";
00395 return QString();
00396 }
00397 QMetaEnum e = metaObject()->enumerator(i);
00398 return e.valueToKey(d->buttoncode);
00399 }
00400
00401 void FormDialog::slotButtonClicked(int button)
00402 {
00403 d->buttoncode = (KDialog::ButtonCode) button;
00404 KDialog::slotButtonClicked(button);
00405 }
00406
00407 void FormDialog::slotCurrentPageChanged(KPageWidgetItem* current)
00408 {
00409 Q_UNUSED(current);
00410
00411
00412 }
00413
00414
00415
00416
00417
00418 namespace Kross {
00419
00421 class UiLoader : public QUiLoader
00422 {
00423 public:
00424 UiLoader() : QUiLoader() {}
00425 virtual ~UiLoader() {}
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444 };
00445
00447 class FormModule::Private
00448 {
00449 public:
00450 };
00451
00452 }
00453
00454 FormModule::FormModule()
00455 : QObject()
00456 , d( new Private() )
00457 {
00458 }
00459
00460 FormModule::~FormModule()
00461 {
00462 delete d;
00463 }
00464
00465 QWidget* FormModule::activeModalWidget()
00466 {
00467 return QApplication::activeModalWidget();
00468 }
00469
00470 QWidget* FormModule::activeWindow()
00471 {
00472 return QApplication::activeWindow();
00473 }
00474
00475 QString FormModule::showMessageBox(const QString& dialogtype, const QString& caption, const QString& message, const QString& details)
00476 {
00477 KMessageBox::DialogType type;
00478 if(dialogtype == "Error") {
00479 if( ! details.isNull() ) {
00480 KMessageBox::detailedError(0, message, details, caption);
00481 return QString();
00482 }
00483 type = KMessageBox::Error;
00484 }
00485 else if(dialogtype == "Sorry") {
00486 if( ! details.isNull() ) {
00487 KMessageBox::detailedSorry(0, message, details, caption);
00488 return QString();
00489 }
00490 type = KMessageBox::Sorry;
00491 }
00492 else if(dialogtype == "QuestionYesNo") type = KMessageBox::QuestionYesNo;
00493 else if(dialogtype == "WarningYesNo") type = KMessageBox::WarningYesNo;
00494 else if(dialogtype == "WarningContinueCancel") type = KMessageBox::WarningContinueCancel;
00495 else if(dialogtype == "WarningYesNoCancel") type = KMessageBox::WarningYesNoCancel;
00496 else if(dialogtype == "QuestionYesNoCancel") type = KMessageBox::QuestionYesNoCancel;
00497 else type = KMessageBox::Information;
00498 switch( KMessageBox::messageBox(0, type, message, caption) ) {
00499 case KMessageBox::Ok: return "Ok";
00500 case KMessageBox::Cancel: return "Cancel";
00501 case KMessageBox::Yes: return "Yes";
00502 case KMessageBox::No: return "No";
00503 case KMessageBox::Continue: return "Continue";
00504 default: break;
00505 }
00506 return QString();
00507 }
00508
00509 QWidget* FormModule::showProgressDialog(const QString& caption, const QString& labelText)
00510 {
00511 return new FormProgressDialog(caption, labelText);
00512 }
00513
00514 QWidget* FormModule::createDialog(const QString& caption)
00515 {
00516 return new FormDialog(caption);
00517 }
00518
00519 QObject* FormModule::createLayout(QWidget* parent, const QString& layout)
00520 {
00521 QLayout* l = 0;
00522 if( layout == "QVBoxLayout" )
00523 l = new QVBoxLayout();
00524 else if( layout == "QHBoxLayout" )
00525 l = new QHBoxLayout();
00526 else if( layout == "QStackedLayout" )
00527 l = new QStackedLayout();
00528 if( parent && l )
00529 parent->setLayout(l);
00530 return l;
00531 }
00532
00533 QWidget* FormModule::createWidget(const QString& className)
00534 {
00535 UiLoader loader;
00536 QWidget* widget = loader.createWidget(className);
00537 return widget;
00538 }
00539
00540 QWidget* FormModule::createWidget(QWidget* parent, const QString& className, const QString& name)
00541 {
00542 UiLoader loader;
00543 QWidget* widget = loader.createWidget(className, parent, name);
00544 if( parent && parent->layout() )
00545 parent->layout()->addWidget(widget);
00546 return widget;
00547 }
00548
00549 QWidget* FormModule::createWidgetFromUI(QWidget* parent, const QString& xml)
00550 {
00551 QFormBuilder builder;
00552 QByteArray ba = xml.toUtf8();
00553 QBuffer buffer(&ba);
00554 buffer.open(QIODevice::ReadOnly);
00555 QWidget* widget = builder.load(&buffer, parent);
00556 if( widget && parent && parent->layout() )
00557 parent->layout()->addWidget(widget);
00558 return widget;
00559 }
00560
00561 QWidget* FormModule::createWidgetFromUIFile(QWidget* parent, const QString& filename)
00562 {
00563 QFile file(filename);
00564 if( ! file.exists() ) {
00565 kDebug() << QString("Kross::FormModule::createWidgetFromUIFile: There exists no such file \"%1\"").arg(filename);
00566 return false;
00567 }
00568 if( ! file.open(QFile::ReadOnly) ) {
00569 kDebug() << QString("Kross::FormModule::createWidgetFromUIFile: Failed to open the file \"%1\"").arg(filename);
00570 return false;
00571 }
00572 const QString xml = file.readAll();
00573 file.close();
00574 return createWidgetFromUI(parent, xml);
00575 }
00576
00577 QWidget* FormModule::createFileWidget(QWidget* parent, const QString& startDirOrVariable)
00578 {
00579 FormFileWidget* widget = new FormFileWidget(parent, startDirOrVariable);
00580 if( parent && parent->layout() )
00581 parent->layout()->addWidget(widget);
00582 return widget;
00583 }
00584
00585 QObject* FormModule::loadPart(QWidget* parent, const QString& name, const QUrl& url)
00586 {
00587
00588 KPluginFactory* factory = KPluginLoader( name.toLatin1() ).factory();
00589 if( ! factory ) {
00590 kWarning() << QString("Kross::FormModule::loadPart: No such library \"%1\"").arg(name);
00591 return 0;
00592 }
00593 KParts::ReadOnlyPart* part = factory->create< KParts::ReadOnlyPart >( parent );
00594 if( ! part ) {
00595 kWarning() << QString("Kross::FormModule::loadPart: Library \"%1\" is not a KPart").arg(name);
00596 return 0;
00597 }
00598 if( url.isValid() )
00599 part->openUrl(url);
00600 if( parent && parent->layout() && part->widget() )
00601 parent->layout()->addWidget( part->widget() );
00602 return part;
00603 }
00604
00605 #include "form.moc"