23 #include "kopetebehaviorsettings.h"
32 #include <QVBoxLayout>
34 #include <kdeversion.h>
35 #include <kinputdialog.h>
37 #include <kcolorcombo.h>
38 #include <kcolorbutton.h>
40 #include <kfontrequester.h>
41 #include <kpluginfactory.h>
42 #include <kio/netaccess.h>
43 #include <khtmlview.h>
44 #include <klineedit.h>
46 #include <kmessagebox.h>
47 #include <kpushbutton.h>
48 #include <kstandarddirs.h>
49 #include <kurlrequesterdialog.h>
51 #include <kfiledialog.h>
53 #include <kemoticons.h>
54 #include <KCMultiDialog>
57 #include <knewstuff2/engine.h>
63 #include <kopetecontactlist.h>
67 #include <kopeteprotocol.h>
68 #include <kopetemetacontact.h>
69 #include <kopeteaccount.h>
70 #include <kopeteidentity.h>
71 #include <kopetecontact.h>
72 #include <kopetemessage.h>
73 #include <kopetechatsession.h>
74 #include <kopetechatsessionmanager.h>
75 #include <kopetestatusmessage.h>
76 #include <kopeteappearancesettings.h>
78 #include "kopeteemoticons.h"
80 #include "kopeteglobal.h"
85 registerPlugin<ChatWindowConfig>(); )
86 K_EXPORT_PLUGIN( KopeteChatWindowConfigFactory(
"kcm_kopete_chatwindowconfig") )
90 class FakeContact : public Kopete::Contact
94 virtual Kopete::ChatSession *
manager(Kopete::Contact::CanCreateFlags ) {
return 0L; }
99 class FakeProtocol :
public Kopete::Protocol
102 FakeProtocol(
const KComponentData &instance,
QObject *parent ) : Kopete::Protocol(instance, parent){}
103 Kopete::Account* createNewAccount(
const QString & ){
return 0L;}
104 AddContactPage* createAddContactWidget(
QWidget *, Kopete::Account *){
return 0L;}
105 KopeteEditAccountWidget* createEditAccountWidget( Kopete::Account *,
QWidget *){
return 0L;}
109 class FakeIdentity :
public Kopete::Identity
112 FakeIdentity() : Kopete::Identity(
"Preview Identity") {};
116 class FakeAccount :
public Kopete::Account
119 FakeAccount(Kopete::Protocol *parent,
const QString &accountID) : Kopete::Account(parent, accountID)
121 m_identity =
new FakeIdentity();
122 setIdentity(m_identity);
125 void setMyself(Kopete::Contact *myself)
127 Kopete::Account::setMyself(myself);
136 void connect(
const Kopete::OnlineStatus& ){}
138 void setOnlineStatus(
const Kopete::OnlineStatus& ,
const Kopete::StatusMessage &,
const OnlineStatusOptions&){}
139 void setStatusMessage(
const Kopete::StatusMessage& ){}
142 FakeIdentity *m_identity;
146 :
KCModule( KopeteChatWindowConfigFactory::componentData(), parent, args ),
147 m_currentStyle (0L), m_loading(false),
148 m_previewProtocol(0L), m_previewAccount(0L),
149 m_jackMetaContact(0L), m_myself(0L), m_jack(0L)
151 KConfigGroup config(KGlobal::config(),
"ChatWindowSettings");
161 m_styleUi.setupUi(styleWidget);
162 m_tab->
addTab(styleWidget, i18n(
"&Style"));
165 connect(m_styleUi.styleList, SIGNAL(currentTextChanged(
QString)),
166 this, SLOT(slotChatStyleSelected(
QString)));
167 connect(m_styleUi.variantList, SIGNAL(activated(
QString)),
168 this, SLOT(slotChatStyleVariantSelected(
QString)));
169 connect(m_styleUi.deleteButton, SIGNAL(clicked()),
170 this, SLOT(slotDeleteChatStyle()));
171 connect(m_styleUi.installButton, SIGNAL(clicked()),
172 this, SLOT(slotInstallChatStyle()));
173 connect(m_styleUi.btnGetStyles, SIGNAL(clicked()),
174 this, SLOT(slotGetChatStyles()));
176 m_styleUi.deleteButton->setIcon(KIcon(
"edit-delete"));
177 m_styleUi.installButton->setIcon(KIcon(
"document-import"));
178 m_styleUi.btnGetStyles->setIcon(KIcon(
"get-hot-new-stuff"));
184 createPreviewChatSession();
185 m_preview =
new ChatMessagePart(m_previewChatSession, m_styleUi.htmlFrame);
186 m_preview->setJScriptEnabled(
false);
187 m_preview->setJavaEnabled(
false);
188 m_preview->setPluginsEnabled(
false);
189 m_preview->setMetaRefreshEnabled(
false);
190 KHTMLView *htmlWidget = m_preview->view();
191 htmlWidget->setMarginWidth(4);
192 htmlWidget->setMarginHeight(4);
193 htmlWidget->setFocusPolicy(Qt::NoFocus);
194 htmlWidget->setSizePolicy(
195 QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
199 m_styleUi.htmlFrame->setLayout(layout);
201 createPreviewMessages();
206 m_emoticonsUi.setupUi(emoticonsWidget);
207 m_tab->
addTab(emoticonsWidget, i18n(
"&Emoticons"));
210 addConfig( Kopete::AppearanceSettings::self(), emoticonsWidget );
212 connect(m_emoticonsUi.icon_theme_list, SIGNAL(itemSelectionChanged()),
213 this, SLOT(emitChanged()));
215 connect(m_emoticonsUi.btnManageThemes, SIGNAL(clicked()),
216 this, SLOT(slotManageEmoticonThemes()));
220 m_colorsUi.setupUi(colorsWidget);
221 m_tab->
addTab(colorsWidget, i18n(
"Colors && Fonts"));
222 addConfig( Kopete::AppearanceSettings::self(), colorsWidget );
226 m_tabUi.setupUi(tabWidget);
227 m_tab->
addTab(tabWidget, i18n(
"&Tabs"));
228 addConfig( Kopete::BehaviorSettings::self(), tabWidget );
235 if (m_previewChatSession)
237 Kopete::ChatSessionManager::self()->removeSession(m_previewChatSession);
241 delete m_previewAccount;
243 delete m_jackMetaContact;
245 delete m_previewProtocol;
259 kDebug(14000) << m_currentStyle->getStyleName();
260 settings->
setStyleName( m_currentStyle->getStyleName() );
263 if( !m_currentVariantMap.
empty() )
265 kDebug(14000) << m_currentVariantMap[ m_styleUi.variantList->currentText()];
266 settings->
setStyleVariant( m_currentVariantMap[m_styleUi.variantList->currentText()] );
269 Kopete::AppearanceSettings *appearanceSettings = Kopete::AppearanceSettings::self();
273 KEmoticons::setTheme( item->
text() );
276 appearanceSettings->setChatTextColor(m_colorsUi.kcfg_chatTextColor->color());
277 appearanceSettings->setUseEmoticons(m_emoticonsUi.kcfg_useEmoticons->isChecked());
280 appearanceSettings->writeConfig();
281 settings->writeConfig();
295 slotLoadChatStyles();
298 updateEmoticonList();
301 slotUpdateChatPreview();
304 void ChatWindowConfig::slotLoadChatStyles()
306 m_styleUi.styleList->clear();
310 if( availableStyles.
empty() )
311 kDebug(14000) <<
"Warning, available styles is empty !";
313 foreach(
const QString& styleName, availableStyles )
316 m_styleUi.styleList->insertItem( 0, styleName );
319 m_styleUi.styleList->setSortingEnabled(
true );
322 QList<QListWidgetItem *> items = m_styleUi.styleList->findItems( currentStyle, Qt::MatchFixedString | Qt::MatchCaseSensitive );
323 if( items.
count() > 0 )
325 kDebug(14000) <<
"Restoring saved style: " << currentStyle;
327 m_styleUi.styleList->setCurrentItem( items[0] );
328 m_styleUi.styleList->scrollToItem( items[0] );
333 void ChatWindowConfig::slotChatStyleSelected(
const QString &styleName)
342 m_currentVariantMap = m_currentStyle->getVariants();
343 kDebug(14000) <<
"Loading style: " << m_currentStyle->getStyleName();
346 m_styleUi.variantList->clear();
351 m_styleUi.variantList->addItem( i18n(
"(No Variant)") );
354 int currentIndex = 0;
355 for(it = m_currentVariantMap.
constBegin(); it != itEnd; ++it)
358 m_styleUi.variantList->addItem( it.key() );
361 m_styleUi.variantList->setCurrentIndex(currentIndex+1);
367 slotUpdateChatPreview();
370 if( !m_currentVariantMap.
empty() ) {
372 m_styleUi.kcfg_useCompact->setEnabled(m_currentStyle->hasCompact(
QString() ) );
378 m_styleUi.variantList->clear();
379 slotUpdateChatPreview();
383 void ChatWindowConfig::slotChatStyleVariantSelected(
const QString &variantName)
390 QString styleName = m_styleUi.styleList->currentItem()->text();
392 if ( !m_currentStyle )
395 if ( m_styleUi.variantList->currentIndex() == 0 ) {
396 m_styleUi.kcfg_useCompact->setEnabled(m_currentStyle->hasCompact(
"" ) );
399 m_styleUi.kcfg_useCompact->setEnabled(m_currentStyle->hasCompact( variantName ) );
406 void ChatWindowConfig::slotInstallChatStyle()
408 KUrl styleUrl = KFileDialog::getOpenUrl( KUrl(),
QString::fromUtf8(
"application/zip application/x-compressed-tar application/x-bzip-compressed-tar"),
this, i18n(
"Choose Chat Window Style to Install") );
410 if ( styleUrl.isEmpty() )
413 int styleInstallReturn = installChatStyle( styleUrl );
415 switch(styleInstallReturn)
419 KMessageBox::queuedMessageBox(
this, KMessageBox::Error, i18n(
"The specified archive cannot be opened.\nMake sure that the archive is a valid ZIP or TAR archive."), i18n(
"Cannot Open Archive") );
424 KMessageBox::queuedMessageBox(
this, KMessageBox::Error, i18n(
"Could not find a suitable place to install the chat window style."), i18n(
"Cannot Find Styles Directory") );
428 KMessageBox::queuedMessageBox(
this, KMessageBox::Error, i18n(
"The specified archive does not contain a valid chat window style."), i18n(
"Invalid Style") );
432 KMessageBox::queuedMessageBox(
this, KMessageBox::Information, i18n(
"The chat window style was successfully installed."), i18n(
"Install Successful") );
438 KMessageBox::queuedMessageBox(
this, KMessageBox::Error, i18n(
"An unknown error occurred while trying to install the chat window style."), i18n(
"Unknown Error") );
444 int ChatWindowConfig::installChatStyle(
const KUrl &styleToInstall)
448 if( !styleToInstall.isEmpty() )
451 if( KIO::NetAccess::download( styleToInstall, stylePath,
this ) )
456 KIO::NetAccess::removeTempFile( stylePath );
460 return styleInstallReturn;
463 void ChatWindowConfig::slotDeleteChatStyle()
465 if (!m_styleUi.styleList->currentItem())
470 QString styleName = m_styleUi.styleList->currentItem()->text();
473 KMessageBox::queuedMessageBox(
this, KMessageBox::Information, i18nc(
"@info",
"The Chat Window Style <resource>%1</resource> was successfully deleted.", styleName));
478 KMessageBox::queuedMessageBox(
this, KMessageBox::Sorry, i18nc(
"@info",
"An error occurred while trying to delete the <resource>%1</resource> Chat Window Style. Your account might not have permission to remove it.", styleName));
480 slotUpdateChatPreview();
483 void ChatWindowConfig::slotGetChatStyles()
485 KConfigGroup configGrp(KGlobal::config(),
"KNewStuff2");
486 configGrp.writeEntry(
"ProvidersUrl",
"http://download.kde.org/khotnewstuff/kopetestyles12-providers.xml");
487 configGrp.writeEntry(
"TargetDir",
"kopete_chatstyles");
490 KNS::Engine *engine =
new KNS::Engine();
491 engine->init(configGrp.config()->name());
496 KGlobal::setActiveComponent(KopeteChatWindowConfigFactory::componentData());
498 KNS::Entry::List entries = engine->downloadDialogModal(
this);
500 if ( entries.size() > 0 )
502 int correctlyInstalled(0);
503 foreach( KNS::Entry* entry, entries )
505 if ( entry->status() == KNS::Entry::Installed && entry->installedFiles().size() > 0 )
507 KUrl styleFile( entry->installedFiles().at(0) );
508 int result = installChatStyle( styleFile );
510 QString packageName(entry->name().representation());
511 QString errorTitle = i18nc(
"@title:window",
"Chat Window Style <resource>%1</resource> installation", packageName);
516 KMessageBox::queuedMessageBox(
this, KMessageBox::Error, i18nc(
"@info",
"The specified archive <filename>%1</filename> cannot be opened.\nMake sure that the archive is a valid ZIP or TAR archive.", styleFile.pathOrUrl()), errorTitle);
521 KMessageBox::queuedMessageBox(
this, KMessageBox::Error, i18nc(
"@info",
"Could not find a suitable place to install the Chat Window Style <resource>%1</resource>.", packageName), errorTitle );
525 KMessageBox::queuedMessageBox(
this, KMessageBox::Error, i18nc(
"@info",
"The specified archive <filename>%1</filename> does not contain a valid Chat Window Style.", styleFile.pathOrUrl()), errorTitle );
529 ++correctlyInstalled;
535 KMessageBox::queuedMessageBox(
this, KMessageBox::Error, i18nc(
"@info",
"An unknown error occurred while trying to install the Chat Window Style <resource>%1</resource>.", packageName), errorTitle );
542 if ( correctlyInstalled > 0)
544 KMessageBox::queuedMessageBox(
this, KMessageBox::Information, i18np(
"One Chat Window Style package has been installed.",
"%1 Chat Window Style packages have been installed.", correctlyInstalled));
551 void ChatWindowConfig::createPreviewChatSession()
553 m_previewProtocol =
new FakeProtocol( KComponentData(
QByteArray(
"kopete-preview-chatwindowstyle")), 0 ); m_previewProtocol->setObjectName(
QLatin1String(
"kopete-preview-chatwindowstyle") );
554 m_previewAccount =
new FakeAccount(m_previewProtocol,
QString(
"previewaccount"));
556 m_myself =
new FakeContact(m_previewAccount, i18nc(
"This is the myself preview contact id",
"myself@preview"), Kopete::ContactList::self()->myself());
557 m_myself->setNickName(i18nc(
"This is the myself preview contact nickname",
"Myself"));
560 m_jackMetaContact->setTemporary();
561 m_jackMetaContact->setDisplayName(i18n(
"Jack"));
562 m_jackMetaContact->setDisplayNameSource(Kopete::MetaContact::SourceCustom);
564 m_jack =
new FakeContact(m_previewAccount, i18nc(
"This is the other preview contact id",
"jack@preview"), m_jackMetaContact);
565 m_jack->setNickName(i18nc(
"This is the other preview contact nickname",
"Jack"));
567 m_previewAccount->setMyself(m_myself);
570 contactList.
append(m_jack);
572 m_previewChatSession = Kopete::ChatSessionManager::self()->create(m_myself, contactList, m_previewProtocol);
573 m_previewChatSession->setDisplayName(i18nc(
"preview of a chat session",
"Preview Session"));
576 void ChatWindowConfig::createPreviewMessages()
578 Kopete::Message msgIn( m_jack,m_myself );
579 msgIn.setPlainBody( i18n(
"Hello, this is an incoming message :-)" ) );
580 msgIn.setDirection( Kopete::Message::Inbound );
582 Kopete::Message msgIn2( m_jack, m_myself );
583 msgIn2.setPlainBody( i18n(
"Hello, this is an incoming consecutive message." ) );
584 msgIn2.setDirection( Kopete::Message::Inbound );
586 Kopete::Message msgOut( m_myself, m_jack );
587 msgOut.setPlainBody( i18n(
"Ok, this is an outgoing message" ) );
588 msgOut.setDirection( Kopete::Message::Outbound );
590 Kopete::Message msgOut2( m_myself, m_jack );
591 msgOut2.setPlainBody( i18n(
"Ok, an outgoing consecutive message." ) );
592 msgOut2.setDirection( Kopete::Message::Outbound );
594 Kopete::Message msgOut3( m_myself, m_jack );
595 msgOut3.setPlainBody( i18n(
"Message that is being sent." ) );
596 msgOut3.setDirection( Kopete::Message::Outbound );
597 msgOut3.setState( Kopete::Message::StateSending );
599 Kopete::Message msgOut4( m_myself, m_jack );
600 msgOut4.setPlainBody( i18n(
"Delivered message." ) );
601 msgOut4.setDirection( Kopete::Message::Outbound );
602 msgOut4.setState( Kopete::Message::StateSent );
604 Kopete::Message msgOut5( m_myself, m_jack );
605 msgOut5.setPlainBody( i18n(
"Message that cannot be delivered." ) );
606 msgOut5.setDirection( Kopete::Message::Outbound );
607 msgOut5.setState( Kopete::Message::StateError );
609 Kopete::Message msgCol( m_jack, m_myself );
610 msgCol.setPlainBody( i18n(
"Here is an incoming colored message.") );
611 msgCol.setDirection( Kopete::Message::Inbound );
612 msgCol.setForegroundColor(
QColor(
"DodgerBlue" ) );
613 msgCol.setBackgroundColor(
QColor(
"LightSteelBlue" ) );
615 Kopete::Message msgInt( m_jack, m_myself );
616 msgInt.setPlainBody( i18n(
"This is an internal message" ) );
617 msgInt.setDirection( Kopete::Message::Internal );
619 Kopete::Message msgAct( m_jack, m_myself );
620 msgAct.setPlainBody( i18n(
"performed an action" ) );
621 msgAct.setType( Kopete::Message::TypeAction );
622 msgAct.setDirection( Kopete::Message::Inbound );
624 Kopete::Message msgHigh( m_jack, m_myself );
625 msgHigh.setPlainBody( i18n(
"This is a highlighted message" ) );
626 msgHigh.setDirection( Kopete::Message::Inbound );
627 msgHigh.setImportance( Kopete::Message::Highlight );
629 Kopete::Message msgFTRequest( m_jack, m_myself );
630 msgFTRequest.setPlainBody( i18n(
"Hello, this is an incoming file transfer request" ) );
631 msgFTRequest.setDirection( Kopete::Message::Inbound );
632 msgFTRequest.setType( Kopete::Message::TypeFileTransferRequest );
633 msgFTRequest.setFileName(
"data.pdf" );
634 msgFTRequest.setFileSize( 10000000 );
636 Kopete::Message msgFTRequestDisabled( m_jack, m_myself );
637 msgFTRequestDisabled.setPlainBody( i18n(
"Hello, this is a disabled incoming file transfer request" ) );
638 msgFTRequestDisabled.setDirection( Kopete::Message::Inbound );
639 msgFTRequestDisabled.setType( Kopete::Message::TypeFileTransferRequest );
640 msgFTRequestDisabled.setFileName(
"data.pdf" );
641 msgFTRequestDisabled.setFileSize( 10000000 );
642 msgFTRequestDisabled.setFileTransferDisabled(
true );
645 Kopete::Message msgRightToLeft( m_myself, m_jack );
646 msgRightToLeft.setPlainBody( i18nc(
"This special UTF-8 string is to test if the style supports Right-to-Left language display.",
"הודעות טקסט") );
647 msgRightToLeft.setDirection( Kopete::Message::Outbound );
649 Kopete::Message msgBye ( m_myself, m_jack );
650 msgBye.setPlainBody( i18n(
"Bye") );
651 msgBye.setDirection( Kopete::Message::Outbound );
671 void ChatWindowConfig::slotUpdateChatPreview()
677 m_preview->
setStyle(m_currentStyle);
683 void ChatWindowConfig::updateEmoticonList()
687 m_emoticonsUi.icon_theme_list->clear();
689 QStringList themeDirs = KGlobal::dirs()->findDirs(
"emoticons",
"");
691 for(
int x = 0;x < themeDirs.
count();x++)
693 QDir themeQDir(themeDirs[x]);
694 themeQDir.setFilter( QDir::Dirs );
695 themeQDir.setSorting( QDir::Name );
696 for(
unsigned int y = 0; y < themeQDir.count(); y++)
698 QStringList themes = themeQDir.entryList(QDir::Dirs, QDir::Name);
701 if ( themeQDir[y] !=
"." && themeQDir[y] !=
".." )
705 m_emoticonsUi.icon_theme_list->addItem(item);
712 QList<QListWidgetItem*> items = m_emoticonsUi.icon_theme_list->findItems( KEmoticons::currentThemeName(), Qt::MatchExactly );
715 m_emoticonsUi.icon_theme_list->setCurrentItem( items.
first() );
717 m_emoticonsUi.icon_theme_list->setCurrentItem( 0 );
721 void ChatWindowConfig::slotManageEmoticonThemes()
726 KGlobal::setActiveComponent(KopeteChatWindowConfigFactory::componentData());
728 KCMultiDialog *kcm =
new KCMultiDialog(
this );
729 kcm->setCaption( i18n(
"Configure Emoticon Themes" ) );
730 kcm->addModule(
"emoticons" );
732 updateEmoticonList();
736 void ChatWindowConfig::emitChanged()
738 emit changed(
true );
741 #include "chatwindowconfig.moc"
static void setStyleVariant(const QString &v)
Set Relative path to a CSS variant for the current style.
void setStyleVariant(const QString &variantPath)
Change the current variant for the current style.
void setContentsMargins(int left, int top, int right, int bottom)
void appendMessage(Kopete::Message &message, bool restoring=false)
Appends a message to the messave view.
static ChatWindowStyleManager * self()
Singleton access to this class.
virtual Kopete::ChatSession * manager(Kopete::Contact::CanCreateFlags)
static void setStyleName(const QString &v)
Set Name of a Adium/Kopete chat window style.
int installStyle(const QString &styleBundlePath)
Install a new style into user style directory Note that you must pass a path to a archive...
static KopeteChatWindowSettings * self()
void setStyle(const QString &styleName)
Change the current style.
int count(const T &value) const
void append(const T &value)
QString fromUtf8(const char *str, int size)
const_iterator constEnd() const
ChatWindowStyle * getStyleFromPool(const QString &styleName)
Get a instance of a ChatWindowStyle from the pool.
void setMargin(int margin)
static QString styleVariant()
Get Relative path to a CSS variant for the current style.
K_PLUGIN_FACTORY(KopeteChatWindowConfigFactory, registerPlugin< ChatWindowConfig >();) class FakeContact
const_iterator constBegin() const
static QString styleName()
Get Name of a Adium/Kopete chat window style.
QStringList getAvailableStyles() const
Get all available styles.
virtual void slotUserInfo()
ChatWindowConfig(QWidget *parent, const QVariantList &args)
static void setChatFmtOverride(bool v)
Set Disable custom formatting set by users.