/* This file is part of the KDE project Copyright (C) 2002 Nash Hoogwater 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; using version 2 of the License. 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 "KWFrameStyleManager.h" #include "KWFrameStyleManager.moc" #include "KWImportStyleDia.h" #include "KWDocument.h" #include "KWFrameDia.h" // for KWBrushStylePreview #include #include #include #include #include #include #include #include #include #include #include /******************************************************************/ /* Class: KWTableStylePreview */ /******************************************************************/ #undef ptToPx #define ptToPx tqRound void KWFrameStylePreview::paintEvent( TQPaintEvent * ) { int wid = ( width() - 20 ); int hei = ( height() - 20 ); TQPainter p; p.begin( this ); // 1: create borders if (frameStyle->topBorder().width()>0) { p.setPen( KoBorder::borderPen(frameStyle->topBorder(), ptToPx( frameStyle->topBorder().width() ), black) ); // Top border p.drawLine( 10 - int(frameStyle->leftBorder().width()/2), 10, 10 + wid + int(frameStyle->rightBorder().width()/2), 10 ); } if (frameStyle->leftBorder().width()>0) { p.setPen( KoBorder::borderPen(frameStyle->leftBorder(), ptToPx( frameStyle->leftBorder().width() ), black) ); // Left border p.drawLine( 10, 10 - int(frameStyle->topBorder().width()/2), 10 , 10 + hei + int(frameStyle->bottomBorder().width()/2) ); } if (frameStyle->bottomBorder().width()>0) { p.setPen( KoBorder::borderPen(frameStyle->bottomBorder(), ptToPx( frameStyle->bottomBorder().width() ), black) ); // Bottom border p.drawLine( 10 + wid + int(ceil(frameStyle->rightBorder().width()/2)), 10 + hei, 10 - int(frameStyle->leftBorder().width()/2), 10 + hei ); } if (frameStyle->rightBorder().width()>0) { p.setPen( KoBorder::borderPen(frameStyle->rightBorder(), ptToPx( frameStyle->rightBorder().width() ), black) ); // Right border p.drawLine( 10 + wid, 10 - int(frameStyle->topBorder().width()/2) , 10 + wid, 10 + hei + int(frameStyle->bottomBorder().width()/2) ); } // 2.1: create background p.fillRect( TQRect( TQPoint(10 + int(ceil(frameStyle->leftBorder().width()/2)), 10 + int(ceil(frameStyle->topBorder().width()/2))), TQPoint(10 + wid - int(floor(frameStyle->rightBorder().width()/2)+1), 10 + hei - int(floor(frameStyle->bottomBorder().width()/2)+1)) ), frameStyle->backgroundColor() ); p.end(); } void KWFrameStylePreview::setFrameStyle( KWFrameStyle *_frameStyle ) { if (!frameStyle) frameStyle = new KWFrameStyle("preview"); frameStyle = _frameStyle; repaint( true ); } /******************************************************************/ /* Class: KWFrameStyleListItem */ /******************************************************************/ KWFrameStyleListItem::~KWFrameStyleListItem() { delete m_changedFrameStyle; } void KWFrameStyleListItem::switchStyle() { delete m_changedFrameStyle; m_changedFrameStyle = 0; if ( m_origFrameStyle ) m_changedFrameStyle = new KWFrameStyle( *m_origFrameStyle ); } void KWFrameStyleListItem::deleteStyle( KWFrameStyle *current ) { Q_ASSERT( m_changedFrameStyle == current ); delete m_changedFrameStyle; m_changedFrameStyle = 0; } void KWFrameStyleListItem::apply() { *m_origFrameStyle = *m_changedFrameStyle; } /******************************************************************/ /* Class: KWFrameStyleManager */ /******************************************************************/ KWFrameStyleManager::KWFrameStyleManager( TQWidget *_parent, KWDocument *_doc, const TQString & activeStyleName ) : KDialogBase( _parent, "", true, i18n("Frame Style Manager"), KDialogBase::Ok | KDialogBase::Cancel | KDialogBase::Apply| KDialogBase::User1 ) { m_doc = _doc; m_currentFrameStyle = 0; noSignals=true; m_frameStyles.setAutoDelete(false); setupWidget(); // build the widget with the buttons and the list selector. addGeneralTab(); KWFrameStyleBordersTab *bordersTab = new KWFrameStyleBordersTab( m_tabs ); bordersTab->setWidget( new KoParagDecorationWidget( bordersTab ) ); addTab( bordersTab ); KWFrameStyleBackgroundTab *bgTab = new KWFrameStyleBackgroundTab( m_tabs ); addTab( bgTab ); TQListBoxItem * item = m_stylesList->findItem( activeStyleName ); m_stylesList->setCurrentItem( item ? m_stylesList->index(item) : 0 ); noSignals=false; switchStyle(); setInitialSize( TQSize( 600, 370 ) ); setButtonText( KDialogBase::User1, i18n("Import From File...") ); connect(this, TQ_SIGNAL(user1Clicked()), this, TQ_SLOT(importFromFile())); } KWFrameStyleManager::~KWFrameStyleManager() { m_frameStyles.setAutoDelete( true ); m_frameStyles.clear(); } void KWFrameStyleManager::addTab( KWFrameStyleManagerTab * tab ) { m_tabsList.append( tab ); m_tabs->insertTab( tab, tab->tabName() ); } void KWFrameStyleManager::setupWidget() { TQFrame * frame1 = makeMainWidget(); TQGridLayout *frame1Layout = new TQGridLayout( frame1, 0, 0, // auto 0, KDialog::spacingHint() ); KWFrameStyleCollection* collection = m_doc->frameStyleCollection(); numFrameStyles = collection->count(); m_stylesList = new TQListBox( frame1, "stylesList" ); m_stylesList->insertStringList( collection->displayNameList() ); const TQValueList styleList = collection->styleList(); for ( TQValueList::const_iterator it = styleList.begin(), end = styleList.end(); it != end ; ++it ) { KWFrameStyle* style = static_cast( *it ); m_frameStyles.append( new KWFrameStyleListItem( style, new KWFrameStyle(*style) ) ); m_styleOrder << style->name(); } Q_ASSERT( m_stylesList->count() == m_styleOrder.count() ); Q_ASSERT( m_styleOrder.count() == m_frameStyles.count() ); frame1Layout->addMultiCellWidget( m_stylesList, 0, 0, 0, 1 ); m_moveUpButton = new TQPushButton( frame1, "moveUpButton" ); m_moveUpButton->setIconSet( SmallIconSet( "go-up" ) ); connect( m_moveUpButton, TQ_SIGNAL( clicked() ), this, TQ_SLOT( moveUpStyle() ) ); frame1Layout->addWidget( m_moveUpButton, 1, 1 ); m_moveDownButton = new TQPushButton( frame1, "moveDownButton" ); m_moveDownButton->setIconSet( SmallIconSet( "go-down" ) ); connect( m_moveDownButton, TQ_SIGNAL( clicked() ), this, TQ_SLOT( moveDownStyle() ) ); frame1Layout->addWidget( m_moveDownButton, 1, 0 ); m_deleteButton = new TQPushButton( frame1, "deleteButton" ); m_deleteButton->setText( i18n( "&Delete" ) ); connect( m_deleteButton, TQ_SIGNAL( clicked() ), this, TQ_SLOT( deleteStyle() ) ); frame1Layout->addWidget( m_deleteButton, 2, 1 ); m_newButton = new TQPushButton( frame1, "newButton" ); m_newButton->setText( i18n( "New" ) ); connect( m_newButton, TQ_SIGNAL( clicked() ), this, TQ_SLOT( addStyle() ) ); frame1Layout->addWidget( m_newButton, 2, 0 ); m_tabs = new TQTabWidget( frame1 ); frame1Layout->addMultiCellWidget( m_tabs, 0, 2, 2, 2 ); connect( m_stylesList, TQ_SIGNAL( selectionChanged() ), this, TQ_SLOT( switchStyle() ) ); connect( m_tabs, TQ_SIGNAL( currentChanged ( TQWidget * ) ), this, TQ_SLOT( switchTabs() ) ); } void KWFrameStyleManager::addGeneralTab() { TQWidget *tab = new TQWidget( m_tabs ); TQGridLayout *tabLayout = new TQGridLayout( tab ); tabLayout->setSpacing( KDialog::spacingHint() ); tabLayout->setMargin( KDialog::marginHint() ); previewBox = new TQGroupBox( 0, TQt::Vertical, i18n( "Preview" ), tab ); previewBox->layout()->setSpacing(KDialog::spacingHint()); previewBox->layout()->setMargin(KDialog::marginHint()); TQGridLayout *previewLayout = new TQGridLayout( previewBox->layout() ); preview = new KWFrameStylePreview( previewBox ); preview->resize(preview->sizeHint()); previewLayout->addWidget( preview, 0, 0 ); tabLayout->addMultiCellWidget( previewBox, 1, 1, 0, 1 ); m_nameString = new TQLineEdit( tab ); m_nameString->resize(m_nameString->sizeHint() ); connect( m_nameString, TQ_SIGNAL( textChanged( const TQString &) ), this, TQ_SLOT( renameStyle(const TQString &) ) ); tabLayout->addWidget( m_nameString, 0, 1 ); TQLabel *nameLabel = new TQLabel( tab ); nameLabel->setText( i18n( "Name:" ) ); nameLabel->resize(nameLabel->sizeHint()); nameLabel->setAlignment( AlignRight | AlignVCenter ); tabLayout->addWidget( nameLabel, 0, 0 ); m_tabs->insertTab( tab, i18n( "General" ) ); } void KWFrameStyleManager::switchStyle() { kdDebug() << "KWFrameStyleManager::switchStyle noSignals=" << noSignals << endl; if(noSignals) return; noSignals=true; if(m_currentFrameStyle !=0L) save(); m_currentFrameStyle = 0L; int num = frameStyleIndex( m_stylesList->currentItem() ); kdDebug() << "KWFrameStyleManager::switchStyle switching to " << num << endl; if( m_frameStyles.at(num)->origFrameStyle() == m_frameStyles.at(num)->changedFrameStyle() ) m_frameStyles.at(num)->switchStyle(); else m_currentFrameStyle = m_frameStyles.at(num)->changedFrameStyle(); updateGUI(); noSignals=false; } void KWFrameStyleManager::switchTabs() { save(); updatePreview(); } int KWFrameStyleManager::frameStyleIndex( int pos ) { int p = 0; for(unsigned int i=0; i < m_frameStyles.count(); i++) { // Skip deleted styles, they're no in m_stylesList anymore KWFrameStyle * style = m_frameStyles.at(i)->changedFrameStyle(); if ( !style ) continue; if ( p == pos ) return i; ++p; } kdWarning() << "KWFrameStyleManager::frameStyleIndex no style found at pos " << pos << " count=" << m_frameStyles.count() << endl; #ifdef __GNUC_ #warning implement undo/redo #endif return 0; } void KWFrameStyleManager::updateGUI() { kdDebug() << "KWFrameStyleManager::updateGUI m_currentFrameStyle=" << m_currentFrameStyle << " " << m_currentFrameStyle->name() << endl; TQPtrListIterator it( m_tabsList ); for ( ; it.current() ; ++it ) { it.current()->setStyle( m_currentFrameStyle ); it.current()->update(); } m_nameString->setText(m_currentFrameStyle->displayName()); // update delete button (can't delete first style); m_deleteButton->setEnabled(m_stylesList->currentItem() != 0); m_moveUpButton->setEnabled(m_stylesList->currentItem() != 0); m_moveDownButton->setEnabled(m_stylesList->currentItem()!=(int)m_stylesList->count()-1); updatePreview(); } void KWFrameStyleManager::updatePreview() { preview->setFrameStyle(m_currentFrameStyle); } void KWFrameStyleManager::save() { if(m_currentFrameStyle) { // save changes from UI to object. TQPtrListIterator it( m_tabsList ); for ( ; it.current() ; ++it ) it.current()->save(); m_currentFrameStyle->setDisplayName( m_nameString->text() ); } } void KWFrameStyleManager::importFromFile() { // ## why not just use collection->displayNameList()? TQStringList lst; for ( int i = 0; i<(int)m_stylesList->count();i++) { lst << m_stylesList->text(i); } KWImportFrameTableStyleDia dia( m_doc, lst, KWImportFrameTableStyleDia::frameStyle, this, 0 ); if ( dia.listOfFrameStyleImported().count() > 0 && dia.exec() ) { addStyles( dia.listOfFrameStyleImported() ); } } void KWFrameStyleManager::addStyles( const TQPtrList &listStyle ) { save(); TQPtrListIterator style( listStyle ); for ( ; style.current() ; ++style ) { noSignals=true; m_stylesList->insertItem( style.current()->displayName() ); m_frameStyles.append( new KWFrameStyleListItem( 0L,new KWFrameStyle(*style.current())) ); m_styleOrder<name(); noSignals=false; } updateGUI(); } void KWFrameStyleManager::addStyle() { save(); TQString str = i18n( "New Framestyle Template (%1)" ).arg(numFrameStyles++); if ( m_currentFrameStyle ) { m_currentFrameStyle = new KWFrameStyle( *m_currentFrameStyle ); // Create a new style, initializing from the current one m_currentFrameStyle->setDisplayName( str ); m_currentFrameStyle->setName( m_doc->frameStyleCollection()->generateUniqueName() ); } else m_currentFrameStyle = new KWFrameStyle( str ); noSignals=true; m_frameStyles.append(new KWFrameStyleListItem(0L,m_currentFrameStyle)); m_stylesList->insertItem( str ); m_styleOrder<< str; m_stylesList->setCurrentItem( m_stylesList->count() - 1 ); noSignals=false; updateGUI(); } void KWFrameStyleManager::deleteStyle() { unsigned int cur = frameStyleIndex( m_stylesList->currentItem() ); m_styleOrder.remove( m_stylesList->currentText()); if ( !m_frameStyles.at(cur)->origFrameStyle() ) m_frameStyles.take(cur ); else { m_frameStyles.at( cur )->deleteStyle( m_currentFrameStyle ); m_currentFrameStyle = 0L; } // Adjust GUI m_stylesList->removeItem(m_stylesList->currentItem()); numFrameStyles--; m_stylesList->setSelected( m_stylesList->currentItem(), true ); } void KWFrameStyleManager::moveUpStyle() { if(m_currentFrameStyle !=0L) save(); unsigned int pos = 0; TQString currentStyleName = m_stylesList->currentText(); if ( currentStyleName.isEmpty() ) return; int pos2 = m_styleOrder.findIndex( currentStyleName ); if ( pos2 > 0 ) // neither -1 nor 0 { m_styleOrder.remove( m_styleOrder.at(pos2)); m_styleOrder.insert( m_styleOrder.at(pos2-1), currentStyleName); } pos=m_stylesList->currentItem(); noSignals=true; m_stylesList->changeItem( m_stylesList->text ( pos-1 ),pos); m_stylesList->changeItem( currentStyleName ,pos-1); m_stylesList->setCurrentItem( m_stylesList->currentItem() ); noSignals=false; updateGUI(); } void KWFrameStyleManager::moveDownStyle() { if(m_currentFrameStyle !=0L) save(); unsigned int pos = 0; TQString currentStyleName=m_stylesList->currentText (); if ( currentStyleName.isEmpty() ) return; int pos2 = m_styleOrder.findIndex( currentStyleName ); if ( pos2 != -1 ) { m_styleOrder.remove( m_styleOrder.at(pos2)); m_styleOrder.insert( m_styleOrder.at(pos2+1), currentStyleName); } pos=m_stylesList->currentItem(); noSignals=true; m_stylesList->changeItem( m_stylesList->text ( pos+1 ),pos); m_stylesList->changeItem( currentStyleName ,pos+1); m_stylesList->setCurrentItem( m_stylesList->currentItem() ); noSignals=false; updateGUI(); } void KWFrameStyleManager::slotOk() { save(); apply(); KDialogBase::slotOk(); } void KWFrameStyleManager::slotApply() { save(); apply(); KDialogBase::slotApply(); } void KWFrameStyleManager::apply() { // ##### missing: undo/redo support noSignals=true; for (unsigned int i =0 ; i < m_frameStyles.count() ; i++) { if(m_frameStyles.at(i)->origFrameStyle() == 0) { // newly added style kdDebug() << "adding new " << m_frameStyles.at(i)->changedFrameStyle()->name() << " (" << i << ")" << endl; KWFrameStyle* style = m_doc->frameStyleCollection()->addStyle(m_frameStyles.take(i)->changedFrameStyle()); m_frameStyles.insert( i, new KWFrameStyleListItem(0, style) ); } else if(m_frameStyles.at(i)->changedFrameStyle() == 0) { // deleted style kdDebug() << "deleting orig " << m_frameStyles.at(i)->origFrameStyle()->name() << " (" << i << ")" << endl; KWFrameStyle *orig = m_frameStyles.at(i)->origFrameStyle(); m_doc->frameStyleCollection()->removeStyle( orig ); } else { kdDebug() << "update style " << m_frameStyles.at(i)->changedFrameStyle()->name() << " (" << i << ")" << endl; // TODO check if modified, so that we can do m_doc->setModified(true) only if a style was changed m_frameStyles.at(i)->apply(); } } m_doc->frameStyleCollection()->updateStyleListOrder( m_styleOrder ); m_doc->updateAllFrameStyleLists(); m_doc->setModified( true ); noSignals=false; } void KWFrameStyleManager::renameStyle(const TQString &theText) { if(noSignals) return; noSignals=true; int index = m_stylesList->currentItem(); kdDebug() << "KWFrameStyleManager::renameStyle " << index << " to " << theText << endl; // rename only in the GUI, not even in the underlying objects (save() does it). m_stylesList->changeItem( theText, index ); m_styleOrder[index]=theText; // Check how many styles with that name we have now int synonyms = 0; for ( uint i = 0; i < m_stylesList->count(); i++ ) { if ( m_stylesList->text( i ) == m_stylesList->currentText() ) ++synonyms; } Q_ASSERT( synonyms > 0 ); // should have found 'index' at least ! noSignals=false; // Can't close the dialog if two styles have the same name bool state=!theText.isEmpty() && (synonyms == 1); enableButtonOK(state ); enableButtonApply(state); m_deleteButton->setEnabled(state&&(m_stylesList->currentItem() != 0)); m_newButton->setEnabled(state); m_stylesList->setEnabled( state ); enableButton( KDialogBase::User1, state ); if ( state ) { m_moveUpButton->setEnabled(m_stylesList->currentItem() != 0); m_moveDownButton->setEnabled(m_stylesList->currentItem()!=(int)m_stylesList->count()-1); } else { m_moveUpButton->setEnabled(false); m_moveDownButton->setEnabled(false); } } /******************************************************************/ /* Class: KWFrameStyleBackgroundTab */ /******************************************************************/ KWFrameStyleBackgroundTab::KWFrameStyleBackgroundTab( TQWidget * parent ) : KWFrameStyleManagerTab( parent ) { bgwidget = this; m_backgroundColor.setStyle( TQt::SolidPattern ); grid = new TQGridLayout( bgwidget, 7, 2, KDialog::marginHint(), KDialog::spacingHint() ); int row=0; brushPreview = new KWBrushStylePreview( bgwidget ); grid->addMultiCellWidget(brushPreview,row,5,1,1); TQLabel *l = new TQLabel( i18n( "Frame background color:" ), bgwidget ); grid->addWidget(l,row++,0); brushColor = new KColorButton( TQt::white, bgwidget ); grid->addWidget(brushColor,row++,0); connect( brushColor, TQ_SIGNAL( changed( const TQColor & ) ), this, TQ_SLOT( updateBrushConfiguration( const TQColor & ) ) ); TQSpacerItem* spacer = new TQSpacerItem( 10, 10, TQSizePolicy::Minimum, TQSizePolicy::Expanding); grid->addItem( spacer,row,0 ); updateBrushConfiguration( TQt::white ); } void KWFrameStyleBackgroundTab::updateBrushConfiguration( const TQColor & _color ) { m_backgroundColor.setColor( _color ); brushPreview->show(); brushPreview->setBrush( m_backgroundColor ); brushPreview->repaint(true); } TQString KWFrameStyleBackgroundTab::tabName() { return i18n("Background"); } void KWFrameStyleBackgroundTab::update() { brushColor->setColor( m_style->backgroundColor().color() ); updateBrushConfiguration( m_style->backgroundColor().color() ); } void KWFrameStyleBackgroundTab::save() { m_style->setBackgroundColor( m_backgroundColor ); } /******************************************************************/ /* Class: KWFrameStyleBordersTab */ /******************************************************************/ KWFrameStyleBordersTab::KWFrameStyleBordersTab( TQWidget * parent ) : KWFrameStyleManagerTab( parent ) { m_widget = 0L; m_borders = new KoParagLayout(); } KWFrameStyleBordersTab::~KWFrameStyleBordersTab() { delete m_borders; } TQString KWFrameStyleBordersTab::tabName() { return m_widget->tabName(); } void KWFrameStyleBordersTab::update() { m_borders->leftBorder = m_style->leftBorder(); m_borders->rightBorder = m_style->rightBorder(); m_borders->topBorder = m_style->topBorder(); m_borders->bottomBorder = m_style->bottomBorder(); m_widget->display( *m_borders ); } void KWFrameStyleBordersTab::save() { m_widget->save( *m_borders ); m_style->setLeftBorder( m_borders->leftBorder ); m_style->setRightBorder( m_borders->rightBorder ); m_style->setTopBorder( m_borders->topBorder ); m_style->setBottomBorder( m_borders->bottomBorder ); } void KWFrameStyleBordersTab::setWidget( KoParagLayoutWidget * widget ) { m_widget = widget; } void KWFrameStyleBordersTab::resizeEvent( TQResizeEvent *e ) { TQWidget::resizeEvent( e ); if ( m_widget ) m_widget->resize( size() ); }