lib

KoTemplateCreateDia.cpp

00001 /*
00002    This file is part of the KDE project
00003    Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
00004                  2000 Werner Trobin <trobin@kde.org>
00005    Copyright (C) 2004 Nicolas GOUTTE <goutte@kde.org>
00006 
00007    This library is free software; you can redistribute it and/or
00008    modify it under the terms of the GNU Library General Public
00009    License as published by the Free Software Foundation; either
00010    version 2 of the License, or (at your option) any later version.
00011 
00012    This library is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015    Library General Public License for more details.
00016 
00017    You should have received a copy of the GNU Library General Public License
00018    along with this library; see the file COPYING.LIB.  If not, write to
00019    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020  * Boston, MA 02110-1301, USA.
00021 */
00022 
00023 #include <KoTemplateCreateDia.h>
00024 
00025 #include <qfile.h>
00026 #include <qlayout.h>
00027 #include <qlabel.h>
00028 #include <qgroupbox.h>
00029 #include <qradiobutton.h>
00030 #include <qpushbutton.h>
00031 #include <qheader.h>
00032 #include <qcheckbox.h>
00033 #include <qtooltip.h>
00034 
00035 #include <ktempfile.h>
00036 #include <klineedit.h>
00037 #include <klistview.h>
00038 #include <klocale.h>
00039 #include <KoTemplates.h>
00040 #include <kicondialog.h>
00041 #include <kinputdialog.h>
00042 #include <kmessagebox.h>
00043 #include <kimageio.h>
00044 #include <kstandarddirs.h>
00045 #include <kdebug.h>
00046 #include <kio/netaccess.h>
00047 #include <kiconloader.h>
00048 #include <kaboutdata.h>
00049 #include <kconfigbase.h>
00050 #include <kconfig.h>
00051 
00052 #include <stdlib.h>
00053 #include <kinstance.h>
00054 
00055 
00056 class KoTemplateCreateDiaPrivate {
00057 public:
00058     KoTemplateCreateDiaPrivate( QWidget* /*parent*/, KInstance * instance)
00059          : m_instance( instance ), m_tempFile( QString::null, ".png" )
00060     {
00061         m_tree=0L;
00062         m_name=0L;
00063         m_default=0L;
00064         m_custom=0L;
00065         m_select=0L;
00066         m_preview=0L;
00067         m_groups=0L;
00068         m_add=0L;
00069         m_remove=0L;
00070         m_defaultTemplate=0L;
00071         m_tempFile.setAutoDelete( true );
00072     }
00073     ~KoTemplateCreateDiaPrivate() {
00074         delete m_tree;
00075     }
00076 
00077     KoTemplateTree *m_tree;
00078     KLineEdit *m_name;
00079     QRadioButton *m_default, *m_custom;
00080     QPushButton *m_select;
00081     QLabel *m_preview;
00082     QString m_customFile;
00083     QPixmap m_customPixmap;
00084     KListView *m_groups;
00085     QPushButton *m_add, *m_remove;
00086     QCheckBox *m_defaultTemplate;
00087     KInstance *m_instance;
00088     bool m_changed;
00090     KTempFile m_tempFile;
00091 };
00092 
00093 
00094 /****************************************************************************
00095  *
00096  * Class: koTemplateCreateDia
00097  *
00098  ****************************************************************************/
00099 
00100 KoTemplateCreateDia::KoTemplateCreateDia( const QCString &templateType, KInstance *instance,
00101                                           const QString &file, const QPixmap &pix, QWidget *parent ) :
00102     KDialogBase( parent, "template create dia", true, i18n( "Create Template" ),
00103                  KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok ), m_file(file), m_pixmap(pix) {
00104 
00105     d=new KoTemplateCreateDiaPrivate( parent, instance );
00106 
00107     QFrame *mainwidget=makeMainWidget();
00108     QHBoxLayout *mbox=new QHBoxLayout(mainwidget, 0, KDialogBase::spacingHint());
00109     QVBoxLayout *leftbox=new QVBoxLayout(mbox);
00110 
00111     QLabel *label=new QLabel(i18n("Name:"), mainwidget);
00112     leftbox->addSpacing(label->fontMetrics().height()/2);
00113     QHBoxLayout *namefield=new QHBoxLayout(leftbox);
00114     namefield->addWidget(label);
00115     d->m_name=new KLineEdit(mainwidget);
00116     d->m_name->setFocus();
00117     connect(d->m_name, SIGNAL(textChanged(const QString &)),
00118             this, SLOT(slotNameChanged(const QString &)));
00119     namefield->addWidget(d->m_name);
00120 
00121     label=new QLabel(i18n("Group:"), mainwidget);
00122     leftbox->addWidget(label);
00123     d->m_groups=new KListView(mainwidget);
00124     leftbox->addWidget(d->m_groups);
00125     d->m_groups->addColumn("");
00126     d->m_groups->header()->hide();
00127     d->m_groups->setRootIsDecorated(true);
00128     d->m_groups->setSorting(0);
00129 
00130     d->m_tree=new KoTemplateTree(templateType, instance, true);
00131     fillGroupTree();
00132     d->m_groups->sort();
00133 
00134     QHBoxLayout *bbox=new QHBoxLayout(leftbox);
00135     d->m_add=new QPushButton(i18n("&Add Group..."), mainwidget);
00136     connect(d->m_add, SIGNAL(clicked()), this, SLOT(slotAddGroup()));
00137     bbox->addWidget(d->m_add);
00138     d->m_remove=new QPushButton(i18n("&Remove"), mainwidget);
00139     connect(d->m_remove, SIGNAL(clicked()), this, SLOT(slotRemove()));
00140     bbox->addWidget(d->m_remove);
00141 
00142     QVBoxLayout *rightbox=new QVBoxLayout(mbox);
00143     QGroupBox *pixbox=new QGroupBox(i18n("Picture"), mainwidget);
00144     rightbox->addWidget(pixbox);
00145     QVBoxLayout *pixlayout=new QVBoxLayout(pixbox, KDialogBase::marginHint(),
00146                                            KDialogBase::spacingHint());
00147     pixlayout->addSpacing(pixbox->fontMetrics().height()/2);
00148     pixlayout->addStretch(1);
00149     d->m_default=new QRadioButton(i18n("&Default"), pixbox);
00150     d->m_default->setChecked(true);
00151     connect(d->m_default, SIGNAL(clicked()), this, SLOT(slotDefault()));
00152     pixlayout->addWidget(d->m_default);
00153     QHBoxLayout *custombox=new QHBoxLayout(pixlayout);
00154     d->m_custom=new QRadioButton(i18n("Custom"), pixbox);
00155     d->m_custom->setChecked(false);
00156     connect(d->m_custom, SIGNAL(clicked()), this, SLOT(slotCustom()));
00157     custombox->addWidget(d->m_custom);
00158     d->m_select=new QPushButton(i18n("&Select..."), pixbox);
00159     connect(d->m_select, SIGNAL(clicked()), this, SLOT(slotSelect()));
00160     custombox->addWidget(d->m_select, 1);
00161     custombox->addStretch(1);
00162     pixlayout->addStretch(1);
00163     label=new QLabel(i18n("Preview:"), pixbox);
00164     pixlayout->addWidget(label);
00165     QHBoxLayout *previewbox=new QHBoxLayout(pixlayout);
00166     previewbox->addStretch(10);
00167     d->m_preview=new QLabel(pixbox); // setPixmap() -> auto resize?
00168     previewbox->addWidget(d->m_preview);
00169     previewbox->addStretch(10);
00170     pixlayout->addStretch(8);
00171 
00172     d->m_defaultTemplate = new QCheckBox( i18n("Use the new template as default"), mainwidget );
00173     d->m_defaultTemplate->setChecked( true );
00174     QToolTip::add( d->m_defaultTemplate, i18n("Use the new template every time %1 starts").arg(instance->aboutData()->programName() ) );
00175     rightbox->addWidget( d->m_defaultTemplate );
00176 
00177     enableButtonOK(false);
00178     d->m_changed=false;
00179     updatePixmap();
00180 
00181     connect(d->m_groups,SIGNAL( selectionChanged()),this,SLOT(slotSelectionChanged()));
00182 
00183     d->m_remove->setEnabled(d->m_groups->currentItem());
00184 }
00185 
00186 KoTemplateCreateDia::~KoTemplateCreateDia() {
00187     delete d;
00188 }
00189 
00190 void KoTemplateCreateDia::slotSelectionChanged()
00191 {
00192     const QListViewItem* item = d->m_groups->currentItem();
00193     d->m_remove->setEnabled( item );
00194     if ( ! item )
00195         return;
00196 
00197     if ( item->depth() > 0 )
00198     {
00199         d->m_name->setText( item->text( 0 ) );
00200     }
00201 }
00202 
00203 void KoTemplateCreateDia::createTemplate( const QCString &templateType, KInstance *instance,
00204                                           const QString &file, const QPixmap &pix, QWidget *parent ) {
00205 
00206     KoTemplateCreateDia *dia = new KoTemplateCreateDia( templateType, instance, file, pix, parent );
00207     dia->exec();
00208     delete dia;
00209 }
00210 
00211 void KoTemplateCreateDia::slotOk() {
00212 
00213     // get the current item, if there is one...
00214     QListViewItem *item=d->m_groups->currentItem();
00215     if(!item)
00216         item=d->m_groups->firstChild();
00217     if(!item) {    // safe :)
00218         d->m_tree->writeTemplateTree();
00219         KDialogBase::slotCancel();
00220         return;
00221     }
00222     // is it a group or a template? anyway - get the group :)
00223     if(item->depth()!=0)
00224         item=item->parent();
00225     if(!item) {    // *very* safe :P
00226         d->m_tree->writeTemplateTree();
00227         KDialogBase::slotCancel();
00228         return;
00229     }
00230 
00231     KoTemplateGroup *group=d->m_tree->find(item->text(0));
00232     if(!group) {    // even safer
00233         d->m_tree->writeTemplateTree();
00234         KDialogBase::slotCancel();
00235         return;
00236     }
00237 
00238     if(d->m_name->text().isEmpty()) {
00239         d->m_tree->writeTemplateTree();
00240         KDialogBase::slotCancel();
00241         return;
00242     }
00243 
00244     // copy the tmp file and the picture the app provides
00245     QString dir=d->m_tree->instance()->dirs()->saveLocation(d->m_tree->templateType());
00246     dir+=group->name();
00247     QString templateDir=dir+"/.source/";
00248     QString iconDir=dir+"/.icon/";
00249 
00250     QString file=KoTemplates::stripWhiteSpace(d->m_name->text());
00251     QString tmpIcon=".icon/"+file;
00252     tmpIcon+=".png";
00253     QString icon=iconDir+file;
00254     icon+=".png";
00255 
00256     // try to find the extension for the template file :P
00257     const int pos = m_file.findRev( '.' );
00258     QString ext;
00259     if ( pos > -1 )
00260         ext = m_file.mid( pos );
00261     else
00262         kdWarning(30004) << "Template extension not found!" << endl;
00263 
00264     KURL dest;
00265     dest.setPath(templateDir+file+ext);
00266     if ( QFile::exists( dest.prettyURL(0, KURL::StripFileProtocol) ) )
00267     {
00268         do
00269         {
00270             file.prepend( '_' );
00271             dest.setPath( templateDir + file + ext );
00272             tmpIcon=".icon/"+file+".png";
00273             icon=iconDir+file+".png";
00274         }
00275         while ( KIO::NetAccess::exists( dest, true, this ) );
00276     }
00277     bool ignore = false;
00278     kdDebug(30004) << "Trying to create template: " << d->m_name->text() << "URL=" << ".source/"+file+ext << " ICON=" << tmpIcon << endl;
00279     KoTemplate *t=new KoTemplate(d->m_name->text(), QString::null, ".source/"+file+ext, tmpIcon, "", "", false, true);
00280     if(!group->add(t)) {
00281         KoTemplate *existingTemplate=group->find(d->m_name->text());
00282         if(existingTemplate && !existingTemplate->isHidden()) {
00283             if(KMessageBox::warningYesNo(this, i18n("Do you really want to overwrite"
00284                                                     " the existing '%1' template?").
00285                                          arg(existingTemplate->name()))==KMessageBox::Yes)
00286                 group->add(t, true);
00287             else
00288             {
00289                 delete t;
00290                 return;
00291             }
00292         }
00293         else
00294             ignore = true;
00295     }
00296 
00297     if(!KStandardDirs::makeDir(templateDir) || !KStandardDirs::makeDir(iconDir)) {
00298         d->m_tree->writeTemplateTree();
00299         KDialogBase::slotCancel();
00300         return;
00301     }
00302 
00303     KURL orig;
00304     orig.setPath( m_file );
00305     // don't overwrite the hidden template file with a new non-hidden one
00306     if ( !ignore )
00307     {
00308         // copy the template file
00309         KIO::NetAccess::file_copy( orig, dest, -1, true, false, this );
00310 
00311         // save the picture
00312         if(d->m_default->isChecked() && !m_pixmap.isNull())
00313             m_pixmap.save(icon, "PNG");
00314         else if(!d->m_customPixmap.isNull())
00315             d->m_customPixmap.save(icon, "PNG");
00316         else
00317             kdWarning(30004) << "Could not save the preview picture!" << endl;
00318     }
00319 
00320     // if there's a .directory file, we copy this one, too
00321     bool ready=false;
00322     QStringList tmp=group->dirs();
00323     for(QStringList::ConstIterator it=tmp.begin(); it!=tmp.end() && !ready; ++it) {
00324         if((*it).contains(dir)==0) {
00325             orig.setPath( (*it)+".directory" );
00326             // Check if we can read the file
00327             if( KIO::NetAccess::exists(orig, true, this) ) {
00328                 dest.setPath( dir+"/.directory" );
00329                 // We copy the file with overwrite
00330                 KIO::NetAccess::file_copy( orig, dest, -1, true, false, this );
00331                 ready=true;
00332             }
00333         }
00334     }
00335 
00336     d->m_tree->writeTemplateTree();
00337 
00338     if ( d->m_defaultTemplate->isChecked() )
00339     {
00340       KConfigGroup grp( d->m_instance->config(), "TemplateChooserDialog" );
00341       grp.writeEntry( "LastReturnType", "Template" );
00342       grp.writePathEntry( "FullTemplateName", dir + "/" + t->file() );
00343       grp.writePathEntry( "AlwaysUseTemplate", dir + "/" + t->file() );
00344     }
00345     KDialogBase::slotOk();
00346 }
00347 
00348 void KoTemplateCreateDia::slotDefault() {
00349 
00350     d->m_default->setChecked(true);
00351     d->m_custom->setChecked(false);
00352     updatePixmap();
00353 }
00354 
00355 void KoTemplateCreateDia::slotCustom() {
00356 
00357     d->m_default->setChecked(false);
00358     d->m_custom->setChecked(true);
00359     if(d->m_customFile.isEmpty())
00360         slotSelect();
00361     else
00362         updatePixmap();
00363 }
00364 
00365 void KoTemplateCreateDia::slotSelect() {
00366 
00367     d->m_default->setChecked(false);
00368     d->m_custom->setChecked(true);
00369 
00370     QString name = KIconDialog::getIcon();
00371     if( name.isEmpty() ) {
00372         if(d->m_customFile.isEmpty()) {
00373             d->m_default->setChecked(true);
00374             d->m_custom->setChecked(false);
00375         }
00376         return;
00377     }
00378     // ### TODO: do a better remote loading without having to have d->m_tempFile
00379     QString path = KGlobal::iconLoader()->iconPath(name, KIcon::Desktop);
00380     d->m_customFile = path;
00381     d->m_customPixmap=QPixmap();
00382     updatePixmap();
00383 }
00384 
00385 void KoTemplateCreateDia::slotNameChanged(const QString &name) {
00386 
00387     if( ( name.stripWhiteSpace().isEmpty() || !d->m_groups->firstChild() ) && !d->m_changed )
00388         enableButtonOK(false);
00389     else
00390         enableButtonOK(true);
00391 }
00392 
00393 void KoTemplateCreateDia::slotAddGroup() {
00394     bool ok=false;
00395     const QString name ( KInputDialog::getText( i18n("Add Group"), i18n("Enter group name:"), QString::null, &ok, this ) );
00396     if(!ok)
00397         return;
00398     KoTemplateGroup *group=d->m_tree->find(name);
00399     if(group && !group->isHidden())
00400     {
00401         KMessageBox::information( this, i18n("This name is already used."), i18n("Add Group") );
00402         return;
00403     }
00404     QString dir=d->m_tree->instance()->dirs()->saveLocation(d->m_tree->templateType());
00405     dir+=name;
00406     KoTemplateGroup *newGroup=new KoTemplateGroup(name, dir, 0, true);
00407     d->m_tree->add(newGroup);
00408     QListViewItem *item=new QListViewItem(d->m_groups, name);
00409     d->m_groups->setCurrentItem(item);
00410     d->m_groups->sort();
00411     d->m_name->setFocus();
00412     enableButtonOK(true);
00413     d->m_changed=true;
00414 }
00415 
00416 void KoTemplateCreateDia::slotRemove() {
00417 
00418     QListViewItem *item=d->m_groups->currentItem();
00419     if(!item)
00420         return;
00421 
00422     QString what;
00423         QString removed;
00424         if (item->depth()==0) {
00425                 what =  i18n("Do you really want to remove that group?");
00426                 removed = i18n("Remove Group");
00427         } else {
00428                 what =  i18n("Do you really want to remove that template?");
00429         removed = i18n("Remove Template");
00430         }
00431 
00432     if(KMessageBox::warningContinueCancel(this, what,
00433                                  removed,KGuiItem(i18n("&Delete"),"editdelete"))==KMessageBox::Cancel) {
00434         d->m_name->setFocus();
00435         return;
00436     }
00437 
00438     if(item->depth()==0) {
00439         KoTemplateGroup *group=d->m_tree->find(item->text(0));
00440         if(group)
00441             group->setHidden(true);
00442     }
00443     else {
00444         bool done=false;
00445         for(KoTemplateGroup *g=d->m_tree->first(); g!=0L && !done; g=d->m_tree->next()) {
00446             KoTemplate *t=g->find(item->text(0));
00447             if(t) {
00448                 t->setHidden(true);
00449                 done=true;
00450             }
00451         }
00452     }
00453     delete item;
00454     item=0L;
00455     enableButtonOK(true);
00456     d->m_name->setFocus();
00457     d->m_changed=true;
00458 }
00459 
00460 void KoTemplateCreateDia::updatePixmap() {
00461 
00462     if(d->m_default->isChecked() && !m_pixmap.isNull())
00463         d->m_preview->setPixmap(m_pixmap);
00464     else if(d->m_custom->isChecked() && !d->m_customFile.isEmpty()) {
00465         if(d->m_customPixmap.isNull()) {
00466             kdDebug(30004) << "Trying to load picture " << d->m_customFile << endl;
00467             // use the code in KoTemplate to load the image... hacky, I know :)
00468             KoTemplate t("foo", "bar", QString::null, d->m_customFile);
00469             d->m_customPixmap=t.loadPicture(d->m_tree->instance());
00470         }
00471         else
00472             kdWarning(30004) << "Trying to load picture" << endl;
00473 
00474         if(!d->m_customPixmap.isNull())
00475             d->m_preview->setPixmap(d->m_customPixmap);
00476         else
00477             d->m_preview->setText(i18n("Could not load picture."));
00478     }
00479     else
00480         d->m_preview->setText(i18n("No picture available."));
00481 }
00482 
00483 void KoTemplateCreateDia::fillGroupTree() {
00484 
00485     for(KoTemplateGroup *group=d->m_tree->first(); group!=0L; group=d->m_tree->next()) {
00486         if(group->isHidden())
00487             continue;
00488         QListViewItem *groupItem=new QListViewItem(d->m_groups, group->name());
00489         for(KoTemplate *t=group->first(); t!=0L; t=group->next()) {
00490             if(t->isHidden())
00491                 continue;
00492             (void)new QListViewItem(groupItem, t->name());
00493         }
00494     }
00495 }
00496 
00497 #include <KoTemplateCreateDia.moc>
KDE Home | KDE Accessibility Home | Description of Access Keys