00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kxmlcommanddlg.h"
00021 #include "driver.h"
00022 #include "kxmlcommand.h"
00023
00024 #include <qlayout.h>
00025 #include <qheader.h>
00026 #include <qlabel.h>
00027 #include <qlineedit.h>
00028 #include <qcombobox.h>
00029 #include <qgroupbox.h>
00030 #include <qwidgetstack.h>
00031 #include <qtoolbutton.h>
00032 #include <kpushbutton.h>
00033 #include <qtooltip.h>
00034 #include <qcheckbox.h>
00035 #include <ktextedit.h>
00036 #include <qregexp.h>
00037 #include <qwhatsthis.h>
00038 #include <qapplication.h>
00039
00040 #include <klistview.h>
00041 #include <klocale.h>
00042 #include <kiconloader.h>
00043 #include <kdialogbase.h>
00044 #include <kseparator.h>
00045 #include <klistbox.h>
00046 #include <kmimetype.h>
00047 #include <kmessagebox.h>
00048 #include <kapplication.h>
00049 #include <kdebug.h>
00050 #include <kguiitem.h>
00051
00052 QString generateId(const QMap<QString, DrBase*>& map)
00053 {
00054 int index(-1);
00055 while (map.contains(QString::fromLatin1("item%1").arg(++index))) ;
00056 return QString::fromLatin1("item%1").arg(index);
00057 }
00058
00059 QListViewItem* findPrev(QListViewItem *item)
00060 {
00061 QListViewItem *prev = item->itemAbove();
00062 while (prev && prev->depth() > item->depth())
00063 prev = prev->itemAbove();
00064 if (prev && prev->depth() == item->depth())
00065 return prev;
00066 else
00067 return 0;
00068 }
00069
00070 QListViewItem* findNext(QListViewItem *item)
00071 {
00072 QListViewItem *next = item->itemBelow();
00073 while (next && next->depth() > item->depth())
00074 next = next->itemBelow();
00075 if (next && next->depth() == item->depth())
00076 return next;
00077 else
00078 return 0;
00079 }
00080
00081 KXmlCommandAdvancedDlg::KXmlCommandAdvancedDlg(QWidget *parent, const char *name)
00082 : QWidget(parent, name)
00083 {
00084 m_xmlcmd = 0;
00085
00086 m_command = new QLineEdit(this);
00087 m_view = new KListView(this);
00088 m_view->addColumn("");
00089 m_view->header()->hide();
00090 m_view->setSorting(-1);
00091 m_apply = new QToolButton(this);
00092 m_apply->setIconSet( QApplication::reverseLayout()? SmallIconSet( "forward" ) : SmallIconSet("back"));
00093 m_addgrp = new QToolButton(this);
00094 m_addgrp->setIconSet(SmallIconSet("folder"));
00095 m_addopt = new QToolButton(this);
00096 m_addopt->setIconSet(SmallIconSet("document"));
00097 m_delopt = new QToolButton(this);
00098 m_delopt->setIconSet(SmallIconSet("editdelete"));
00099 m_up = new QToolButton(this);
00100 m_up->setIconSet(SmallIconSet("up"));
00101 m_down = new QToolButton(this);
00102 m_down->setIconSet(SmallIconSet("down"));
00103 m_dummy = new QWidget(this);
00104 m_desc = new QLineEdit(m_dummy);
00105 m_name = new QLineEdit(m_dummy);
00106 m_type = new QComboBox(m_dummy);
00107 m_type->insertItem(i18n("String"));
00108 m_type->insertItem(i18n("Integer"));
00109 m_type->insertItem(i18n("Float"));
00110 m_type->insertItem(i18n("List"));
00111 m_type->insertItem(i18n("Boolean"));
00112 m_format = new QLineEdit(m_dummy);
00113 m_default = new QLineEdit(m_dummy);
00114 QLabel *m_namelab = new QLabel(i18n("&Name:"), m_dummy);
00115 QLabel *m_desclab = new QLabel(i18n("&Description:"), m_dummy);
00116 QLabel *m_formatlab = new QLabel(i18n("&Format:"), m_dummy);
00117 QLabel *m_typelab = new QLabel(i18n("&Type:"), m_dummy);
00118 QLabel *m_defaultlab = new QLabel(i18n("Default &value:"), m_dummy);
00119 QLabel *m_commandlab = new QLabel(i18n("Co&mmand:"), this);
00120 m_namelab->setBuddy(m_name);
00121 m_desclab->setBuddy(m_desc);
00122 m_formatlab->setBuddy(m_format);
00123 m_typelab->setBuddy(m_type);
00124 m_defaultlab->setBuddy(m_default);
00125 m_commandlab->setBuddy(m_command);
00126 m_persistent = new QCheckBox( i18n( "&Persistent option" ), m_dummy );
00127
00128 QGroupBox *gb = new QGroupBox(0, Qt::Horizontal, i18n("Va&lues"), m_dummy);
00129 m_stack = new QWidgetStack(gb);
00130 QWidget *w1 = new QWidget(m_stack), *w2 = new QWidget(m_stack), *w3 = new QWidget(m_stack);
00131 m_stack->addWidget(w1, 1);
00132 m_stack->addWidget(w2, 2);
00133 m_stack->addWidget(w3, 3);
00134 m_edit1 = new QLineEdit(w1);
00135 m_edit2 = new QLineEdit(w1);
00136 QLabel *m_editlab1 = new QLabel(i18n("Minimum v&alue:"), w1);
00137 QLabel *m_editlab2 = new QLabel(i18n("Ma&ximum value:"), w1);
00138 m_editlab1->setBuddy(m_edit1);
00139 m_editlab2->setBuddy(m_edit2);
00140 m_values = new KListView(w2);
00141 m_values->addColumn(i18n("Name"));
00142 m_values->addColumn(i18n("Description"));
00143 m_values->setAllColumnsShowFocus(true);
00144 m_values->setSorting(-1);
00145 m_values->setMaximumHeight(110);
00146 m_addval = new QToolButton(w2);
00147 m_addval->setIconSet(SmallIconSet("editcopy"));
00148 m_delval = new QToolButton(w2);
00149 m_delval->setIconSet(SmallIconSet("editdelete"));
00150 QToolTip::add(m_addval, i18n("Add value"));
00151 QToolTip::add(m_delval, i18n("Delete value"));
00152
00153 QToolTip::add(m_apply, i18n("Apply changes"));
00154 QToolTip::add(m_addgrp, i18n("Add group"));
00155 QToolTip::add(m_addopt, i18n("Add option"));
00156 QToolTip::add(m_delopt, i18n("Delete item"));
00157 QToolTip::add(m_up, i18n("Move up"));
00158 QToolTip::add(m_down, i18n("Move down"));
00159
00160 KSeparator *sep1 = new KSeparator(KSeparator::HLine, m_dummy);
00161
00162 QGroupBox *gb_input = new QGroupBox(0, Qt::Horizontal, i18n("&Input From"), this);
00163 QGroupBox *gb_output = new QGroupBox(0, Qt::Horizontal, i18n("O&utput To"), this);
00164 QLabel *m_inputfilelab = new QLabel(i18n("File:"), gb_input);
00165 QLabel *m_inputpipelab = new QLabel(i18n("Pipe:"), gb_input);
00166 QLabel *m_outputfilelab = new QLabel(i18n("File:"), gb_output);
00167 QLabel *m_outputpipelab = new QLabel(i18n("Pipe:"), gb_output);
00168 m_inputfile = new QLineEdit(gb_input);
00169 m_inputpipe = new QLineEdit(gb_input);
00170 m_outputfile = new QLineEdit(gb_output);
00171 m_outputpipe = new QLineEdit(gb_output);
00172
00173 m_comment = new KTextEdit( this );
00174 m_comment->setTextFormat(Qt::RichText );
00175 m_comment->setReadOnly(true);
00176 QLabel *m_commentlab = new QLabel( i18n( "Comment:" ), this );
00177
00178 QVBoxLayout *l2 = new QVBoxLayout(this, 0, KDialog::spacingHint());
00179 QHBoxLayout *l3 = new QHBoxLayout(0, 0, KDialog::spacingHint());
00180 QVBoxLayout *l7 = new QVBoxLayout(0, 0, 0);
00181 l2->addLayout(l3, 0);
00182 l3->addWidget(m_commandlab);
00183 l3->addWidget(m_command);
00184 QHBoxLayout *l0 = new QHBoxLayout(0, 0, KDialog::spacingHint());
00185 QGridLayout *l10 = new QGridLayout(0, 2, 2, 0, KDialog::spacingHint());
00186 l2->addLayout(l0, 1);
00187 l0->addLayout(l10);
00188 l10->addMultiCellWidget(m_view, 0, 0, 0, 1);
00189 l10->addWidget(gb_input, 1, 0);
00190 l10->addWidget(gb_output, 1, 1);
00191 l10->setRowStretch(0, 1);
00192 l0->addLayout(l7);
00193 l7->addWidget(m_apply);
00194 l7->addSpacing(5);
00195 l7->addWidget(m_addgrp);
00196 l7->addWidget(m_addopt);
00197 l7->addWidget(m_delopt);
00198 l7->addSpacing(5);
00199 l7->addWidget(m_up);
00200 l7->addWidget(m_down);
00201 l7->addStretch(1);
00202 l0->addWidget(m_dummy, 1);
00203 QGridLayout *l1 = new QGridLayout(m_dummy, 9, 2, 0, KDialog::spacingHint());
00204 l1->addWidget(m_desclab, 0, 0, Qt::AlignRight|Qt::AlignVCenter);
00205 l1->addWidget(m_desc, 0, 1);
00206 l1->addMultiCellWidget(sep1, 1, 1, 0, 1);
00207 l1->addWidget(m_namelab, 2, 0, Qt::AlignRight|Qt::AlignVCenter);
00208 l1->addWidget(m_name, 2, 1);
00209 l1->addWidget(m_typelab, 3, 0, Qt::AlignRight|Qt::AlignVCenter);
00210 l1->addWidget(m_type, 3, 1);
00211 l1->addWidget(m_formatlab, 4, 0, Qt::AlignRight|Qt::AlignVCenter);
00212 l1->addWidget(m_format, 4, 1);
00213 l1->addWidget(m_defaultlab, 5, 0, Qt::AlignRight|Qt::AlignVCenter);
00214 l1->addWidget(m_default, 5, 1);
00215 l1->addWidget( m_persistent, 6, 1 );
00216 l1->addMultiCellWidget(gb, 7, 7, 0, 1);
00217 l1->setRowStretch(8, 1);
00218
00219 QHBoxLayout *l4 = new QHBoxLayout(w2, 0, KDialog::spacingHint());
00220 l4->addWidget(m_values);
00221 QVBoxLayout *l6 = new QVBoxLayout(0, 0, 0);
00222 l4->addLayout(l6);
00223 l6->addWidget(m_addval);
00224 l6->addWidget(m_delval);
00225 l6->addStretch(1);
00226 QGridLayout *l5 = new QGridLayout(w1, 3, 2, 0, KDialog::spacingHint());
00227 l5->setRowStretch(2, 1);
00228 l5->addWidget(m_editlab1, 0, 0, Qt::AlignRight|Qt::AlignVCenter);
00229 l5->addWidget(m_editlab2, 1, 0, Qt::AlignRight|Qt::AlignVCenter);
00230 l5->addWidget(m_edit1, 0, 1);
00231 l5->addWidget(m_edit2, 1, 1);
00232
00233 QGridLayout *l8 = new QGridLayout(gb_input->layout(), 2, 2,
00234 KDialog::spacingHint());
00235 QGridLayout *l9 = new QGridLayout(gb_output->layout(), 2, 2,
00236 KDialog::spacingHint());
00237 l8->addWidget(m_inputfilelab, 0, 0);
00238 l8->addWidget(m_inputpipelab, 1, 0);
00239 l8->addWidget(m_inputfile, 0, 1);
00240 l8->addWidget(m_inputpipe, 1, 1);
00241 l9->addWidget(m_outputfilelab, 0, 0);
00242 l9->addWidget(m_outputpipelab, 1, 0);
00243 l9->addWidget(m_outputfile, 0, 1);
00244 l9->addWidget(m_outputpipe, 1, 1);
00245
00246 QVBoxLayout *l11 = new QVBoxLayout(gb->layout());
00247 l11->addWidget(m_stack);
00248
00249 QVBoxLayout *l12 = new QVBoxLayout( 0, 0, 0 );
00250 l2->addSpacing( 10 );
00251 l2->addLayout( l12 );
00252 l12->addWidget( m_commentlab );
00253 l12->addWidget( m_comment );
00254
00255 connect(m_view, SIGNAL(selectionChanged(QListViewItem*)), SLOT(slotSelectionChanged(QListViewItem*)));
00256 connect(m_values, SIGNAL(selectionChanged(QListViewItem*)), SLOT(slotValueSelected(QListViewItem*)));
00257 connect(m_type, SIGNAL(activated(int)), SLOT(slotTypeChanged(int)));
00258 connect(m_addval, SIGNAL(clicked()), SLOT(slotAddValue()));
00259 connect(m_delval, SIGNAL(clicked()), SLOT(slotRemoveValue()));
00260 connect(m_apply, SIGNAL(clicked()), SLOT(slotApplyChanges()));
00261 connect(m_addgrp, SIGNAL(clicked()), SLOT(slotAddGroup()));
00262 connect(m_addopt, SIGNAL(clicked()), SLOT(slotAddOption()));
00263 connect(m_delopt, SIGNAL(clicked()), SLOT(slotRemoveItem()));
00264 connect(m_up, SIGNAL(clicked()), SLOT(slotMoveUp()));
00265 connect(m_down, SIGNAL(clicked()), SLOT(slotMoveDown()));
00266 connect(m_command, SIGNAL(textChanged(const QString&)), SLOT(slotCommandChanged(const QString&)));
00267 connect(m_view, SIGNAL(itemRenamed(QListViewItem*,int)), SLOT(slotOptionRenamed(QListViewItem*,int)));
00268 connect(m_desc, SIGNAL(textChanged(const QString&)), SLOT(slotChanged()));
00269 connect(m_name, SIGNAL(textChanged(const QString&)), SLOT(slotChanged()));
00270 connect(m_format, SIGNAL(textChanged(const QString&)), SLOT(slotChanged()));
00271 connect(m_default, SIGNAL(textChanged(const QString&)), SLOT(slotChanged()));
00272 connect(m_edit1, SIGNAL(textChanged(const QString&)), SLOT(slotChanged()));
00273 connect(m_edit2, SIGNAL(textChanged(const QString&)), SLOT(slotChanged()));
00274 connect(m_type, SIGNAL(activated(int)), SLOT(slotChanged()));
00275 connect(m_addval, SIGNAL(clicked()), SLOT(slotChanged()));
00276 connect(m_delval, SIGNAL(clicked()), SLOT(slotChanged()));
00277 connect( m_persistent, SIGNAL( toggled(bool) ), SLOT( slotChanged() ) );
00278 m_dummy->setEnabled(false);
00279 viewItem(0);
00280
00284 QWhatsThis::add( m_name, i18n(
00285 "An identification string. Use only alphanumeric characters except spaces. "
00286 "The string <b>__root__</b> is reserved for internal use." ) );
00287 QWhatsThis::add( m_namelab, QWhatsThis::textFor( m_name ) );
00288 QWhatsThis::add( m_desc, i18n(
00289 "A description string. This string is shown in the interface, and should "
00290 "be explicit enough about the role of the corresponding option." ) );
00291 QWhatsThis::add( m_desclab, QWhatsThis::textFor( m_desc ) );
00292 QWhatsThis::add( m_type, i18n(
00293 "The type of the option. This determines how the option is presented "
00294 "graphically to the user." ) );
00295 QWhatsThis::add( m_typelab, QWhatsThis::textFor( m_type ) );
00296 QWhatsThis::add( m_format, i18n(
00297 "The format of the option. This determines how the option is formatted "
00298 "for inclusion in the global command line. The tag <b>%value</b> can be used "
00299 "to represent the user selection. This tag will be replaced at run-time by a "
00300 "string representation of the option value." ) );
00301 QWhatsThis::add( m_formatlab, QWhatsThis::textFor( m_format ) );
00302 QWhatsThis::add( m_default, i18n(
00303 "The default value of the option. For non persistent options, nothing is "
00304 "added to the command line if the option has that default value. If this "
00305 "value does not correspond to the actual default value of the underlying "
00306 "utility, make the option persistent to avoid unwanted effects." ) );
00307 QWhatsThis::add( m_defaultlab, QWhatsThis::textFor( m_default ) );
00308 QWhatsThis::add( m_persistent, i18n(
00309 "Make the option persistent. A persistent option is always written to the "
00310 "command line, whatever its value. This is useful when the chosen default "
00311 "value does not match with the actual default value of the underlying utility." ) );
00312 QWhatsThis::add( m_command, i18n(
00313 "The full command line to execute the associated underlying utility. This "
00314 "command line is based on a mechanism of tags that are replaced at run-time. "
00315 "The supported tags are:<ul>"
00316 "<li><b>%filterargs</b>: command options</li>"
00317 "<li><b>%filterinput</b>: input specification</li>"
00318 "<li><b>%filteroutput</b>: output specification</li>"
00319 "<li><b>%psu</b>: the page size in upper case</li>"
00320 "<li><b>%psl</b>: the page size in lower case</li></ul>" ) );
00321 QWhatsThis::add( m_commandlab, QWhatsThis::textFor( m_command ) );
00322 QWhatsThis::add( m_inputfile, i18n(
00323 "Input specification when the underlying utility reads input data from a file. Use "
00324 "the tag <b>%in</b> to represent the input filename." ) );
00325 QWhatsThis::add( m_inputfilelab, QWhatsThis::textFor( m_inputfile ) );
00326 QWhatsThis::add( m_outputfile, i18n(
00327 "Output specification when the underlying utility writes output data to a file. Use "
00328 "the tag <b>%out</b> to represent the output filename." ) );
00329 QWhatsThis::add( m_outputfilelab, QWhatsThis::textFor( m_outputfile ) );
00330 QWhatsThis::add( m_inputpipe, i18n(
00331 "Input specification when the underlying utility reads input data from its "
00332 "standard input." ) );
00333 QWhatsThis::add( m_inputpipelab, QWhatsThis::textFor( m_inputpipe ) );
00334 QWhatsThis::add( m_outputpipe, i18n(
00335 "Output specification when the underlying utility writes output data to its "
00336 "standard output." ) );
00337 QWhatsThis::add( m_outputpipelab, QWhatsThis::textFor( m_outputpipe ) );
00338 QWhatsThis::add( m_comment, i18n(
00339 "A comment about the underlying utility, which can be viewed by the user "
00340 "from the interface. This comment string supports basic HTML tags like "
00341 "<a>, <b> or <i>." ) );
00342 QWhatsThis::add( m_commentlab, QWhatsThis::textFor( m_comment ) );
00343
00344 resize(660, 200);
00345 }
00346
00347 KXmlCommandAdvancedDlg::~KXmlCommandAdvancedDlg()
00348 {
00349 if (m_opts.count() > 0)
00350 {
00351 kdDebug() << "KXmlCommandAdvancedDlg: " << m_opts.count() << " items remaining" << endl;
00352 for (QMap<QString,DrBase*>::ConstIterator it=m_opts.begin(); it!=m_opts.end(); ++it)
00353 {
00354
00355 delete (*it);
00356 }
00357 }
00358 }
00359
00360 void KXmlCommandAdvancedDlg::setCommand(KXmlCommand *xmlcmd)
00361 {
00362 m_xmlcmd = xmlcmd;
00363 if (m_xmlcmd)
00364 parseXmlCommand(m_xmlcmd);
00365 }
00366
00367 void KXmlCommandAdvancedDlg::parseXmlCommand(KXmlCommand *xmlcmd)
00368 {
00369 m_view->clear();
00370 QListViewItem *root = new QListViewItem(m_view, xmlcmd->name(), xmlcmd->name());
00371 DrMain *driver = xmlcmd->driver();
00372
00373 root->setPixmap(0, SmallIcon("fileprint"));
00374 root->setOpen(true);
00375 if (driver)
00376 {
00377 DrMain *clone = driver->cloneDriver();
00378 if (!clone->get("text").isEmpty())
00379 root->setText(0, clone->get("text"));
00380 root->setText(1, "__root__");
00381 clone->setName("__root__");
00382 m_opts["__root__"] = clone;
00383 parseGroupItem(clone, root);
00384 clone->flatten();
00385 }
00386 m_command->setText(xmlcmd->command());
00387 m_inputfile->setText(xmlcmd->io(true, false));
00388 m_inputpipe->setText(xmlcmd->io(true, true));
00389 m_outputfile->setText(xmlcmd->io(false, false));
00390 m_outputpipe->setText(xmlcmd->io(false, true));
00391 m_comment->setText( xmlcmd->comment() );
00392
00393 viewItem(0);
00394 }
00395
00396 void KXmlCommandAdvancedDlg::parseGroupItem(DrGroup *grp, QListViewItem *parent)
00397 {
00398 QListViewItem *item(0);
00399
00400 QPtrListIterator<DrGroup> git(grp->groups());
00401 for (; git.current(); ++git)
00402 {
00403 QString namestr = git.current()->name();
00404 if (namestr.isEmpty())
00405 {
00406 namestr = "group_"+kapp->randomString(4);
00407 }
00408 git.current()->setName(namestr);
00409 item = new QListViewItem(parent, item, git.current()->get("text"), git.current()->name());
00410 item->setPixmap(0, SmallIcon("folder"));
00411 item->setOpen(true);
00412 item->setRenameEnabled(0, true);
00413 parseGroupItem(git.current(), item);
00414 m_opts[namestr] = git.current();
00415 }
00416
00417 QPtrListIterator<DrBase> oit(grp->options());
00418 for (; oit.current(); ++oit)
00419 {
00420 QString namestr = oit.current()->name().mid(m_xmlcmd->name().length()+6);
00421 if (namestr.isEmpty())
00422 {
00423 namestr = "option_"+kapp->randomString(4);
00424 }
00425 oit.current()->setName(namestr);
00426 item = new QListViewItem(parent, item, oit.current()->get("text"), namestr);
00427 item->setPixmap(0, SmallIcon("document"));
00428 item->setRenameEnabled(0, true);
00429 m_opts[namestr] = oit.current();
00430 }
00431 }
00432
00433 void KXmlCommandAdvancedDlg::slotSelectionChanged(QListViewItem *item)
00434 {
00435 if (item && item->depth() == 0)
00436 item = 0;
00437 viewItem(item);
00438 }
00439
00440 void KXmlCommandAdvancedDlg::viewItem(QListViewItem *item)
00441 {
00442 m_dummy->setEnabled((item != 0));
00443 m_name->setText("");
00444 m_desc->setText("");
00445 m_format->setText("");
00446 m_default->setText("");
00447 m_values->clear();
00448 m_edit1->setText("");
00449 m_edit2->setText("");
00450 m_persistent->setChecked( false );
00451 int typeId(-1);
00452 if (item)
00453 {
00454 m_name->setText(item->text(1));
00455 m_desc->setText(item->text(0));
00456
00457 DrBase *opt = (m_opts.contains(item->text(1)) ? m_opts[item->text(1)] : 0);
00458 if (opt)
00459 {
00460 bool isgroup = (opt->type() < DrBase::String);
00461 if (!isgroup)
00462 {
00463 m_type->setCurrentItem(opt->type() - DrBase::String);
00464 typeId = m_type->currentItem();
00465 m_format->setText(opt->get("format"));
00466 m_default->setText(opt->get("default"));
00467 }
00468 m_type->setEnabled(!isgroup);
00469 m_default->setEnabled(!isgroup);
00470 m_format->setEnabled(!isgroup);
00471 m_stack->setEnabled(!isgroup);
00472
00473 switch (opt->type())
00474 {
00475 case DrBase::Float:
00476 case DrBase::Integer:
00477 m_edit1->setText(opt->get("minval"));
00478 m_edit2->setText(opt->get("maxval"));
00479 break;
00480 case DrBase::Boolean:
00481 case DrBase::List:
00482 {
00483 QPtrListIterator<DrBase> it(*(static_cast<DrListOption*>(opt)->choices()));
00484 QListViewItem *item(0);
00485 for (; it.current(); ++it)
00486 {
00487 item = new QListViewItem(m_values, item, it.current()->name(), it.current()->get("text"));
00488 item->setRenameEnabled(0, true);
00489 item->setRenameEnabled(1, true);
00490 }
00491 break;
00492 }
00493 default:
00494 break;
00495 }
00496
00497 m_addgrp->setEnabled(isgroup);
00498 m_addopt->setEnabled(isgroup);
00499
00500 QListViewItem *prevItem = findPrev(item), *nextItem = findNext(item);
00501 DrBase *prevOpt = (prevItem && m_opts.contains(prevItem->text(1)) ? m_opts[prevItem->text(1)] : 0);
00502 DrBase *nextOpt = (nextItem && m_opts.contains(nextItem->text(1)) ? m_opts[nextItem->text(1)] : 0);
00503 m_up->setEnabled(prevOpt && !(prevOpt->type() < DrBase::String && opt->type() >= DrBase::String));
00504 m_down->setEnabled(nextOpt && !(isgroup && nextOpt->type() >= DrBase::String));
00505
00506 m_persistent->setChecked( opt->get( "persistent" ) == "1" );
00507 }
00508
00509 m_delopt->setEnabled(true);
00510 m_dummy->setEnabled(opt);
00511 }
00512 else
00513 {
00514 m_delopt->setEnabled(false);
00515 m_addopt->setEnabled(m_view->currentItem() && m_view->isEnabled());
00516 m_addgrp->setEnabled(m_view->currentItem() && m_view->isEnabled());
00517 m_up->setEnabled(false);
00518 m_down->setEnabled(false);
00519 }
00520 slotTypeChanged(typeId);
00521 m_apply->setEnabled(false);
00522 }
00523
00524 void KXmlCommandAdvancedDlg::slotTypeChanged(int ID)
00525 {
00526 int wId(3);
00527 ID += DrBase::String;
00528 switch (ID)
00529 {
00530 case DrBase::Float:
00531 case DrBase::Integer:
00532 wId = 1;
00533 break;
00534 case DrBase::Boolean:
00535 case DrBase::List:
00536 wId = 2;
00537 slotValueSelected(m_values->currentItem());
00538 break;
00539 }
00540 m_stack->raiseWidget(wId);
00541 }
00542
00543 void KXmlCommandAdvancedDlg::slotAddValue()
00544 {
00545 QListViewItem *item = new QListViewItem(m_values, m_values->lastItem(), i18n("Name"), i18n("Description"));
00546 item->setRenameEnabled(0, true);
00547 item->setRenameEnabled(1, true);
00548 m_values->ensureItemVisible(item);
00549 slotValueSelected(item);
00550 item->startRename(0);
00551 }
00552
00553 void KXmlCommandAdvancedDlg::slotRemoveValue()
00554 {
00555 QListViewItem *item = m_values->currentItem();
00556 if (item)
00557 delete item;
00558 slotValueSelected(m_values->currentItem());
00559 }
00560
00561 void KXmlCommandAdvancedDlg::slotApplyChanges()
00562 {
00563 QListViewItem *item = m_view->currentItem();
00564 if (item)
00565 {
00566 if (m_name->text().isEmpty() || m_name->text() == "__root__")
00567 {
00568 KMessageBox::error(this, i18n("Invalid identification name. Empty strings and \"__root__\" are not allowed."));
00569 return;
00570 }
00571
00572 m_apply->setEnabled(false);
00573
00574 DrBase *opt = (m_opts.contains(item->text(1)) ? m_opts[item->text(1)] : 0);
00575 m_opts.remove(item->text(1));
00576 delete opt;
00577
00578
00579 item->setText(0, m_desc->text());
00580 item->setText(1, m_name->text());
00581
00582
00583 if (m_type->isEnabled())
00584 {
00585 int type = m_type->currentItem() + DrBase::String;
00586 switch (type)
00587 {
00588 case DrBase::Integer:
00589 case DrBase::Float:
00590 if (type == DrBase::Integer)
00591 opt = new DrIntegerOption;
00592 else
00593 opt = new DrFloatOption;
00594 opt->set("minval", m_edit1->text());
00595 opt->set("maxval", m_edit2->text());
00596 break;
00597 case DrBase::List:
00598 case DrBase::Boolean:
00599 {
00600 if (type == DrBase::List)
00601 opt = new DrListOption;
00602 else
00603 opt = new DrBooleanOption;
00604 DrListOption *lopt = static_cast<DrListOption*>(opt);
00605 QListViewItem *item = m_values->firstChild();
00606 while (item)
00607 {
00608 DrBase *choice = new DrBase;
00609 choice->setName(item->text(0));
00610 choice->set("text", item->text(1));
00611 lopt->addChoice(choice);
00612 item = item->nextSibling();
00613 }
00614 break;
00615 }
00616 case DrBase::String:
00617 opt = new DrStringOption;
00618 break;
00619
00620 }
00621 opt->set("format", m_format->text());
00622 opt->set("default", m_default->text());
00623 opt->setValueText(opt->get("default"));
00624 }
00625 else
00626 opt = new DrGroup;
00627
00628 opt->setName((m_name->text().isEmpty() ? generateId(m_opts) : m_name->text()));
00629 opt->set("text", m_desc->text());
00630 opt->set( "persistent", m_persistent->isChecked() ? "1" : "0" );
00631
00632 m_opts[opt->name()] = opt;
00633 }
00634 }
00635
00636 void KXmlCommandAdvancedDlg::slotChanged()
00637 {
00638 m_apply->setEnabled(true);
00639 }
00640
00641 void KXmlCommandAdvancedDlg::slotAddGroup()
00642 {
00643 if (m_view->currentItem())
00644 {
00645 QString ID = generateId(m_opts);
00646
00647 DrGroup *grp = new DrGroup;
00648 grp->setName(ID);
00649 grp->set("text", i18n("New Group"));
00650 m_opts[ID] = grp;
00651
00652 QListViewItem *item = new QListViewItem(m_view->currentItem(), i18n("New Group"), ID);
00653 item->setRenameEnabled(0, true);
00654 item->setPixmap(0, SmallIcon("folder"));
00655 m_view->ensureItemVisible(item);
00656 item->startRename(0);
00657 }
00658 }
00659
00660 void KXmlCommandAdvancedDlg::slotAddOption()
00661 {
00662 if (m_view->currentItem())
00663 {
00664 QString ID = generateId(m_opts);
00665
00666 DrBase *opt = new DrStringOption;
00667 opt->setName(ID);
00668 opt->set("text", i18n("New Option"));
00669 m_opts[ID] = opt;
00670
00671 QListViewItem *item = new QListViewItem(m_view->currentItem(), i18n("New Option"), ID);
00672 item->setRenameEnabled(0, true);
00673 item->setPixmap(0, SmallIcon("document"));
00674 m_view->ensureItemVisible(item);
00675 item->startRename(0);
00676 }
00677 }
00678
00679 void KXmlCommandAdvancedDlg::slotRemoveItem()
00680 {
00681 QListViewItem *item = m_view->currentItem();
00682 if (item)
00683 {
00684 QListViewItem *newCurrent(item->nextSibling());
00685 if (!newCurrent)
00686 newCurrent = item->parent();
00687 removeItem(item);
00688 delete item;
00689 m_view->setSelected(newCurrent, true);
00690 }
00691 }
00692
00693 void KXmlCommandAdvancedDlg::removeItem(QListViewItem *item)
00694 {
00695 delete m_opts[item->text(1)];
00696 m_opts.remove(item->text(1));
00697 QListViewItem *child = item->firstChild();
00698 while (child && item)
00699 {
00700 removeItem(child);
00701 if ( item )
00702 item = item->nextSibling();
00703 }
00704 }
00705
00706 void KXmlCommandAdvancedDlg::slotMoveUp()
00707 {
00708 QListViewItem *item = m_view->currentItem(), *prev = 0;
00709 if (item && (prev=findPrev(item)))
00710 {
00711 QListViewItem *after(0);
00712 if ((after=findPrev(prev)) != 0)
00713 item->moveItem(after);
00714 else
00715 {
00716 QListViewItem *parent = item->parent();
00717 parent->takeItem(item);
00718 parent->insertItem(item);
00719 }
00720 m_view->setSelected(item, true);
00721 slotSelectionChanged(item);
00722 }
00723 }
00724
00725 void KXmlCommandAdvancedDlg::slotMoveDown()
00726 {
00727 QListViewItem *item = m_view->currentItem(), *next = 0;
00728 if (item && (next=findNext(item)))
00729 {
00730 item->moveItem(next);
00731 m_view->setSelected(item, true);
00732 slotSelectionChanged(item);
00733 }
00734 }
00735
00736 void KXmlCommandAdvancedDlg::slotCommandChanged(const QString& cmd)
00737 {
00738 m_inputfile->parentWidget()->setEnabled(cmd.find("%filterinput") != -1);
00739 m_outputfile->parentWidget()->setEnabled(cmd.find("%filteroutput") != -1);
00740 m_view->setEnabled(cmd.find("%filterargs") != -1);
00741 m_name->parentWidget()->setEnabled(m_view->isEnabled());
00742 slotSelectionChanged((m_view->isEnabled() ? m_view->currentItem() : 0));
00743 m_view->setOpen(m_view->firstChild(), m_view->isEnabled());
00744 }
00745
00746 void KXmlCommandAdvancedDlg::slotValueSelected(QListViewItem *item)
00747 {
00748 m_addval->setEnabled(m_type->currentItem() != 4 || m_values->childCount() < 2);
00749 m_delval->setEnabled(item != 0);
00750 }
00751
00752 void KXmlCommandAdvancedDlg::slotOptionRenamed(QListViewItem *item, int)
00753 {
00754 if (item && m_opts.contains(item->text(1)))
00755 {
00756 DrBase *opt = m_opts[item->text(1)];
00757 opt->set("text", item->text(0));
00758 slotSelectionChanged(item);
00759 }
00760 }
00761
00762 void KXmlCommandAdvancedDlg::recreateGroup(QListViewItem *item, DrGroup *grp)
00763 {
00764 if (!item)
00765 return;
00766
00767 QListViewItem *child = item->firstChild();
00768 while (child)
00769 {
00770 DrBase *opt = (m_opts.contains(child->text(1)) ? m_opts[child->text(1)] : 0);
00771 if (opt)
00772 {
00773 if (opt->type() == DrBase::Group)
00774 {
00775 DrGroup *childGroup = static_cast<DrGroup*>(opt);
00776 recreateGroup(child, childGroup);
00777 grp->addGroup(childGroup);
00778 }
00779 else
00780 {
00781 opt->setName("_kde-"+m_xmlcmd->name()+"-"+opt->name());
00782 grp->addOption(opt);
00783 }
00784 m_opts.remove(child->text(1));
00785 }
00786 child = child->nextSibling();
00787 }
00788 }
00789
00790 bool KXmlCommandAdvancedDlg::editCommand(KXmlCommand *xmlcmd, QWidget *parent)
00791 {
00792 if (!xmlcmd)
00793 return false;
00794
00795 KDialogBase dlg(parent, 0, true, i18n("Command Edit for %1").arg(xmlcmd->name()), KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok, false);
00796 KXmlCommandAdvancedDlg *xmldlg = new KXmlCommandAdvancedDlg(&dlg);
00797 dlg.setMainWidget(xmldlg);
00798
00799 xmldlg->setCommand(xmlcmd);
00800 if (dlg.exec())
00801 {
00802 xmlcmd->setCommand(xmldlg->m_command->text());
00803 xmlcmd->setIo(xmldlg->m_inputfile->text(), true, false);
00804 xmlcmd->setIo(xmldlg->m_inputpipe->text(), true, true);
00805 xmlcmd->setIo(xmldlg->m_outputfile->text(), false, false);
00806 xmlcmd->setIo(xmldlg->m_outputpipe->text(), false, true);
00807 xmlcmd->setComment( xmldlg->m_comment->text().replace( QRegExp( "\n" ), " " ) );
00808
00809
00810 DrMain *driver = (xmldlg->m_opts.contains("__root__") ? static_cast<DrMain*>(xmldlg->m_opts["__root__"]) : 0);
00811 if (!driver && xmldlg->m_opts.count() > 0)
00812 {
00813 kdDebug() << "KXmlCommandAdvancedDlg: driver structure not found, creating one" << endl;
00814 driver = new DrMain;
00815 driver->setName(xmlcmd->name());
00816 }
00817 xmldlg->recreateGroup(xmldlg->m_view->firstChild(), driver);
00818 xmldlg->m_opts.remove("__root__");
00819 xmlcmd->setDriver(driver);
00820
00821
00822
00823 return true;
00824 }
00825 return false;
00826 }
00827
00828
00829
00830 KXmlCommandDlg::KXmlCommandDlg(QWidget *parent, const char *name)
00831 : KDialogBase(parent, name, true, QString::null, Ok|Cancel|Details, Ok, true)
00832 {
00833 setButtonText(Details, i18n("&Mime Type Settings"));
00834 m_cmd = 0;
00835
00836 QWidget *dummy = new QWidget(this, "TopDetail");
00837 QWidget *topmain = new QWidget(this, "TopMain");
00838
00839 QGroupBox *m_gb1 = new QGroupBox(0, Qt::Horizontal, i18n("Supported &Input Formats"), dummy);
00840 QGroupBox *m_gb2 = new QGroupBox(0, Qt::Horizontal, i18n("Requirements"), topmain);
00841
00842 m_description = new QLineEdit(topmain);
00843 m_idname = new QLabel(topmain);
00844 m_requirements = new KListView(m_gb2);
00845 m_requirements->addColumn("");
00846 m_requirements->header()->hide();
00847 m_addreq = new QToolButton(m_gb2);
00848 m_addreq->setIconSet(SmallIconSet("filenew"));
00849 m_removereq = new QToolButton(m_gb2);
00850 m_removereq->setIconSet(SmallIconSet("editdelete"));
00851 QPushButton *m_edit = new KPushButton(KGuiItem(i18n("&Edit Command..."), "edit"), topmain);
00852 m_mimetype = new QComboBox(dummy);
00853 m_availablemime = new KListBox(m_gb1);
00854 m_selectedmime = new KListBox(m_gb1);
00855 m_addmime = new QToolButton(m_gb1);
00856 m_addmime->setIconSet(QApplication::reverseLayout()? SmallIconSet("forward") : SmallIconSet("back"));
00857 m_removemime = new QToolButton(m_gb1);
00858 m_removemime->setIconSet(QApplication::reverseLayout()? SmallIconSet("back" ) : SmallIconSet("forward"));
00859 m_gb2->setMinimumWidth(380);
00860 m_gb1->setMinimumHeight(180);
00861 m_requirements->setMaximumHeight(80);
00862 m_removereq->setEnabled(false);
00863 m_addmime->setEnabled(false);
00864 m_removemime->setEnabled(false);
00865
00866 QLabel *m_desclab = new QLabel(i18n("&Description:"), topmain);
00867 m_desclab->setBuddy(m_description);
00868 QLabel *m_mimetypelab = new QLabel(i18n("Output &format:"), dummy);
00869 m_mimetypelab->setBuddy(m_mimetype);
00870 QLabel *m_idnamelab = new QLabel(i18n("ID name:"), topmain);
00871
00872 QFont f(m_idname->font());
00873 f.setBold(true);
00874 m_idname->setFont(f);
00875
00876 KSeparator *sep1 = new KSeparator(QFrame::HLine, dummy);
00877
00878 QVBoxLayout *l0 = new QVBoxLayout(topmain, 0, 10);
00879 QGridLayout *l5 = new QGridLayout(0, 2, 2, 0, 5);
00880 l0->addLayout(l5);
00881 l5->addWidget(m_idnamelab, 0, 0);
00882 l5->addWidget(m_idname, 0, 1);
00883 l5->addWidget(m_desclab, 1, 0);
00884 l5->addWidget(m_description, 1, 1);
00885 l0->addWidget(m_gb2);
00886 QHBoxLayout *l3 = new QHBoxLayout(0, 0, 0);
00887 l0->addLayout(l3);
00888 l3->addWidget(m_edit);
00889 l3->addStretch(1);
00890
00891 QVBoxLayout *l7 = new QVBoxLayout(dummy, 0, 10);
00892 QHBoxLayout *l6 = new QHBoxLayout(0, 0, 5);
00893 l7->addWidget(sep1);
00894 l7->addLayout(l6);
00895 l6->addWidget(m_mimetypelab, 0);
00896 l6->addWidget(m_mimetype, 1);
00897 l7->addWidget(m_gb1);
00898 QGridLayout *l2 = new QGridLayout(m_gb1->layout(), 4, 3, 10);
00899 l2->addMultiCellWidget(m_availablemime, 0, 3, 2, 2);
00900 l2->addMultiCellWidget(m_selectedmime, 0, 3, 0, 0);
00901 l2->addWidget(m_addmime, 1, 1);
00902 l2->addWidget(m_removemime, 2, 1);
00903 l2->setRowStretch(0, 1);
00904 l2->setRowStretch(3, 1);
00905 QHBoxLayout *l4 = new QHBoxLayout(m_gb2->layout(), 10);
00906 l4->addWidget(m_requirements);
00907 QVBoxLayout *l8 = new QVBoxLayout(0, 0, 0);
00908 l4->addLayout(l8);
00909 l8->addWidget(m_addreq);
00910 l8->addWidget(m_removereq);
00911 l8->addStretch(1);
00912
00913 connect(m_addmime, SIGNAL(clicked()), SLOT(slotAddMime()));
00914 connect(m_removemime, SIGNAL(clicked()), SLOT(slotRemoveMime()));
00915 connect(m_edit, SIGNAL(clicked()), SLOT(slotEditCommand()));
00916 connect(m_requirements, SIGNAL(selectionChanged(QListViewItem*)), SLOT(slotReqSelected(QListViewItem*)));
00917 connect(m_availablemime, SIGNAL(selectionChanged(QListBoxItem*)), SLOT(slotAvailableSelected(QListBoxItem*)));
00918 connect(m_selectedmime, SIGNAL(selectionChanged(QListBoxItem*)), SLOT(slotSelectedSelected(QListBoxItem*)));
00919 connect(m_addreq, SIGNAL(clicked()), SLOT(slotAddReq()));
00920 connect(m_removereq, SIGNAL(clicked()), SLOT(slotRemoveReq()));
00921
00922 KMimeType::List list = KMimeType::allMimeTypes();
00923 for (QValueList<KMimeType::Ptr>::ConstIterator it=list.begin(); it!=list.end(); ++it)
00924 {
00925 QString mimetype = (*it)->name();
00926 m_mimelist << mimetype;
00927 }
00928
00929 m_mimelist.sort();
00930 m_mimetype->insertStringList(m_mimelist);
00931 m_availablemime->insertStringList(m_mimelist);
00932
00933 setMainWidget(topmain);
00934 setDetailsWidget(dummy);
00935 }
00936
00937 void KXmlCommandDlg::setCommand(KXmlCommand *xmlCmd)
00938 {
00939 setCaption(i18n("Command Edit for %1").arg(xmlCmd->name()));
00940
00941 m_cmd = xmlCmd;
00942 m_description->setText(i18n(xmlCmd->description().utf8()));
00943 m_idname->setText(xmlCmd->name());
00944
00945 m_requirements->clear();
00946 QStringList list = xmlCmd->requirements();
00947 QListViewItem *item(0);
00948 for (QStringList::ConstIterator it=list.begin(); it!=list.end(); ++it)
00949 {
00950 item = new QListViewItem(m_requirements, item, *it);
00951 item->setRenameEnabled(0, true);
00952 }
00953
00954 int index = m_mimelist.findIndex(xmlCmd->mimeType());
00955 if (index != -1)
00956 m_mimetype->setCurrentItem(index);
00957 else
00958 m_mimetype->setCurrentItem(0);
00959
00960 list = xmlCmd->inputMimeTypes();
00961 m_selectedmime->clear();
00962 m_availablemime->clear();
00963 m_availablemime->insertStringList(m_mimelist);
00964 for (QStringList::ConstIterator it=list.begin(); it!=list.end(); ++it)
00965 {
00966 m_selectedmime->insertItem(*it);
00967 delete m_availablemime->findItem(*it, Qt::ExactMatch);
00968 }
00969 }
00970
00971 void KXmlCommandDlg::slotOk()
00972 {
00973 if (m_cmd)
00974 {
00975 m_cmd->setMimeType((m_mimetype->currentText() == "all/all" ? QString::null : m_mimetype->currentText()));
00976 m_cmd->setDescription(m_description->text());
00977 QStringList l;
00978 QListViewItem *item = m_requirements->firstChild();
00979 while (item)
00980 {
00981 l << item->text(0);
00982 item = item->nextSibling();
00983 }
00984 m_cmd->setRequirements(l);
00985 l.clear();
00986 for (uint i=0; i<m_selectedmime->count(); i++)
00987 l << m_selectedmime->text(i);
00988 m_cmd->setInputMimeTypes(l);
00989 }
00990 KDialogBase::slotOk();
00991 }
00992
00993 bool KXmlCommandDlg::editCommand(KXmlCommand *xmlCmd, QWidget *parent)
00994 {
00995 if (!xmlCmd)
00996 return false;
00997
00998 KXmlCommandDlg xmldlg(parent, 0);
00999 xmldlg.setCommand(xmlCmd);
01000
01001 return (xmldlg.exec() == Accepted);
01002 }
01003
01004 void KXmlCommandDlg::slotAddMime()
01005 {
01006 int index = m_availablemime->currentItem();
01007 if (index != -1)
01008 {
01009 m_selectedmime->insertItem(m_availablemime->currentText());
01010 m_availablemime->removeItem(index);
01011 m_selectedmime->sort();
01012 }
01013 }
01014
01015 void KXmlCommandDlg::slotRemoveMime()
01016 {
01017 int index = m_selectedmime->currentItem();
01018 if (index != -1)
01019 {
01020 m_availablemime->insertItem(m_selectedmime->currentText());
01021 m_selectedmime->removeItem(index);
01022 m_availablemime->sort();
01023 }
01024 }
01025
01026 void KXmlCommandDlg::slotEditCommand()
01027 {
01028 KXmlCommandAdvancedDlg::editCommand(m_cmd, parentWidget());
01029 }
01030
01031 void KXmlCommandDlg::slotAddReq()
01032 {
01033 QListViewItem *item = new QListViewItem(m_requirements, m_requirements->lastItem(), i18n("exec:/"));
01034 item->setRenameEnabled(0, true);
01035 m_requirements->ensureItemVisible(item);
01036 item->startRename(0);
01037 }
01038
01039 void KXmlCommandDlg::slotRemoveReq()
01040 {
01041 delete m_requirements->currentItem();
01042 }
01043
01044 void KXmlCommandDlg::slotReqSelected(QListViewItem *item)
01045 {
01046 m_removereq->setEnabled(item);
01047 }
01048
01049 void KXmlCommandDlg::slotAvailableSelected(QListBoxItem *item)
01050 {
01051 m_addmime->setEnabled(item);
01052 }
01053
01054 void KXmlCommandDlg::slotSelectedSelected(QListBoxItem *item)
01055 {
01056 m_removemime->setEnabled(item);
01057 }
01058
01059 #include "kxmlcommanddlg.moc"