/* This file is part of the KDE project Copyright (C) 1998, 1999 Reginald Stadlbauer 2000 Werner Trobin Copyright (C) 2004 Nicolas GOUTTE This library 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 library 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 library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class KoTemplateCreateDiaPrivate { public: KoTemplateCreateDiaPrivate( TQWidget* /*parent*/, TDEInstance * instance) : m_instance( instance ), m_tempFile( TQString(), ".png" ) { m_tree=0L; m_name=0L; m_default=0L; m_custom=0L; m_select=0L; m_preview=0L; m_groups=0L; m_add=0L; m_remove=0L; m_defaultTemplate=0L; m_tempFile.setAutoDelete( true ); } ~KoTemplateCreateDiaPrivate() { delete m_tree; } KoTemplateTree *m_tree; KLineEdit *m_name; TQRadioButton *m_default, *m_custom; TQPushButton *m_select; TQLabel *m_preview; TQString m_customFile; TQPixmap m_customPixmap; KListView *m_groups; TQPushButton *m_add, *m_remove; TQCheckBox *m_defaultTemplate; TDEInstance *m_instance; bool m_changed; /// Temp file for remote picture file KTempFile m_tempFile; }; /**************************************************************************** * * Class: koTemplateCreateDia * ****************************************************************************/ KoTemplateCreateDia::KoTemplateCreateDia( const TQCString &templateType, TDEInstance *instance, const TQString &file, const TQPixmap &pix, TQWidget *parent ) : KDialogBase( parent, "template create dia", true, i18n( "Create Template" ), KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok ), m_file(file), m_pixmap(pix) { d=new KoTemplateCreateDiaPrivate( parent, instance ); TQFrame *mainwidget=makeMainWidget(); TQHBoxLayout *mbox=new TQHBoxLayout(mainwidget, 0, KDialogBase::spacingHint()); TQVBoxLayout *leftbox=new TQVBoxLayout(mbox); TQLabel *label=new TQLabel(i18n("Name:"), mainwidget); leftbox->addSpacing(label->fontMetrics().height()/2); TQHBoxLayout *namefield=new TQHBoxLayout(leftbox); namefield->addWidget(label); d->m_name=new KLineEdit(mainwidget); d->m_name->setFocus(); connect(d->m_name, TQT_SIGNAL(textChanged(const TQString &)), this, TQT_SLOT(slotNameChanged(const TQString &))); namefield->addWidget(d->m_name); label=new TQLabel(i18n("Group:"), mainwidget); leftbox->addWidget(label); d->m_groups=new KListView(mainwidget); leftbox->addWidget(d->m_groups); d->m_groups->addColumn(""); d->m_groups->header()->hide(); d->m_groups->setRootIsDecorated(true); d->m_groups->setSorting(0); d->m_tree=new KoTemplateTree(templateType, instance, true); fillGroupTree(); d->m_groups->sort(); TQHBoxLayout *bbox=new TQHBoxLayout(leftbox); d->m_add=new TQPushButton(i18n("&Add Group..."), mainwidget); connect(d->m_add, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotAddGroup())); bbox->addWidget(d->m_add); d->m_remove=new TQPushButton(i18n("&Remove"), mainwidget); connect(d->m_remove, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotRemove())); bbox->addWidget(d->m_remove); TQVBoxLayout *rightbox=new TQVBoxLayout(mbox); TQGroupBox *pixbox=new TQGroupBox(i18n("Picture"), mainwidget); rightbox->addWidget(pixbox); TQVBoxLayout *pixlayout=new TQVBoxLayout(pixbox, KDialogBase::marginHint(), KDialogBase::spacingHint()); pixlayout->addSpacing(pixbox->fontMetrics().height()/2); pixlayout->addStretch(1); d->m_default=new TQRadioButton(i18n("&Default"), pixbox); d->m_default->setChecked(true); connect(d->m_default, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotDefault())); pixlayout->addWidget(d->m_default); TQHBoxLayout *custombox=new TQHBoxLayout(pixlayout); d->m_custom=new TQRadioButton(i18n("Custom"), pixbox); d->m_custom->setChecked(false); connect(d->m_custom, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotCustom())); custombox->addWidget(d->m_custom); d->m_select=new TQPushButton(i18n("&Select..."), pixbox); connect(d->m_select, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotSelect())); custombox->addWidget(d->m_select, 1); custombox->addStretch(1); pixlayout->addStretch(1); label=new TQLabel(i18n("Preview:"), pixbox); pixlayout->addWidget(label); TQHBoxLayout *previewbox=new TQHBoxLayout(pixlayout); previewbox->addStretch(10); d->m_preview=new TQLabel(pixbox); // setPixmap() -> auto resize? previewbox->addWidget(d->m_preview); previewbox->addStretch(10); pixlayout->addStretch(8); d->m_defaultTemplate = new TQCheckBox( i18n("Use the new template as default"), mainwidget ); d->m_defaultTemplate->setChecked( true ); TQToolTip::add( d->m_defaultTemplate, i18n("Use the new template every time %1 starts").arg(instance->aboutData()->programName() ) ); rightbox->addWidget( d->m_defaultTemplate ); enableButtonOK(false); d->m_changed=false; updatePixmap(); connect(d->m_groups,TQT_SIGNAL( selectionChanged()),this,TQT_SLOT(slotSelectionChanged())); d->m_remove->setEnabled(d->m_groups->currentItem()); } KoTemplateCreateDia::~KoTemplateCreateDia() { delete d; } void KoTemplateCreateDia::slotSelectionChanged() { const TQListViewItem* item = d->m_groups->currentItem(); d->m_remove->setEnabled( item ); if ( ! item ) return; if ( item->depth() > 0 ) { d->m_name->setText( item->text( 0 ) ); } } void KoTemplateCreateDia::createTemplate( const TQCString &templateType, TDEInstance *instance, const TQString &file, const TQPixmap &pix, TQWidget *parent ) { KoTemplateCreateDia *dia = new KoTemplateCreateDia( templateType, instance, file, pix, parent ); dia->exec(); delete dia; } void KoTemplateCreateDia::slotOk() { // get the current item, if there is one... TQListViewItem *item=d->m_groups->currentItem(); if(!item) item=d->m_groups->firstChild(); if(!item) { // safe :) d->m_tree->writeTemplateTree(); KDialogBase::slotCancel(); return; } // is it a group or a template? anyway - get the group :) if(item->depth()!=0) item=item->parent(); if(!item) { // *very* safe :P d->m_tree->writeTemplateTree(); KDialogBase::slotCancel(); return; } KoTemplateGroup *group=d->m_tree->find(item->text(0)); if(!group) { // even safer d->m_tree->writeTemplateTree(); KDialogBase::slotCancel(); return; } if(d->m_name->text().isEmpty()) { d->m_tree->writeTemplateTree(); KDialogBase::slotCancel(); return; } // copy the tmp file and the picture the app provides TQString dir=d->m_tree->instance()->dirs()->saveLocation(d->m_tree->templateType()); dir+=group->name(); TQString templateDir=dir+"/.source/"; TQString iconDir=dir+"/.icon/"; TQString file=KoTemplates::stripWhiteSpace(d->m_name->text()); TQString tmpIcon=".icon/"+file; tmpIcon+=".png"; TQString icon=iconDir+file; icon+=".png"; // try to find the extension for the template file :P const int pos = m_file.findRev( '.' ); TQString ext; if ( pos > -1 ) ext = m_file.mid( pos ); else kdWarning(30004) << "Template extension not found!" << endl; KURL dest; dest.setPath(templateDir+file+ext); if ( TQFile::exists( dest.prettyURL(0, KURL::StripFileProtocol) ) ) { do { file.prepend( '_' ); dest.setPath( templateDir + file + ext ); tmpIcon=".icon/"+file+".png"; icon=iconDir+file+".png"; } while ( KIO::NetAccess::exists( dest, true, this ) ); } bool ignore = false; kdDebug(30004) << "Trying to create template: " << d->m_name->text() << "URL=" << ".source/"+file+ext << " ICON=" << tmpIcon << endl; KoTemplate *t=new KoTemplate(d->m_name->text(), TQString(), ".source/"+file+ext, tmpIcon, "", "", false, true); if(!group->add(t)) { KoTemplate *existingTemplate=group->find(d->m_name->text()); if(existingTemplate && !existingTemplate->isHidden()) { if(KMessageBox::warningYesNo(this, i18n("Do you really want to overwrite" " the existing '%1' template?"). arg(existingTemplate->name()))==KMessageBox::Yes) group->add(t, true); else { delete t; return; } } else ignore = true; } if(!KStandardDirs::makeDir(templateDir) || !KStandardDirs::makeDir(iconDir)) { d->m_tree->writeTemplateTree(); KDialogBase::slotCancel(); return; } KURL orig; orig.setPath( m_file ); // don't overwrite the hidden template file with a new non-hidden one if ( !ignore ) { // copy the template file KIO::NetAccess::file_copy( orig, dest, -1, true, false, this ); // save the picture if(d->m_default->isChecked() && !m_pixmap.isNull()) m_pixmap.save(icon, "PNG"); else if(!d->m_customPixmap.isNull()) d->m_customPixmap.save(icon, "PNG"); else kdWarning(30004) << "Could not save the preview picture!" << endl; } // if there's a .directory file, we copy this one, too bool ready=false; TQStringList tmp=group->dirs(); for(TQStringList::ConstIterator it=tmp.begin(); it!=tmp.end() && !ready; ++it) { if((*it).contains(dir)==0) { orig.setPath( (*it)+".directory" ); // Check if we can read the file if( KIO::NetAccess::exists(orig, true, this) ) { dest.setPath( dir+"/.directory" ); // We copy the file with overwrite KIO::NetAccess::file_copy( orig, dest, -1, true, false, this ); ready=true; } } } d->m_tree->writeTemplateTree(); if ( d->m_defaultTemplate->isChecked() ) { KConfigGroup grp( d->m_instance->config(), "TemplateChooserDialog" ); grp.writeEntry( "LastReturnType", "Template" ); grp.writePathEntry( "FullTemplateName", dir + "/" + t->file() ); grp.writePathEntry( "AlwaysUseTemplate", dir + "/" + t->file() ); } KDialogBase::slotOk(); } void KoTemplateCreateDia::slotDefault() { d->m_default->setChecked(true); d->m_custom->setChecked(false); updatePixmap(); } void KoTemplateCreateDia::slotCustom() { d->m_default->setChecked(false); d->m_custom->setChecked(true); if(d->m_customFile.isEmpty()) slotSelect(); else updatePixmap(); } void KoTemplateCreateDia::slotSelect() { d->m_default->setChecked(false); d->m_custom->setChecked(true); TQString name = KIconDialog::getIcon(); if( name.isEmpty() ) { if(d->m_customFile.isEmpty()) { d->m_default->setChecked(true); d->m_custom->setChecked(false); } return; } // ### TODO: do a better remote loading without having to have d->m_tempFile TQString path = KGlobal::iconLoader()->iconPath(name, KIcon::Desktop); d->m_customFile = path; d->m_customPixmap=TQPixmap(); updatePixmap(); } void KoTemplateCreateDia::slotNameChanged(const TQString &name) { if( ( name.stripWhiteSpace().isEmpty() || !d->m_groups->firstChild() ) && !d->m_changed ) enableButtonOK(false); else enableButtonOK(true); } void KoTemplateCreateDia::slotAddGroup() { bool ok=false; const TQString name ( KInputDialog::getText( i18n("Add Group"), i18n("Enter group name:"), TQString(), &ok, this ) ); if(!ok) return; KoTemplateGroup *group=d->m_tree->find(name); if(group && !group->isHidden()) { KMessageBox::information( this, i18n("This name is already used."), i18n("Add Group") ); return; } TQString dir=d->m_tree->instance()->dirs()->saveLocation(d->m_tree->templateType()); dir+=name; KoTemplateGroup *newGroup=new KoTemplateGroup(name, dir, 0, true); d->m_tree->add(newGroup); TQListViewItem *item=new TQListViewItem(d->m_groups, name); d->m_groups->setCurrentItem(item); d->m_groups->sort(); d->m_name->setFocus(); enableButtonOK(true); d->m_changed=true; } void KoTemplateCreateDia::slotRemove() { TQListViewItem *item=d->m_groups->currentItem(); if(!item) return; TQString what; TQString removed; if (item->depth()==0) { what = i18n("Do you really want to remove that group?"); removed = i18n("Remove Group"); } else { what = i18n("Do you really want to remove that template?"); removed = i18n("Remove Template"); } if(KMessageBox::warningContinueCancel(this, what, removed,KGuiItem(i18n("&Delete"),"editdelete"))==KMessageBox::Cancel) { d->m_name->setFocus(); return; } if(item->depth()==0) { KoTemplateGroup *group=d->m_tree->find(item->text(0)); if(group) group->setHidden(true); } else { bool done=false; for(KoTemplateGroup *g=d->m_tree->first(); g!=0L && !done; g=d->m_tree->next()) { KoTemplate *t=g->find(item->text(0)); if(t) { t->setHidden(true); done=true; } } } delete item; item=0L; enableButtonOK(true); d->m_name->setFocus(); d->m_changed=true; } void KoTemplateCreateDia::updatePixmap() { if(d->m_default->isChecked() && !m_pixmap.isNull()) d->m_preview->setPixmap(m_pixmap); else if(d->m_custom->isChecked() && !d->m_customFile.isEmpty()) { if(d->m_customPixmap.isNull()) { kdDebug(30004) << "Trying to load picture " << d->m_customFile << endl; // use the code in KoTemplate to load the image... hacky, I know :) KoTemplate t("foo", "bar", TQString(), d->m_customFile); d->m_customPixmap=t.loadPicture(d->m_tree->instance()); } else kdWarning(30004) << "Trying to load picture" << endl; if(!d->m_customPixmap.isNull()) d->m_preview->setPixmap(d->m_customPixmap); else d->m_preview->setText(i18n("Could not load picture.")); } else d->m_preview->setText(i18n("No picture available.")); } void KoTemplateCreateDia::fillGroupTree() { for(KoTemplateGroup *group=d->m_tree->first(); group!=0L; group=d->m_tree->next()) { if(group->isHidden()) continue; TQListViewItem *groupItem=new TQListViewItem(d->m_groups, group->name()); for(KoTemplate *t=group->first(); t!=0L; t=group->next()) { if(t->isHidden()) continue; (void)new TQListViewItem(groupItem, t->name()); } } } #include