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::setButtonText(const QString& button, const QString& text)
00343 {
00344 int i = metaObject()->indexOfEnumerator("ButtonCode");
00345 Q_ASSERT( i >= 0 );
00346 QMetaEnum e = metaObject()->enumerator(i);
00347 int v = e.keysToValue( button.toUtf8() );
00348 if( v < 0 )
00349 return false;
00350 KDialog::setButtonText( (KDialog::ButtonCode) v, text);
00351 return true;
00352 }
00353
00354 bool FormDialog::setFaceType(const QString& facetype)
00355 {
00356 int i = KPageView::staticMetaObject.indexOfEnumerator("FaceType");
00357 Q_ASSERT( i >= 0 );
00358 QMetaEnum e = KPageView::staticMetaObject.enumerator(i);
00359 int v = e.keysToValue( facetype.toUtf8() );
00360 if( v < 0 )
00361 return false;
00362 KPageDialog::setFaceType( (KPageDialog::FaceType) v );
00363 return true;
00364 }
00365
00366 QString FormDialog::currentPage() const
00367 {
00368 KPageWidgetItem* item = KPageDialog::currentPage();
00369 return item ? item->name() : QString();
00370 }
00371
00372 bool FormDialog::setCurrentPage(const QString& name)
00373 {
00374 if( ! d->items.contains(name) )
00375 return false;
00376 KPageDialog::setCurrentPage( d->items[name] );
00377 return true;
00378 }
00379
00380 QWidget* FormDialog::page(const QString& name) const
00381 {
00382 return d->items.contains(name) ? d->items[name]->widget() : 0;
00383 }
00384
00385 QWidget* FormDialog::addPage(const QString& name, const QString& header, const QString& iconname)
00386 {
00387 QWidget* widget = new QWidget( mainWidget() );
00388 QVBoxLayout* boxlayout = new QVBoxLayout(widget);
00389 boxlayout->setSpacing(0);
00390 boxlayout->setMargin(0);
00391 widget->setLayout(boxlayout);
00392
00393 KPageWidgetItem* item = KPageDialog::addPage(widget, name);
00394 item->setHeader(header.isNull() ? name : header);
00395 if( ! iconname.isEmpty() )
00396 item->setIcon( KIcon(iconname) );
00397 d->items.insert(name, item);
00398
00399 return item->widget();
00400 }
00401
00402 void FormDialog::setMainWidget(QWidget *newMainWidget)
00403 {
00404 KDialog::setMainWidget(newMainWidget);
00405 }
00406
00407 QString FormDialog::result()
00408 {
00409 int i = metaObject()->indexOfEnumerator("ButtonCode");
00410 if( i < 0 ) {
00411 kWarning() << "Kross::FormDialog::setButtons No such enumerator \"ButtonCode\"";
00412 return QString();
00413 }
00414 QMetaEnum e = metaObject()->enumerator(i);
00415 return e.valueToKey(d->buttoncode);
00416 }
00417
00418 void FormDialog::slotButtonClicked(int button)
00419 {
00420 d->buttoncode = (KDialog::ButtonCode) button;
00421 KDialog::slotButtonClicked(button);
00422 }
00423
00424 void FormDialog::slotCurrentPageChanged(KPageWidgetItem* current)
00425 {
00426 Q_UNUSED(current);
00427
00428
00429 }
00430
00431
00432
00433
00434
00435 namespace Kross {
00436
00438 class UiLoader : public QUiLoader
00439 {
00440 public:
00441 UiLoader() : QUiLoader() {}
00442 virtual ~UiLoader() {}
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461 };
00462
00464 class FormModule::Private
00465 {
00466 public:
00467 };
00468
00469 }
00470
00471 FormModule::FormModule()
00472 : QObject()
00473 , d( new Private() )
00474 {
00475 }
00476
00477 FormModule::~FormModule()
00478 {
00479 delete d;
00480 }
00481
00482 QWidget* FormModule::activeModalWidget()
00483 {
00484 return QApplication::activeModalWidget();
00485 }
00486
00487 QWidget* FormModule::activeWindow()
00488 {
00489 return QApplication::activeWindow();
00490 }
00491
00492 QString FormModule::showMessageBox(const QString& dialogtype, const QString& caption, const QString& message, const QString& details)
00493 {
00494 KMessageBox::DialogType type;
00495 if(dialogtype == "Error") {
00496 if( ! details.isNull() ) {
00497 KMessageBox::detailedError(0, message, details, caption);
00498 return QString();
00499 }
00500 type = KMessageBox::Error;
00501 }
00502 else if(dialogtype == "Sorry") {
00503 if( ! details.isNull() ) {
00504 KMessageBox::detailedSorry(0, message, details, caption);
00505 return QString();
00506 }
00507 type = KMessageBox::Sorry;
00508 }
00509 else if(dialogtype == "QuestionYesNo") type = KMessageBox::QuestionYesNo;
00510 else if(dialogtype == "WarningYesNo") type = KMessageBox::WarningYesNo;
00511 else if(dialogtype == "WarningContinueCancel") type = KMessageBox::WarningContinueCancel;
00512 else if(dialogtype == "WarningYesNoCancel") type = KMessageBox::WarningYesNoCancel;
00513 else if(dialogtype == "QuestionYesNoCancel") type = KMessageBox::QuestionYesNoCancel;
00514 else type = KMessageBox::Information;
00515 switch( KMessageBox::messageBox(0, type, message, caption) ) {
00516 case KMessageBox::Ok: return "Ok";
00517 case KMessageBox::Cancel: return "Cancel";
00518 case KMessageBox::Yes: return "Yes";
00519 case KMessageBox::No: return "No";
00520 case KMessageBox::Continue: return "Continue";
00521 default: break;
00522 }
00523 return QString();
00524 }
00525
00526 QWidget* FormModule::showProgressDialog(const QString& caption, const QString& labelText)
00527 {
00528 return new FormProgressDialog(caption, labelText);
00529 }
00530
00531 QWidget* FormModule::createDialog(const QString& caption)
00532 {
00533 return new FormDialog(caption);
00534 }
00535
00536 QObject* FormModule::createLayout(QWidget* parent, const QString& layout)
00537 {
00538 QLayout* l = 0;
00539 if( layout == "QVBoxLayout" )
00540 l = new QVBoxLayout();
00541 else if( layout == "QHBoxLayout" )
00542 l = new QHBoxLayout();
00543 else if( layout == "QStackedLayout" )
00544 l = new QStackedLayout();
00545 if( parent && l )
00546 parent->setLayout(l);
00547 return l;
00548 }
00549
00550 QWidget* FormModule::createWidget(const QString& className)
00551 {
00552 UiLoader loader;
00553 QWidget* widget = loader.createWidget(className);
00554 return widget;
00555 }
00556
00557 QWidget* FormModule::createWidget(QWidget* parent, const QString& className, const QString& name)
00558 {
00559 UiLoader loader;
00560 QWidget* widget = loader.createWidget(className, parent, name);
00561 if( parent && parent->layout() )
00562 parent->layout()->addWidget(widget);
00563 return widget;
00564 }
00565
00566 QWidget* FormModule::createWidgetFromUI(QWidget* parent, const QString& xml)
00567 {
00568 QFormBuilder builder;
00569 QByteArray ba = xml.toUtf8();
00570 QBuffer buffer(&ba);
00571 buffer.open(QIODevice::ReadOnly);
00572 QWidget* widget = builder.load(&buffer, parent);
00573 if( widget && parent && parent->layout() )
00574 parent->layout()->addWidget(widget);
00575 return widget;
00576 }
00577
00578 QWidget* FormModule::createWidgetFromUIFile(QWidget* parent, const QString& filename)
00579 {
00580 QFile file(filename);
00581 if( ! file.exists() ) {
00582 kDebug() << QString("Kross::FormModule::createWidgetFromUIFile: There exists no such file \"%1\"").arg(filename);
00583 return false;
00584 }
00585 if( ! file.open(QFile::ReadOnly) ) {
00586 kDebug() << QString("Kross::FormModule::createWidgetFromUIFile: Failed to open the file \"%1\"").arg(filename);
00587 return false;
00588 }
00589 const QString xml = file.readAll();
00590 file.close();
00591 return createWidgetFromUI(parent, xml);
00592 }
00593
00594 QWidget* FormModule::createFileWidget(QWidget* parent, const QString& startDirOrVariable)
00595 {
00596 FormFileWidget* widget = new FormFileWidget(parent, startDirOrVariable);
00597 if( parent && parent->layout() )
00598 parent->layout()->addWidget(widget);
00599 return widget;
00600 }
00601
00602 QObject* FormModule::loadPart(QWidget* parent, const QString& name, const QUrl& url)
00603 {
00604
00605 KPluginFactory* factory = KPluginLoader( name.toLatin1() ).factory();
00606 if( ! factory ) {
00607 kWarning() << QString("Kross::FormModule::loadPart: No such library \"%1\"").arg(name);
00608 return 0;
00609 }
00610 KParts::ReadOnlyPart* part = factory->create< KParts::ReadOnlyPart >( parent );
00611 if( ! part ) {
00612 kWarning() << QString("Kross::FormModule::loadPart: Library \"%1\" is not a KPart").arg(name);
00613 return 0;
00614 }
00615 if( url.isValid() )
00616 part->openUrl(url);
00617 if( parent && parent->layout() && part->widget() )
00618 parent->layout()->addWidget( part->widget() );
00619 return part;
00620 }
00621
00622 #include "form.moc"